2016-04-27 44 views
0

私は、プレーヤーが爆弾を撃つためにキーを押すことができる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  

明示的フィールドの値を設定し、フィールドがインスタンス間で共有されていません。これが誰かを助けることを望みます。

答えて

0

Kivyのウィジェットは自動的にこれを実行しません。誤ってコードを書いたようです。あなたがそれを追跡するのを助けたいなら、問題を示す実行可能な例を投稿してください。

+0

追加したばかりのコードをご覧ください。 –

+0

デバッグは、プレーヤーと爆弾の両方が 'ObjectProperty(Vector(0、0)) 'を使って作成された同じ' velocity'オブジェクトを参照していたという問題を示しています。つまり、プレーヤーと爆弾はそれぞれ独自の「速度」ベクトルオブジェクトを持つ必要がありますが、そうではありません。あなたは私が問題を理解するのを助けることができますか? –

関連する問題