refactor: improve room handling and tower expiration logic
This commit is contained in:
+16
-14
@@ -66,7 +66,7 @@ class Game:
|
|||||||
self.player_name: str = ""
|
self.player_name: str = ""
|
||||||
self.game_start_time = 0
|
self.game_start_time = 0
|
||||||
self.endscreen: Optional[Endscreen] = None
|
self.endscreen: Optional[Endscreen] = None
|
||||||
self.current_item_room_key: Optional[tuple[int, int, int, int]] = None
|
self.current_room_key: Optional[tuple[int, int, int, int]] = None
|
||||||
|
|
||||||
self.map = Map()
|
self.map = Map()
|
||||||
self.active_door: Optional[Door] = None
|
self.active_door: Optional[Door] = None
|
||||||
@@ -151,7 +151,10 @@ class Game:
|
|||||||
self.player.update_animation(dt)
|
self.player.update_animation(dt)
|
||||||
self.ects.update(self.is_player_at_desk())
|
self.ects.update(self.is_player_at_desk())
|
||||||
self.handle_room_table_collision()
|
self.handle_room_table_collision()
|
||||||
self.update_items()
|
player_rect = self.get_actor_rect(self.player)
|
||||||
|
room_rect = self.map.get_current_room(player_rect)
|
||||||
|
self.handle_room_change(room_rect)
|
||||||
|
self.update_items(player_rect, room_rect)
|
||||||
self.monsters.update(
|
self.monsters.update(
|
||||||
dt,
|
dt,
|
||||||
self.player.position,
|
self.player.position,
|
||||||
@@ -202,7 +205,7 @@ class Game:
|
|||||||
room_rect = self.map.get_current_room(player_rect)
|
room_rect = self.map.get_current_room(player_rect)
|
||||||
monster = self.monsters.monsters[0] if self.monsters.monsters else None
|
monster = self.monsters.monsters[0] if self.monsters.monsters else None
|
||||||
if monster is None or not monster.is_alive:
|
if monster is None or not monster.is_alive:
|
||||||
self.tower.clear()
|
self.tower.expire_if_needed()
|
||||||
return
|
return
|
||||||
|
|
||||||
damage = self.tower.update(
|
damage = self.tower.update(
|
||||||
@@ -213,19 +216,18 @@ class Game:
|
|||||||
)
|
)
|
||||||
if monster is not None and damage > 0:
|
if monster is not None and damage > 0:
|
||||||
monster.take_damage(damage)
|
monster.take_damage(damage)
|
||||||
if not monster.is_alive:
|
|
||||||
self.tower.clear()
|
|
||||||
|
|
||||||
def update_items(self) -> None:
|
def handle_room_change(self, room_rect: Optional[pygame.Rect]) -> None:
|
||||||
"""Spawn room items and process one player purchase request."""
|
|
||||||
|
|
||||||
player_rect = self.get_actor_rect(self.player)
|
|
||||||
room_rect = self.map.get_current_room(player_rect)
|
|
||||||
room_key = self.get_room_key(room_rect) if room_rect is not None else None
|
room_key = self.get_room_key(room_rect) if room_rect is not None else None
|
||||||
|
if room_key == self.current_room_key:
|
||||||
|
return
|
||||||
|
|
||||||
if room_key != self.current_item_room_key:
|
|
||||||
self.item_manager.clear()
|
self.item_manager.clear()
|
||||||
self.current_item_room_key = room_key
|
self.tower.clear(reset_spawned=True)
|
||||||
|
self.current_room_key = room_key
|
||||||
|
|
||||||
|
def update_items(self, player_rect: pygame.Rect, room_rect: Optional[pygame.Rect]) -> None:
|
||||||
|
"""Spawn room items and process one player purchase request."""
|
||||||
|
|
||||||
self.item_manager.update(room_rect, self.get_item_spawn_blockers())
|
self.item_manager.update(room_rect, self.get_item_spawn_blockers())
|
||||||
|
|
||||||
@@ -269,8 +271,8 @@ class Game:
|
|||||||
self.ects = ECTS()
|
self.ects = ECTS()
|
||||||
self.shop = Shop(self.ects, self.item_manager.items, self.sound_manager)
|
self.shop = Shop(self.ects, self.item_manager.items, self.sound_manager)
|
||||||
self.item_manager.clear()
|
self.item_manager.clear()
|
||||||
self.current_item_room_key = None
|
self.current_room_key = None
|
||||||
self.tower.clear()
|
self.tower.clear(reset_spawned=True)
|
||||||
self.active_door = None
|
self.active_door = None
|
||||||
self.doors_by_room = {}
|
self.doors_by_room = {}
|
||||||
self.player.set_position(self.find_start_position())
|
self.player.set_position(self.find_start_position())
|
||||||
|
|||||||
+15
-5
@@ -25,6 +25,7 @@ class Tower:
|
|||||||
self.projectiles: list[dict[str, float]] = []
|
self.projectiles: list[dict[str, float]] = []
|
||||||
self.tower_start: Optional[int] = None
|
self.tower_start: Optional[int] = None
|
||||||
self.last_shot: int = 0
|
self.last_shot: int = 0
|
||||||
|
self.has_spawned = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.tower_image = pygame.image.load("assets/items/tower.png").convert_alpha()
|
self.tower_image = pygame.image.load("assets/items/tower.png").convert_alpha()
|
||||||
@@ -46,7 +47,7 @@ class Tower:
|
|||||||
def try_spawn(self, room_rect: Optional[pygame.Rect], blocked_rects: list[pygame.Rect], ects) -> bool:
|
def try_spawn(self, room_rect: Optional[pygame.Rect], blocked_rects: list[pygame.Rect], ects) -> bool:
|
||||||
"""Spawn and pay for one tower when the player has enough ECTS."""
|
"""Spawn and pay for one tower when the player has enough ECTS."""
|
||||||
|
|
||||||
if room_rect is None or self.tower_rect is not None:
|
if room_rect is None or self.tower_rect is not None or self.has_spawned:
|
||||||
return False
|
return False
|
||||||
if ects.ects_balance < TOWER_COST:
|
if ects.ects_balance < TOWER_COST:
|
||||||
return False
|
return False
|
||||||
@@ -59,6 +60,7 @@ class Tower:
|
|||||||
ects.decrease_balance(TOWER_COST)
|
ects.decrease_balance(TOWER_COST)
|
||||||
self.tower_rect = rect
|
self.tower_rect = rect
|
||||||
self.tower_start = pygame.time.get_ticks()
|
self.tower_start = pygame.time.get_ticks()
|
||||||
|
self.has_spawned = True
|
||||||
self.projectiles = []
|
self.projectiles = []
|
||||||
self._play_sfx("buy_success")
|
self._play_sfx("buy_success")
|
||||||
return True
|
return True
|
||||||
@@ -97,12 +99,18 @@ class Tower:
|
|||||||
self.projectiles.remove(projectile)
|
self.projectiles.remove(projectile)
|
||||||
self._play_sfx("monster_hit")
|
self._play_sfx("monster_hit")
|
||||||
|
|
||||||
if self.tower_rect is not None and self.tower_start is not None:
|
self.expire_if_needed(now)
|
||||||
if now - self.tower_start >= TOWER_TIMER:
|
|
||||||
self.clear()
|
|
||||||
|
|
||||||
return total_damage
|
return total_damage
|
||||||
|
|
||||||
|
def expire_if_needed(self, now: Optional[int] = None) -> None:
|
||||||
|
if self.tower_rect is None or self.tower_start is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
current_time = pygame.time.get_ticks() if now is None else now
|
||||||
|
if current_time - self.tower_start >= TOWER_TIMER:
|
||||||
|
self.clear()
|
||||||
|
|
||||||
def draw(self, surface: pygame.Surface, font: pygame.font.Font, cam_x: int = 0, cam_y: int = 0) -> None:
|
def draw(self, surface: pygame.Surface, font: pygame.font.Font, cam_x: int = 0, cam_y: int = 0) -> None:
|
||||||
if self.tower_rect is not None and self.tower_start is not None:
|
if self.tower_rect is not None and self.tower_start is not None:
|
||||||
draw_rect = pygame.Rect(
|
draw_rect = pygame.Rect(
|
||||||
@@ -134,11 +142,13 @@ class Tower:
|
|||||||
else:
|
else:
|
||||||
pygame.draw.rect(surface, COLOR_PROJECTILE, projectile_rect)
|
pygame.draw.rect(surface, COLOR_PROJECTILE, projectile_rect)
|
||||||
|
|
||||||
def clear(self) -> None:
|
def clear(self, reset_spawned: bool = False) -> None:
|
||||||
self.tower_rect = None
|
self.tower_rect = None
|
||||||
self.projectiles = []
|
self.projectiles = []
|
||||||
self.tower_start = None
|
self.tower_start = None
|
||||||
self.last_shot = 0
|
self.last_shot = 0
|
||||||
|
if reset_spawned:
|
||||||
|
self.has_spawned = False
|
||||||
|
|
||||||
def _shoot_at(self, monster_rect: pygame.Rect) -> None:
|
def _shoot_at(self, monster_rect: pygame.Rect) -> None:
|
||||||
if self.tower_rect is None:
|
if self.tower_rect is None:
|
||||||
|
|||||||
Reference in New Issue
Block a user