Refactor unit classes to reduce code duplication and improve maintainability
- Updated the Unit base class to include common attributes and methods for all units. - Refactored Bomb, Point, and Rat classes to inherit from the new Unit class structure. - Implemented a consistent die method across units for better cleanup. - Removed redundant code in unit initialization and added specific attributes where necessary. - Deleted obsolete configuration file and added a comprehensive architecture guide for future reference.
This commit is contained in:
+13
-15
@@ -8,16 +8,9 @@ AGE_THRESHOLD = 200
|
||||
|
||||
class Bomb(Unit):
|
||||
def __init__(self, game, position=(0,0), id=None):
|
||||
super().__init__(position)
|
||||
self.id = id if id else uuid.uuid4()
|
||||
self.game = game
|
||||
self.position = position
|
||||
self.bbox = (0, 0, 0, 0)
|
||||
self.stop = 0
|
||||
self.age = 0
|
||||
self.speed = 4
|
||||
self.partial_move = 0
|
||||
self.position_before = position
|
||||
super().__init__(game, position, id)
|
||||
# Specific attributes for bombs
|
||||
self.speed = 4 # Bombs age faster
|
||||
self.fight = False
|
||||
|
||||
def move(self):
|
||||
@@ -54,16 +47,21 @@ class Timer(Bomb):
|
||||
self.die()
|
||||
|
||||
def die(self, unit=None, score=None):
|
||||
"""Handle bomb explosion and chain reactions."""
|
||||
score = 10
|
||||
print("BOOM")
|
||||
if not unit:
|
||||
unit = self
|
||||
target_unit = unit if unit else self
|
||||
self.game.play_sound("BOMB.WAV")
|
||||
|
||||
# Use base class cleanup with error handling
|
||||
try:
|
||||
self.game.units.pop(unit.id)
|
||||
if target_unit.id in self.game.units:
|
||||
self.game.units.pop(target_unit.id)
|
||||
except:
|
||||
print(f"Unit {unit.id} already dead")
|
||||
self.game.spawn_unit(Explosion, unit.position)
|
||||
print(f"Unit {target_unit.id} already dead")
|
||||
|
||||
# Bomb-specific behavior: create explosion
|
||||
self.game.spawn_unit(Explosion, target_unit.position)
|
||||
for direction in ["N", "S", "E", "W"]:
|
||||
x, y = unit.position
|
||||
while True:
|
||||
|
||||
+7
-13
@@ -8,16 +8,9 @@ AGE_THRESHOLD = 200
|
||||
|
||||
class Point(Unit):
|
||||
def __init__(self, game, position=(0,0), id=None, value=5):
|
||||
super().__init__(position)
|
||||
self.id = id if id else uuid.uuid4()
|
||||
self.game = game
|
||||
self.position = position
|
||||
self.bbox = (0, 0, 0, 0)
|
||||
self.stop = 0
|
||||
self.age = 0
|
||||
self.speed = 4
|
||||
self.partial_move = 0
|
||||
self.position_before = position
|
||||
super().__init__(game, position, id)
|
||||
# Specific attributes for points
|
||||
self.speed = 4 # Points age faster
|
||||
self.fight = False
|
||||
self.value = value
|
||||
self.game.add_point(self.value)
|
||||
@@ -31,9 +24,10 @@ class Point(Unit):
|
||||
pass
|
||||
|
||||
def die(self, unit=None, score=None):
|
||||
if not unit:
|
||||
unit = self
|
||||
self.game.units.pop(unit.id)
|
||||
"""Handle point cleanup. Points just disappear when they expire."""
|
||||
target_unit = unit if unit else self
|
||||
# Use base class cleanup
|
||||
super().die()
|
||||
|
||||
|
||||
def draw(self):
|
||||
|
||||
+16
-18
@@ -13,17 +13,12 @@ BABY_INTERVAL = 50
|
||||
|
||||
class Rat(Unit):
|
||||
def __init__(self, game, position=(0,0), id=None):
|
||||
super().__init__(position)
|
||||
self.id = id if id else uuid.uuid4()
|
||||
self.game = game
|
||||
self.position = self.find_next_position()
|
||||
self.bbox = (0, 0, 0, 0)
|
||||
self.stop = 0
|
||||
self.age = 0
|
||||
self.speed = .10
|
||||
self.partial_move = 0
|
||||
self.position_before = position
|
||||
super().__init__(game, position, id)
|
||||
# Specific attributes for rats
|
||||
self.speed = 0.10 # Rats are slower
|
||||
self.fight = False
|
||||
# Initialize position using pathfinding
|
||||
self.position = self.find_next_position()
|
||||
|
||||
def calculate_rat_direction(self):
|
||||
x, y = self.position
|
||||
@@ -94,10 +89,13 @@ class Rat(Unit):
|
||||
self.fuck(unit)
|
||||
|
||||
def die(self, unit=None, score=10):
|
||||
if not unit:
|
||||
unit = self
|
||||
self.game.units.pop(unit.id)
|
||||
self.game.spawn_unit(Point, unit.position_before, value=score)
|
||||
"""Handle rat death and spawn points."""
|
||||
target_unit = unit if unit else self
|
||||
# Use base class cleanup
|
||||
if target_unit.id in self.game.units:
|
||||
self.game.units.pop(target_unit.id)
|
||||
# Rat-specific behavior: spawn points
|
||||
self.game.spawn_unit(Point, target_unit.position_before, value=score)
|
||||
|
||||
def draw(self):
|
||||
start_perf = self.game.engine.get_perf_counter()
|
||||
@@ -121,8 +119,8 @@ class Rat(Unit):
|
||||
#self.game.engine.draw_rectangle(self.bbox[0], self.bbox[1], self.bbox[2] - self.bbox[0], self.bbox[3] - self.bbox[1], "unit")
|
||||
|
||||
class Male(Rat):
|
||||
def __init__(self, map, position=(0,0), id=None):
|
||||
super().__init__(map, position, id)
|
||||
def __init__(self, game, position=(0,0), id=None):
|
||||
super().__init__(game, position, id)
|
||||
self.sex = "MALE"
|
||||
|
||||
def fuck(self, unit):
|
||||
@@ -134,11 +132,11 @@ class Male(Rat):
|
||||
unit.babies = random.randint(1, 3)
|
||||
|
||||
class Female(Rat):
|
||||
def __init__(self, map, position=(0,0), id=None):
|
||||
def __init__(self, game, position=(0,0), id=None):
|
||||
super().__init__(game, position, id)
|
||||
self.sex = "FEMALE"
|
||||
self.pregnant = False
|
||||
self.babies = 0
|
||||
super().__init__(map, position, id)
|
||||
|
||||
def procreate(self):
|
||||
self.pregnant -= 1
|
||||
|
||||
+57
-14
@@ -1,27 +1,70 @@
|
||||
class Unit:
|
||||
from abc import ABC, abstractmethod
|
||||
import uuid
|
||||
|
||||
|
||||
class Unit(ABC):
|
||||
"""
|
||||
A class to represent a unit in the game.
|
||||
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 (default is (0, 0)).
|
||||
The current position of the unit (x, y).
|
||||
position_before : tuple
|
||||
The position of the unit before the last update.
|
||||
state : int
|
||||
The current state of the unit (default is 0).
|
||||
age : int
|
||||
The age of the unit in game ticks.
|
||||
speed : float
|
||||
The delay between updates in seconds (default is 0.05).
|
||||
partial_move : int
|
||||
The partial move value (default is 0).
|
||||
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.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(self, position=(0,0))
|
||||
Initializes the unit with a given position.
|
||||
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, position=(0,0)):
|
||||
def __init__(self, game, position=(0, 0), id=None):
|
||||
"""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 = self.position
|
||||
self.state = 0
|
||||
self.partial_move = 1
|
||||
self.position_before = position
|
||||
self.age = 0
|
||||
self.speed = 1.0
|
||||
self.partial_move = 0
|
||||
self.bbox = (0, 0, 0, 0)
|
||||
self.stop = 0
|
||||
|
||||
@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 die(self):
|
||||
"""Remove unit from game and handle basic cleanup."""
|
||||
if self.id in self.game.units:
|
||||
self.game.units.pop(self.id)
|
||||
|
||||
Reference in New Issue
Block a user