I'm trying to build a simulation on python.
I want a grid of 50x50 cells of different colors And balls that spawn on the grid and move until they collid a cell of another color.
When a ball collide a cell of another color, the cell change her color and the ball disapear.
The basics of the simulation is working but i'm facing a huge performance issue.
Below ~40 balls, i'm able to keep a 60FPS simulation. but when i have more (and i would like to handle thousands balls without problem) the FPS are impacted.
How could i optimize this collision detection please? here is part of the code:
GRID_SIZE = 50
CELL_SIZE = 10
self.balls = arcade.SpriteList()
self.cells = arcade.SpriteList(use_spatial_hash=True, spatial_hash_cell_size=CELL_SIZE)
def on_update(self, delta_time):
self.balls.update()
class Cell(arcade.SpriteSolidColor):
def __init__(self, x, y, color, grid_app):
super().__init__(CELL_SIZE, CELL_SIZE, arcade.color.WHITE)
self.gridApp = grid_app
self.center_x = x
self.center_y = y
self.update_color(color)
def update_color(self, color):
self.color = color
class Ball(arcade.Sprite):
def __init__(self, x, y, velocity, angle, spriteConf, grid_app, scale=1):
super().__init__(SPRITE_CONF[spriteConf]["imagePath"], scale=scale)
self.center_x = x
self.center_y = y
self.my_color=SPRITE_CONF[spriteConf]["color"]
self.velocity = velocity
self.my_angle = angle
self.gridApp = grid_app
def update(self):
self.center_x += self.velocity * REFRESH_RATE * math.cos(math.radians(self.my_angle))
self.center_y += self.velocity * REFRESH_RATE * math.sin(math.radians(self.my_angle))
# Check for collision with grid sides
if self.center_x < 0 or self.center_x > WINDOW_WIDTH:
self.my_angle = 180 - self.my_angle
if self.center_y < 0 or self.center_y > WINDOW_HEIGHT:
self.my_angle = 360 - self.my_angle
################################################################################
# HERE THE SLOW CODE #
################################################################################
collidedCells = arcade.check_for_collision_with_lists(
self,
[
self.gridApp.cells
]
)
hasToBeDelete = False
for cell in collidedCells:
if cell.color != self.my_color:
hasToBeDelete = True
cell.update_color(self.my_color)
if hasToBeDelete:
self.gridApp.removeBall(self)
################################################################################
# HERE THE SLOW CODE #
################################################################################
This is what the game looks like at the max balls before starting having FPS issues: