Ich arbeite an einem Spiel mit Kivy, wo der Spieler eine Taste drücken kann, um eine Bombe zu schießen. Hier ist eine vereinfachte Funktion:Wie kann verhindert werden, dass Eigenschaften zwischen Widgets freigegeben werden?
def shoot(self, world):
# self is the player widget
bomb = Bomb(pos=self.pos)
world.add_entity(bomb)
Die lustige Sache, wenn der Spieler schießt, bewegt sich die Bombe mit ihm, wohin er geht.
Nach dem Debuggen wurde mir klar, das liegt daran, dass sowohl der Spieler als auch die Bombe die velocity
Eigenschaft teilen.
Die Klassen Player
und Bomb
erben beide Entity
, die velocity = ObjectProperty(Vector(0, 0))
auf Klassenebene definiert. Das Debugging zur Laufzeit zeigt, dass die beiden Objekte das exakt gleiche Objekt referenzieren.
Die Sache ist, Kivy Eigenschaften sollten eigentlich separate Attribute für jede Instanz erstellen. Warum ist dieser unerwünschte gemeinsame Status und wie kann ich das beheben?
Die Lösung
Dank eines Kommentars durch @Tshirtman auf die Antwort auf this question, habe ich das Problem und die Lösung gefunden.
Es stellt sich heraus, dass Kivy-Eigenschaften einen Fehler aufweisen, wobei der Anfangswert, der beim Instanziieren festgelegt wird, von allen Instanzen der Klasse gemeinsam genutzt wird.
Zur Klarstellung:
# 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
Wie Sie sehen können, ist my_field
tatsächlich zwischen den beiden Instanzen gemeinsam genutzt.
Um dieses Verhalten zu vermeiden, stellen Sie sicher, dass Sie das Attribut für das jeweilige Objekt festlegen und zusätzlich die Eigenschaft auf Klassenebene festlegen.
Zum Beispiel:
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
Wenn explizit den Wert für das Feld Einstellung wird das Feld zwischen den Instanzen nicht geteilt. Hoffe, das hilft jemandem.
Bitte beachten Sie den Code, den ich gerade hinzugefügt habe. –
Debugging zeigt das Problem, dass der Spieler und die Bombe beide das gleiche "velocity" -Objekt referenzieren, das mit einer 'ObjectProperty (Vector (0, 0))' erzeugt wird. Die Sache ist, der Spieler und die Bombe sollten jeweils ihr eigenes "Geschwindigkeits-" Vektorobjekt haben, was nicht der Fall ist. Kannst du mir helfen, das Problem zu verstehen? –