【6日でできるPython入門】一筆書きアプリを作ろう①

 これから2回にわたり、Tkinter を使ったパズルゲーム 「一筆書きアプリ」 の実装を分解しながら解説していきます。第 1 回となる今回は、ゲーム全体の雰囲気とコードの骨格をつかむことを目的に、以下のトピックをまとめて確認します。各項目では プログラム全体を再掲せず、必要な断片だけを抜粋して説明します。

1.このゲームの遊び方

  1. 盤面(12×10 マス)のすべてを 一筆書き で塗りつぶせばステージクリア
  2. ステージは 3 つ。最後まで進むと「ALL STAGES CLEAR!」
  3. チェックポイント(赤い○)を通過しても構いませんが、塗り残しがあるとクリアになりません

2.操作方法

キー動作
← → ↑ ↓ペンを左右・上下に 1 マス移動
g / G / 左Shiftギブアップ確認ダイアログを表示

 移動できるのは 未塗り(0) または チェックポイントの赤い●(3) のマスだけ。踏んだ瞬間に現在マスを 塗り済み(2) に更新します(後述の move_pen() 参照)。

ゲーム画面イメージ

3.プログラム処理フロー(俯瞰)

game_main()  # 0.2 秒おきに root.after で無限ループ
 ├─ idx == 0 → ステージ準備
 ├─ idx == 1 → プレイ中
 │    └─ move_pen() → プレイヤー操作反映
 │            └─ count_tile() が 0 になれば idx = 2
 └─ idx == 2 → クリア演出&次ステージ移行
  • ゲーム全体を 状態番号 idx で管理し、タイマーイベントだけで制御しています。
  • 描画やロジックが混線しないよう、「準備 → 入力 → 判定 → 演出」 の流れを毎フレーム同じ順序で処理しています。

4.ウィンドウの表示(Tkinter 初期化)

root = tkinter.Tk()
root.title("一筆書きアプリ")
root.resizable(False, False)
cvs = tkinter.Canvas(root, width=W*TS, height=H*TS)
cvs.pack()
  • ゲーム画面は Canvas 1 枚のみ。ウィンドウサイズは タイルサイズ TS × マップ幅/高さ で計算。
  • キー操作は root.bind("<KeyPress>", key_down)key_up で低レイテンシに取得。

5.画像リソースの読み込みと配置

pen  = tkinter.PhotoImage(file="pen.png")
wall = tkinter.PhotoImage(file="wall.png")
  • ペンは常に タグ "PEN" で 1 枚だけ配置し、座標が変わるたびに delete → create
  • 壁は描画時に create_image() を使い、背景色 (COL_WALL) との二重描画で視認性を確保。

6.MAP の座標系とタイルコード

コード意味描画初期化場所
0未塗りタイルCOL_FLOOR各ステージ配列
2塗り済みタイルCOL_PAINTstage_data() 初期マスで設定
3ゴール赤い円ステージ配列
9wall.png + 背景色ステージ配列

※ 配列は maze[y][x](左上が (0,0))。ix, iy はプレイヤー位置。

7.マップ描画処理 draw_bg()

抜粋:

for y in range(H):
    for x in range(W):
        gx, gy = TS*x, TS*y
        v = maze[y][x]
        if v == 0 or v == 3:
            cvs.create_rectangle(gx, gy, gx+TS, gy+TS,
                                 fill=COL_FLOOR, width=0, tag="BG")
        if v == 2:
            cvs.create_rectangle(gx, gy, gx+TS, gy+TS,
                                 fill=COL_PAINT, width=0, tag="BG")
        if v == 9:
            cvs.create_rectangle(gx, gy, gx+TS, gy+TS,
                                 fill=COL_WALL, width=0, tag="BG")
            cvs.create_image(gx+TS//2, gy+TS//2, image=wall, tag="BG")
  • 描画タグ "BG" をまとめて消してから再描画するため、画面更新が一括で行えます。
  • ペンだけは "PEN" タグで別管理し、プレイ中の再描画コストを抑制。

8.ステージデータ stage_data()

if stage == 1:
    ix, iy = 1, 1
    maze = [
        [9,9,9,9, … ],
        [9,0,0,0, … ],
        …
    ]
elif stage == 2:
    …
  • 各ステージを 二次元リスト で直書き。数字は先ほどのタイルコード。
  • 開始位置 (ix, iy) を決めたあと、maze[iy][ix] = 2スタートマスを塗り済みに更新
  • 配列を編集するときは global maze を宣言している点に注意。

まとめ ― 次回予告

 今回は「一筆書きアプリ」を動かすうえで欠かせない 骨格部分(ウィンドウ生成・描画・ステージ切替えなど)を概観しました。次回 「一筆書きアプリを作ろう②」 では、

  • ペンの移動処理
  • ステージクリア判定
  • ゲームクリア判定
  • 改造のポイント

など、より発展的な処理を掘り下げていき「一筆書きアプリ」を完成させます。お楽しみに!