私は、プレーヤーが爆弾を撃つためにキーを押すことができるKivyを使ってゲームに取り組んでいます。ここに簡略化された関数があります:プロパティがウィジェット間で共有されないようにするにはどうすればよいですか?
def shoot(self, world):
# self is the player widget
bomb = Bomb(pos=self.pos)
world.add_entity(bomb)
面白いことに、プレイヤーが撃つとき、爆弾はどこに行っても彼と一緒に動き続けます。
デバッグ後、これはプレーヤーと爆弾の両方がvelocity
プロパティを共有しているためです。
クラスおよびBomb
クラスは両方とも、クラスレベルでvelocity = ObjectProperty(Vector(0, 0))
を定義したEntity
を継承します。実行時のデバッグは、2つのオブジェクトが全く同じオブジェクトを参照していることを示しています。
実際には、Kivyプロパティは各インスタンスに別々の属性を作成する必要があります。だから、なぜこのような望ましくない共有状態があり、どうすればこの問題を解決できますか?
ソリューションthis question上の答えに@Tshirtmanによってコメントに
おかげで、私は、問題と解決策を発見しました。
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
は実際には2つのインスタンス間で共有されています。
この現象を回避するには、クラスレベルプロパティの設定に加えて、特定のオブジェクトに属性を設定してください。例えば
:
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
明示的フィールドの値を設定し、フィールドがインスタンス間で共有されていません。これが誰かを助けることを望みます。
追加したばかりのコードをご覧ください。 –
デバッグは、プレーヤーと爆弾の両方が 'ObjectProperty(Vector(0、0)) 'を使って作成された同じ' velocity'オブジェクトを参照していたという問題を示しています。つまり、プレーヤーと爆弾はそれぞれ独自の「速度」ベクトルオブジェクトを持つ必要がありますが、そうではありません。あなたは私が問題を理解するのを助けることができますか? –