Обнаружение столкновений - это широкая тема, особенно если вы хотите узнать, с какой стороны произошла сборка. (Общий подход в plattformers состоит в том, чтобы выполнить обнаружение столкновения дважды, один раз для горизонтального и один раз для вертикального движения, как в 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» имеет четыре края, поэтому края двух из них могут сталкиваться или «касаться» разными способами. Пожалуйста, опишите точно, какие комбинации вы хотите обнаружить. Кроме того, вы считали бы, что два горизонтальных ребра сталкиваются, если они были нарисованы в двух соседних смежных положениях или только тогда, когда они были точно друг на друга? – martineau