Создание игры 2048 на Python с использованием Tkinter

PythonBeginner
Практиковаться сейчас

Введение

В этом проекте вы узнаете, как создать простую игру 2048 на Python с использованием библиотеки Tkinter для графического пользовательского интерфейса. 2048 - это популярная игра-головоломка с перемещаемыми плитками, в которой вы объединяете плитки, чтобы получить плитку со значением 2048. Хотя в этом проекте не будет создан самый современный и красивый пользовательский интерфейс, он предоставит прочный фундамент, на основе которого вы сможете улучшить внешний вид.

👀 Предпросмотр

2048 game

🎯 Задачи

В этом проекте вы научитесь:

  • Импортировать необходимые библиотеки для игры
  • Создавать класс Game2048 для обработки логики игры и пользовательского интерфейса
  • Рисовать игровую сетку с использованием Tkinter
  • Создавать начальные плитки на сетке
  • Обновлять пользовательский интерфейс в соответствии с текущим состоянием игровой сетки
  • Определять цвета плиток в зависимости от их значений
  • Обрабатывать нажатия клавиш для перемещения плиток
  • Определять методы для перемещения плиток в разных направлениях
  • Проверять, закончилась ли игра

🏆 Достижения

После завершения этого проекта вы сможете:

  • Использовать библиотеку Tkinter для создания графического пользовательского интерфейса
  • Обрабатывать нажатия клавиш и запускать соответствующие действия
  • Обновлять пользовательский интерфейс в зависимости от состояния игры
  • Реализовывать логику игры для перемещения и объединения плиток
  • Проверять, закончилась ли игра

Создание файлов проекта

Сначала создайте новый файл с именем 2048_game.py и откройте его в вашем любимом текстовом редакторе кода.

cd ~/project
touch 2048_game.py

Импорт необходимых библиотек

Для работы вашей игры вам нужно импортировать основные библиотеки. В файле 2048_game.py включите библиотеку random Python и Tkinter для создания графического пользовательского интерфейса.

import random
import tkinter as tk

Эти библиотеки будут использоваться для создания функциональности игры и пользовательского интерфейса.

Создание класса Game2048

Определите класс Game2048 в файле 2048_game.py. Этот класс будет обрабатывать логику игры и пользовательский интерфейс.

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 сетку меток (labels), которые будут отображать игровые плитки.

Создание начальных плиток

Теперь вам нужно реализовать метод, который создает начальные плитки при запуске игры. Этот метод поместит одну или две плитки со значением 2 или 4 на игровую сетку.

    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()

Этот метод находит пустые ячейки на сетке и случайным образом помещает новую плитку в одну из них.

Обновление пользовательского интерфейса

Создайте метод для обновления пользовательского интерфейса, чтобы отразить текущее состояние игровой сетки.

    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)

Этот метод проходит по всей сетке, обновляя метки (labels) в графическом пользовательском интерфейсе так, чтобы они соответствовали состоянию сетки.

Определение цветов плиток

Создайте метод для присвоения фоновых цветов плиткам в зависимости от их значений.

    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

2048 game

Резюме

В этом проекте вы научились создавать простую игру 2048 на Python с использованием библиотеки Tkinter. Вы начали с настройки проекта, создания основного Python-файла и определения класса Game2048. Затем вы реализовали обработку нажатий клавиш, перемещение плиток и проверку условий окончания игры. Интерфейс игры может не быть самым современным и красивым, но у вас теперь есть фундамент, который вы можете улучшить и настроить для создания более совершенной игры 2048. Чтобы запустить проект, вы можете следовать шагам ниже.

✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться✨ Проверить решение и практиковаться