b243cf04d3
- Added BMP_1_EXPLOSION_DOWN.png to original and preview directories. - Added BMP_1_EXPLOSION_LEFT.png to original and preview directories. - Added BMP_1_EXPLOSION_RIGHT.png to original and preview directories. - Added BMP_1_EXPLOSION_UP.png to original and preview directories. These assets are part of the explosion animation for the game, enhancing visual effects during gameplay.
90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
from abc import ABC, abstractmethod
|
|
import uuid
|
|
|
|
|
|
class Unit(ABC):
|
|
"""
|
|
Abstract base class for all game units.
|
|
|
|
Attributes
|
|
----------
|
|
id : UUID
|
|
Unique identifier for the unit.
|
|
game : Game
|
|
Reference to the main game object.
|
|
position : tuple
|
|
The current position of the unit (x, y).
|
|
position_before : tuple
|
|
The position of the unit before the last update.
|
|
age : int
|
|
The age of the unit in game ticks.
|
|
speed : float
|
|
Movement speed of the unit.
|
|
partial_move : float
|
|
Partial movement progress for smooth animation.
|
|
bbox : tuple
|
|
Bounding box for collision detection (x1, y1, x2, y2).
|
|
stop : int
|
|
Number of ticks to remain stationary.
|
|
collision_layer : int
|
|
Collision layer for the optimized collision system.
|
|
|
|
Methods
|
|
-------
|
|
move()
|
|
Update unit position and state (must be implemented by subclasses).
|
|
draw()
|
|
Render the unit on screen (must be implemented by subclasses).
|
|
collisions()
|
|
Handle collisions with other units (optional override).
|
|
die()
|
|
Remove unit from game and handle cleanup.
|
|
"""
|
|
def __init__(self, game, position=(0, 0), id=None, collision_layer=0):
|
|
"""Initialize a unit with game reference and position."""
|
|
self.id = id if id else uuid.uuid4()
|
|
self.game = game
|
|
self.position = position
|
|
self.position_before = position
|
|
self.age = 0
|
|
self.speed = 1.0
|
|
self.partial_move = 0
|
|
self.bbox = (0, 0, 0, 0)
|
|
self.stop = 0
|
|
self.collision_layer = collision_layer
|
|
|
|
@abstractmethod
|
|
def move(self):
|
|
"""Update unit position and state. Must be implemented by subclasses."""
|
|
pass
|
|
|
|
@abstractmethod
|
|
def draw(self):
|
|
"""Render the unit on screen. Must be implemented by subclasses."""
|
|
pass
|
|
|
|
def collisions(self):
|
|
"""Handle collisions with other units. Default implementation does nothing."""
|
|
pass
|
|
|
|
def is_hidden_in_tunnel(self, image_size, position=None):
|
|
"""Return True when the sprite center falls inside a tunnel cell."""
|
|
if position is None:
|
|
position = self.position_before
|
|
|
|
x_pos = position[0] * self.game.cell_size + (self.game.cell_size - image_size[0]) // 2
|
|
y_pos = position[1] * self.game.cell_size + (self.game.cell_size - image_size[1]) // 2
|
|
center_x = int(x_pos + image_size[0] / 2)
|
|
center_y = int(y_pos + image_size[1] / 2)
|
|
cell_x = center_x // self.game.cell_size
|
|
cell_y = center_y // self.game.cell_size
|
|
|
|
if not self.game.map.in_bounds(cell_x, cell_y):
|
|
return False
|
|
return self.game.map.is_tunnel(cell_x, cell_y)
|
|
|
|
def die(self, score=None):
|
|
"""Remove unit from game and handle basic cleanup."""
|
|
if self.id in self.game.units:
|
|
self.game.units.pop(self.id)
|