在Pygame中点击精灵时遇到麻烦

时间:2014-08-15 19:18:50

标签: python pygame

对不起,如果这个问题是重复的,但是我已经在这个网站上的许多页面试图找到答案,而我还没有能够找到一个工作。 我使用过的一些页面是:

Pygame mouse clicking detection

self.rect not found?

how does collide.rect work in pygame

可能是我缺乏编码理解,如果是这样的话,我道歉。但是,我找到了最有帮助的#34;页面是第一个链接。使用Sloth的第一个答案,它看起来非常简单,我可以做的事情。一旦他的方法不起作用,我尝试在YouTube和其他网站上搜索更多内容。我也找不到答案。

我想做的只是打印"点击"当点击一个精灵时。这是我的代码。

import pygame
size = (700,500)
screen = pygame.display.set_mode(size)
done = False
clock = pygame.time.Clock()
itunes = pygame.image.load('itunes.png')
screen.blit(itunes,(200,200))
sprites = [itunes]
while not done:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            clicked_sprites = [s for s in sprites if s.rect.collidepoint(pos)]
            for i in clicked_sprites:
                print('clicked sprite')
    pygame.display.flip()
    clock.tick(60)

我对Python语言的了解很少,但我发现自己厌倦了制作相同的基于文本的程序,并希望继续前进。

编辑:对不起,我应该说明了我的错误。我得到了:AttributeError:' pygame.Surface'对象没有属性' rect'

编辑:在屏幕上绘制图像时遇到问题

import pygame
size = (700,500)
screen = pygame.display.set_mode(size)
done = False
clock = pygame.time.Clock()
white = (0,0,0)
image = 'itunes.png'
class Thing(pygame.sprite.Sprite):
    def __init__(self, image, x, y):
        self.image = pygame.image.load('itunes.png')
        self.x = x
        self.y = y

    @property
    def rect(self):
        return self.image.get_rect(topleft=(self.x, self.y))

itunes = Thing(image,200,200)

SpriteGroup = pygame.sprite.Group()    
SpriteGroup.add(itunes)                

while not done:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            clicked_sprites = [s for s in SpriteGroup if s.rect.collidepoint(pos)]
            for i in clicked_sprites:
                print('clicked sprite')
    screen.fill((0, 0, 0))             
    SpriteGroup.draw(screen)           
    pygame.display.flip()
    clock.tick(60)

2 个答案:

答案 0 :(得分:1)

图片是pygame.Surface个对象,他们没有rect作为属性。但是,您可以通过调用SurfaceObject.get_rect() 获取一个Surface对象。这将创建一个pygame.Rect对象,表示Surface的尺寸,如果不是它的位置。

根据您的对象创建新rect的频率或根据其在窗口中的位置对其进行修改,您可以继承pygame.sprite.Sprite并使用属性在正确的位置检索Rect。例如:

class Thing(pygame.sprite.Sprite):
    def __init__(self, image, x, y):
        super(Thing, self).__init__()    #don't forget to do this!! (like I did :D, haha)
        self.image = pygame.image.load(image)
        self.x = x
        self.y = y

    @property
    def rect(self):
        return self.image.get_rect(topleft=(self.x, self.y))

surface.get_rect()调用采用关键字参数,允许您在创建对象时设置对象的属性。通过这种方式,它基本上只用于:

new_rect = self.image.get_rect()
new_rect.x = self.x
new_rect.y = self.y
return new_rect

整个过程返回一个位于窗口中正确位置的矩形,这样它就可以用于碰撞检测,或只是看它是否是你示例中点击的对象。

这种方法的另一个结果(使用rect的属性)是它使对象与pygame.sprite.Group.draw()方法一起工作,该方法绘制了Sprite中的所有Group个对象1}}通过blitting obj.imageobj.rect属性来对象。

因此,您可以将spriteslist转换为sprite.Group对象,并对代码进行以下更改,从而充分利用此功能:

SpriteGroup = pygame.sprite.Group()    #use these for working with Sprite objects
SpriteGroup.add(itunes)                #add itunes to sprites Group
while not done:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            clicked_sprites = [s for s in sprites if s.rect.collidepoint(pos)]
            for i in clicked_sprites:
                print('clicked sprite')
    screen.fill((0, 0, 0))             #wipes the screen
    SpriteGroup.draw(screen)           #draws every Sprite object in this Group
    pygame.display.flip()
    clock.tick(60)

答案 1 :(得分:0)

让我们来看看您的代码所做的事情。

  • 您将新图像加载到itunes变量中。
  • 您将此图像以200,200
  • 显示在屏幕上
  • 您将图像添加到精灵列表中。
  • 单击鼠标时,循环精灵列表以检查鼠标点是否位于精灵列表中对象的矩形。

现在我们如何知道精灵列​​表中对象的位置?答案是我们没有。没有关于物体在表面本身位置的信息。

要解决此问题,您可以创建自己的Sprite类,其中包含rect和曲面,或者更优选使用已包含rect的pygame.sprite.Sprite