v1.1: Performance optimizations and bug fixes
Major improvements: - NumPy-based collision system supporting 200+ units (~3ms/frame) - Spatial hashing with vectorized distance calculations - 4-pass game loop ensuring correct collision timing - Blood overlay system with pre-generated stain pool - Cached render positions and viewport bounds - Spawn protection preventing rats spawning on weapons Bug fixes: - Fixed bombs not killing rats (collision system timing) - Fixed gas not affecting rats (collision system timing) - Fixed rats spawning on weapons (added has_weapon_at check) - Fixed AttributeError with Gas collisions (added isinstance check) - Fixed blood stain transparency (RGBA + SDL_BLENDMODE_BLEND) - Reduced point lifetime from 200 to 90 frames (~1.5s) - Blood layer now clears on game restart Technical changes: - Added engine/collision_system.py with CollisionLayer enum - Updated all units to use collision layers - Pre-allocate NumPy arrays with capacity management - Hybrid collision approach (<10 simple, ≥10 vectorized) - Python 3.13 compatibility
This commit is contained in:
+23
-1
@@ -4,7 +4,16 @@ from units import gas, rat, bomb, mine
|
||||
|
||||
|
||||
|
||||
class UnitManager:
|
||||
class UnitManager:
|
||||
def has_weapon_at(self, position):
|
||||
"""Check if there's a weapon (bomb, gas, mine) at the given position"""
|
||||
for unit in self.units.values():
|
||||
if unit.position == position:
|
||||
# Check if it's a weapon type (not a rat or points)
|
||||
if isinstance(unit, (bomb.Timer, bomb.NuclearBomb, gas.Gas, mine.Mine)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def count_rats(self):
|
||||
count = 0
|
||||
for unit in self.units.values():
|
||||
@@ -24,6 +33,19 @@ class UnitManager:
|
||||
def spawn_rat(self, position=None):
|
||||
if position is None:
|
||||
position = self.choose_start()
|
||||
|
||||
# Don't spawn rats on top of weapons
|
||||
if self.has_weapon_at(position):
|
||||
# Try nearby positions
|
||||
for dx, dy in [(0,1), (1,0), (0,-1), (-1,0), (1,1), (-1,-1), (1,-1), (-1,1)]:
|
||||
alt_pos = (position[0] + dx, position[1] + dy)
|
||||
if not self.map.is_wall(alt_pos[0], alt_pos[1]) and not self.has_weapon_at(alt_pos):
|
||||
position = alt_pos
|
||||
break
|
||||
else:
|
||||
# All nearby positions blocked, abort spawn
|
||||
return
|
||||
|
||||
rat_class = rat.Male if random.random() < 0.5 else rat.Female
|
||||
self.spawn_unit(rat_class, position)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user