phantomcastle use overlap
This commit is contained in:
parent
f1b7b2e860
commit
b8ecdd8f23
@ -262,11 +262,29 @@ class DrawableGameObject(ABC):
|
|||||||
self.rect = pygame.Rect(coords, coords)
|
self.rect = pygame.Rect(coords, coords)
|
||||||
self.assets = assets or (parent.assets if parent else None)
|
self.assets = assets or (parent.assets if parent else None)
|
||||||
self._surface = None
|
self._surface = None
|
||||||
|
self._mask = None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.__class__.__name__}({self.coords})"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def surface(self) -> pygame.Surface | None:
|
def surface(self) -> pygame.Surface | None:
|
||||||
return self._surface or (self.parent.surface if self.parent else None)
|
return self._surface or (self.parent.surface if self.parent else None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mask(self) -> pygame.Mask | None:
|
||||||
|
if not self._mask:
|
||||||
|
self._mask = pygame.mask.from_surface(self.surface.convert_alpha())
|
||||||
|
return self._mask
|
||||||
|
|
||||||
|
def overlap(self, rect: pygame.Rect, mask: pygame.Mask) -> bool:
|
||||||
|
if not self.rect.colliderect(rect):
|
||||||
|
return False
|
||||||
|
|
||||||
|
offset = Coords(*self.rect.topleft) - Coords(*rect.topleft)
|
||||||
|
overlap = mask.overlap(self.mask, offset)
|
||||||
|
return overlap is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def scene(self):
|
def scene(self):
|
||||||
return self.parent.scene if self.parent else self
|
return self.parent.scene if self.parent else self
|
||||||
@ -321,10 +339,9 @@ class Hero(DrawableGameObject, EventHandler):
|
|||||||
|
|
||||||
def _check_collision(self, coords):
|
def _check_collision(self, coords):
|
||||||
"""Проверка пересечения со стенами"""
|
"""Проверка пересечения со стенами"""
|
||||||
new_rect = self.surface.get_bounding_rect()
|
new_rect = self.rect.copy()
|
||||||
new_rect.topleft = coords
|
new_rect.topleft = coords
|
||||||
new_rect.scale_by_ip(0.99, 0.99)
|
return self.scene.walls.check_collision(new_rect, self.mask)
|
||||||
return self.scene.walls.check_collision(new_rect)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def speed(self):
|
def speed(self):
|
||||||
@ -378,7 +395,7 @@ class Hero(DrawableGameObject, EventHandler):
|
|||||||
def move(self, direction: Direction, step: int = 1):
|
def move(self, direction: Direction, step: int = 1):
|
||||||
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
|
||||||
self.scene.coins.collect(self.rect)
|
self.scene.coins.collect(self)
|
||||||
|
|
||||||
def handle_event(self, event: pygame.event.Event):
|
def handle_event(self, event: pygame.event.Event):
|
||||||
if not self.active:
|
if not self.active:
|
||||||
@ -449,9 +466,9 @@ class Walls(DrawableGameObject):
|
|||||||
for block in self.blocks:
|
for block in self.blocks:
|
||||||
block.draw()
|
block.draw()
|
||||||
|
|
||||||
def check_collision(self, rect: pygame.Rect) -> bool:
|
def check_collision(self, rect: pygame.Rect, mask: pygame.Mask) -> bool:
|
||||||
for block in self.blocks:
|
for block in self.blocks:
|
||||||
if block.rect.colliderect(rect):
|
if block.overlap(rect, mask):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -552,8 +569,8 @@ class Coins(DrawableGameObject):
|
|||||||
coin.coords = last_pos
|
coin.coords = last_pos
|
||||||
self.collected_coins.append(coin)
|
self.collected_coins.append(coin)
|
||||||
|
|
||||||
def collect(self, rect: pygame.Rect):
|
def collect(self, actor: DrawableGameObject):
|
||||||
mined = [*filter(lambda coin: coin.bounding_rect.colliderect(rect), self.coins)]
|
mined = [*filter(lambda coin: coin.overlap(actor.rect, actor.mask), self.coins)]
|
||||||
for coin in mined:
|
for coin in mined:
|
||||||
self.coins.remove(coin)
|
self.coins.remove(coin)
|
||||||
self.add_to_collected(coin)
|
self.add_to_collected(coin)
|
||||||
|
@ -177,11 +177,29 @@ class DrawableGameObject(ABC):
|
|||||||
self.rect = pygame.Rect(coords, coords)
|
self.rect = pygame.Rect(coords, coords)
|
||||||
self.assets = assets or (parent.assets if parent else None)
|
self.assets = assets or (parent.assets if parent else None)
|
||||||
self._surface = None
|
self._surface = None
|
||||||
|
self._mask = None
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.__class__.__name__}({self.coords})"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def surface(self) -> pygame.Surface | None:
|
def surface(self) -> pygame.Surface | None:
|
||||||
return self._surface or (self.parent.surface if self.parent else None)
|
return self._surface or (self.parent.surface if self.parent else None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mask(self) -> pygame.Mask | None:
|
||||||
|
if not self._mask:
|
||||||
|
self._mask = pygame.mask.from_surface(self.surface.convert_alpha())
|
||||||
|
return self._mask
|
||||||
|
|
||||||
|
def overlap(self, rect: pygame.Rect, mask: pygame.Mask) -> bool:
|
||||||
|
if not self.rect.colliderect(rect):
|
||||||
|
return False
|
||||||
|
|
||||||
|
offset = Coords(*self.rect.topleft) - Coords(*rect.topleft)
|
||||||
|
overlap = mask.overlap(self.mask, offset)
|
||||||
|
return overlap is not None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def scene(self):
|
def scene(self):
|
||||||
return self.parent.scene if self.parent else self
|
return self.parent.scene if self.parent else self
|
||||||
@ -236,10 +254,9 @@ class Hero(DrawableGameObject, KeysHandler):
|
|||||||
|
|
||||||
def _check_collision(self, coords):
|
def _check_collision(self, coords):
|
||||||
"""Проверка пересечения со стенами"""
|
"""Проверка пересечения со стенами"""
|
||||||
new_rect = self.surface.get_bounding_rect()
|
new_rect = self.rect.copy()
|
||||||
new_rect.topleft = coords
|
new_rect.topleft = coords
|
||||||
new_rect.scale_by_ip(0.99, 0.99)
|
return self.scene.walls.check_collision(new_rect, self.mask)
|
||||||
return self.scene.walls.check_collision(new_rect)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def speed(self):
|
def speed(self):
|
||||||
@ -293,7 +310,7 @@ class Hero(DrawableGameObject, KeysHandler):
|
|||||||
def move(self, direction: Direction, step: int = 1):
|
def move(self, direction: Direction, step: int = 1):
|
||||||
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
|
||||||
self.scene.coins.collect(self.rect)
|
self.scene.coins.collect(self)
|
||||||
|
|
||||||
def handle_keys(self, keys_pressed):
|
def handle_keys(self, keys_pressed):
|
||||||
if not self.active:
|
if not self.active:
|
||||||
@ -362,9 +379,9 @@ class Walls(DrawableGameObject):
|
|||||||
for block in self.blocks:
|
for block in self.blocks:
|
||||||
block.draw()
|
block.draw()
|
||||||
|
|
||||||
def check_collision(self, rect: pygame.Rect) -> bool:
|
def check_collision(self, rect: pygame.Rect, mask: pygame.Mask) -> bool:
|
||||||
for block in self.blocks:
|
for block in self.blocks:
|
||||||
if block.rect.colliderect(rect):
|
if block.overlap(rect, mask):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -463,8 +480,8 @@ class Coins(DrawableGameObject):
|
|||||||
coin.coords = last_pos
|
coin.coords = last_pos
|
||||||
self.collected_coins.append(coin)
|
self.collected_coins.append(coin)
|
||||||
|
|
||||||
def collect(self, rect: pygame.Rect):
|
def collect(self, actor: DrawableGameObject):
|
||||||
mined = [*filter(lambda coin: coin.bounding_rect.colliderect(rect), self.coins)]
|
mined = [*filter(lambda coin: coin.overlap(actor.rect, actor.mask), self.coins)]
|
||||||
for coin in mined:
|
for coin in mined:
|
||||||
self.coins.remove(coin)
|
self.coins.remove(coin)
|
||||||
self.add_to_collected(coin)
|
self.add_to_collected(coin)
|
||||||
|
Loading…
Reference in New Issue
Block a user