碰撞检测是一个广泛的话题,特别是如果您想知道收集发生在哪一侧。(平台中的一种常见方法是进行两次碰撞检测,一次用于水平移动,一次用于垂直移动,就像在这个例子中一样)。
如果您只想知道 a 是否Rect
与 another 的底部发生碰撞Rect
,以下示例代码应该是一个很好的起点:
def collide_top(a, b):
return a.top <= b.bottom <= a.bottom and (a.left <= b.left <= a.right or b.left <= a.left <= b.right)
def collide_bottom(a, b):
return a.bottom >= b.top >= a.top and (a.left <= b.left <= a.right or b.left <= a.left <= b.right)
def collide_left(a, b):
return a.left <= b.right <= a.right and (a.top <= b.top <= a.bottom or b.top <= a.top <= b.bottom)
def collide_right(a, b):
return a.right >= b.left >= a.left and (a.top <= b.top <= a.bottom or b.top <= a.top <= b.bottom)
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
center = Rect((100, 100, 100, 100))
player = Rect((10, 0, 75, 75))
move = {K_UP: ( 0, -1),
K_DOWN: ( 0, 1),
K_LEFT: (-1, 0),
K_RIGHT: ( 1, 0)}
while True:
screen.fill((0, 0 ,0))
pressed = pygame.key.get_pressed()
for d in [m for (k, m) in move.items() if pressed[k]]:
player.move_ip(*d)
pygame.draw.rect(screen, (120, 0, 120), center, 3)
pygame.draw.rect(screen, (0, 200, 55), player, 2)
# check if 'player' collides with the bottom of 'center'
print collide_bottom(center, player)
pygame.display.flip()
if pygame.event.get(QUIT): break
pygame.event.poll()
clock.tick(60)
(在这张图片中,player
与底部和左侧碰撞center
,但不与顶部或右侧碰撞)
一些进一步的问题:
当一个矩形完全在另一个矩形内时会发生什么?在这种情况下,它会与所有边缘碰撞还是不碰撞?
回应您的评论:
您可以简单地将碰撞检查更改为
def collide_top(a, b):
return a.top == b.bottom and (a.left <= b.left <= a.right or b.left <= a.left <= b.right)
def collide_bottom(a, b):
return a.bottom == b.top and (a.left <= b.left <= a.right or b.left <= a.left <= b.right)
def collide_left(a, b):
return a.left == b.right and (a.top <= b.top <= a.bottom or b.top <= a.top <= b.bottom)
def collide_right(a, b):
return a.right == b.left and (a.top <= b.top <= a.bottom or b.top <= a.top <= b.bottom)