如何在Pygame中为rect指定和测试属性

时间:2013-07-23 21:33:03

标签: python attributes pygame collision rect

这个问题不需要代码,但这是一个我无法在其他地方找到答案的问题。

如何测试Pygame中的rects只在rect的边缘碰撞?我看了http://www.pygame.org/docs/ref/rect.html,感觉答案就在那里,但是我看不到它。这非常重要,我希望这是一个简单的解决方案,并且可以回答。

if <rectname>.colliderect.bottom(<otherRect>):
    output = True

^不起作用,但我怀疑答案可能类似。如果有人可以提供帮助,请提前致谢!

1 个答案:

答案 0 :(得分:1)

碰撞检测是一个广泛的主题,特别是如果您想知道收集发生在哪一方。 (平台游戏中常见的方法是两次进行碰撞检测,一次用于水平,一次用于垂直移动,如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)

enter image description here

(在此图片中,playercenter的底部和左侧发生碰撞,但不与顶部或右侧碰撞)

还有一些问题:

当一个矩形完全进入另一个矩形时会发生什么?在这种情况下它是否与所有边缘碰撞或没有碰撞?


回复您的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)