Uma collision ocorre quando dois objetos se sobrepõem no espaço. Detectá-la é essencial para: receber dano, coletar itens, bloquear o movimento, atirar, e mais.
Pygame oferece vários níveis de precisão, com um trade-off claro:
Faster ←──────────────────────────────→ More Precise
Rect-Rect Circle-Circle Pixel-perfect
(AABB) (distance) (mask)
Rect-Rect Collision (AABB)
AABB = Axis-Aligned Bounding Box. O método mais rápido e mais usado.
# Method 1: rect.colliderect()if player.rect.colliderect(enemy.rect):print("Collision!")# Method 2: rect.collidepoint() — point inside rectif player.rect.collidepoint(pygame.mouse.get_pos()):print("Mouse is over the player")# Method 3: rect.collidelist() — against a list of rectsindex = player.rect.collidelist([rect1, rect2, rect3])# Returns the index of the first collided rect, or -1
Rect-Rect Collision (AABB)
AABB = Axis-Aligned Bounding Box. O método mais rápido e mais usado.
# Method 1: rect.colliderect()if player.rect.colliderect(enemy.rect):print("Collision!")# Method 2: rect.collidepoint() — point inside rectif player.rect.collidepoint(pygame.mouse.get_pos()):print("Mouse is over the player")# Method 3: rect.collidelist() — against a list of rectsindex = player.rect.collidelist([rect1, rect2, rect3])# Returns the index of the first collided rect, or -1
Implementação Manual de AABB
AABB Collision — tests:
=======================================================
Parcialmente sobrepostos → ✅ COLLISION
Separados horizontalmente → ❌ sem COLLISION
B totalmente dentro de A → ✅ COLLISION
Apenas se tocando (borda) → ✅ COLLISION
Separados por 1px → ❌ sem COLLISION
Circle-Circle Collision
Mais preciso para objetos redondos (balas, moedas, personagens circulares). A lógica: há collision entre dois círculos se a distância entre seus centros for menor que a soma de seus raios.
A B
(●) (●)
←── d ──→
If d < rA + rB → collision
Circle-Circle Collision
Mais preciso para objetos redondos (balas, moedas, personagens circulares). A lógica: há collision entre dois círculos se a distância entre seus centros for menor que a soma de seus raios.
Esta é a função de collision mais poderosa do Pygame.
# Detect collision of ONE sprite against a GROUPhits = pygame.sprite.spritecollide( player, # individual sprite bullets, # group to check againstTrue# True = remove colliding sprites from the group)# hits is a list of sprites that collidedif hits: health -=len(hits)# Detect collisions between TWO GROUPSclashes = pygame.sprite.groupcollide( bullets, # group 1 enemies, # group 2True, # remove from group 1True# remove from group 2)# clashes is a dict: {bullet: [enemies_hit], ...}# Using circular collision (more precise)hits = pygame.sprite.spritecollide( player, bullets, True, collided=pygame.sprite.collide_circle)# Using pixel masks (maximum precision, slowest)hits = pygame.sprite.spritecollide( player, bullets, True, collided=pygame.sprite.collide_mask)
Collision Response
Detectar a collision é apenas metade do trabalho. A outra metade é o que fazer quando isso acontece.
Collision Response
Detectar a collision é apenas metade do trabalho. A outra metade é o que fazer quando isso acontece.
Padrão 1 — Separation (platforms, paredes)
# Move first, then correctplayer.rect.x += vel_xfor platform in platforms:if player.rect.colliderect(platform.rect):if vel_x >0: # Moving right player.rect.right = platform.rect.leftelif vel_x <0: # Moving left player.rect.left = platform.rect.right vel_x =0
Collision Response
Detectar a collision é apenas metade do trabalho. A outra metade é o que fazer quando isso acontece.
Padrão 1 — Separation (platforms, paredes)
# Move first, then correctplayer.rect.x += vel_xfor platform in platforms:if player.rect.colliderect(platform.rect):if vel_x >0: # Moving right player.rect.right = platform.rect.leftelif vel_x <0: # Moving left player.rect.left = platform.rect.right vel_x =0
Collision method comparison
============================================================
Method Cost Precision When to use
--------------------------------------------------------------------------------
AABB (Rect-Rect) O(1) Baixa — caixa invisível Plataformas, itens, a maioria dos objetos
Circle-Circle O(1) Média — circular Balas, moedas, personagens redondos
collide_rect_ratio O(1) Média — rect reduzido Hitbox menor que o sprite
collide_mask O(n) Máxima — pixel a pixel Bosses, formas irregulares (usar com moderação)
Regra geral: comece com AABB. Troque apenas quando a imprecisão
for perceptível. Reserve collide_mask para pouquíssimos sprites.
Collisions — Resumo
AABB (colliderect) = o mais rápido, suficiente para a maioria dos casos
spritecollide(sprite, group, kill) = collision de um contra muitos
groupcollide(g1, g2, k1, k2) = collision de group contra group
A response depende do tipo: separate, bounce, ou destroy