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:
@@ -7,7 +7,7 @@ import json
|
||||
from engine import maze, sdl2 as engine, controls, graphics, unit_manager, scoring
|
||||
from engine.collision_system import CollisionSystem
|
||||
from units import points
|
||||
from engine.user_profile_integration import UserProfileIntegration, get_global_leaderboard
|
||||
from engine.user_profile_integration import UserProfileIntegration
|
||||
|
||||
|
||||
class MiceMaze(
|
||||
@@ -103,6 +103,10 @@ class MiceMaze(
|
||||
}
|
||||
self.blood_stains = {}
|
||||
self.background_texture = None
|
||||
|
||||
# Clear blood layer on game start/restart
|
||||
self.blood_layer_sprites.clear()
|
||||
|
||||
for _ in range(5):
|
||||
self.spawn_rat()
|
||||
|
||||
@@ -167,12 +171,16 @@ class MiceMaze(
|
||||
self.unit_positions.clear()
|
||||
self.unit_positions_before.clear()
|
||||
|
||||
# First pass: move all units and update their positions
|
||||
for unit in self.units.copy().values():
|
||||
unit.move()
|
||||
|
||||
# Second pass: register all units in collision system and draw
|
||||
# First pass: Register all units in collision system BEFORE move
|
||||
# This allows bombs/gas to find victims during their move()
|
||||
for unit in self.units.values():
|
||||
# Calculate bbox if not yet set (first frame)
|
||||
if not hasattr(unit, 'bbox') or unit.bbox == (0, 0, 0, 0):
|
||||
# Temporary bbox based on position
|
||||
x_pos = unit.position[0] * self.cell_size
|
||||
y_pos = unit.position[1] * self.cell_size
|
||||
unit.bbox = (x_pos, y_pos, x_pos + self.cell_size, y_pos + self.cell_size)
|
||||
|
||||
# Register unit in optimized collision system
|
||||
self.collision_system.register_unit(
|
||||
unit.id,
|
||||
@@ -182,11 +190,33 @@ class MiceMaze(
|
||||
unit.collision_layer
|
||||
)
|
||||
|
||||
# Maintain backward compatibility dictionaries (can be removed later)
|
||||
# Maintain backward compatibility dictionaries
|
||||
self.unit_positions.setdefault(unit.position, []).append(unit)
|
||||
self.unit_positions_before.setdefault(unit.position_before, []).append(unit)
|
||||
|
||||
# Third pass: check collisions and draw
|
||||
# Second pass: move all units (can now access collision system)
|
||||
for unit in self.units.copy().values():
|
||||
unit.move()
|
||||
|
||||
# Third pass: Update collision system with new positions after move
|
||||
self.collision_system.clear()
|
||||
self.unit_positions.clear()
|
||||
self.unit_positions_before.clear()
|
||||
|
||||
for unit in self.units.values():
|
||||
# Register with updated positions/bbox from move()
|
||||
self.collision_system.register_unit(
|
||||
unit.id,
|
||||
unit.bbox,
|
||||
unit.position,
|
||||
unit.position_before,
|
||||
unit.collision_layer
|
||||
)
|
||||
|
||||
self.unit_positions.setdefault(unit.position, []).append(unit)
|
||||
self.unit_positions_before.setdefault(unit.position_before, []).append(unit)
|
||||
|
||||
# Fourth pass: check collisions and draw
|
||||
for unit in self.units.copy().values():
|
||||
unit.collisions()
|
||||
unit.draw()
|
||||
@@ -205,7 +235,7 @@ class MiceMaze(
|
||||
def game_over(self):
|
||||
if self.game_end[0]:
|
||||
if not self.combined_scores:
|
||||
self.combined_scores = get_global_leaderboard(4)
|
||||
self.combined_scores = self.profile_integration.get_global_leaderboard(4)
|
||||
global_scores = []
|
||||
|
||||
for entry in self.combined_scores:
|
||||
|
||||
Reference in New Issue
Block a user