phantomcastle: automove by mouse click

This commit is contained in:
Dmitry Belyaev 2024-04-06 23:56:26 +03:00
parent a985199441
commit 087886955d

View File

@ -3,6 +3,21 @@ from coords import Coords, Direction
from common import DrawableGameObject, EventHandler 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): class Hero(DrawableGameObject, EventHandler):
"""объект главного героя""" """объект главного героя"""
@ -23,10 +38,13 @@ class Hero(DrawableGameObject, EventHandler):
self._speed = 1 self._speed = 1
self.direction = Direction.RIGHT self.direction = Direction.RIGHT
self.mouse_active = False self.mouse_active = False
self.auto_move_target = None
# картинка изначально влево, а надо бы начинать со взгляда вправо # картинка изначально влево, а надо бы начинать со взгляда вправо
self.flip() self.flip()
def draw(self): def draw(self):
self.auto_move()
self.parent.surface.blit(self.surface, self.rect) self.parent.surface.blit(self.surface, self.rect)
def _check_collision(self, coords): def _check_collision(self, coords):
@ -61,6 +79,8 @@ class Hero(DrawableGameObject, EventHandler):
self.scene.coins.collect(self) self.scene.coins.collect(self)
return return
self.auto_move_target = None
# уменьшение шага # уменьшение шага
while has_collision and coords != self.coords: while has_collision and coords != self.coords:
coords_new = self._reduce_step(coords) coords_new = self._reduce_step(coords)
@ -91,6 +111,21 @@ class Hero(DrawableGameObject, EventHandler):
self.update_direction(direction) self.update_direction(direction)
self.coords += direction.as_coords() * step * self.speed // 3 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): def handle_mouse_event(self, event: pygame.event.Event):
if event.type not in ( if event.type not in (
pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONDOWN,
@ -101,6 +136,12 @@ class Hero(DrawableGameObject, EventHandler):
match event.type: match event.type:
case pygame.MOUSEBUTTONDOWN: case pygame.MOUSEBUTTONDOWN:
self.mouse_active = self.rect.collidepoint(event.pos) 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: case pygame.MOUSEBUTTONUP:
self.mouse_active = False self.mouse_active = False
case pygame.MOUSEMOTION if self.mouse_active: case pygame.MOUSEMOTION if self.mouse_active: