2016-04-16 13 views
1

ちょうど楽しみのために、私はPython/Tkinterで古典的なヘビゲームを実装しようとしました。それは非常に遅れていると感じ、私はそれを修正することができますかどうか、私は非常に確かではありません。私は、プログラムの短い概要を与えることを試みる:Tkinterで円滑に動作するスネークゲームを書くことはできますか?

私が最初にキャンバスを構築し、私は、各矢印キーのイベントハンドラを追加します。

root = self.root = Tk() 
canvas = Canvas(root, width = width, height = height) 
canvas.pack() 
canvas.bind("<Left>", on_left) # on_left is a very short function 

私もタイムステップのための機能を持っています。グラフィックをペイントし、再び呼び出されるようにスケジュールを設定します。私は20のフレームにinterval 0.05周りtimestep()中(等価選択したときでさえ

  • :今

    def timestep(self): 
        # draw the graphics here (about 100 filled rectangles) 
        timer = threading.Timer(interval, timestep) 
        timer.start() 
    

    、私は2つの問題を抱えている:それは100枚の長方形たびに再描画などの機能は、非常に効率的ではありません毎秒3〜5フレーム以上は得られません。

  • キーボードからの制御入力が約0.5秒遅れているようです。

    • が、それはあなたが100枚の長方形たびにステップを描きたいときTkinterのキャンバスとのスムーズな、非遅れ(20 FPS)蛇を書くことで、すべてのことが可能です:

    は、私は約3つのことを疑問に思います?

  • threading.Timerはタイムステップ機能を呼び出す正しい選択ですか?

  • なぜキーボード入力が遅れているようですか?

+0

各フレーム間でcanvas.delete(...)を使用していない場合、メモリリークが発生します。 100個の四角形はわずか200個の三角形です(それほど多くはないが、ゲームエンジンは60+ fpsで何百万ということができます) – kpie

+0

各ステップで100個の四角形を作成する理由を尋ねますか? – TigerhawkT3

+0

'self.parent.after(interval、timestep)'はおそらくもっと簡単で簡単です。問題を再現できるだけのコードを表示できますか? – TigerhawkT3

答えて

-1

既存の答えは、まさに私が最終的に問題を解決できる方法を説明していないので、私はここで自分の質問への答えを与えますすべてのコール。非常に短い時間が経過しても長方形が多すぎるため、パフォーマンスの問題にぶつかります。

canvas.delete(...)を使用すると、一部またはすべての長方形を削除できます。すべての既存の四角形を削除し、各タイムステップで新しい四角形を作成すると、パフォーマンスは良好ですが、画面がちらつきます。私はまだ色を変更するにもかかわらず、それと

# on startup: 
rect[x][y] = canvas.create_rectangle(...) 

# in each timestep 
canvas.itemconfig(rect[x][y], fill = myColor) 

私は良いパフォーマンスと無ちらつきを取得:

最良の方法は、初期化時に一度長方形を作成し、その後、ちょうど各タイムステップで自分の色を変更することです毎秒100回の長方形の20回。

0

各フレーム間でcanvas.delete(...)を使用していない場合、メモリリークが発生します。

+1

OPのマシンがその最大メモリに達するまで、これは問題ではありません。すぐに低いフレームレートが発生するように思えます。 – TigerhawkT3

+0

@ TigerhawkT3:キャンバスには非常に多数のオブジェクトが存在することが知られています。 1秒間に2000個の長方形を作成すると、システムがメモリ不足になる前に壁にかなり早く当たるようになります。それは唯一の問題ではありませんが、それは間違いなく_a_問題です。 –

+0

投票が下に来るように、私は人々を助けようとしています。 – kpie

1

スレッドタイマーの代わりにcanvas.after(funciton,interval)を組み込みます。主な問題は、canvas.create_rectangle(...)のような機能は、実際に新しい長方形を追加することである

0

はい、画面上に多数のオブジェクトがある滑らかなランニングゲームを作成できます。スレッドなしで実行できます。しかし、それはあなたが "滑らかな"と "多くの"をどのように定義するかによって異なりますが、それは実装方法に依存します。

すべての繰り返しでシーンのすべてを削除して再作成するアルゴリズムを使用している場合、非常に遅く実行されます。アニメーションを行う適切な方法は、一度だけアニメーション化したいオブジェクトを作成することです。次に、フレームごとにキャンバスメソッドitemconfiguremove、およびcoordsで再構成または移動できます。

私はキャンバス上の何百ものアイテムでこの作業がうまくいくのを見ました。しかし、もしあなたが何千人もいたら、それはうんざりしてしまいます。また、古いアイテムを削除しても、何千ものアイテムを作成すると、キャンバスには既知のパフォーマンスの問題があります。

パフォーマンスに関連する多くの質問と同様に、最終的なアルゴリズムの一部になります。たとえば、スネークゲームでは、すべてのフレームにスネーク全体を再描画するか、問題を見てスネークの1つまたは2つのセグメントを移動するだけで済みます。最初の方法は遅く、2番目の方法は非常に速くなります。

結論として、tkinterキャンバスは、適切なアルゴリズムで実装されたときに一度に数十個のアイテムをスムーズにアニメーション化するのに十分強力です。

関連する問題