Pong Python
Pong Python
Pygame: Pong
Historia de Pong
Aunque desde la aparición de los ordenadores programables en los años 40 del siglo XX se han escrito programas que
podían considerarse juegos, se suele considerar que el primer videojuego fue Computer Tennis. Este videojuego fue
creado en 1958 para la exposición anual del Laboratorio Nacional de Brookhaven (EEUU) y simulaba un pista de tenis
vista lateralmente. El juego se visualizaba en la pantalla de un osciloscopio y se convirtió en la mayor atracción de esa
exposición. Aunque al año siguiente la exposición contó con una versión mejorada, tras ella el equipo se desmontó para
reutilizar los componentes en el Laboratorio.
Bastante años después, en septiembre de 1972, se comercializó la primera videoconsola de la historia dirigida a los
hogares, Magnavox Odyssey. Esta videoconsola se conectaba a una pantalla de televisor y uno de los juegos incluidos era
Table Tennis. En este juego cada jugador controlaba una paleta que golpeaba una pelota. El mismo año, pero en
noviembre, la compañía Atari comercializó Pong, una de las primeras máquinas de arcade, destinadas a lugares públicos.
Con Pong, un juego trivial para los estándares actuales, empezaba la era moderna de
los videojuegos. Pong es un juego de deportes en dos dimensiones que simula un tenis
de mesa. El jugador controla en el juego una paleta moviéndola verticalmente en la
parte izquierda de la pantalla, y puede competir tanto contra un oponente controlado
por computadora, como con otro jugador humano que controla una segunda paleta en
la parte opuesta. Los jugadores pueden usar las raquetas para pegarle a la pelota
hacia un lado u otro. El objetivo consiste en que uno de los jugadores consiga más
puntos que el oponente al finalizar el juego. Estos puntos se obtienen cuando el
jugador adversario falla al devolver la pelota.
La palabra Pong es una marca registrada por Atari Interactive (aunque la patente del juego la tuvo la empresa de
Magnavox Odyssey), pero la palabra genérica "pong" se usa para describir el género de videojuegos.
Por todo ello, cuando se aprende a programar videojuegos, es habitual comenzar programando un juego como Pong, por
su sencillez y también como homenaje al gran clásico.
Pygame
Pygame es un conjunto de módulos de Python que facilitan la creación de videojuegos. Pygame utiliza internamente la
biblioteca SDL (Simple DirectMedia Layer), escrita principalmente en C.
Pygame se distribuye bajo la licencia libre LGPL, lo que permite utilizarla tanto en proyecto libres como comerciales.
Además de la Documentación oficial de pygame, en Internet se pueden encontrar sitios y libros dedicados a la introducción
a la programación en general, o a la introducción a la programación de videojuegos en particular, mediante pygame, como
los siguientes:
Programar Juegos Arcade con Python y Pygame
Making Games with Python & Pygame
Instalación de pygame
Los pasos para instalar pygame como módulo de sistema en Windows son los siguientes:
Abra una ventana de terminal y escriba los siguientes comandos.
Actualice pip:
Instale pygame:
1 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
El juego se ejecutará en una ventana independiente. Para crear la ventana, necesitamos bastante código específico de
pygame, que no es necesario conocer de memoria, ya que lo podemos reutilizar de un proyecto a otro.
El siguiente programa genera una ventana en blanco con el título del juego, similar a la captura siguiente (la ventana está
recortada en la captura).
2 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Cada una de las instrucciones tiene una función específica, que se comenta a continuación:
Importación de módulos
Importamos los módulos pygame. Para que al hacer referencia en el programa a las constantes de pygame no
tengamos que incluir el nombre del módulo, las importamos todas del módulo [Link].
Definición de constantes
Python no tiene un tipo de dato "constante" (es decir, un valor que no se pueda modificar). La costumbre, heredada de
otros lenguajes, es simplemente escribir el nombre de una variable en mayúsculas para indicar a quien lea nuestro
código fuente que esa variable no se va a modificar en ningún momento del programa. Definimos así varias constantes:
El tamaño de la ventana de juego (en este caso, 800 x 600 px, la llamada resolución SVGA original).
Normalmente FPS hace referencia al número de veces por segundo que se actualiza la imagen en la ventana. En
principio, cuanto más alto es ese valor, mejor se verán los objetos en movimiento, aunque cada pantalla admite un
valor máximo y dependiendo de la complejidad de la creación de la imagen puede que no se puedan alcanzar
valores muy altos. En pygame, la ventana se está actualizando constantemente y en cada actualización los objetos
se desplazan, por lo que si la ventana se actualiza demasiadas veces, los objetos se desplazarán demasiado rápido.
Para evitarlo, en pygame FPS significa el número máximo de veces que queremos que se actualice la ventana,
aunque si debido a la complejidad de la imagen el número de veces que se actualiza la imagen es inferior, pygame
no podrá alcanzarlo.
En pygame los colores se indican mediante códigos RGB, así que definimos una constante con el nombre del color
para facilitar su referencia.
Inicialización
3 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
El primer elemento del juego que programaremos será la pelota. Para definir la pelota crearemos una clase a la que
llamaremos PelotaPong. Las clases son propias de la programación orientada a objetos y permiten ampliar los tipos de
datos del lenguaje. Una vez definida la clase, podemos crear tantas variables de esa clase como queramos (por ejemplo,
una o varias pelotas, en el caso de que quisiéramos jugar con varias pelotas a la vez).
El siguiente programa dibuja una pelota cuadrada de color rojo en el centro de la ventana y la desplaza en línea recta en
una de las cuatro direcciones diagonales. Cuando llega al borde de la ventana, la pelota deja de verse aunque sigue
moviéndose indefinidamente en la misma dirección.
Para situar los objetos en la ventana pygame utiliza un sistema de coordenadas cartesianas en el que el origen se
encuentran en la esquina superior izquierda de la ventana y en el que el eje vertical está dirigido hacia abajo. De esta
manera, los valores de las coordenadas serán siempre positivos: cuanto mayor sea la coordenada x más a la derecha
estará el objeto y cuanto mayor sea la coordenada y más hacia abajo estará el objeto. Si se asignan valores negativos o
mayores que el tamaño de la ventana, no se produce ningún error, pero el objeto simplemente no se verá (dependiendo
del tamaño que tenga y de los valores utilizados, el objeto puede verse parcialmente).
4 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
5 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
En la definición de una clase se definen los atributos y los métodos de la clase. Los atributos son variables que van
asociadas automáticamente a los objetos. Los métodos son funciones que se pueden aplicar a los objetos. En la
definición de la clase para hacer referencia a que los atributos son los del propio objeto se indica con self.
El método __init__() es la función que se ejecuta automáticamente cuando se cree un objeto de la clase. Por eso,
aprovechamos este método para definir los atributos de la clase. En el caso de la pelota de este juego, sus atributos
serán: la imagen que se muestra en la pantalla, su tamaño, la posición en la pantalla y la dirección del movimiento:
Todos los métodos incluyen el argumento self que hace referencia al propio objeto. En este caso, también
añadimos el argumento imagen que indicará el camino hasta el fichero de imagen de la pelota:
Otros dos atributos serán el ancho y alto de la imagen, ancho y alto que se obtienen a partir del atributo imagen
con el método get_size():
6 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Dos atributos más serán la posición horizontal y vertical de la imagen, x e y. Inicialmente, queremos que la pelota
se dibuje en el centro de la pantalla. Para ello, tenemos que tener en cuenta que cuando indicamos la posición de
un objeto, estamos indicando la posición de la esquina superior izquierda de su imagen. Si el objeto es muy
pequeño, no se notará la diferencia, pero lo mejor es tener en cuenta el ancho y alto del objeto, restando la mitad
del tamaño del objeto a la posición del centro de la ventana.
VENTANA_HORI / 2
[Link] / 2
[Link] / 2
VENTANA_VERT / 2
Dos atributos más serán la dirección horizontal y vertical de movimiento de la imagen, dir_x y dir_y.
Numéricamente, serán los píxeles que se desplazará la pelota cada vez que se redibuje la [Link], la
pelota se desplazará 5px aleatoriamente hacia arriba (-5) o hacia abajo (5), hacia la izquierda (-5) o hacia la
derecha (5):
El método mover() es la función que define cómo se mueve la pelota. En este caso, simplemente añadimos a las
posiciones los valores de las direcciones. Este método sólo se ejecutará cuando la llamemos en el cuerpo del
programa.
La imagen siguiente muestra tres posiciones sucesivas de la pelota. La pelota se desplaza cada vez dir_x unidades
en horizontal y dir_y unidades en vertical.
dir_x
dir_y
dir_x
dir_y
(3)
(2)
(1)
Creación de la pelota
Una vez definida una clase, en el cuerpo del programa podemos crear objetos (es decir, variables) de esa clase. En
este caso, creamos la variable pelota de la clase PelotaPong. Esta variable automáticamente tendrá los atributos
definidos en la clase (imagen, tamaño, posición, dirección) y se le podrán aplicar los métodos definidos en la clase
(mover()). Al crear la variable le debemos indicar el fichero de imagen a utilizar, en este caso una imagen png.
Mover la pelota
7 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Para que la pelota se mueva y se dibuje en la pantalla, en el bucle principal del programa debemos:
Llamar al método mover(), para que se modifique la posición de la pelota (es decir sus atributos x e y):
Dibujar la pelota en su posición en la ventana. Para ello recurrimos al método bit() del objeto ventana, indicando la
imagen que queremos dibujar y su posición en la ventana:
En este paso mejoraremos el comportamiento de la pelota haciendo que la pelota rebote al chocar con los cuatro lados de
la ventana. Para ello, añadiremos un nuevo método a la clase (rebotar()) que utilizaremos en el bucle principal del
programa.
8 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
9 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
self.y < 0
self.x < 0 self.x + [Link] > VENTANA_HORI
Realmente, en el juego de Pong la pelota no debe rebotar en todos los lados, como hacía en el programa anterior.
Únicamente debe rebotar arriba y abajo. Si la pelota llega a alguno de los lados, significará que uno de los jugadores no ha
devuelto la pelota. En ese caso, el jugador habrá perdido un punto y la pelota debe volver a lanzarse desde el centro (en
dirección al jugador que ha ganado el punto, por ejemplo).
En este paso, modificaremos el método rebotar() y añadiremos un método reiniciar() para conseguir el comportamiento
comentado en el párrafo anterior.
10 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
11 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Método rebotar():
Modificamos el método rebotar(), de manera que cuando detecte que la pelota ha salido por los lados derecho e
izquierdo, llame al método reiniciar().
En este paso añadiremos las raquetas. Para ello definiremos una clase RaquetaPong, similar a PelotaPong y crearemos
dos variables de esa clase.
12 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
13 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
14 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
15 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
El ancho y alto de la imagen, ancho y alto se obtienen a partir del atributo imagen con el método get_size():
16 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Las posiciones iniciales horizontal y vertical de la imagen, x e y que asignemos en la definición de la clase no es
realmente importante, ya que cuando creemos las raquetas deberemos situarlas en posiciones distintas
cambiando estos valores. Para ahorrarnos instrucciones en el cuerpo del programa, estableceremos la posición
vertical centrada en la ventana (que es común a ambas raquetas).
Como la raqueta sólo se desplaza en vertical, únicamente necesitamos el atributo dir_y, que guardará la dirección
vertical de movimiento de la imagen. Numéricamente, serán los píxeles que se desplazará la raqueta. Inicialmente,
la raqueta estará inmóvil (0):
El método mover() es la función que define cómo se mueve la raqueta. Aunque lo modificaremos en el paso
siguiente, por el momento simplemente añadimos a la posición vertical el valor de la dirección vertical.
17 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
18 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
19 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
20 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Ahora que la raqueta se mueve, debemos impedir que se salga de la ventana. Para añadiremos en el método
mover() dos condiciones que detecten si la raqueta se está saliendo (por arriba o por abajo).
21 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
22 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
23 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
24 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
25 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
líneas 83 y 84: Para evitar que el programa detecte colisión en dos o más iteraciones consecutivas (lo que
provocaría cambios continuos de dirección, es decir, el zigzazeo de la pelota), además de cambiar la dirección de
movimiento de la pelota, desplazaremos explícitamente la pelota fuera de la raqueta.
Un detalle que no tiene en cuenta el programa es cuando la raqueta golpea verticalmente la pelota, es decir, cuando
la golpea desde abajo o desde arriba cuando está pasando. Tal y como está redactado el programa, este golpe
produce la devolución de la pelota, cuando realmente no debería hacerlo.
En este paso, añadiremos el control de la raqueta del jugador controlado por el propio programa.
Para ello, crearemos los método mover_raqueta_ia() y golpear_raqueta_ia() en la clase RaquetaPong y en el bucle
principal llamaremos a estos métodos.
26 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
27 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
28 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
29 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
30 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Método golpear_ia()
Este método es como el método golpear() del jugador humano, pero teniendo en cuenta que la pelota se acerca por el
lado izquierdo de la raqueta en vez de por el derecho.
cdcd
31 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
ventana.
32 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
33 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
34 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
35 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Modificar la puntuación
La puntuación debe modificarse cuando un jugador gana, es decir, cuando la pelota supera uno de los laterales. El
programa detecta esa situación en el método rebotar de PelotaPong, así que añadimos en ese método las líneas 44
y 47.
Para mostrar en la ventana la puntuación de ambos jugadores, añadimos las siguientes instrucciones:
Color del texto
Definimos el color NEGRO como constante:
Escritura en la pantalla
36 de 37 17/03/2021 11:09 p. m.
Pong. pygame. Python. Bartolomé Sintes Marco. [Link] [Link]
Detalles pendientes
Estos son los aspectos pendientes de completar en el programa:
En el programa actual, la raqueta puede golpear a la pelota verticalmente (desde arriba o desde abajo) y la pelota se
devuelve, cuando lo que debería de hacer es cambiar de dirección vertical, pero no horizontal (y si la raqueta se mueve
más rápido que la pelota en la misma dirección, no debería cambiar de dirección porque estaría empujándola).
Esta página forma parte del curso Introducción a la programación con Python por Bartolomé Sintes Marco
que se distribuye bajo una Licencia Creative Commons Reconocimiento-CompartirIgual 4.0 Internacional (CC BY-SA 4.0).
37 de 37 17/03/2021 11:09 p. m.