我正在使用Kivy进行游戏,玩家可以按一个键来射击炸弹。这是一个简化的功能:
def shoot(self, world):
# self is the player widget
bomb = Bomb(pos=self.pos)
world.add_entity(bomb)
有趣的是,当玩家射击时,无论他走到哪里,炸弹都随身携带。
调试后我意识到这是因为玩家和炸弹共享velocity
属性。
Player
类和Bomb
类都继承Entity
,它在类级定义velocity = ObjectProperty(Vector(0, 0))
。在运行时调试显示两个对象引用完全相同的对象。
问题是,Kivy属性实际上应该在每个实例上创建单独的属性。那么为什么这个不需要的共享状态,我该如何解决这个问题?
解决方案
感谢@Tshirtman对this question的回答,我发现了问题和解决方案。
结果证明Kivy属性有一个问题,实例化它们时设置的初始值将由该类的所有实例共享。
澄清:
# this implementation results in the property shared by all instances
class MyWidget(Widget):
my_field = ObjectProperty(MyObject())
w1 = MyWidget()
w2 = MyWidget()
w1.my_field is w2.my_field # True
如您所见,my_field
实际上是在两个实例之间共享的。
要避免此行为,除了设置类级属性外,还要确保在特定对象上设置属性。
例如:
class MyWidget(Widget):
my_field = ObjectProperty()
def __init__(self, **kwargs):
super(MyWidget, self).__init__(**kwargs)
self.my_field = MyObject() # explicitly set the value on the object
w1 = MyWidget()
w2 = MyWidget()
w1.my_field is w2.my_field # False
当显式设置字段的值时,不在实例之间共享该字段。希望这有助于某人。
答案 0 :(得分:0)
Kivy的小工具不会自动执行此操作,可能是您编写的代码无意中造成了这种情况。如果您需要帮助来跟踪它,请发布一个可运行的示例来演示问题。