python - 如果内置文件 sprite.py 出错怎么办?
问题描述
我是 python 编码的新手(我 11 岁)并且正在一个帮助新编码人员制作他们的第一款游戏的网站上练习,但我偶然发现了 sprite.py 中的一个错误。我不确定如何处理这个问题的原因是 sprite.py 内置在我下载的 python 文件中。错误消息说 add_internal() 缺少必需的位置参数:'sprite'。我不太确定如何解决这个问题,因为我没有创建或编码 sprite.py,也没有对文件进行任何编辑。这是我的错误信息:
Traceback (most recent call last):
File "C:\Users\aveil\Desktop\CodaKid Python 2\PEW PEW ROBO MASSACRE\src\main.py", line 46, in <module>
PowerUp(screen, 300, 700)
File "C:\Users\aveil\Desktop\CodaKid Python 2\PEW PEW ROBO MASSACRE\src\powerup.py", line 7, in __init__
pygame.sprite.Sprite.__init__(self, self.containers)
File "C:\Users\aveil\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py", line 124, in __init__
self.add(groups)
File "C:\Users\aveil\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py", line 142, in add
self.add(*group)
File "C:\Users\aveil\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py", line 139, in add
group.add_internal(self)
TypeError: add_internal() missing 1 required positional argument: 'sprite'.
我不确定如何处理此错误,但检查了 sprite.py 以查看是否有任何我可以解决的问题。我没有发现我知道如何修复的错误。
这是来自 Traceback 错误的代码。我还包括解释上下文代码的注释。为冗长的代码片段道歉。
## pygame - Python Game Library
## Copyright (C) 2000-2003, 2007 Pete Shinners
## (C) 2004 Joe Wreschnig
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Library General Public
## License as published by the Free Software Foundation; either
## version 2 of the License, or (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## Library General Public License for more details.
##
## You should have received a copy of the GNU Library General Public
## License along with this library; if not, write to the Free
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
## Pete Shinners
## pete@shinners.org
"""pygame module with basic game object classes
This module contains several simple classes to be used within games. There
are the main Sprite class and several Group classes that contain Sprites.
The use of these classes is entirely optional when using Pygame. The classes
are fairly lightweight and only provide a starting place for the code
that is common to most games.
The Sprite class is intended to be used as a base class for the different
types of objects in the game. There is also a base Group class that simply
stores sprites. A game could create new types of Group classes that operate
on specially customized Sprite instances they contain.
The basic Sprite class can draw the Sprites it contains to a Surface. The
Group.draw() method requires that each Sprite have a Surface.image attribute
and a Surface.rect. The Group.clear() method requires these same attributes
and can be used to erase all the Sprites with background. There are also
more advanced Groups: pygame.sprite.RenderUpdates() and
pygame.sprite.OrderedUpdates().
Lastly, this module contains several collision functions. These help find
sprites inside multiple groups that have intersecting bounding rectangles.
To find the collisions, the Sprites are required to have a Surface.rect
attribute assigned.
The groups are designed for high efficiency in removing and adding Sprites
to them. They also allow cheap testing to see if a Sprite already exists in
a Group. A given Sprite can exist in any number of groups. A game could use
some groups to control object rendering, and a completely separate set of
groups to control interaction or player movement. Instead of adding type
attributes or bools to a derived Sprite class, consider keeping the
Sprites inside organized Groups. This will allow for easier lookup later
in the game.
Sprites and Groups manage their relationships with the add() and remove()
methods. These methods can accept a single or multiple group arguments for
membership. The default initializers for these classes also take a
single group or list of groups as argments for initial membership. It is safe
to repeatedly add and remove the same Sprite from a Group.
While it is possible to design sprite and group classes that don't derive
from the Sprite and AbstractGroup classes below, it is strongly recommended
that you extend those when you create a new Sprite or Group class.
Sprites are not thread safe, so lock them yourself if using threads.
"""
##todo
## a group that holds only the 'n' most recent elements.
## sort of like the GroupSingle class, but holding more
## than one sprite
##
## drawing groups that can 'automatically' store the area
## underneath so they can "clear" without needing a background
## function. obviously a little slower than normal, but nice
## to use in many situations. (also remember it must "clear"
## in the reverse order that it draws :])
##
## the drawing groups should also be able to take a background
## function, instead of just a background surface. the function
## would take a surface and a rectangle on that surface to erase.
##
## perhaps more types of collision functions? the current two
## should handle just about every need, but perhaps more optimized
## specific ones that aren't quite so general but fit into common
## specialized cases.
import pygame
from pygame import Rect
from pygame.time import get_ticks
from operator import truth
# Python 3 does not have the callable function, but an equivalent can be made
# with the hasattr function.
if 'callable' not in dir(__builtins__):
callable = lambda obj: hasattr(obj, '__call__')
# Don't depend on pygame.mask if it's not there...
try:
from pygame.mask import from_surface
except:
pass
class Sprite(object):
"""simple base class for visible game objects
pygame.sprite.Sprite(*groups): return Sprite
The base class for visible game objects. Derived classes will want to
override the Sprite.update() method and assign Sprite.image and Sprite.rect
attributes. The initializer can accept any number of Group instances that
the Sprite will become a member of.
When subclassing the Sprite class, be sure to call the base initializer
before adding the Sprite to Groups.
"""
def __init__(self, *groups):
self.__g = {} # The groups the sprite is in
if groups:
self.add(*groups)
def add(self, *groups):
"""add the sprite to groups
Sprite.add(*groups): return None
Any number of Group instances can be passed as arguments. The
Sprite will be added to the Groups it is not already a member of.
"""
has = self.__g.__contains__
for group in groups:
if hasattr(group, '_spritegroup'):
if not has(group):
group.add_internal(self)
self.add_internal(group)
else:
self.add(*group)
def remove(self, *groups):
"""remove the sprite from groups
Sprite.remove(*groups): return None
Any number of Group instances can be passed as arguments. The Sprite
will be removed from the Groups it is currently a member of.
"""
has = self.__g.__contains__
for group in groups:
if hasattr(group, '_spritegroup'):
if has(group):
group.remove_internal(self)
self.remove_internal(group)
else:
self.remove(*group)
def add_internal(self, group):
self.__g[group] = 0
def remove_internal(self, group):
del self.__g[group]
def update(self, *args):
"""method to control sprite behavior
Sprite.update(*args):
The default implementation of this method does nothing; it's just a
convenient "hook" that you can override. This method is called by
Group.update() with whatever arguments you give it.
There is no need to use this method if not using the convenience
method by the same name in the Group class.
"""
pass
def kill(self):
"""remove the Sprite from all Groups
Sprite.kill(): return None
The Sprite is removed from all the Groups that contain it. This won't
change anything about the state of the Sprite. It is possible to
continue to use the Sprite after this method has been called, including
adding it to Groups.
"""
for c in self.__g:
c.remove_internal(self)
self.__g.clear()
def groups(self):
"""list of Groups that contain this Sprite
Sprite.groups(): return group_list
Returns a list of all the Groups that contain this Sprite.
"""
return list(self.__g)
def alive(self):
"""does the sprite belong to any groups
Sprite.alive(): return bool
Returns True when the Sprite belongs to one or more Groups.
"""
return truth(self.__g)
def __repr__(self):
return "<%s sprite(in %d groups)>" % (self.__class__.__name__, len(self.__g))
我将不胜感激任何帮助。提前致谢!
这是@Kingsly 的 PowerUp init () 语句,感谢您的帮助!
import pygame
import random
import toolbox
class PowerUp(pygame.sprite.Sprite):
def __init__(self, screen, x, y):
pygame.sprite.Sprite.__init__(self, self.containers)
self.screen = self.screen
self.x = x
self.y = y
self.pick_power = random.randint(0, 0)
if self.pick_power == 0: #Crate ammo
self.image = pygame.image.oad("../update/powerupCrate.png")
self.background_image = pygame.image.load("../assets/powerupBackgroundBlue.png")
self.power_type = 'crateammo'
self.rect = self.image.get_rect()
self.rect.center = (self.x, self.y)
self.background_angle = 0
self.spinny_speed = 2
def update(self):
self.background_angle += self.spinny_speed
bg_image_to_draw, bg_rect = toolbox,getRotatedImage(self.background_image, self.rect, self.background_angle)
self.screen.blit(bg_image_to_draw, bg_rect)
self.screen.blit(self.image, self.rect)
解决方案
我怀疑问题可能是__init__
您的 PowerUp 初始化函数中的基本对象调用。通常,类pygame.sprite.Sprite.__init__()
函数只是每个传递pygame.sprite.Group
的,代表这个新精灵应该是成员的组对象。
所以可能在你的代码的某个地方,有类似的东西:
power_up_group = pygame.sprite.group # <-- BUG!
PowerUp.containers = power_up_group
理论上,这会导致新PowerUp
的精灵自动添加到power_up_group
精灵组中。
但是,您已经离开了()
语句的结尾,它应该是:
power_up_group = pygame.sprite.group() # <-- FIXED
您看到的错误是因为没有()
,它不会创建新的组对象,只是传递了如何创建组的定义。
像这样设置一个类成员并不是一个很好的编程习惯,因为它使代码的可读性降低并且更复杂而没有真正的收获。任何组都可以作为参数传递给 sprite __init__()
,然后传递给基本初始化程序。这样可以更清楚地看到初始化程序中发生了什么,因为我们不必四处寻找代码来找出self.containers
可能设置的内容。
class PowerUp(pygame.sprite.Sprite):
def __init__(self, screen, x, y, power_up_group):
pygame.sprite.Sprite.__init__(self, power_up_group)
self.screen = self.screen
# [...]
但是,如果您不使用任何 sprite-group 容器逻辑,也可以将其从您的类代码中删除:
class PowerUp(pygame.sprite.Sprite):
def __init__(self, screen, x, y):
pygame.sprite.Sprite.__init__(self) # <-- HERE, no containers
self.screen = self.screen
# [...]
您可以在创建精灵后将它们添加到精灵组中。一般来说,我就是这样做的,因为很明显发生了什么。
推荐阅读
- c - 为什么我们在初始化链表的根时使用 node* 而不是只说 node ?
- r - 是否有可以在 R 中找到特定站点的服务器时间的编码?
- unity3d - 2D 盒子碰撞器在 Unity 中不起作用
- php - phpMyAdmin sql 查询总是返回 500 内部错误?
- python - 如何在 Robot Framework-SeleniumLibrary 中获取多个元素并打印?
- php - 根据搜索条件创建一个新的数组形式的多维数组
- ios - 从Nsnumber转换为数据发送rssi到蓝牙模块IOS swift 4
- swift - 一对 DatePickers SwiftUI
- javascript - 在 tensorflow.js 中使用 ip-camera
- javascript - 如何为给定的输出编写逻辑?