From 087886955d6ea9a821c771895e88c254c7b48c4e Mon Sep 17 00:00:00 2001 From: Dmitry Date: Sat, 6 Apr 2024 23:56:26 +0300 Subject: [PATCH] phantomcastle: automove by mouse click --- pygame-wasm/phantomcastle/game/hero.py | 41 ++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/pygame-wasm/phantomcastle/game/hero.py b/pygame-wasm/phantomcastle/game/hero.py index 9ac0c76..128818d 100644 --- a/pygame-wasm/phantomcastle/game/hero.py +++ b/pygame-wasm/phantomcastle/game/hero.py @@ -3,6 +3,21 @@ from coords import Coords, Direction from common import DrawableGameObject, EventHandler +def point_at(coords: Coords) -> tuple[pygame.Rect, pygame.Mask]: + rect = pygame.Rect(coords.x, coords.y, 1, 1) + mask = pygame.Mask((1, 1), fill=True) + return rect, mask + + +def collide_with_walls(coords: Coords, walls: DrawableGameObject) -> bool: + rect, mask = point_at(coords) + return walls.check_collision(rect, mask) + + +def is_valid_point_to_move(coords: Coords, walls: DrawableGameObject) -> bool: + return not collide_with_walls(coords, walls) + + class Hero(DrawableGameObject, EventHandler): """объект главного героя""" @@ -23,10 +38,13 @@ class Hero(DrawableGameObject, EventHandler): self._speed = 1 self.direction = Direction.RIGHT self.mouse_active = False + self.auto_move_target = None + # картинка изначально влево, а надо бы начинать со взгляда вправо self.flip() def draw(self): + self.auto_move() self.parent.surface.blit(self.surface, self.rect) def _check_collision(self, coords): @@ -61,6 +79,8 @@ class Hero(DrawableGameObject, EventHandler): self.scene.coins.collect(self) return + self.auto_move_target = None + # уменьшение шага while has_collision and coords != self.coords: coords_new = self._reduce_step(coords) @@ -91,6 +111,21 @@ class Hero(DrawableGameObject, EventHandler): self.update_direction(direction) self.coords += direction.as_coords() * step * self.speed // 3 + def auto_move(self): + if self.auto_move_target is None: + return + + rect, mask = point_at(self.auto_move_target) + if self.overlap(rect, mask): + self.auto_move_target = None + return + + direction = Direction.from_coords(self.auto_move_target - self.coords) + if direction: + self.move(direction, step=1) + else: + self.auto_move_target = None + def handle_mouse_event(self, event: pygame.event.Event): if event.type not in ( pygame.MOUSEBUTTONDOWN, @@ -101,6 +136,12 @@ class Hero(DrawableGameObject, EventHandler): match event.type: case pygame.MOUSEBUTTONDOWN: self.mouse_active = self.rect.collidepoint(event.pos) + if not self.mouse_active and is_valid_point_to_move( + Coords(*event.pos), self.scene.walls + ): + self.auto_move_target = Coords(*event.pos) + else: + self.auto_move_target = None case pygame.MOUSEBUTTONUP: self.mouse_active = False case pygame.MOUSEMOTION if self.mouse_active: