Juego de Ping Pong
Presentación
El presente proyecto consiste en porgramar en Python el tradicional juego de Ping Pong emulando la original version del juego Pong desarrollada por ATARI .
El siguiente video muestra el proyecto en funcionamiento:
Código
pingpong.py
import turtle
import threading
import time
import tkinter as tk
from tkinter import simpledialog
# Configuración inicial de la pantalla
pantalla = turtle.Screen()
pantalla.title("Ping Pong")
pantalla.bgcolor("lightgreen") # Fondo verde claro
pantalla.setup(width=800, height=1000)
pantalla.tracer(0)
# Crear ventana de tkinter para entradas personalizadas
root = tk.Tk()
root.withdraw() # Oculta la ventana principal de tkinter
def pedir_nombre(jugador, nombre_por_defecto):
# Crear una ventana personalizada de entrada
ventana = tk.Toplevel(root)
ventana.title(f"Nombre del {jugador}")
ventana.configure(bg="lightblue") # Color de fondo
ventana.geometry("400x200") # Ajustar tamaño de la ventana
# Etiqueta de texto
label = tk.Label(ventana, text=f"Ingrese el nombre del {jugador}:", bg="lightblue", font=("Fixedsys", 12, "bold"))
label.pack(pady=10)
# Variable y cuadro de entrada
entrada_nombre = tk.Entry(ventana, font=("Fixedsys", 12), width=30)
entrada_nombre.insert(0, nombre_por_defecto) # Establecer nombre por defecto
entrada_nombre.pack(pady=5)
entrada_nombre.focus() # Activar el campo de entrada
# Variable para almacenar el texto ingresado
nombre = tk.StringVar()
# Función para capturar el nombre y cerrar la ventana
def confirmar_nombre():
nombre.set(entrada_nombre.get())
ventana.destroy()
# Botón para confirmar
boton_confirmar = tk.Button(ventana, text="Confirmar", font=("Fixedsys", 12), command=confirmar_nombre)
boton_confirmar.pack(pady=10)
# Esperar hasta que la ventana se cierre
ventana.grab_set()
ventana.wait_window()
# Devolver el nombre ingresado
return nombre.get()
# Pedir nombres de jugadores usando ventanas personalizadas
nombre_jugador_a = pedir_nombre("Jugador A", "Uno")
nombre_jugador_b = pedir_nombre("Jugador B", "Dos")
# Variables para el puntaje y el tiempo
puntaje_a = 0
puntaje_b = 0
tiempo_juego = 0
jugando = False
# Linea Arriiba
linea_a = turtle.Turtle()
linea_a.speed(0)
linea_a.shape("square")
linea_a.color("yellow")
linea_a.shapesize(stretch_wid=0.5, stretch_len=40)
linea_a.penup()
linea_a.goto(0, 300)
# Linea Abajo
linea_b = turtle.Turtle()
linea_b.speed(0)
linea_b.shape("square")
linea_b.color("yellow")
linea_b.shapesize(stretch_wid=0.5, stretch_len=40)
linea_b.penup()
linea_b.goto(0, -300)
# Paleta A
paleta_a = turtle.Turtle()
paleta_a.speed(0)
paleta_a.shape("square")
paleta_a.color("blue")
paleta_a.shapesize(stretch_wid=5, stretch_len=1)
paleta_a.penup()
paleta_a.goto(-350, 0)
# Paleta B
paleta_b = turtle.Turtle()
paleta_b.speed(0)
paleta_b.shape("square")
paleta_b.color("blue")
paleta_b.shapesize(stretch_wid=5, stretch_len=1)
paleta_b.penup()
paleta_b.goto(350, 0)
# Pelota
pelota = turtle.Turtle()
pelota.speed(0)
pelota.shape("circle")
pelota.shapesize(stretch_wid=2, stretch_len=2)
pelota.color("red")
pelota.penup()
pelota.goto(0, 0)
pelota.dx = 0.3
pelota.dy = 0.3
static = True
titulo = turtle.Turtle()
titulo.speed(0)
titulo.color("green")
titulo.penup()
titulo.hideturtle()
titulo.goto(0, 420)
titulo.write("Jugadores", align="center", font=("Fixedsys", 30, "bold"))
# Marcador de puntaje
marcador = turtle.Turtle()
marcador.speed(0)
marcador.color("green")
marcador.penup()
marcador.hideturtle()
marcador.goto(0, 380)
marcador.write(f"{nombre_jugador_a}: 0 {nombre_jugador_b}: 0", align="center", font=("Fixedsys", 24, "bold"))
# Marcador de tiempo
marcador_tiempo = turtle.Turtle()
marcador_tiempo.speed(0)
marcador_tiempo.color("green")
marcador_tiempo.penup()
marcador_tiempo.hideturtle()
marcador_tiempo.goto(0, 340)
marcador_tiempo.write("Tiempo: 0 minutos 0 segundos", align="center", font=("Fixedsys", 24, "bold"))
# Mensaje de inicio
aviso1 = turtle.Turtle()
aviso1.speed(0)
aviso1.color("red")
aviso1.penup()
aviso1.hideturtle()
aviso1.goto(0, 120)
aviso1.write("PRESIONE ENTER PARA COMENZAR", align="center", font=("Fixedsys", 24, "bold"))
# Mensaje de inicio
aviso2 = turtle.Turtle()
aviso2.speed(0)
aviso2.color("black")
aviso2.penup()
aviso2.hideturtle()
aviso2.goto(0, -120)
aviso2.write("PRESIONE ESC PARA SALIR", align="center", font=("Fixedsys", 24, "bold"))
#Instrucciones
inst1 = turtle.Turtle()
inst1.speed(0)
inst1.color("black")
inst1.penup()
inst1.hideturtle()
inst1.goto(0, -340)
inst1.write("Comandos", align="center", font=("Fixedsys", 16, "bold"))
inst2 = turtle.Turtle()
inst2.speed(0)
inst2.color("black")
inst2.penup()
inst2.hideturtle()
inst2.goto(0, -370)
inst2.write("Paleta Izquierda Paleta Derecha", align="center", font=("Fixedsys", 16, "bold"))
inst3 = turtle.Turtle()
inst3.speed(0)
inst3.color("black")
inst3.penup()
inst3.hideturtle()
inst3.goto(0, -420)
inst3.write("w arriba p", align="center", font=("Fixedsys", 16, "bold"))
inst4 = turtle.Turtle()
inst4.speed(0)
inst4.color("black")
inst4.penup()
inst4.hideturtle()
inst4.goto(0, -450)
inst4.write("s abajo l", align="center", font=("Fixedsys", 16, "bold"))
def update_puntaje():
marcador.clear()
marcador.write(f"{nombre_jugador_a}: {puntaje_a} {nombre_jugador_b}: {puntaje_b}", align="center", font=("Fixedsys", 24, "bold"))
def update_tiempo_display():
minutos = tiempo_juego // 60
segundos = tiempo_juego % 60
marcador_tiempo.clear()
marcador_tiempo.write(f"Tiempo: {minutos} minutos {segundos} segundos", align="center", font=("Fixedsys", 24, "bold"))
def paleta_a_up():
y = paleta_a.ycor()
if y <= 240:
y += 20
paleta_a.sety(y)
def paleta_a_down():
y = paleta_a.ycor()
if y >= -220:
y -= 20
paleta_a.sety(y)
def paleta_b_up():
y = paleta_b.ycor()
if y <= 240:
y += 20
paleta_b.sety(y)
def paleta_b_down():
y = paleta_b.ycor()
if y >= -220:
y -= 20
paleta_b.sety(y)
def inicio_juego():
global static, jugando, tiempo_juego
static = False
jugando = True
tiempo_juego = 0
aviso1.clear()
aviso2.clear()
def limpia_pantalla():
global jugando
pelota.goto(0, 0)
pelota.dx *= -1
aviso1.write("PRESIONE ENTER PARA COMENZAR", align="center", font=("Fixedsys", 24, "bold"))
aviso2.write("PRESIONE ESC PARA SALIR", align="center", font=("Fixedsys", 24, "bold"))
paleta_a.goto(-350, 0)
paleta_b.goto(350, 0)
jugando = False
def temporizador():
global tiempo_juego
while True:
if jugando:
time.sleep(1)
tiempo_juego += 1
# Función para cerrar el programa al presionar "Esc"
def cerrar_programa():
pantalla.bye()
# Hilo para el temporizador
hilo_temporizador = threading.Thread(target=temporizador)
hilo_temporizador.daemon = True
hilo_temporizador.start()
pantalla.listen()
pantalla.onkeypress(paleta_a_up, "w")
pantalla.onkeypress(paleta_a_down, "s")
pantalla.onkeypress(paleta_b_up, "p")
pantalla.onkeypress(paleta_b_down, "l")
pantalla.onkeypress(inicio_juego, "Return")
pantalla.onkeypress(cerrar_programa, "Escape") # Asignar la tecla "Esc" para cerrar el programa
while True:
try:
pantalla.update()
update_tiempo_display()
if not static:
pelota.setx(pelota.xcor() + pelota.dx)
pelota.sety(pelota.ycor() + pelota.dy)
if pelota.ycor() > 290:
pelota.sety(290)
pelota.dy *= -1
if pelota.ycor() < -290:
pelota.sety(-290)
pelota.dy *= -1
if pelota.xcor() > 390:
puntaje_a += 1
update_puntaje()
static = True
time.sleep(1)
limpia_pantalla()
if pelota.xcor() < -390:
puntaje_b += 1
update_puntaje()
static = True
time.sleep(1)
limpia_pantalla()
if (pelota.xcor() > 340 and pelota.xcor() < 350) and (pelota.ycor() < paleta_b.ycor() + 50 and pelota.ycor() > paleta_b.ycor() - 50):
pelota.setx(340)
pelota.dx *= -1
if (pelota.xcor() < -340 and pelota.xcor() > -350) and (pelota.ycor() < paleta_a.ycor() + 50 and pelota.ycor() > paleta_a.ycor() - 50):
pelota.setx(-340)
pelota.dx *= -1
except:
break