2017-04-08 113 views
-2

我正在关注如何检测类玩家与精​​灵群体MudballGroup之间的冲突。当在语句pg.sprite.spritecollide(Player,mudballGroup,False)中设置碰撞时,我得到错误类型对象'Player'没有属性'rect'。我从我的播放器精灵的代码显示rect在下面的语句中定义:self.rect = self.image.get_rect()。我不知道为什么我得到这个错误。请有人帮忙。玩家与精灵群体之间的Pygame中的碰撞检测mudballGroup

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() 
+0

''Player''是一类。你需要制作一个实例来实际使用它。程序。请参阅https://learnpythonthehardway.org/book/ex40.html –

+0

我宁愿推荐程序街机游戏[关于类和精灵的章节](http://programarcadegames.com/index.php?chapter=introduction_to_classes&lang=de#section_12 )(12和13)。 – skrx

+1

请记住,您应该在这里发布[完整但很少的示例](http://stackoverflow.com/help/mcve)。我们需要我们可以复制,粘贴和运行的代码。 – skrx

回答

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) 

它还看起来很奇怪,我认为你定义mudballGroupshoot方法里面。这意味着这个小组只会包含一个模拟球,但是你也可以检查球员的反应和泥球是否碰撞:player.rect.colliderect(mudball.rect)而不是spritecollide。但是,如果你想多mudballs您需要将mudballGroup存储为其他类的属性,在__init__方法写:

self.mudballGroup = pg.sprite.Group() 

编辑:好吧,你已经有了一个self.player比如在你的游戏实例。我建议在Game类别中定义mudballGroup,然后将其传递给玩家的shoot方法,并将其传递给all_sprites组,以添加模糊球。碰撞检测可以在游戏的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:这里的其他变种。在创建实例时(您不必传递完整的游戏实例)将两个需要的精灵组传递给玩家,然后将它们设置为玩家的属性。

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属性(也只是需要对播放器实例,以检查用户是否正在拍摄)。您也不需要在游戏类中调用特朗普的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) 
+0

对不起,我是新手。为了简单起见,我宁愿使用spritecollide。我如何编码一个球员的实例?它是self.Player?如果我不在那里制造泥巴小组,那它应该去哪里?非常感谢您的帮助。 –

+0

我编辑了答案,向您展示如何创建播放器实例/对象。此外,mudballGroup可能应该是其他类的属性,那么你可以继续使用'spritecollide'函数。 – skrx

+0

我实际上猜测你已经有一个播放器实例,否则你的游戏根本无法工作。所以另一个类或者需要引用这个'player'实例,或者你需要将它作为参数传递给'shoot'方法。如果我能看到完整的代码,我可能会给你更多的建议,但Stack Overflow不是正确的代码审查网站。当您的代码正常工作时,您可以在http://codereview.stackexchange.com/上发布它以获取一些提示。 – skrx