Pygame中使用精灵的碰撞检测

问题描述:

我正尝试使用碰撞检测来检测我的鼠标何时击中了我导入的图像。我得到错误“元组没有属性矩形”Pygame中使用精灵的碰撞检测

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') 

问题是,pygame.sprite.collide_rect()需要两个Sprite对象。你传递给它两个元组 - 游标和图像都不是Sprites,所以缺少rect属性。

您可以使用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!' 

注意,我测试鼠标是否已经测试它是否是图像中的前移动,以避免不必要的重复计算。

+0

非常好的帮助!我发现了一个更简单的方法来解决它。当你将图像“blit”到屏幕上时,它会返回一个Rect。您只需指定一个等于该矩形的变量,即:FirstL_Rect = screen.blit(image_one,(185,400)),然后使用“碰撞”功能执行碰撞检测。你可以通过简单地做这个来改变你的mous einto: mousecoords = pygame.mouse.get_pos() coordinateRect = Rect(mousecoords [0],mousecoords [1],10,10) – Parseltongue 2011-01-16 00:39:30

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

Lazy Foo为SDL提供了许多优秀的教程,但它们都是用C++编写的。尽管他们评论非常好。他们的链接在这里:http://www.lazyfoo.net/SDL_tutorials/index.php

彼得建议,你也想通了,它的更容易碰撞检测处理时Rects工作位置代替。

我会更进一步:总是与精灵

使用精灵,您可以访问pygame.sprite中所有那些方便的碰撞检测功能。如果您决定移动该图像,则更新位置和动画更容易。它还包含图像表面,全部在一个对象中。更不用说雪碧了群组

精灵也有.rect属性,所以你总是可以做低水平的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 所有图像,每一个在其自己的位置!很酷,嗯?

让我们创建一个“假”雪碧鼠标光标:

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 

在你测试对碰撞的所有图像单行线,而不是只有你知道如果鼠标相撞任何,也哪一个它做到了!

确实值得使用Sprites;)