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
      



    


Cerrar