ウィジェットの使い方ですが、関数内で毎回新規ウィジェットを作成されてるので、
初回起動時に一度のみ作成し、必要に応じ表示・非表示やテキスト変更と使うようにして見て下さい。
大量のオブジェクト生成によるパフォーマンス低下は有りえます。
この場合、何度もプレイすると発現します。
確認方法:
# block_move_sub関数内で
print(label2)
一例ですが、ゲームを2度程プレイすると
実際の表示、数値の部分は、どれだけ長く続けられたかにより異なります。
この名前は連番で作成される為に、1800個ものウィジェットが作成されてることになります。
→タスクマネージャ等から、長時間プレイ時のメモリの増加を見て見ましょう。
(といっても、相当数プレイしないとパフォーマンスに影響するには至りませんが。)
解決策:
- Label を何度も作らず、生成済みのウィジェットを再利用する
- 生成時に固定のname引数を付ける事で、再生成を抑制する
- ウィジェットは作らず、キャンバスに直接 create_text で描画する
途中プログラムが応答するまで時間がかかりすぎます。
after で、3秒~5秒待ってる部分ではないでしょうか?
それともウィンドウを閉じようとする時?
他にある場合、再現手順を具体的に書いてみてください。
例えば、スコアを 20, 6, 66, 77, 40 で5回プレイした後に
ウィンドウを閉じようとした時、応答に時間が掛かる、等。
(※ 補足追記: 例として挙げただけで、実際に試して重たくなったわけではありません)
スコアは適当ですが、何回クリックしたか→
関数が呼ばれる回数 → ウィジェットが生成される数を、大雑把に把握する為の目安です。
クリック数の方がより詳細な情報なので、デバッグ情報として
関数を呼び出した回数等を数えログに表示したりすると、より正確に状況が把握できます。
上記に書いた問題は、一応起こりえる問題なのですが、
実際にパフォーマンスに影響するまでやるとすると相当な時間が掛かります。
テストの為にプログラム内で無駄に関数を呼んだりして、
耐久テストをしないと、手作業のデバッグでの再現は難しい。
意図的に起こすとしたら以下のような感じです。
python
1import tkinter as tk
2
3root = tk.Tk()
4for _ in range(20000):
5 label = tk.Label(root)
6 label.place(x=0, y=0)
7 label.place_forget()
8else:
9 print(label)
10tk.Button(root, text="destroy", command=root.destroy).pack()
11tk.Button(root, text="quit", command=root.quit).pack()
12root.mainloop()
quit ではメインループの終了フラグを立てるだけなので直ぐに終了できますが、
ウィンドウの閉じるアイコンや、destroy ボタンでは、
ウィジェットを全て破棄しようとする為、ウィジェットの数に応じた時間が掛かります。
20000 の部分の数を減らすと、destroy でも直ぐに終了できるようになるので、
ウィジェットの数がパフォーマンスに影響する事があるのは解ると思います。
追記2: 終了時ではなく、プレイ中にパフォーマンス低下するとしたら、
大量のオブジェクトを生成した時のGCの影響が考えられます。
追記: ウィジェット生成時の name 引数について
python
1label = tk.Label(root, name="a")
とすると、上のコードでウィジェット数は 20002 -> 3 になります。
(同じnameを付ける事で、再生成を抑制)
代わりにクラス初期化時の速度は遅くなるので、起動が遅く感じますが。
一度に大量に生成しないなら、許容範囲位には収まるはずです。