2017-04-08 16 views
-2

クラスPlayerとスプライトグループMudballGroupの間の衝突を検出する方法についてのチュートリアルに続きます。ステートメントpg.sprite.spritecollide(Player、mudballGroup、False)で衝突を設定すると、エラータイプオブジェクト 'Player'に属性 'rect'がありません。私はPlayerのスプライトのコードをここにrectを次のステートメントで定義しています:self.rect = self.image.get_rect()。なぜこのエラーが出るのか分かりません。もし誰かが助けてくれたらどうぞ。プレイヤーとスプライトグループmudballGroup間のPygameでの衝突検出

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

を参照してください。Program Arcade Games [クラスとスプライトについての章](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) 

をそれはまた、あなたがshoot方法のmudballGroup内部を定義するように私には奇妙に見えます。つまり、グループには1つのマッドボールだけが含まれますが、プレーヤーとマッドボールの矩形が衝突するかどうかを確認することもできます:spritecollideの代わりにplayer.rect.colliderect(mudball.rect)。あなたが複数のmudballsをしたい場合しかし、あなたは__init__メソッドの書き込みでは、他のクラスの属性としてmudballGroupを保存する必要があります。

self.mudballGroup = pg.sprite.Group() 

編集:さて、あなたはすでにあなたのゲームのインスタンスにself.playerインスタンスを持っています。私はを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:ここでは他の変種です。インスタンスを作成するときに、必要な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属性を忘れてしまいました。 Gameクラスのトランプの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を使用することをお勧めします。どのようにしてプレーヤーのインスタンスをコーディングするのですか?それは自己です。プレイヤー?私がmudballグループをそこに作らなければ、どこに行かなければならないのでしょうか?助けてくれてありがとう。 –

+0

答えを編集して、プレーヤーインスタンス/オブジェクトの作成方法を示しました。また、mudballGroupはおそらく他のクラスの属性でなければなりません。そして、あなたは 'spritecollide'関数を使い続けることができます。 – skrx

+0

私は実際にどこかのプレイヤーインスタンスを既に持っていると思います。そうしなければ、ゲームはまったく動作しません。したがって、もう一方のクラスはこの 'player'インスタンスへの参照を必要とするか、' shoot'メソッドの引数として渡す必要があります。私は完全なコードを見ることができれば、おそらくあなたにもっとアドバイスを与えることができますが、スタックオーバーフローはコードレビューのための正しいサイトではありません。コードが正しく動作するときは、http://codereview.stackexchange.com/に投稿してヒントを得ることができます。 – skrx

関連する問題