在*之后添加()参数必须是可迭代的,而不是int" [英] Pygame - Issues creating projectiles, "add() argument after * must be an iterable, not int"

查看:13
本文介绍了在*之后添加()参数必须是可迭代的,而不是int"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用PYGAME创建一个小行星类型的游戏,我在发射炮弹时遇到了困难。我有一个投射物对象的精灵组和一些添加投射物的代码。

if pressed[pygame.K_SPACE]:
     projectiles.add(Projectile(player.rect.x, player.rect.y, player.direction))

问题是,当我在游戏中按空格键来发射炮弹时,我收到错误消息"在*之后添加()参数必须是可迭代的,而不是int"。

我有一个非常类似的声明,在游戏第一次开始时添加小行星没有任何问题,所以我不太确定问题是什么。我将把剩下的代码留在下面。给出问题的ADD语句位于靠近底部的主函数中。如有任何帮助,我们不胜感激。

#Import Modules
import pygame
import math
import random

#Movement Function
def calculate_new_xy(old_xy,speed,direction):
    new_x = old_xy[0] + (speed*math.cos(direction))
    new_y = old_xy[1] + (speed*math.sin(direction))
    return new_x, new_y

#Collision Function
def isColliding(x, y, xTo, yTo, size):
    if x > xTo - size and x < xTo + size and y > yTo - size and y < yTo + size:
        return True
    return False

#Draw Text Function
def drawText(msg, color, x, y, s, center=True):
    screen_text = pygame.font.SysFont("Impact", s).render(msg, True, color)
    if center:
        rect = screen_text.get_rect()
        rect.center = (x, y-50)
    else:
        rect = (x, y)
    display.blit(screen_text, rect)

#Initialize Variables

#Colors
white = (255, 255, 255)
black = (0, 0, 0)

#Display Height/Width
display_width = 800
display_height = 600

#Asteroid Class
class Asteroid(pygame.sprite.Sprite):
    #Initialize values
    def __init__(self, pos=(0, 0)):
        #Initialize sprite class
        pygame.sprite.Sprite.__init__(self)
        #Asteroid sprite
        self.asteroid = pygame.image.load("asteroid.png").convert()
        self.image = self.asteroid
        #Rectangle
        self.rect = self.image.get_rect()
        self.rect.center = pos
        #Initialize random starting angle
        self.angle = random.randint(0, 360)
        #Asteroid random Speed
        self.speed = random.randint(2, 3)
        #Asteroid random direction
        self.direction = math.radians(random.randrange(0, 360, 3))

    #Update asteroid object
    def update(self):
        #Constantly rotate asteroid
        self.angle -= 3 % 360

        #Get image angle and position
        self.image = pygame.transform.rotate(self.asteroid, self.angle*-1)

        #Use rectangle to get center of image
        #Save ship's current center.
        x, y = self.rect.center
        #Replace old rect with new rect.
        self.rect = self.image.get_rect()
        #Put the new rect's center at old center.
        self.rect.center = (x, y)

        #Move Asteroid
        self.rect.center = calculate_new_xy(self.rect.center,self.speed,self.direction)

        #Screen Border
        #Moves the asteroid to the opposite side of the screen if they go outside the border
        if self.rect.x > display_width:
            self.rect.x = -20
        elif self.rect.x < -20:
            self.rect.x = display_width
        elif self.rect.y > display_height:
            self.rect.y = -20
        elif self.rect.y < -20:
            self.rect.y = display_height

#Projectile Class
class Projectile(pygame.sprite.Sprite):
    #Initialize values
    def _init_(self,x,y,direction):
        self.x = x
        self.y = y
        self.dir = direction
        self.ttl = 30

    #Update projectile object
    def update(self):
        #Changing direction
        self.x += projectilespd * math.cos(self.direction)
        self.y += projectilespd * math.sin(self.direction)

        #Draw projectile
        pygame.draw.circle(display, white, (self.x,self.y),1)

        #Screen Border
        if self.x > display_width:
            self.x = 0
        elif self.x < 0:
            self.x = display_width
        elif self.y > display_height:
            self.y = 0
        elif self.y < 0:
            self.y = display_height
        self.ttl -= 1        

