

当たり判定のコードを書きたいです。

playerを十字キーで操作して、動いてやってくるen1に当たったら、playerが初期位置に戻るプログラムです。

「player とen1が当たったら」としたいのですが、以下の箇所でエラーが出ます。  
どうすれば良いのでしょうか。

**該当箇所:**

[code]

    if self.rect.colliderect(self.en1.rect):
    
[/code]

**エラーメッセージ:**

[code]

    ‘int’ object has no attribute ‘rect’
    
[/code]

初心者で、見よう見まねでやっているので、無駄な点が多いとは思いますが、どうかよろしくお願いします。

参考にしたページ:  
<https://algorithm.joho.info/programming/python/pygame-blockout/>

**現状のコード:**

[code]

    import pygame
    from pygame.locals import *
    import sys
    pygame.mixer
    import random
    
    SCREEN = Rect(1500, 800, 0, 32)
    
    #雲
    class ClSprite(pygame.sprite.Sprite):
    def __init__(self, filename, x, y, vx, vy):
        pygame.sprite.Sprite.__init__(self,self.containers)
        self.image = pygame.image.load(filename).convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.vx = vx
        self.vy = vy
        w = self.image.get_width()
    def update(self):
        self.rect.move_ip(self.vx, self.vy)
        if self.rect.right < 0:
            self.rect.left = 1500
       
    #Player
    class PlayerSprite(pygame.sprite.Sprite):
    def __init__(self, filename, en1, x, y, vx, vy, angle=0):
        pygame.sprite.Sprite.__init__(self,self.containers)
        self.image = pygame.image.load(filename).convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.center = [x, y]
        self.vx = vx
        self.vy = vy
        self.angle = angle
        if angle != 0: self.image = pygame.transform.rotate(self.image, angle)
        self.jump = pygame.mixer.Sound("j2.mp3")
        self.deth = pygame.mixer.Sound("aa.wav")
        w = self.image.get_width()
        h = self.image.get_height()
        self.rect = Rect(x, y, w, h)   
        self.en1 = en1
    
    def Rmove(self):
        self.rect.move_ip(30, 0)
    def Lmove(self):
        self.rect.move_ip(-30, 0)
    def Umove(self):
        self.rect.move_ip(0, -70)
    def update(self):
        self.rect.move_ip(self.vx, self.vy)
        if self.rect.left < 0 :
           self.rect.left = 0
        if self.rect.top < 0 :
           self.rect.top = 0
        if self.rect.top > 810 :
           self.de()
        if self.rect.top > 930 :
           pygame.quit()
           sys.exit()
           
        if self.rect.colliderect(self.en1.rect):
         self.rect.left = 0 
    def de(self):
        self.deth.play(1)
    def bjump(self):
        self.jump.play(1)    
    
    #En1
    class En1Sprite(pygame.sprite.Sprite):
    def __init__(self, filename, xy, vxy, angle=0):
        x, y = xy
        vx, vy = vxy
        pygame.sprite.Sprite.__init__(self,self.containers)
        self.image = pygame.image.load(filename).convert_alpha()
        self.rect = self.image.get_rect()
        w = self.image.get_width()
        h = self.image.get_height()
        self.rect = Rect(x, y, w, h)
        self.vx = vx
        self.vy = vy
        self.angle = angle
        if angle != 0: self.image = pygame.transform.rotate(self.image, angle)
    
    def update(self):
        self.rect.move_ip(self.vx, self.vy)
        if self.rect.top < 0 or self.rect.bottom > 850:
           self.vy = -self.vy
    
    def main():
        pygame.init()
    screen = pygame.display.set_mode((1500, 801), 0, 32)
    screen = pygame.display.get_surface()
    pygame.display.set_caption("Test") 
    
    bg = pygame.image.load("img.jpg").convert_alpha()
    rect_bg = bg.get_rect()
    
       #supurite group
        group = pygame.sprite.RenderUpdates()
    en1 = pygame.sprite.Group() 
    
    En1Sprite.containers = group, en1
    PlayerSprite.containers = group
    ClSprite.containers = group
    
        #sprite
        s = -10
    for m in range(7):
        m = random.randint(0, 800)
        for n in range(300):
         n = random.randint(200, 1000000)
         en1 = En1Sprite("to.PNG", (n, m), (s, 3), 0)
    en1 = En1Sprite("to.PNG", (4400, 0), (-4,3), 0)
    
    player = PlayerSprite("m.png", 0, 600, 0, 5, 0)
    
    cloud = ClSprite("clo.png", 700, 600, s, 0)
    cloud = ClSprite("clo.png", 900, 100, s, 0)
    cloud = ClSprite("clo.png", 300, 500, s, 0)
    cloud = ClSprite("clo.png", 100, 300, s, 0)
    
    clock = pygame.time.Clock()
    
    while (1):
        clock.tick(30)
        screen.fill((0, 100, 0, 0)) 
        screen.blit(bg, rect_bg) 
        group.update()
        group.draw(screen)
        pygame.display.update()  
    
        for event in pygame.event.get():
            if event.type ==  pygame.KEYDOWN: 
               if event.key == pygame.K_LEFT:
                 player.Lmove()
               if event.key == pygame.K_RIGHT:
                 player.Rmove()
               if event.key == pygame.K_UP:
                 player.Umove()
                 player.bjump()
              
            if event.type == QUIT:
                pygame.quit()
                sys.exit()          
            
    if __name__ == "__main__":
            main() 
    
