Python/Pygame:重启后所有实例仍在屏幕上
Python/Pygame: All Instances Still On Screen After Restart
我正在 Python 和 Pygame 开发横向卷轴射击游戏。在游戏开始时,我创建了一堆列表,例如 enemy[] 和 shots[]。游戏重启后,我想尽了所有方法,但屏幕上仍然显示上次通关的所有实例!
在我的重启代码中我有这个...
for item in enemies:
enemies.remove(item)
del item
for item in shots:
shots.remove(item)
del item
之后我什至添加了重新初始化列表的代码,所以:
enemies=[]
shots=[]
但是在新的游戏中一切都还在那里。求助!
你的主要问题是你的列表确实存在于多个上下文中(另一种方法或另一种函数)
当您执行 enemies = []
时,您清除了名为 "enemies" 的局部变量 - 但它不再指向先前的对象,该对象在另一个 funtcion/method 中使用(尽管您没有不要在这里列出代码)。
你的另一种方法,使用 for
尝试在修改列表时迭代它 - 它应该(并且确实)以意想不到的方式中断。
只需执行:
enemies[:] = []
shots[:] = []
相反:这些将更改这些名称当前引用的对象,而不是创建新对象并在本地使用它们。这样,使用这些列表的任何其他函数的内容也将被清空。(这不是魔术:[:]
切片语法处理列表的所有元素 - 从第一个到最后一个,以及属性使这些元素被空列表的内容替换:无)
虽然这暂时可行,但如果您在多个 functions/methods 中使用敌人、射击和其他数据结构,也许您会使用 class
进行更简洁的设计,保存您所有的数据数据结构作为 class 的属性,并将您的功能提升为方法(即使您当前没有使用面向对象设计的其他用途)。这样,就可以明确地表明您正在尝试修改代码其他部分中使用的相同对象。
另一个建议:阅读文档,并熟悉 pygame 组(和 Sprites)——它们对于干净的设计非常方便,并且肯定可以更好地执行您使用上面的列表对象所做的任何事情
(例如,如果 enemies
是一个组,在这种情况下您只需调用 enemies.empty()
)
您是否在使用 Pygame 对象,例如 Sprites
和 Groups
?
Pygame 有一个用于 Sprite
存储的对象,称为 Group
。它有许多用于命中检测、绘图和 adding/removing 精灵的便捷方法,因此您永远不必删除任何东西。
此外,Sprites 有一个 self.kill()
方法可以将它们从它们所属的所有组中移除。这样,一个Sprite属于1个Group还是703个Group都没有关系;它将从所有人中删除。
最后,您发布的 none 代码似乎涵盖了在屏幕上实际绘制的任何内容。您是否可能遗漏了某种 "draw-these-to-screen" 序列中的对象实例?如果是这样,那么尝试以您在此处执行的方式删除它们不一定会从每个列表或每个相关范围中删除它们。示例:
>>> foo = {}
>>> bar = []
>>> bar.append(foo)
>>> del foo
>>> foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
>>> bar
[{}] # the object lives!
最终你可能会想要使用 pygame.sprite.Sprite
和 pygame.sprite.Group
对象来让生活变得更简单——同样,它们有处理所有这些东西的便捷方法,所以你不需要当您不再需要对象时,不必寻找并销毁对象的每个实例。
抱歉,我的回答取决于您的完整代码。
这主要取决于你如何调用敌人和射击更新。
因此,如果您遍历列表并更新每个对象,这应该有效:
enemies = []
shots = []
但是你说不行
你做错了两件最可信的事情:
enemies
和 shots
不是真正的迭代列表,因此您要通过其他列表更新它们。如果您正在使用其他库,他们可能会在更新列表中列出它们。
- 你没有更新旧的
enemies
也没有更新 shots
,但你没有填满你的屏幕或熟悉的东西。
请注意,如果您添加了更多代码并且还没有迟到,这个答案可能会更好。
我正在 Python 和 Pygame 开发横向卷轴射击游戏。在游戏开始时,我创建了一堆列表,例如 enemy[] 和 shots[]。游戏重启后,我想尽了所有方法,但屏幕上仍然显示上次通关的所有实例!
在我的重启代码中我有这个...
for item in enemies:
enemies.remove(item)
del item
for item in shots:
shots.remove(item)
del item
之后我什至添加了重新初始化列表的代码,所以:
enemies=[]
shots=[]
但是在新的游戏中一切都还在那里。求助!
你的主要问题是你的列表确实存在于多个上下文中(另一种方法或另一种函数)
当您执行 enemies = []
时,您清除了名为 "enemies" 的局部变量 - 但它不再指向先前的对象,该对象在另一个 funtcion/method 中使用(尽管您没有不要在这里列出代码)。
你的另一种方法,使用 for
尝试在修改列表时迭代它 - 它应该(并且确实)以意想不到的方式中断。
只需执行:
enemies[:] = []
shots[:] = []
相反:这些将更改这些名称当前引用的对象,而不是创建新对象并在本地使用它们。这样,使用这些列表的任何其他函数的内容也将被清空。(这不是魔术:[:]
切片语法处理列表的所有元素 - 从第一个到最后一个,以及属性使这些元素被空列表的内容替换:无)
虽然这暂时可行,但如果您在多个 functions/methods 中使用敌人、射击和其他数据结构,也许您会使用 class
进行更简洁的设计,保存您所有的数据数据结构作为 class 的属性,并将您的功能提升为方法(即使您当前没有使用面向对象设计的其他用途)。这样,就可以明确地表明您正在尝试修改代码其他部分中使用的相同对象。
另一个建议:阅读文档,并熟悉 pygame 组(和 Sprites)——它们对于干净的设计非常方便,并且肯定可以更好地执行您使用上面的列表对象所做的任何事情
(例如,如果 enemies
是一个组,在这种情况下您只需调用 enemies.empty()
)
您是否在使用 Pygame 对象,例如 Sprites
和 Groups
?
Pygame 有一个用于 Sprite
存储的对象,称为 Group
。它有许多用于命中检测、绘图和 adding/removing 精灵的便捷方法,因此您永远不必删除任何东西。
此外,Sprites 有一个 self.kill()
方法可以将它们从它们所属的所有组中移除。这样,一个Sprite属于1个Group还是703个Group都没有关系;它将从所有人中删除。
最后,您发布的 none 代码似乎涵盖了在屏幕上实际绘制的任何内容。您是否可能遗漏了某种 "draw-these-to-screen" 序列中的对象实例?如果是这样,那么尝试以您在此处执行的方式删除它们不一定会从每个列表或每个相关范围中删除它们。示例:
>>> foo = {}
>>> bar = []
>>> bar.append(foo)
>>> del foo
>>> foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined
>>> bar
[{}] # the object lives!
最终你可能会想要使用 pygame.sprite.Sprite
和 pygame.sprite.Group
对象来让生活变得更简单——同样,它们有处理所有这些东西的便捷方法,所以你不需要当您不再需要对象时,不必寻找并销毁对象的每个实例。
抱歉,我的回答取决于您的完整代码。
这主要取决于你如何调用敌人和射击更新。
因此,如果您遍历列表并更新每个对象,这应该有效:
enemies = []
shots = []
但是你说不行
你做错了两件最可信的事情:
enemies
和shots
不是真正的迭代列表,因此您要通过其他列表更新它们。如果您正在使用其他库,他们可能会在更新列表中列出它们。- 你没有更新旧的
enemies
也没有更新shots
,但你没有填满你的屏幕或熟悉的东西。
请注意,如果您添加了更多代码并且还没有迟到,这个答案可能会更好。