Added Tetris Game to windows with start, pause and restart button

This commit is contained in:
Dennis Eckerskorn 2024-12-04 22:21:53 +01:00
parent 7221395724
commit f91047a7f2
4 changed files with 184 additions and 7 deletions

Binary file not shown.

136
src/services/tetris_game.py Normal file
View File

@ -0,0 +1,136 @@
import tkinter as tk
import random
class TetrisGame(tk.Canvas):
def __init__(self, parent, width=300, height=600, cell_size=30):
super().__init__(parent, width=width, height=height, bg="black")
self.cell_size = cell_size
self.cols = width // cell_size
self.rows = height // cell_size
self.grid = [[0] * self.cols for _ in range(self.rows)]
self.current_piece = None
self.running = True
self.init_game()
def init_game(self):
self.bind_all("<Key>", self.handle_keypress)
self.spawn_piece()
self.update_game()
def spawn_piece(self):
shapes = [
[[1, 1, 1], [0, 1, 0]], # T-shape
[[1, 1], [1, 1]], # Square
[[1, 1, 1, 1]], # Line
[[0, 1, 1], [1, 1, 0]], # S-shape
[[1, 1, 0], [0, 1, 1]], # Z-shape
]
shape = random.choice(shapes)
self.current_piece = {
"shape": shape,
"row": 0,
"col": (self.cols - len(shape[0])) // 2,
}
def draw_piece(self):
shape = self.current_piece["shape"]
row = self.current_piece["row"]
col = self.current_piece["col"]
for r, line in enumerate(shape):
for c, block in enumerate(line):
if block:
self.draw_cell(row + r, col + c, "cyan")
def draw_cell(self, row, col, color):
x1 = col * self.cell_size
y1 = row * self.cell_size
x2 = x1 + self.cell_size
y2 = y1 + self.cell_size
self.create_rectangle(x1, y1, x2, y2, fill=color, outline="gray")
def move_piece(self, drow, dcol):
if self.can_move(drow, dcol):
self.current_piece["row"] += drow
self.current_piece["col"] += dcol
def rotate_piece(self):
"""Rota la pieza actual en el sentido horario."""
shape = self.current_piece["shape"]
rotated_shape = list(zip(*shape[::-1])) # Rotar la matriz en sentido horario
# Verifica si la pieza rotada cabe en la posición actual
if self.can_place(rotated_shape, self.current_piece["row"], self.current_piece["col"]):
self.current_piece["shape"] = rotated_shape
def can_place(self, shape, row, col):
for r, line in enumerate(shape):
for c, block in enumerate(line):
if block:
if row + r >= self.rows or col + c < 0 or col + c >= self.cols:
return False # Fuera de los límites del tablero
if self.grid[row + r][col + c]:
return False # Choca con otro bloque
return True
def can_move(self, drow, dcol):
shape = self.current_piece["shape"]
row = self.current_piece["row"] + drow
col = self.current_piece["col"] + dcol
return self.can_place(shape, row, col)
def place_piece(self):
shape = self.current_piece["shape"]
row = self.current_piece["row"]
col = self.current_piece["col"]
for r, line in enumerate(shape):
for c, block in enumerate(line):
if block:
self.grid[row + r][col + c] = 1
self.clear_lines()
self.spawn_piece()
def clear_lines(self):
self.grid = [line for line in self.grid if any(cell == 0 for cell in line)]
while len(self.grid) < self.rows:
self.grid.insert(0, [0] * self.cols)
def handle_keypress(self, event):
if event.keysym == "Left":
self.move_piece(0, -1)
elif event.keysym == "Right":
self.move_piece(0, 1)
elif event.keysym == "Down":
self.move_piece(1, 0)
elif event.keysym == "Up":
self.rotate_piece()
def update_game(self):
if self.running:
if not self.can_move(1, 0):
self.place_piece()
else:
self.move_piece(1, 0)
self.render()
self.after(500, self.update_game)
def render(self):
self.delete("all")
for r, line in enumerate(self.grid):
for c, block in enumerate(line):
if block:
self.draw_cell(r, c, "blue")
self.draw_piece()
def stop_game(self):
self.running = False
def reset_game(self):
"""Reinicia el estado del juego."""
self.running = False # Detener el juego actual
self.grid = [[0] * self.cols for _ in range(self.rows)] # Reiniciar la cuadrícula
self.current_piece = None # Eliminar la pieza actual
self.delete("all") # Limpiar el lienzo
self.spawn_piece() # Generar una nueva pieza
self.running = True # Habilitar el juego nuevamente
self.update_game() # Reanudar el ciclo del juego

View File

@ -1,10 +1,13 @@
import customtkinter as ctk
import tkinter as tk
import webbrowser
import subprocess
import os
import threading
from services.threads_manager import ThreadsManager
from services.processes_manager import ProcessManager
from services.tetris_game import TetrisGame
class CenteredWindow(ctk.CTk):
@ -75,14 +78,52 @@ class CenteredWindow(ctk.CTk):
tab_view = ctk.CTkTabview(center_panel, width=500, height=500)
tab_view.pack(fill=ctk.BOTH, expand=True)
tabs = ["Resultados Scrapping", "Navegador", "Correos", "Juego", "Sistema"]
for tab in tabs:
tab_view.add(tab)
# Crear pestañas y manejar contenido por separado
for tab_name in ["Resultados Scrapping", "Navegador", "Correos", "Juego", "Sistema"]:
tab = tab_view.add(tab_name)
if tab_name == "Juego":
# Crear un marco intermedio para centrar
game_frame = ctk.CTkFrame(tab)
game_frame.pack(expand=True)
# Botones para el juego
button_frame = ctk.CTkFrame(game_frame)
button_frame.pack(pady=10)
start_button = ctk.CTkButton(button_frame, text="Start Game", command=self.start_tetris_game)
start_button.pack(side=tk.LEFT, padx=5)
pause_button = ctk.CTkButton(button_frame, text="Pause Game", command=self.pause_tetris_game)
pause_button.pack(side=tk.LEFT, padx=5)
restart_button = ctk.CTkButton(button_frame, text="Restart Game", command=self.restart_tetris_game)
restart_button.pack(side=tk.LEFT, padx=5)
# Agregar el Tetris dentro de un contenedor
self.tetris_game = TetrisGame(game_frame)
self.tetris_game.pack()
else:
# Agregar contenido genérico a otras pestañas
label = ctk.CTkLabel(tab, text=f"Contenido de {tab_name}", font=("Arial", 12))
label.pack(pady=10)
def start_tetris_game(self):
"""Método para iniciar el juego."""
if not self.tetris_game.running:
self.tetris_game.running = True
self.tetris_game.update_game()
def pause_tetris_game(self):
"""Método para pausar el juego."""
self.tetris_game.running = False
def restart_tetris_game(self):
"""Método para reiniciar el juego."""
self.tetris_game.reset_game()
# Agregar contenido a las pestañas
for tab in tabs:
label = ctk.CTkLabel(tab_view.tab(tab), text=f"Contenido de {tab}", font=("Arial", 12))
label.pack(pady=10)
def create_right_panel(self):
# Panel derecho