diff --git a/src/services/__pycache__/tetris_game.cpython-312.pyc b/src/services/__pycache__/tetris_game.cpython-312.pyc new file mode 100644 index 0000000..3129ef5 Binary files /dev/null and b/src/services/__pycache__/tetris_game.cpython-312.pyc differ diff --git a/src/services/tetris_game.py b/src/services/tetris_game.py new file mode 100644 index 0000000..318e45f --- /dev/null +++ b/src/services/tetris_game.py @@ -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("", 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 diff --git a/src/ui/__pycache__/centered_window.cpython-312.pyc b/src/ui/__pycache__/centered_window.cpython-312.pyc index 678a6b6..e240a8e 100644 Binary files a/src/ui/__pycache__/centered_window.cpython-312.pyc and b/src/ui/__pycache__/centered_window.cpython-312.pyc differ diff --git a/src/ui/centered_window.py b/src/ui/centered_window.py index 53bec22..5aca4fc 100644 --- a/src/ui/centered_window.py +++ b/src/ui/centered_window.py @@ -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