Aug-30-2022, 12:42 AM
Anchor in my code. Is using pygame rect position. "topleft", "midleft", "center", so on.
Here a more functional example.
Here a more functional example.
import pygame from pygame.sprite import Group, Sprite from itertools import count class ButtonGroup: def __init__(self): self.buttons = Group() self.text = Group() def add(self, *buttons): for button in buttons: self.buttons.add(button) self.text.add(button.text) def draw(self, surface): self.buttons.draw(surface) self.text.draw(surface) def on_event(self, event): if event.type == pygame.MOUSEMOTION: for button in self.buttons: button.collide(event.pos) elif event.type == pygame.MOUSEBUTTONDOWN: for button in self.buttons: if event.button == 1: button.mouse_down() elif event.type == pygame.MOUSEBUTTONUP: for button in self.buttons: if event.button == 1: button.mouse_up() class Pen: def __init__(self, font, color): self.font = font self.color = color def write(self, text): return Text(pen, text) def render(self, text): return self.font.render(text, 1, self.color) class Text(Sprite): def __init__(self, pen, text): super().__init__() self.pen = pen self.text = text self.image = pen.render(text) self.rect = self.image.get_rect() def set_text(self, text, anchor): pos = getattr(self.rect, anchor) self.text = text self.image = self.pen.render(text) self.rect = self.image.get_rect() setattr(self.rect, anchor, pos) class ButtonImages: def __init__(self, normal, press, hover): self.normal = normal self.press = press self.hover = hover class Callback: def __init__(self, callback, user_data=None): self.callback = callback self.user_data = user_data def call(self, widget): self.callback(widget, self) class Button(Sprite): def __init__(self, images, text, callback, position, anchor): super().__init__() self.callback = callback self.images = images self.image = images.normal self.rect = self.image.get_rect() setattr(self.rect, anchor, position) self.text = text self.text.rect.center = self.rect.center self.is_hovering = False self.is_press = False def collide(self, mpos): hovering = self.rect.collidepoint(mpos) if hovering is not self.is_hovering: self.update_image(hovering) self.is_hovering = hovering def mouse_up(self): if self.is_hovering: self.is_press = False self.update_image(self.is_hovering) self.callback.call(self) def mouse_down(self): if self.is_hovering: self.is_press = True self.update_image(self.is_hovering) else: self.is_press = False def update_image(self, hovering): if hovering: if self.is_press: self.image = self.images.press else: self.image = self.images.hover else: self.image = self.images.normal class ButtonManager: def __init__(self, window, color, mix_color, size): self.window = window self.color_buttons = ButtonGroup() self.create(color, mix_color, size) # Shortcuts. # Link button on_event and draw methods from ButtonGroup. self.draw = self.color_buttons.draw self.on_event = self.color_buttons.on_event def create(self, color, mix_color, size): # Build Pen font = pygame.font.Font(None, 24) pen = Pen(font, "white") # Creating Images hcolor = pygame.Color(color).lerp(mix_color, 0.15) pcolor = pygame.Color(color).lerp(mix_color, 0.2) surfaces = [] for color in [color, pcolor, hcolor]: surface = pygame.Surface(size) surface.fill(color) surfaces.append(surface) images = ButtonImages(*surfaces) # Data for buttons colors = ("blue", "darkred", "darkgreen", "dodgerblue", "orange", "gray30") num = count(20, 40) # Create and add Button to group. for color in colors: y = next(num) self.color_buttons.add( Button(images, Text(pen, color), Callback(self.push_color_button, color), (20, y), "topleft") ) def push_color_button(self, button, callback): self.window.background = callback.user_data class QuickWindow: def __init__(self, caption, size, fps=60, flags=0): # Basic Pygame Setup pygame.display.set_caption(caption) self.surface = pygame.display.set_mode(size, flags) self.rect = self.surface.get_rect() self.clock = pygame.time.Clock() self.running = False self.delta = 0 self.fps = fps # Variables self.background = 'gray30' self.buttons = ButtonManager(self, "navy", "white", (140, 30)) def on_draw(self): self.surface.fill(self.background) self.buttons.draw(self.surface) def on_event(self, event): if event.type == pygame.QUIT: self.running = False else: self.buttons.on_event(event) def main_loop(self): self.running = True while self.running: for event in pygame.event.get(): self.on_event(event) self.on_draw() pygame.display.flip() self.delta = self.clock.tick(self.fps) if __name__ == "__main__": pygame.init() window = QuickWindow("Pygame Window", (400, 300)) window.main_loop() pygame.quit()
99 percent of computer problems exists between chair and keyboard.