需要帮助处理pygame spritegroups

1 投票
1 回答
1046 浏览
提问于 2025-04-17 01:34

我对pygame的Chimp示例做了一些修改,把Chimp的图片换成了一个圆圈和一条从圆心画出的线。同时,我把拳头换成了一个10x10的黑色方块。

我遇到的问题是这样的。

当这个黑色方块(拳头)打到圆圈(Chimp)时,圆圈(Chimp)需要旋转360度。对于Chimp类中描述的单个圆圈精灵,这个效果很好,但当我创建多个精灵并把它们放到一个精灵组中时,只有第一个创建的精灵会旋转,其他的圆圈(Chimp)精灵却没有反应。有没有人能告诉我该怎么解决这个问题?我使用的是Python 3.x和pygame 1.9。

    #Import Modules
    import os, pygame
    from pygame.locals import *
    from pygame.compat import geterror
    import random

    def load_image(x=40,y=40,r=0,g=0,b=0):
        image = pygame.Surface((x,y))
        image.fill((r,g,b))
        pygame.draw.circle(image,(r,g,255),(20,20),10)
        pygame.draw.line(image,(r,255,b),(20,20),(30,30),2)
        image = image.convert()
        image.set_colorkey((255,0,0))
        return image, image.get_rect()
    class Fist(pygame.sprite.Sprite):
        def __init__(self):
             pygame.sprite.Sprite.__init__(self)
             self.image,self.rect = load_image(x=10,y=10)
             self.punching = 0

        def update(self):
             pos = pygame.mouse.get_pos()
             self.rect.midtop = pos
             if self.punching:
                 self.rect.move_ip(5,10)

        def punch(self,target) :
             if not self.punching:
                 self.punching = 1
                 hitbox = self.rect.inflate(-5,-5)
                 return hitbox.colliderect(target.rect)

        def unpunch(self):
                 self.punching = 0

    class Chimp (pygame.sprite.Sprite):

        def __init__(self):
             pygame.sprite.Sprite.__init__(self)
             self.image,self.rect = load_image(r=255)
             screen = pygame.display.get_surface()
             self.area = screen.get_rect()
             self.rect.topleft = random.randint(0,300),random.randint(0,300)
             self.move = 0
             self.dizzy = 0
        def update(self):
             if self.dizzy:
                   self._spin()
             else:
                   self._walk()
        def _walk(self):
             newpos = self.rect.move((self.move,0))
             if self.rect.left < self.area.left or self.rect.right > self.area.right:
                   self.move = -self.move
                   newpos = self.rect.move((self.move,0))
             self.rect = newpos
         def _spin(self) :
             center = self.rect.center
             self.dizzy = self.dizzy + 6
             if self.dizzy >= 360:
                   self.dizzy = 0
                   self.image = self.original
             else :
                   rotate = pygame.transform.rotate
                   self.image = rotate(self.original,self.dizzy)
             self.rect = self.image.get_rect(center=center)

         def punched(self):
             if not self.dizzy:
                   self.dizzy = 1
                   self.original = self.image

    def main():

         pygame.init()
         screen = pygame.display.set_mode((640,480))

         background = pygame.Surface(screen.get_size())
         background = background.convert()
         background.fill((250,250,250))

         screen.blit(background,(0,0))
         pygame.display.flip()

         clock = pygame.time.Clock()

         fist = Fist()
         allsprites = pygame.sprite.Group()
         for i in range(10):
             chimp = Chimp()
             allsprites.add(chimp)
         fistsprite = pygame.sprite.Group((fist))
         going = True
         while going:
             clock.tick(60)

             for event in pygame.event.get():
                  if event.type == QUIT:
                      going = False
                  elif event.type == MOUSEBUTTONDOWN:
                      for chimp in allsprites.sprites:
                           if fist.punch(chimp):
                               chimp.punched()

                  elif event.type == MOUSEBUTTONUP:
                      fist.unpunch()

             allsprites.update()
             fistsprite.update()

             screen.blit(background,(0,0))
             allsprites.draw(screen)
             fistsprite.draw(screen)
             pygame.display.flip()
         pygame.quit()

    if __name__ == '__main__':
         main()

1 个回答

1

答案在于 punch 方法:

def punch(self,target) :
    if not self.punching:
        self.punching = 1
        hitbox = self.rect.inflate(-5,-5)
        return hitbox.colliderect(target.rect)

属性 self.punching 对于第一个猩猩被设置为1。对于其他的猩猩来说,这段代码就不再执行了,因为 self.punching 已经是1了。

试着把最后两行的缩进去掉:

def punch(self,target) :
    if not self.punching:
        self.punching = 1
    hitbox = self.rect.inflate(-5,-5)
    return hitbox.colliderect(target.rect)

这样做会增加一个新的“功能”,就是你可以在还没有取消拳击之前再次出拳。

撰写回答