はじめに
このプロジェクトでは、Python とグラフィカルユーザーインターフェイス用の Tkinter ライブラリを使用して、シンプルな 2048 ゲームを作成する方法を学びます。2048 は、タイルを組み合わせて値が 2048 のタイルを目指す人気のスライドパズルゲームです。このプロジェクトで作成されるユーザーインターフェイスは、最新かつ美しいものにはなりませんが、美観を向上させるための堅実な基礎を提供します。
👀 プレビュー

🎯 タスク
このプロジェクトでは、以下のことを学びます。
- ゲームに必要なライブラリをインポートする方法
- ゲームのロジックとユーザーインターフェイスを処理する Game2048 クラスを作成する方法
- Tkinter を使用してゲームグリッドを描画する方法
- グリッド上に初期タイルを生成する方法
- ゲームグリッドの現在の状態を反映するようにユーザーインターフェイスを更新する方法
- タイルの値に基づいてタイルの色を定義する方法
- タイルを移動させるためのキー押下を処理する方法
- タイルを異なる方向に移動させるメソッドを定義する方法
- ゲームが終了したかどうかをチェックする方法
🏆 達成目標
このプロジェクトを完了した後、以下のことができるようになります。
- Tkinter ライブラリを使用してグラフィカルユーザーインターフェイスを作成する
- キー押下を処理し、対応するアクションをトリガーする
- ゲームの状態に基づいてユーザーインターフェイスを更新する
- タイルの移動とマージのゲームロジックを実装する
- ゲームが終了したかどうかをチェックする
プロジェクトファイルを作成する
まず、2048_game.py という名前の新しいファイルを作成し、好みのコードエディタで開きます。
cd ~/project
touch 2048_game.py
必要なライブラリをインポートする
ゲームを動作させるには、必須のライブラリをインポートする必要があります。2048_game.py ファイルに、Python の random ライブラリとグラフィカルユーザーインターフェイスを構築するための Tkinter を含めます。
import random
import tkinter as tk
これらのライブラリは、ゲームの機能とユーザーインターフェイスを作成するために使用されます。
Game2048 クラスを作成する
2048_game.py ファイル内で Game2048 クラスを定義します。このクラスは、ゲームのロジックとユーザーインターフェイスを処理します。
class Game2048:
def __init__(self, root):
self.root = root
self.root.title("2048 Game")
self.root.geometry("400x400")
## Initialize the game grid and score
self.grid = [[0 for _ in range(4)] for _ in range(4)]
self.score = 0
## Create an empty list to store tile labels
self.tiles = []
ここでは、ゲームのルートウィンドウを初期化し、そのタイトルとサイズを設定し、ゲームグリッドを初期化し、ゲームタイルを保持するためのリストを作成するクラスコンストラクタを作成しています。
ゲームグリッドを描画する
Game2048 クラスに、Tkinter を使用してゲームグリッドを描画するメソッドを追加します。このメソッドは、初期のユーザーインターフェイスグリッドを作成します。
def draw_grid(self):
for i in range(4):
row = []
for j in range(4):
cell = tk.Label(self.root, text="", font=("Helvetica", 24), width=5, height=2, borderwidth=4, relief="ridge")
cell.grid(row=i, column=j, padx=5, pady=5)
row.append(cell)
self.tiles.append(row)
このメソッドは、ゲームタイルを表示する 4x4 のラベルグリッドを作成します。
初期のタイルを生成する
ここで、ゲーム開始時に初期タイルを生成するメソッドを実装する必要があります。このメソッドは、グリッド上に値が 2 または 4 の 1 つまたは 2 つのタイルを配置します。
def spawn_tile(self):
empty_cells = [(i, j) for i in range(4) for j in range(4) if self.grid[i][j] == 0]
if empty_cells:
i, j = random.choice(empty_cells)
self.grid[i][j] = 2 if random.random() < 0.9 else 4
self.update_tiles()
このメソッドは、グリッド上の空のセルを見つけ、その中の 1 つに新しいタイルをランダムに配置します。
ユーザーインターフェイスを更新する
ゲームグリッドの現在の状態を反映するようにユーザーインターフェイスを更新するメソッドを作成します。
def update_tiles(self):
for i in range(4):
for j in range(4):
tile_value = self.grid[i][j]
self.tiles[i][j]["text"] = str(tile_value) if tile_value > 0 else ""
self.tiles[i][j]["background"] = self.get_tile_color(tile_value)
このメソッドはグリッドを繰り返し処理し、グラフィカルユーザーインターフェイスのラベルをグリッドの状態に合わせて更新します。
タイルの色を定義する
タイルの値に基づいて背景色を割り当てるメソッドを作成します。
def get_tile_color(self, value):
colors = {
0: "#CDC1B4",
2: "#EEE4DA",
4: "#EDE0C8",
8: "#F2B179",
16: "#F59563",
32: "#F67C5F",
64: "#F65E3B",
128: "#EDCF72",
256: "#EDCC61",
512: "#EDC850",
1024: "#EDC53F",
2048: "#EDC22E"
}
return colors.get(value, "#FF0000")
このメソッドは、タイルの値に基づいて色コードを返します。
キー押下を処理する
キー押下を処理するメソッドを実装します。このステップでは、矢印キーの押下を捕捉し、それに応じて応答します。
def key_pressed(self, event):
if self.is_game_over():
return
if event.keysym == "Up":
self.move("up")
elif event.keysym == "Down":
self.move("down")
elif event.keysym == "Left":
self.move("left")
elif event.keysym == "Right":
self.move("right")
self.spawn_tile()
self.update_tiles()
このメソッドは矢印キーの押下を監視し、対応する移動関数をトリガーします。
タイルを移動する
タイルを上、下、左、右の希望する方向に移動するメソッドを実装します。
def move(self, direction):
if direction == "up":
self.grid = list(map(list, zip(*self.grid)))
self.move_left()
self.grid = list(map(list, zip(*self.grid)))
elif direction == "down":
self.grid = list(map(list, zip(*self.grid)))
self.move_right()
self.grid = list(map(list, zip(*self.grid)))
elif direction == "left":
self.move_left()
elif direction == "right":
self.move_right()
このメソッドは、移動のためにグリッドを準備し、適切な移動関数を呼び出し、その後グリッドをリセットします。
タイルを左に移動する
行内でタイルを左に移動するメソッドを定義します。
def move_left(self):
for i in range(4):
row = self.grid[i]
row = [value for value in row if value!= 0]
while len(row) < 4:
row.append(0)
for j in range(3):
if row[j] == row[j + 1] and row[j]!= 0:
row[j] *= 2
row[j + 1] = 0
self.score += row[j]
row = [value for value in row if value!= 0]
while len(row) < 4:
row.append(0)
self.grid[i] = row
このメソッドは、タイルを左に移動させ、可能な場合は隣接するタイルをマージし、空のセルを埋めます。
タイルを右に移動する
行内でタイルを右に移動するメソッドを定義します。
def move_right(self):
for i in range(4):
row = self.grid[i]
row = [value for value in row if value!= 0]
while len(row) < 4:
row.insert(0, 0)
for j in range(3, 0, -1):
if row[j] == row[j - 1] and row[j]!= 0:
row[j] *= 2
row[j - 1] = 0
self.score += row[j]
row = [value for value in row if value!= 0]
while len(row) < 4:
row.insert(0, 0)
self.grid[i] = row
このメソッドは、タイルを右に移動させ、適切な場合にはタイルをマージし、空きスペースを埋める役割を担っています。
ゲームオーバーをチェックする
ゲームが終了したかどうかをチェックするメソッドを作成します。もう移動ができない場合、ゲームは終了です。
def is_game_over(self):
for i in range(4):
for j in range(4):
if self.grid[i][j] == 0:
return False
for i in range(4):
for j in range(3):
if self.grid[i][j] == self.grid[i][j + 1]:
return False
for j in range(4):
for i in range(3):
if self.grid[i][j] == self.grid[i + 1][j]:
return False
return True
このメソッドは、グリッドに空のセルがあるか、または同じ値を持つ隣接するセルがあるかを調べることで、さらに移動が可能かどうかをチェックします。もう移動ができない場合、ゲームは終了です。
プロジェクトを実行する
最後に、デスクトップに切り替えて、以下のコマンドを使用してプロジェクトを実行します。
python 2048_game.py

まとめ
このプロジェクトでは、Tkinter ライブラリを使用して Python でシンプルな 2048 ゲームを作成する方法を学びました。まずはプロジェクトのセットアップを行い、メインの Python ファイルを作成し、Game2048 クラスを定義しました。次に、キー入力、タイルの移動を実装し、ゲームオーバーの条件をチェックしました。ゲームインターフェイスは必ずしも最新かつ美しいものではないかもしれませんが、より洗練された 2048 ゲームを作成するための基礎ができました。プロジェクトを実行するには、以下の手順に従ってください。



