class Title(pg.sprite.Sprite): sprite_group: Type['pg.sprite.Group'] pos: 'Coords' size: 'Coords' tp_config: 'TypewriterConfig' = TypewriterConfig(size=72, pos='center') title: str = 'AI Wars' def __post_init__(self): super().__init__(self.sprite_group) self.image = pg.Surface( (s.TILESIZE * self.size.x, s.TILESIZE * self.size.y)) self.image.fill(s.DARKGREY) self.rect = self.image.get_rect() self.x = self.pos.x self.y = self.pos.y self.rect.midtop = (self.x * s.TILESIZE, self.y * s.TILESIZE) self.title_writer = Typewriter(surface=self.image, config=self.tp_config) self.draw_pixel_art() self.draw_title() def draw_title(self): if self.title: self.title_writer.type(self.title) def draw_pixel_art(self): px = s.TILESIZE / 4 pg.draw.rect(self.image, s.BLACK, (0, 0, px, px)) pg.draw.rect(self.image, s.BLACK, (0, self.image.get_height() - px, px, px)) pg.draw.rect(self.image, s.BLACK, (self.image.get_width() - px, self.image.get_height() - px, px, px)) pg.draw.rect(self.image, s.BLACK, (self.image.get_width() - px, 0, px, px))
def draw_mouse_pos(self, screen): mpos = pg.mouse.get_pos() coords = Coords(x=s.TILESIZE * 3, y=s.TILESIZE) follow = pg.Surface((coords.x, coords.y)) rect = follow.get_rect(topleft=(0, 0)) tp = Typewriter(follow, TypewriterConfig(size=12, pos='center')) tp.type(str(mpos)) screen.blit(follow, rect)
class GameOver(Panel): color: tuple = s.BLACK draw_px_art: bool = False go_config: 'TypewriterConfig' = TypewriterConfig(size=72, pos='center') def __post_init__(self): self.backdrop = Backdrop(sprite_group=self.sprite_group, pos=Coords(x=0, y=0), size=Coords(x=s.GRIDWIDTH, y=s.GRIDHEIGHT)) self.tp = Typewriter(surface=self.backdrop.image, config=self.go_config) self.tp.type('Game over')
class Panel(pg.sprite.Sprite): sprite_group: pg.sprite.Group pos: 'Coords' size: 'Coords' tp_config: 'TypewriterConfig' = TypewriterConfig(size=44, surface_color=s.DARKGREY, pos='midtop') title: Union[None, str] = None alpha: Union[None, int] = None parent_color: tuple = s.BLACK color: tuple = s.DARKGREY draw_title: bool = True draw_px_art: bool = True def __post_init__(self): super().__init__(self.sprite_group) args = [(s.TILESIZE * self.size.x, s.TILESIZE * self.size.y)] if self.alpha: args.append(pg.SRCALPHA) self.image = pg.Surface(*args) if self.alpha: self.color = (*self.color, self.alpha) self.image.fill(self.color) self.rect = self.image.get_rect() self.x = self.pos.x self.y = self.pos.y self.rect = self.image.get_rect(topleft=(self.x * s.TILESIZE, self.y * s.TILESIZE)) self.title_writer = Typewriter(surface=self.image, config=self.tp_config) self.draw_pixel_art() self._draw_title() def _draw_title(self): if self.draw_title and self.title: self.title_writer.type(self.title) def draw_pixel_art(self): if self.draw_px_art: px = s.TILESIZE / 4 pg.draw.rect(self.image, self.parent_color, (0, 0, px, px)) pg.draw.rect(self.image, self.parent_color, (0, self.image.get_height() - px, px, px)) pg.draw.rect(self.image, self.parent_color, (self.image.get_width() - px, self.image.get_height() - px, px, px)) pg.draw.rect(self.image, self.parent_color, (self.image.get_width() - px, 0, px, px))
class Button: surface: 'pg.Surface' pos: 'Coords' size: 'Coords' text: str value: str config: 'TypewriterConfig' = TypewriterConfig( size=32, color=s.GREEN, pos='center' ) desc: str = '' hovering: bool = False def __post_init__(self): self.scaled_pos = self.pos * s.TILESIZE self.scaled_size = self.size * s.TILESIZE self.rect = pg.Rect( self.scaled_pos.x, self.scaled_pos.y, self.scaled_size.x, self.scaled_size.y ) self.surf = self.surface.subsurface(self.rect) self.tp = Typewriter(self.surf, self.config) self.new() def new(self): self.surf.fill(s.BLACK) self.draw_text() def draw_text(self): self.tp.type(self.text) def update(self): if self.hovering: self.hover() else: self.new() def hover(self): self.surf.fill(s.DARKGREEN) self.draw_text() pg.draw.rect( self.surf, s.GREEN, (0, 0, self.scaled_size.x, self.scaled_size.y), 2 ) def on_click(self): return self.value
def draw_legend(self): letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] config = TypewriterConfig(size=22, color=s.WHITE, padding=10, surface_color=s.DARKGREY) tp = Typewriter(surface=self.image, config=config) for i, l in enumerate(letters, start=1): num_w, num_h = tp.get_text_size(str(i)) l_w, l_h = tp.get_text_size(l) tp.type(text=str(i), coords=Coords(x=s.TILESIZE // 2 - num_w // 2, y=s.TILESIZE * 2 * i - num_h // 2)) tp.type(text=l, coords=Coords(x=i * s.TILESIZE * 2 - l_w // 2, y=self.image.get_height() - s.TILESIZE + l_h // 4))
class PlayerMenu: pos: 'Coords' size: 'Coords' surface: 'pg.Surface' current: 'Color' = Color.white selection: dict = field(default_factory=dict) pmenu_title: 'TypewriterConfig' = TypewriterConfig(pos='midtop', size=16, surface_color=s.BLACK, padding=5) def __post_init__(self): self.scaled_pos = self.pos * s.TILESIZE self.scaled_size = self.size * s.TILESIZE self.pmenu = self.draw_frame() self.title_printer = Typewriter(surface=self.pmenu, config=self.pmenu_title) self.selection_buttons = { Color.white: self._draw_buttons(), Color.black: self._draw_buttons() + self._back_button() } def draw(self): self.pmenu.fill(s.BLACK) self.draw_player() for button in self.selection_buttons[self.current]: button.new() return self.selection_buttons[self.current] def draw_player(self): player = f'{self.current.name}' p_size = self.title_printer.get_text_size(player) self.title_printer.type(player) pad = self.title_printer.config.padding pg.draw.line(self.pmenu, s.GREEN, (0, p_size[1] + pad), (self.pmenu.get_width(), p_size[1] + pad), 1) def click(self, button): action = button.on_click() if action == 'back': self.current = Color.white else: self.selection[self.current] = action for button in self.selection_buttons[self.current]: if button.text != self.selection[self.current]: button.selected = False else: button.selected = True Player = namedtuple('Player', ['player', 'color']) p = Player(action, self.current) self.current = Color.black return p def _draw_buttons(self): size = Coords(x=6, y=1) return [ SelectionButton( surface=self.surface, pos=Coords(x=8, y=2), size=size, text='human', value='human', desc= """A typical human scum. Tends to have 4 legs and a gender of her choice. They love to watch the fire burn and have Vietnam flashbacks."""), SelectionButton(surface=self.surface, pos=Coords(x=8, y=3), size=size, text='random AI', value='random AI', desc="""Cute AI that shoots bullets in the dark. I\'m actually going to tell you what it does: import random as r r.choice(possible_moves) """) ] def _back_button(self): size = Coords(x=6, y=1) return [ Button(surface=self.surface, pos=Coords(x=8, y=4), size=size, text='back', value='back', config=TypewriterConfig(size=16, color=s.GREEN, pos='midleft')) ] def draw_frame(self): subsurface = pg.Rect(self.scaled_pos.x, self.scaled_pos.y, self.scaled_size.x, self.scaled_size.y) frame = self.surface.subsurface(subsurface) frame.fill(s.BLACK) return frame