碰撞檢測是一個廣泛的話題,特別是如果你想知道收集從哪一側發生的話。 (在platformer中常見的做法是進行兩次碰撞檢測,一次是水平方向,一次是垂直方向運動,如this example)。
如果你只是想知道,如果一個Rect
與另一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
的底部和左側碰撞,但不與頂部或右側碰撞)
一些進一步的問題:
當一個矩形完全在另一個矩形內時會發生什麼?在這種情況下它會與所有邊緣碰撞還是沒有碰撞?
在回答您的comment:
您可以簡單地改變碰撞檢查
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)
你想知道'rect_a.bottom == rect_b.top'? – ninMonkey
是的,確切地說。我嘗試編碼的確如此,但它處理的是像無限寬的矩形,所以如果它與另一個矩形一樣位於屏幕的同一層,則會觸發輸出。我正在尋找屏幕上的特定線段......還有什麼想法? – user2597443
一個'Rect'有四條邊,所以它們中的兩條邊可能以多種方式碰撞或「碰觸」。請準確描述您想要檢測的組合。另外,如果在兩個緊鄰的x位置繪製兩個水平邊緣,或者僅當它們恰好在另一個上面時,你會考慮兩個水平邊緣是否會發生碰撞? – martineau