首页 > 解决方案 > 按下空格键时出现错误“TypeError: pygame.sprite.Sprite.add() argument after * must be an iterable, not Settings”

问题描述

我见过类似的编码,但有相同的错误,但他们输入了init错误,据我所知,这不是我的情况。

代码完美运行,只有当我按下空格键时才会收到错误“TypeError:pygame.sprite.Sprite.add() 参数在 * 之后必须是可迭代的,而不是设置”。当我在“game_functions.py”中删除以下代码时

new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)

并添加 print("this is a test") 来测试以查看是否出现问题,而事实并非如此。按空格键时,即使按向上箭头,我也会看到文本出现。所以看起来bullet.py有问题,但我就是找不到这个问题出在哪里。我检查了初始化,我什至试图删除它,因为对其他人来说它有效,但对我无效。谁能帮我解决这个问题。我在 Windows 10 上使用 Python 3.9.6。

以下是代码和回溯。:

外星人入侵.py

import pygame
import sys

from pygame.sprite import Group
from settings import Settings
from ship import Ship
#from mario_alien import Mario_alien
import game_functions as gf

def run_game():
    pygame.init()
    ai_settings = Settings()
    
    screen = pygame.display.set_mode((ai_settings.width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")
    ship = Ship(ai_settings, screen)
    #mario_alien = Mario_alien(screen)
    # Make a group to store bullets in.
    bullets = Group()

    #Start the main loop for the game
    while True:
        gf.check_events(ai_settings, screen, ship, bullets)
        ship.update()
        gf.update_screen(ai_settings, screen, ship, bullets)
        #gf.update_screen(ai_settings, screen, mario_alien)
run_game()

设置.py

class Settings():
    """A class to store all settings for Alien Invasion."""
    def __init__(self):
        #Screen settings
        self.screen_width = 1200
        self.screen_height = 800
        self.width = 900
        self.bg_color = (0, 0, 150)
        #Ship settings
        self.ship_speed_factor =  1.5

        #Bullet settings
        self.bullet_speed_factor = 1
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = 60, 60, 60

子弹.py

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """A class to manage bullets fired from the shiop"""

def __init__(self, ai_settings, screen, ship):
    """Create a bullet object at the ship's current position."""
    #super(Bullet, self).__init__()
    #or
    super().__init__()
    self.screen = screen

    #Create a bullet rect at (0, 0) and then set correct position.
    self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
        ai_settings.bullet_height)
    self.rect.centerx = ship.rect.centerx
    self.rect.top = ship.rect.top

    #Store the bullet's position as a decimal value
    self.y = float(self.rect.y)

    self.color = ai_settings.bullet_color
    self.speed_factor = ai_settings.bullet_speed_factor
def update(self):
    """"Move the bullet up the screen. """
    #Update the decimal position of the bullet
    self.y -= self.speed_factor
    # Update the rect position.
    self.rect.y = self.y

def draw_bullet(self):
    """Draw the bullet to the screen"""
    pygame.draw.rect(self.screen, self.color, self.rect) 

游戏功能.py

import sys

import pygame

from bullet import Bullet

def check_keydown_events(event, ai_settings, screen, ship, bullets):
    """Respond to keypresses."""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    if event.key == pygame.K_DOWN:
        ship.moving_down = True
    elif event.key == pygame.K_UP:
        ship.moving_up = True

    elif event.key == pygame.K_SPACE:
        # Create a new bullet and add it to the bullets group.
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)
        #print("this is a test")

def check_keyup_events(event, ship):
    """Respond to key releases."""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False
    if event.key == pygame.K_DOWN:
         ship.moving_down = False
    elif event.key == pygame.K_UP:
        ship.moving_up = False


def check_events(ai_settings, screen, ship, bullets):
    """Respond to keypresses and mouse events."""
    #Watch for keyboard and mouse events.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.display.quit()
            pygame.quit
            sys.exit()

        elif event.type == pygame.KEYDOWN:
           check_keydown_events(event, ai_settings, screen, ship, bullets)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event, ship)
    
def update_screen(ai_settings, screen, ship, bullets):
    """Update images on the screen and flip to the new screen."""
    #Redraw the screen during each pass through the loop.
    screen.fill(ai_settings.bg_color)
    # Redraw all bullets behind ship and aliens.
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
   

    # Make the most recently drawn screen visible.
    pygame.display.flip()

船.py


class Ship():
    def __init__(self, ai_settings, screen):
        #Initialize the ship and set its starting position.
        self.screen = screen
        self.ai_settings = ai_settings

        #Load the ship image and get its rect.
        self.image = pygame.image.load("img/ship.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        #Start each new shiip at the bottom center of the screen
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        # Store a decimal value for the ship's center
        self.center = float(self.rect.centerx)
        self.center_v = float(self.rect.centery)

        #Movement flag
        self.moving_right = False
        self.moving_left = False
        self.moving_up = False
        self.moving_down = False

    def update(self):
        """Update the ship's position based on the movement flag."""
        #Update the ship's center value, not the rect.
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.right > 100:
            self.center -= self.ai_settings.ship_speed_factor
        if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
            self.center_v += self.ai_settings.ship_speed_factor
        if self.moving_up and self.rect.top > 0:
            self.center_v -= self.ai_settings.ship_speed_factor

        # Update rect object from self.center.
        self.rect.centerx = self.center
        self.rect.centery = self.center_v

    def blitme(self):
        #Draw the ship at its currrent location
        self.screen.blit(self.image, self.rect)

追溯

Traceback(最近一次调用最后):文件“C:\Users\Hexad\OneDrive\Documents\Programming\Tutorial\Crash Course\AlienInvasion\alien_invasion.py”,第 27 行,在 run_game() 文件“C:\Users\Hexad \OneDrive\Documents\Programming\Tutorial\Crash Course\AlienInvasion\alien_invasion.py”,第 23 行,在 run_game gf.check_events(ai_settings, screen, ship, bullets) 文件“C:\Users\Hexad\OneDrive\Documents\Programming \Tutorial\Crash Course\AlienInvasion\game_functions.py”,第 46 行,在 check_events check_keydown_events(event, ai_settings, screen, ship, bullets) 文件“C:\Users\Hexad\OneDrive\Documents\Programming\Tutorial\Crash Course\ AlienInvasion\game_functions.py”,第 20 行,在 check_keydown_events new_bullet = Bullet(ai_settings, screen, ship) 文件“C:\Users\Hexad\AppData\Roaming\Python\Python39\site-packages\pygame\sprite.py",第 115 行,在init self.add(*groups) 文件“C:\Users\Hexad\AppData\Roaming\Python\Python39\site-packages\pygame\sprite.py”,第 133 行,添加 self.add(*group) 类型错误: * 之后的 pygame.sprite.Sprite.add() 参数必须是可迭代的,而不是设置

标签: pythonpython-3.xpygametypeerror

解决方案


推荐阅读