在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 个回答
这段内容和pygame或python没有直接关系,但可能对你有帮助。
Lazy Foo有很多关于SDL的很棒的教程,不过这些教程是用C++写的。不过它们的注释非常详细,容易理解。你可以在这里找到这些教程:http://www.lazyfoo.net/SDL_tutorials/index.php
彼得提到,你也发现了,处理碰撞检测时,用矩形比用位置要简单得多。
我想再进一步说:总是使用精灵!
使用精灵,你可以访问pygame.sprite
中的所有方便的碰撞检测功能。如果你决定移动这个图像,更新位置和动画会简单得多。精灵还包含了图像表面,所有这些都在一个对象里。更不用说精灵组了!
精灵还有一个.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)
这样就可以一次性绘制所有图像,每个图像都在自己的位置上!酷吧?
让我们为鼠标光标创建一个“假”精灵:
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
你只用一行代码就测试了与所有图像的碰撞,不仅知道是否有碰撞,还知道是哪一个发生了碰撞!
使用精灵真的很划算;)
问题在于,pygame.sprite.collide_rect() 这个函数需要两个 Sprite 对象作为参数。你现在传入的是两个元组——光标和图像都不是 Sprite,因此它们没有 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!'
注意,我在检查光标是否在图像内之前,先判断鼠标是否移动过,以避免不必要的重复计算。