玩家和精灵组mudballGroup之间Pygame中的碰撞检测

时间:2017-04-08 13:15:56

标签: python pygame

我正在学习如何检测类Player和精灵组MudballGroup之间的冲突。在语句pg.sprite.spritecollide(Player,mudballGroup,False)中设置碰撞时,我得到错误类型对象'Player'没有属性'rect'。我在这里使用了我的Player精灵的代码,它显示了在以下语句中定义的rect:self.rect = self.image.get_rect()。我不知道为什么我会收到这个错误。请有人帮忙。

class Player(pg.sprite.Sprite):
     def __init__(self, game):
       pg.sprite.Sprite.__init__(self)
       self.game = game
       self.walking = False
       self.jumping = False
       self.current_frame = 0
       self.last_update = 0
       self.load_images()
       self.image = self.girl_standing[0]
       #Isn't this my rect attribute for Player?
       self.rect = self.image.get_rect()
       self.rect.center = (WIDTH / 2, HEIGHT / 2)
       self.pos = vec(WIDTH / 2, HEIGHT / 2)
       self.vel = vec(0, 0)
       self.acc = vec(0, 0)
       self.screen = pg.display.set_mode((WIDTH, HEIGHT))
       self.clock = pg.time.Clock()

 def shoot(self):

          mudball = MUDBALL(self.rect.centerx, self.rect.centery)
          print("SHOOT function")
          self.game.all_sprites.add(mudball)

          mudballGroup = pg.sprite.Group()
          mudballGroup.add(mudball)

 # Me attempting collision

        hits = pg.sprite.spritecollide(self.player, mudballGroup, False)
        if hits:
            print("HITS!!!!!!!!", hits)


def hailing(self):
        jets = JETS()
        print("FLYOVER")
        self.game.all_sprites.add(jets)
        jetsGroup = pg.sprite.Group()

        jetsGroup.add(jets)

 class MUDBALL(pg.sprite.Sprite):
      def __init__(self, x, y):
          pg.sprite.Sprite.__init__(self)
          self.image = pg.image.load("SLIMEballGREEN.png")
          # self.mudballGroup = pg.sprite.Group()
          self.rect = self.image.get_rect()
          self.rect.bottom = y
          self.rect.centerx = x
          self.speedx = -30


  def update(self):
          self.rect.x += self.speedx
          #kill if moves off screen
          if self.rect.centerx < 0:
            self.kill()

 class JETS(pg.sprite.Sprite):
     def __init__(self):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load("JETSscaled.png")
        #self.jetsGroup = pg.sprite.Group()
        self.rect = self.image.get_rect()
        self.rect.x = 1366
        self.rect.y = 0
        self.speedx = -70

 def update(self):
        self.rect.x += self.speedx
        #kill if moves off screen
        if self.rect.x + 848 < 0:
            self.kill()

1 个答案:

答案 0 :(得分:1)

您正在使用Player类进行碰撞检测,但您必须使用此类的实例。

# Player is the class, but spritecollide needs an instance.
hits = pg.sprite.spritecollide(Player, mudballGroup, False)

要创建Player类的实例,只需写:

# Don't forget to pass the game instance to the `Player`s __init__ method.
player = Player(game)

对我来说,在mudballGroup方法中定义shoot也很奇怪。这意味着该组只会包含一个泥球,但您还可以检查玩家和泥球的影响是否发生碰撞:player.rect.colliderect(mudball.rect)而不是spritecollide。但是,如果你想要多个泥球,你需要将mudballGroup存储为另一个类的属性,在__init__方法中写:

self.mudballGroup = pg.sprite.Group()

编辑:好的,您的游戏实例中已经有self.player个实例。我建议您同时在mudballGroup课程中定义Game,然后将all_sprites群组传递给玩家的shoot方法以添加泥球。碰撞检测可以在游戏的update方法中完成。

class Game:

    def new(self):
        # Other code omitted ...
        self.mudballGroup = pg.sprite.Group()

    def update(self):
        # Check if the player is shooting.
        if self.player.shooting:  # You have to add a `shooting` attribute to player.
            # `shoot` just adds a mudball to these groups.
            self.player.shoot(self.all_sprites, self.mudballGroup)
        # Then detect collisions.
        hits = pg.sprite.spritecollide(self.player, self.mudballGroup, False)
        if hits:
            print("HITS!!!!!!!!", hits)


class Player(pg.sprite.Sprite):

    # Pass the sprite groups of the game to the shoot method.
    def shoot(self, all_sprites, mudballGroup):
        mudball = MUDBALL(self.player.centerx, self.player.centery)
        # Add sprite to the passed groups.
        all_sprites.add(mudball)
        mudballGroup.add(mudball)

编辑2 :这是另一种变体。在创建实例时将两个所需的sprite组传递给播放器(您不必传递完整的游戏实例),然后将它们设置为播放器的属性。

class Game:

    def new(self):
        # Other code omitted ...
        self.all_sprites = pg.sprite.Group()
        self.mudballGroup = pg.sprite.Group()
        self.player = Player(self.all_sprites, self.mudballGroup)

    def update(self):
        # Check if the player is shooting.
        if self.player.shooting:
            # `shoot` adds a mudball to self.all_sprites & self.mudballGroup.
            self.player.shoot()
        # Then detect collisions.
        hits = pg.sprite.spritecollide(self.player, self.mudballGroup, False)
        if hits:
            print("HITS!!!!!!!!", hits)


class Player(pg.sprite.Sprite):

    def __init__(self, all_sprites, mudballGroup):
        # Other code omitted ...
        # These two attributes are references to the groups
        # that were defined in the Game class.
        self.all_sprites = all_sprites
        self.mudballGroup = mudballGroup

    def shoot(self):
        mudball = MUDBALL(self.player.centerx, self.player.centery)
        # Add sprite to the passed groups.
        self.all_sprites.add(mudball)
        self.mudballGroup.add(mudball)

编辑3 :好的,忘记shooting属性(只有在播放器实例检查用户是否正在拍摄时才需要)。你也不需要在Game类中调用trump的shoot方法,因为你已经用他的update方法调用了它。所以这是更新的代码:

class Game(pg.sprite.Sprite):

    def new(self):
        # Other code omitted ...
        self.all_sprites = pg.sprite.Group()
        self.mudballGroup = pg.sprite.Group()
        # Pass the groups to trump during the instantiation.
        # You don't have to pass the complete game instance (self).
        self.trump = TRUMP(self.all_sprites, self.mudballGroup)
        self.all_sprites.add(self.trump)

    def update(self):
        hits = pg.sprite.spritecollide(self.player, self.mudballGroup, False)
        for collided_sprite in hits:
            print("HIT", collided_sprite)


class TRUMP(pg.sprite.Sprite):

    def __init__(self, all_sprites, mudballGroup):
        # Now set the passed groups as attributes of the trump instance.
        # These attributes are references to the same sprite groups as
        # in the Game class.
        self.all_sprites = all_sprites
        self.mudballGroup = mudballGroup

    def shoot(self):
        print("SHOOT function")
        mudball = MUDBALL(self.rect.centerx, self.rect.centery)
        # Add the mudball to the groups.
        self.all_sprites.add(mudball)
        self.mudballGroup.add(mudball)