TypeError:' Alien'对象不可迭代

时间:2017-02-07 01:55:29

标签: python pygame collision-detection collision

我正在拍摄太空射击游戏并且我已经制作了精灵并添加了一些基本的碰撞检测,但是当我在碰撞检测中添加alien精灵是否与player精灵,它给了我这个错误信息:

Traceback (most recent call last):
  File "main.py", line 93, in <module>
    game.new()
  File "main.py", line 33, in new
    self.run()
  File "main.py", line 45, in run
    self.collision()
  File "main.py", line 58, in collision
    hits = pygame.sprite.spritecollide(self.player, self.alien, False)
  File "C:\Users\sidna\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pygame\sprite.py", line 1525, in spritecollide
    return [s for s in group if spritecollide(s.rect)]
TypeError: 'Alien' object is not iterable

这是我的代码:

main.py

# IMPORTS
import pygame, random
from sprites import *
from config import *

# GAME
class Game():
    def __init__(self):
        # INIT PYGAME
        pygame.init()
        pygame.mixer.init()

        pygame.display.set_caption(TITLE)

        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        self.clock = pygame.time.Clock()
        self.running = True

    # NEW GAME
    def new(self):
        self.allSprites = pygame.sprite.Group()
        self.allAliens = pygame.sprite.Group()

        self.player = Player()

        for i in range(ALIEN_AMOUNT):
            self.alien = Alien()
            self.allSprites.add(self.alien)
            self.allAliens.add(self.alien)

        self.allSprites.add(self.player)

        self.run()

    # RUN GAME
    def run(self):
        self.playing = True

        while self.playing:
            self.clock.tick(FPS)

            self.events()
            self.update()
            self.draw()
            self.collision()

    # DRAW
    def draw(self):
        self.screen.fill(BLACK)

        self.allSprites.draw(self.screen)
        self.allAliens.draw(self.screen)
        pygame.display.update()

    # DETECT COLLISION
    def collision(self):
        # alien collision with player
        hits = pygame.sprite.spritecollide(self.player, self.alien, False)

        if hits:
            running = False

    # CHECK FOR EVENTS
    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                if self.playing:
                    self.playing = False

                self.running = False

    # UPDATE GAME
    def update(self):
        self.allSprites.update()
        self.allAliens.update()

    # GAME OVER
    def gameOver(self):
        pass

    # START SCREEN
    def startScreen(self):
        pass

    # END SCREEN
    def endScreen(self):
        pass

game = Game()
game.startScreen()

while game.running:
    game.new()
    game.gameOver()

pygame.quit()
quit()

sprites.py

import pygame, random
from config import *

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load("assets/img/player.png").convert()
        self.image.set_colorkey(BLACK)

        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH / 2
        self.rect.bottom = HEIGHT - 10
        self.velX = 0

    def animate(self):
        self.rect.x += self.velX

    def collision(self):
        # collision with walls
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        if self.rect.left < 0:
            self.rect.left = 0

    def control(self):
        self.velX = 0

        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_LEFT]:
            self.velX = -5
        if keystate[pygame.K_RIGHT]:
            self.velX = 5

    def update(self):
        self.animate()
        self.collision()
        self.control()

class Alien(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load("assets/img/alien.png").convert()
        self.image.set_colorkey(BLACK)

        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(0, WIDTH - self.rect.width)
        self.rect.y = random.randrange(-100, -40)
        self.velY = random.randrange(1, 4)
        self.velX = random.randrange(-4, 4)

    def animate(self):
        self.rect.y += self.velY
        self.rect.x += self.velX

    def collision(self):
        # collision with walls
        if self.rect.top > HEIGHT + 10 or self.rect.left < -20 or self.rect.right > WIDTH + 20:
            self.rect.x = random.randrange(0, WIDTH - self.rect.width)
            self.rect.y = random.randrange(-100, -40)
            self.velY = random.randrange(1, 4)
            self.velX = random.randrange(-4, 4)

    def update(self):
        self.animate()
        self.collision()

config.py

# IMPORTS
import pygame

# ENTIRE GAME VARIABLES
TITLE = "Alien Invasion"
WIDTH = 360
HEIGHT = 570
FPS = 60

# ALIEN CONFIG
ALIEN_AMOUNT = 10

# COLORS
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)

1 个答案:

答案 0 :(得分:1)

问题在于:

hits = pygame.sprite.spritecollide(self.player, self.alien, False)

spritecollide()函数的工作原理如下(来自文档):

spritecollide(sprite, group, dokill, collided = None) -> Sprite_list

你把'self.alien'作为第二个参数,但是spritecollide希望有一个组。如果你只想碰撞两个不同的精灵,你想使用collide_rect:

hits = pygame.sprite.collide_rect(self.player, self.alien)

无论两个精灵是否发生碰撞,你都会回到真/假。

有关所有各种碰撞方法的详细信息,请参见此处: http://www.pygame.org/docs/ref/sprite.html