#Player Class
class Player(pygame.sprite.Sprite):
    #Initialize ship sprite, angle lines, and rectangle
    def __init__(self, pos=(0, 0), size=(200, 200)):
        #Player sprite
        self.ship = pygame.image.load("ship.png").convert()
        self.image = self.ship
        #Rectangle
        self.rect = self.image.get_rect()
        self.rect.center = pos
        #Initialize angle
        self.angle = 0
        #Initialize direction
        self.direction = 0

    #Update player object
    def update(self):
        #Rotation
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_LEFT]: self.angle -= 3 % 360
        if pressed[pygame.K_RIGHT]: self.angle += 3 % 360

        #Get image angle and position
        self.image = pygame.transform.rotate(self.ship, self.angle*-1)

        #Use rectangle to get center of image
        #Save ship's current center.
        x, y = self.rect.center
        #Replace old rect with new rect.
        self.rect = self.image.get_rect()
        #Put the new rect's center at old center.
        self.rect.center = (x, y)

        #Convert angle to radians
        self.direction = math.radians(self.angle-90)

        #Increase speed if Up is pressed
        if pressed[pygame.K_UP]: self.speed = 5
        else: self.speed = 0

        #Move Ship
        self.rect.center = calculate_new_xy(self.rect.center,self.speed,self.direction)

        #Screen Border
        #Moves the player to the opposite side of the screen if they go outside the border
        if self.rect.x > display_width:
            self.rect.x = -50
        elif self.rect.x < -50:
            self.rect.x = display_width
        elif self.rect.y > display_height:
            self.rect.y = -50
        elif self.rect.y < -50:
            self.rect.y = display_height

#Main Function
def main(gameState):
    #Player starting position
    player = Player(pos=(400, 300))
    #Asteroid group
    asteroids = pygame.sprite.Group()
    #Projectile group
    projectiles = pygame.sprite.Group()

    #Create asteroids
    for x in range(8):
        asteroids.add(Asteroid(pos=(100 + (x*120), 100 + (x*20))))

    while True:
        for event in pygame.event.get():
            #closes game
            if event.type == pygame.QUIT:
                done = True
                pygame.quit()
                exit()
        #Game Menu
        while gameState == "Menu":
            #Fill background
            display.fill((0,0,0))
            #Display menu text
            drawText("ASTEROIDS", white, display_width / 2, display_height / 2, 150)
            drawText("Press any key to START", white, display_width / 2, display_height / 2 + 120, 40)
            #Check game start or end
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    done = True
                    pygame.quit()
                    exit()
                if event.type == pygame.KEYDOWN:
                    gameState = "Playing"
            pygame.display.update()
            #Low frame rate for menu
            clock.tick(5)

        #Get key inputs
        pressed = pygame.key.get_pressed()

        #Fill background
        display.fill(black)

        #Check for player collision with asteroid
        for asteroid in asteroids:
            if gameState != "Game Over":
                if isColliding(player.rect.x, player.rect.y, asteroid.rect.x, asteroid.rect.y, 30):
                    gameState = "Game Over"

        #Update and draw player if not game over
        if gameState != "Game Over":
            #Update player
            player.update()
            #Draw player
            display.blit(player.image, player.rect)

        #Update asteroids
        asteroids.update()

        #Draw asteroids
        asteroids.draw(display)

        #Fire Projectiles
        if pressed[pygame.K_SPACE]:
            projectiles.add(Projectile(player.rect.x, player.rect.y, player.direction))

        #Update projectiles
        projectiles.update()

        #Draw projectiles
        projectiles.draw(display)

        #Display Game Over and restart option
        if gameState == "Game Over":
            drawText("GAME OVER", white, display_width / 2, display_height / 2, 150)
            drawText("Press R to restart", white, display_width / 2, display_height / 2 + 120, 40)
            if pressed[pygame.K_r]: 
                main(gameState = "Playing")

        #Makes updates to the game screen
        pygame.display.update()

        #Frame rate
        clock.tick(60)

#Initialize Game
if __name__ == '__main__':
    #initialize pygame
    pygame.init()

    #initialize display settings
    display = pygame.display.set_mode((display_width,display_height))
    pygame.display.set_caption('Asteroids')

    #initialize game clock
    clock = pygame.time.Clock()

    #start main function
    main(gameState = "Menu")

推荐答案

问题不在pygame.sprite.Group.add操作,但您要添加的objct不是pygame.sprite.Sprite对象,因为该对象根本不是构造的。
您错过了Projectile的构造函数中的super调用。此外,构造函数的名称必须是__init__而不是_init_

class Projectile(pygame.sprite.Sprite):
    #Initialize values
    def __init__(self,x,y,direction):
        super.__init__()
        self.x = x
        self.y = y
        self.dir = direction
        self.ttl = 30

这篇关于在*之后添加()参数必须是可迭代的,而不是int&quot;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