[/code]


CC BY-SA 4.0
2022-05-01T03:36:10.137
88595
2023-11-08T10:03:00.377
2022-05-01T05:34:30.420
3060
52420
question
python pygame
Pygame のコードでエラー: ‘int’ object has no attribute ‘rect’


質問のソースコードが正しく修正され、問題を再現できるようになったという前提で考えると、原因は以下になるでしょう。  
(引用しているソースコードは全て現時点でのインデント等が正しくないと思われるソースコードです)

以下の行で`PlayerSprite`の初期化パラメータの2つ目が
[pygame.Rect](http://westplain.sakuraweb.com/translate/pygame/Rect.cgi)
を含むオブジェクト(おそらく`class En1Sprite`のインスタンス)ではなく、単なる整数の`0`が指定されているために発生していると思われます。

[code]

    player = PlayerSprite("m.png", 0, 600, 0, 5, 0)
    
[/code]

PlayerSpriteクラスの関連するソースは以下のようになっており、初期化で整数の`0`が指定されていた`en1`をそのまま代入して、`update()`の中で`en1`に`rect`という変数があることを前提に処理が行われています。

[code]

    #Player
    class PlayerSprite(pygame.sprite.Sprite):
    def __init__(self, filename, en1, x, y, vx, vy, angle=0):
                      ...途中省略...
        self.en1 = en1
                      ...途中省略...
    def update(self):
                      ...途中省略...
        if self.rect.colliderect(self.en1.rect):
                      ...以後省略...
    
[/code]

そのため整数が代入された`self.en1`には`rect`というattributeは無いということでエラーになっているのでしょう。

* * *

正しいかどうかわかりませんが、その上の行で作成している`en1`をパラメータとして指定して試してみると良いかもしれません。

[code]

    en1 = En1Sprite("to.PNG", (4400, 0), (-4,3), 0)
    
    #### player = PlayerSprite("m.png", 0, 600, 0, 5, 0) #### 元の行
    player = PlayerSprite("m.png", en1, 600, 0, 5, 0) #### 新しい行 0 を en1 に変更
    
[/code]

しかし、その直前の2重の`for`ループの中で多数の`En1Sprite`のオブジェクトを同じ名前の`en1`という変数に代入する処理を行っており、この処理との関係が不明なため、何が起こるか？
あるいはループの外で`en1`に再度オブジェクトが代入されることなどにより、意図したことが発生しないといった別の現象が発生する可能性も考えられます。

[code]

        #sprite
        s = -10
    for m in range(7):
        m = random.randint(0, 800)
        for n in range(300):
         n = random.randint(200, 1000000)
         en1 = En1Sprite("to.PNG", (n, m), (s, 3), 0)
    
[/code]


CC BY-SA 4.0
2022-05-01T08:59:18.690
88600
2022-05-01T08:59:18.690
26370
88595
answer