Crea un juego 2048 con Python y Tkinter

PythonPythonBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este proyecto, aprenderás cómo crear un sencillo juego de 2048 utilizando Python y la biblioteca Tkinter para la interfaz gráfica de usuario. 2048 es un popular juego de rompecabezas deslizante en el que combinas fichas para alcanzar la ficha con un valor de 2048. Si bien este proyecto no creará la interfaz de usuario más moderna y bonita, proporcionará una base sólida sobre la cual puedes construir para mejorar la estética.

👀 Vista previa

2048 game

🎯 Tareas

En este proyecto, aprenderás:

  • Cómo importar las bibliotecas necesarias para el juego
  • Cómo crear la clase Game2048 para manejar la lógica del juego y la interfaz de usuario
  • Cómo dibujar la cuadrícula del juego utilizando Tkinter
  • Cómo generar las fichas iniciales en la cuadrícula
  • Cómo actualizar la interfaz de usuario para reflejar el estado actual de la cuadrícula del juego
  • Cómo definir los colores de las fichas según sus valores
  • Cómo manejar las pulsaciones de teclas para mover las fichas
  • Cómo definir métodos para mover las fichas en diferentes direcciones
  • Cómo comprobar si el juego ha terminado

🏆 Logros

Después de completar este proyecto, podrás:

  • Utilizar la biblioteca Tkinter para crear una interfaz gráfica de usuario
  • Manejar las pulsaciones de teclas y activar las acciones correspondientes
  • Actualizar la interfaz de usuario según el estado del juego
  • Implementar la lógica del juego para los movimientos y combinaciones de fichas
  • Comprobar si un juego ha terminado

Crear los archivos del proyecto

Primero, crea un nuevo archivo llamado 2048_game.py y ábrelo en tu editor de código preferido.

cd ~/project
touch 2048_game.py
✨ Revisar Solución y Practicar

Importar bibliotecas necesarias

Para que tu juego funcione, necesitas importar las bibliotecas esenciales. En el archivo 2048_game.py, incluye la biblioteca random de Python y Tkinter para construir la interfaz gráfica de usuario.

import random
import tkinter as tk

Estas bibliotecas se utilizarán para crear la funcionalidad del juego y la interfaz de usuario.

✨ Revisar Solución y Practicar

Crear la clase Game2048

Define la clase Game2048 en tu archivo 2048_game.py. Esta clase manejará la lógica del juego y la interfaz de usuario.

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 = []

Aquí, estás creando un constructor de clase que inicializa la ventana principal del juego, establece su título y tamaño, inicializa la cuadrícula del juego y crea una lista para almacenar las fichas del juego.

✨ Revisar Solución y Practicar

Dibujar la cuadrícula del juego

En la clase Game2048, agrega un método para dibujar la cuadrícula del juego utilizando Tkinter. Este método crea la cuadrícula inicial de la interfaz de usuario.

    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)

Este método crea una cuadrícula de etiquetas de 4x4 que mostrarán las fichas del juego.

✨ Revisar Solución y Practicar

Colocar las fichas iniciales

Ahora, necesitas implementar un método que coloque las fichas iniciales cuando el juego comience. Este método colocará una o dos fichas con el valor 2 o 4 en la cuadrícula.

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

Este método localiza las celdas vacías en la cuadrícula y coloca aleatoriamente una nueva ficha en una de ellas.

✨ Revisar Solución y Practicar

Actualizar la interfaz de usuario

Crea un método para actualizar la interfaz de usuario y reflejar el estado actual de la cuadrícula del juego.

    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)

Este método recorre la cuadrícula, actualizando las etiquetas en la interfaz gráfica de usuario para que coincidan con el estado de la cuadrícula.

✨ Revisar Solución y Practicar

Definir colores de las fichas

Crea un método para asignar colores de fondo a las fichas según sus valores.

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

Este método devuelve un código de color basado en el valor de la ficha.

✨ Revisar Solución y Practicar

Manejar las pulsaciones de teclas

Implementa un método para manejar las pulsaciones de teclas. En este paso, capturarás las pulsaciones de las flechas del teclado y responderás en consecuencia.

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

Este método escucha las pulsaciones de las flechas del teclado y activa la función de movimiento correspondiente.

✨ Revisar Solución y Practicar

Mover las fichas

Implementa métodos para mover las fichas en la dirección deseada: arriba, abajo, izquierda o derecha.

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

Este método prepara la cuadrícula para el movimiento, invoca la función de movimiento adecuada y luego restablece la cuadrícula.

✨ Revisar Solución y Practicar

Mover las fichas hacia la izquierda

Define un método para mover las fichas hacia la izquierda dentro de una fila.

    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

Este método procesa los movimientos de las fichas hacia la izquierda, fusionando las fichas adyacentes cuando es posible y llenando las celdas vacías.

✨ Revisar Solución y Practicar

Mover las fichas hacia la derecha

Define un método para mover las fichas hacia la derecha dentro de una fila.

    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

Este método es responsable de mover las fichas hacia la derecha, fusionarlas cuando sea apropiado y llenar los espacios vacíos.

✨ Revisar Solución y Practicar

Comprobar si el juego ha terminado

Crea un método para comprobar si el juego ha terminado. El juego termina cuando ya no son posibles más movimientos.

    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

Este método comprueba si son posibles más movimientos examinando si la cuadrícula contiene celdas vacías o celdas adyacentes con el mismo valor. Si ya no son posibles más movimientos, el juego ha terminado.

✨ Revisar Solución y Practicar

Ejecutar el proyecto

Finalmente, cambia al escritorio (Desktop) y ejecuta el proyecto utilizando el siguiente comando:

python 2048_game.py
2048 game
✨ Revisar Solución y Practicar

Resumen

En este proyecto, has aprendido cómo crear un sencillo juego 2048 en Python utilizando la biblioteca Tkinter. Comenzaste configurando el proyecto, creando el archivo principal de Python y definiendo la clase Game2048. Luego, implementaste las pulsaciones de teclas, los movimientos de las fichas y comprobaste las condiciones de fin de juego. La interfaz del juego puede no ser la más moderna y bonita, pero ahora tienes una base que puedes mejorar y personalizar para crear un juego 2048 más pulido. Para ejecutar el proyecto, puedes seguir los pasos a continuación.