在Pygame中使用精灵进行碰撞检测

时间:2011-01-13 05:06:55

标签: python collision-detection pygame

我正在尝试使用碰撞检测来检测我的鼠标何时触及我导入的图像。我收到错误“元组没有属性rect”

 def main():


    #Call the SDL arg to center the window when it's inited, and then init pygame
    os.environ["SDL_VIDEO_CENTERED"] = "1"
    pygame.init()

    #Set up the pygame window
    screen = pygame.display.set_mode((600,600))


    image_one = pygame.image.load("onefinger.jpg").convert()

    screen.fill((255, 255, 255))
    screen.blit(image_one, (225,400))
    pygame.display.flip()

    while 1:
        mousecoords = pygame.mouse.get_pos() 
        left = (mousecoords[0], mousecoords[1], 10, 10)
        right = image_one.get_bounding_rect()
        if pygame.sprite.collide_rect((left[0]+255, left[1]+400, left[2], left[3]), right):
            print('Hi')

3 个答案:

答案 0 :(得分:1)

问题是pygame.sprite.collide_rect()需要两个Sprite对象。你传递了两个元组 - 光标和图像都不是精灵,因此没有矩形属性。

你可以使用image_one创建一个Sprite,但将光标转换为Sprite会更加棘手。我认为手动测试光标是否在图像中会更容易。

#Set up the pygame window
screen = pygame.display.set_mode((200,200))
screen.fill((255, 255, 255))

#Set up image properties (would be better to make an object)
image_one = pygame.image.load("image_one.png").convert()
image_x = 225
image_y = 400
image_width = image_one.get_width()
image_height = image_one.get_height()

# Mouse properties
mouse_width = 10
mouse_height = 10

screen.blit(image_one, (image_x, image_y))
pygame.display.flip()

while 1:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEMOTION:
            mouse_x, mouse_y = pygame.mouse.get_pos()

            # Test for 'collision'
            if image_x - mouse_width < mouse_x < image_x + image_width and image_y - mouse_height < mouse_y < image_y + image_height:
                print 'Hi!'

请注意,在测试鼠标是否在图像中之前,我会测试鼠标是否已移动,以避免不必要地重复计算。

答案 1 :(得分:0)

这与pygame或python无关,但可能有所帮助。

Lazy Foo为SDL提供了许多很棒的教程,但它们都是用C ++编写的。他们评论得非常好。它们的链接位于:http://www.lazyfoo.net/SDL_tutorials/index.php

答案 2 :(得分:0)

彼得建议,并且你也明白了,在处理碰撞检测时,使用 Rects 而不是位置更容易。

我会更进一步:始终使用 Sprites

使用Sprites,您可以访问pygame.sprite中所有便捷的碰撞检测功能。如果您决定移动该图像,则更新位置和动画会更容易。它还包含图像表面,所有这些都在一个对象中。更不用说sprite Groups

Sprites也有一个.rect属性,因此如果您想使用mysprite.rect

,可以随时进行低级别的直接操作

那就是说,你可以从图像中获取精灵:

image_one = pygame.sprite.Sprite()
image_one.image = pygame.image.load("image_one.png").convert()
image_one.rect = pygame.Rect((image_x, image_y), image_one.image.get_size())

image_two_three等创建更多精灵。或者创建一个函数(或者更好的是,子类Sprite),接收位置和文件名作为参数,这样你就可以创建行中的精灵:

image_two = MySprite(filename, x, y)

现在您可以选择将它们分组:

my_images = pygame.sprite.Group(image_one, image_two, image_three)

绘图就像:

my_images.draw(screen)

这将会立即blit 所有图片 ,每个人都在自己的位置!很酷,嗯?

让我们为鼠标光标创建一个“假的”Sprite:

mouse = pygame.sprite.Sprite()
mouse.rect = pygame.Rect(pygame.mouse.get_pos(), (1, 1))

我已经使它成为1x1精灵,所以它只会碰撞鼠标热点。请注意,它没有.image属性(因此是“假”精灵),但是pygame并不关心,因为我们无论如何都不会绘制它。

现在最好的部分:

imagehit = pygame.sprite.spritecollideany(mouse, my_images)
print imagehit

在单行中,您测试了与所有图片的碰撞,并且您不仅知道如果鼠标与任何图片相撞,还 哪一个 确实如此!

使用精灵确实是值得的;)

相关问题