Implement optimized collision detection system using NumPy
- Introduced a hybrid collision detection approach that utilizes NumPy for vectorized operations, improving performance for games with many entities (200+). - Added a spatial grid for efficient lookups and AABB (Axis-Aligned Bounding Box) collision detection. - Implemented a new `CollisionSystem` class with methods for registering units, checking collisions, and managing spatial data. - Created performance tests to benchmark the new collision system against the old O(n²) method, demonstrating significant speed improvements. - Updated existing code to integrate the new collision detection system and ensure compatibility with game logic.
This commit is contained in:
+34
-20
@@ -1,5 +1,6 @@
|
||||
from .unit import Unit
|
||||
from .points import Point
|
||||
from engine.collision_system import CollisionLayer
|
||||
|
||||
import random
|
||||
import uuid
|
||||
@@ -13,7 +14,7 @@ BABY_INTERVAL = 50
|
||||
|
||||
class Rat(Unit):
|
||||
def __init__(self, game, position=(0,0), id=None):
|
||||
super().__init__(game, position, id)
|
||||
super().__init__(game, position, id, collision_layer=CollisionLayer.RAT)
|
||||
# Specific attributes for rats
|
||||
self.speed = 0.10 # Rats are slower
|
||||
self.fight = False
|
||||
@@ -72,30 +73,43 @@ class Rat(Unit):
|
||||
self.direction = self.calculate_rat_direction()
|
||||
|
||||
def collisions(self):
|
||||
"""
|
||||
Optimized collision detection using the vectorized collision system.
|
||||
Uses spatial hashing and numpy for efficient checks with 200+ units.
|
||||
"""
|
||||
OVERLAP_TOLERANCE = self.game.cell_size // 4
|
||||
|
||||
# Only adult rats can collide for reproduction/fighting
|
||||
if self.age < AGE_THRESHOLD:
|
||||
return
|
||||
units = []
|
||||
units.extend(self.game.unit_positions.get(self.position_before, []))
|
||||
units.extend(self.game.unit_positions.get(self.position, []))
|
||||
|
||||
for unit in units:
|
||||
if unit.id == self.id or unit.age < AGE_THRESHOLD or self.position != unit.position_before:
|
||||
continue
|
||||
x1, y1, x2, y2 = self.bbox
|
||||
ox1, oy1, ox2, oy2 = unit.bbox
|
||||
# Get collisions from the optimized collision system
|
||||
collisions = self.game.collision_system.get_collisions_for_unit(
|
||||
self.id,
|
||||
CollisionLayer.RAT,
|
||||
tolerance=OVERLAP_TOLERANCE
|
||||
)
|
||||
|
||||
# Process each collision
|
||||
for _, other_id in collisions:
|
||||
other_unit = self.game.get_unit_by_id(other_id)
|
||||
|
||||
# Verifica se c'è collisione con una tolleranza di sovrapposizione
|
||||
if (x1 < ox2 - OVERLAP_TOLERANCE and
|
||||
x2 > ox1 + OVERLAP_TOLERANCE and
|
||||
y1 < oy2 - OVERLAP_TOLERANCE and
|
||||
y2 > oy1 + OVERLAP_TOLERANCE):
|
||||
if self.id in self.game.units and unit.id in self.game.units:
|
||||
if self.sex == unit.sex and self.fight:
|
||||
self.die(unit)
|
||||
elif self.sex != unit.sex:
|
||||
if "fuck" in dir(self):
|
||||
self.fuck(unit)
|
||||
if not other_unit or other_unit.age < AGE_THRESHOLD:
|
||||
continue
|
||||
|
||||
# Check if units are actually moving towards each other
|
||||
if self.position != other_unit.position_before:
|
||||
continue
|
||||
|
||||
# Both units still exist in game
|
||||
if self.id in self.game.units and other_id in self.game.units:
|
||||
if self.sex == other_unit.sex and self.fight:
|
||||
# Same sex + fight mode = combat
|
||||
self.die(other_unit)
|
||||
elif self.sex != other_unit.sex:
|
||||
# Different sex = reproduction
|
||||
if "fuck" in dir(self):
|
||||
self.fuck(other_unit)
|
||||
|
||||
def die(self, unit=None, score=10):
|
||||
"""Handle rat death and spawn points."""
|
||||
|
||||
Reference in New Issue
Block a user