I’m working on a machine learning project where I need to teach an AI agent to navigate around obstacles using pygame. The setup is similar to the classic Snake game where the AI needs to avoid walls and player trails.
My current approach uses multiple sensors that extend from each player to detect nearby obstacles. Each sensor is built from several small rectangular sprites that check for collisions with obstacle sprites. When a collision happens, I calculate the distance and pass this data to the neural network.
However, the collision detection is extremely slow and takes up around half of my program’s execution time according to profiling results.
Here’s my current sensor implementation:
def generate_sensor_rays(player_x, player_y, heading, ray_spacing, field_of_view, ray_length):
directions = [angle for angle in np.ceil(np.arange(heading-field_of_view, heading+field_of_view, ray_spacing))]
move_x = np.cos(np.deg2rad(heading))
move_y = np.sin(np.deg2rad(heading))
return list(map(functools.partial(build_ray_segments, player_x, player_y, ray_length), directions))
def make_segment(player_x, player_y, delta_x, delta_y, step):
return create_sprite(player_x + step * delta_x, player_y + step * delta_y, 1, 1, 0, RED)
build_segment = make_segment
def build_ray_segments(player_x, player_y, max_length, direction):
segments = pygame.sprite.Group()
add_segment = segments.add
delta_x = np.cos(np.deg2rad(direction))
delta_y = np.sin(np.deg2rad(direction))
steps = [step for step in range(2, max_length, 8)]
add_segment(map(functools.partial(build_segment, player_x, player_y, delta_x, delta_y), steps))
return segments
build_ray = build_ray_segments
My obstacle class:
class GameObstacle(pygame.sprite.Sprite):
def __init__(self, pos_x, pos_y, w, h, rotation, sprite_color):
super().__init__()
self.image = pygame.Surface([w, h])
self.image.fill(sprite_color)
self.rect = self.image.get_rect()
self.rect.centerx = pos_x
self.rect.centery = pos_y
I’ve tried several optimizations like using map functions instead of loops and caching function references, but nothing helped much. I also experimented with Bresenham’s algorithm for line drawing, which was faster but missed obstacles because it only checked exact pixel coordinates rather than overlapping areas.
What are some better approaches for fast obstacle detection in pygame? Any suggestions for improving this collision system would be really helpful.