Programación de juegos en Python - Tutorial 2
Esto es lo que pretendemos conseguir en este segundo tutorial, un pong, aprendiendo por el camino a crear una ventana, colocar imagenes en pantalla, crear sprites, mover los sprites, detectar colisiones y controlar las entradas del ratón.
Como veis, este tutorial será más completo que el anterior, dejandonos la puerta abierta para empezar a hacer nuestros primeros juegos.
NOTA: SerÃa conveniente que se siga el tutorial escribiendo código a la vez, en lugar de limitarse a ejecutar el ejemplo.
1. IMPORTANDO LIBRERIAS
Tenemos que importar las librerias que usaremos en el juego, para empezar nos bastará con PYGAME.
import pygame
from pygame.locals import *
SCREEN_WIDTH = 640
SCREEN_HEIGHT = 480
También definimos dos variables globales (por metodologÃa se suelen poner en mayusculas) que nos indicarán la resolución del area de juego.
2. CONFIGURANDO LA PANTALLA
Empezaremos siempre por crear una función principal y escribiremos el siguiente código:
def main():
pygame.init()
screen = pygame.display.set_mode( (SCREEN_WIDTH,SCREEN_HEIGHT) )
pygame.display.set_caption( "PyPong" )
if __name__ == '__main__': main()
Iniciamos la librerÃa y seteamos el modo de visualización a la resolución seleccionada.
Le ponemos un nombre a la ventana y listo, ya tenemos nuestra ventana funcionando.
* Descargar código escrito hasta ahora: aquÃ
3. CARGANDO IMAGENES
Cargar una imagen es una instrucción muy sencilla, pero como es una tarea repetitiva que haremos muchas veces, nos crearemos una función para cargar imagenes con algunas opciones extras.
def load_image(name, colorkey = False):
try: image = pygame.image.load(name)
except pygame.error, message:
print 'No se puede cargar la imagen: ', name
raise SystemExit, message
image = image.convert()
if(colorkey):
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
return image, image.get_rect()
Expliquemos esta función empezando por lo que recibe, que es el nombre de una imagen y si llevará colorkey.
El colorkey es el color de la imagen que se tomará como transparente, es algo realmente util para imagenes con bordes no uniformes o redondeados, como bolas, bombas, ect …
Despues nos encontramos con un try, que es como un “espera, voy a probar esto … y si hay una excepción (algo falla), haz esto otro”.
Probamos a cargar la imagen, y si algo falla (no está en el mismo directorio o simplemente no está, o no se tienen permisos, ect …) imprimimos un mensaje en consola y cerramos la aplicación (raise SystemExit, message).
Luego convertimos la imagen al formato interno que usa SDL, esto hará que todas las operaciones que manejen esta imagen vayan más sueltas.
Luego miramos si queremos usar colorkey en esta imagen, si es asÃ, lo cogemos del pixel que esta en la posición 0,0 (arriba a la izquierda), y lo seteamos en la imagen con la constante RLEACCEL, por que no cambiará y esto hará que se cargue más rápido.
Por último devolvemos la imagen y las dimensiones de la imagen con la función get_rect().
4. COLOCAR UN FONDO.
Cambiaremos un poco el código en la función principal para que quede algo asi …
background_image, background_rect = load_image( "fondo.jpg" )
pygame.mouse.set_visible( False )
screen.blit(background_image, (0,0))
pygame.display.flip()
Las dos primeras sentencias son sencillas de entender, la primera carga una imagen y sus dimensiones y la guarda en background_image y background_rec respectivamente (este último por compatibilidad con la función de cargar imagenes, que nos devuelve un segundo parámetro). La segunda sentencia oculta el puntero del ratón.
Luego colocamos el fondo en la posición 0,0 (arriba a la izquierda) y por ultimo mostramos todo en pantalla (esta última orden es la que muestra todo).
*Descargar la imagen de fondo oficial: aquÃ
*Descargar código fuente realizado hasta ahora: aquÃ
5. EMPEZANDO CON SPRITES
Es una buena costumbre hacer una clase con cada sprite, de manera que tengamos controlados sus datos, parametros y acciones.
Quien no tenga idea sobre clases y objetos, aconsejo que se lean este articulo de la wikipedia, aunque no utilizaremos propiedades mas avanzadas como la jerarquia o la herencia de clases.
Vamos a empezar creando el objeto bola y haciendo que rebote sobre los limites de la pantalla.
class bola(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image, self.rect = load_image('ball.gif', 0)
self.rect.centerx = SCREEN_WIDTH / 2
self.rect.centery = SCREEN_HEIGHT / 2
self.speed = [2,2]
def update(self):
if self.rect.left < 0 or self.rect.right > SCREEN_WIDTH: self.speed[0] = -self.speed[0]
if self.rect.top < 0 or self.rect.bottom > SCREEN_HEIGHT: self.speed[1] = -self.speed[1]
self.rect.move_ip( (self.speed[0],self.speed[1]) )
La variable self indica la clase actual en la que se está, normalmente se pasan a todas las funciones dentro de una clase.
Despues de definir el nombre y tipo de la clase creamos el constructor (__init__) iniciliazando la clase sprite en pygame, despues cargamos la imagen y las dimensiones que tendrá esa imagen mediante la función que hicimos antes.
Luego seleccionamos como posición inicial el centro de la pantalla, y por último especificamos su velocidad, que esta formado por la cantidad de pixel que avanzará arriba/abajo y derecha/izquierda.
La función update se encargará de hacer avanzar la bola y rebotarla cuando haya llegado a los lÃmites de la pantalla. La función move_ip(x,y) mueve de forma relativa el sprite por pantalla, esto es, subirá o bajará x pixel y avanzará retrocederá y pixel.
Esto explicado puede que haya quedado confuso, pero creo que mirando el código se entiende que es lo que hace cada paso.
6. PONIENDO EL SPRITE EN LA PANTALLA
Una vez creada la clase tenemos que instanciarla en un bucle principal que crearemos a tal efecto, con lo que la función principal quedarÃa asi:
def main():
pygame.init()
screen = pygame.display.set_mode( (SCREEN_WIDTH,SCREEN_HEIGHT) )
pygame.display.set_caption( "PyPong" )
background_image, background_rect = load_image( "fondo.jpg" )
screen.blit(background_image, (0,0))
pygame.mouse.set_visible( False )
sbola = bola()
gtodos = pygame.sprite.RenderPlain((sbola))
clock = pygame.time.Clock()
while 1:
clock.tick(60)
sbola.update()
screen.blit( background_image, (0,0) )
gtodos.draw(screen)
pygame.display.flip()
Lo primero que hacemos es instanciar la bola y guardar el objeto en la variable sbola, normalmente se suele poner la primer letra del tipo que sea la variable, aunque la nomenclatura de las variables depende del programador, cada cual tiene sus métodos.
Despues viene una acción muy importante, ya que creo un grupo de sprites (renderplain) con TODOS los sprites que se usen en el juego, para despues realizar acciones globales a todos a la vez (como pintar todos en pantalla, actualizar, ect…) .
Por último creo un reloj, ahora veremos para que lo usaremos.
Creamos un bucle infinito, que es donde se desarrollará toda la acción y lo primero que haremos es poner el reloj a un paso de 60, esto se hace para que nunca se pase de 60 frames por segundo, asi no importará si estamos ejecutando esto en un pentium 2 que en el mare nostrum, la velocidad será, como máximo, de 60 frames por segundo.
Movemos la bola llamando a la función del objeto que hace esta acción.
Para acabar colocamos el fondo (ya que lo hemos “despintado” al mover la bola) y por último pintamos todos los sprites en pantalla.
Todo esto lo hemos hecho en un fondo “oculto”, ya que al usuario se le estará mostrando solo el fondo. La última instrucción es la que se encarga de volcar el buffer oculto al buffer principal.
Esta técnica es la que se conoce como double-buffering, SDL la realiza por hardware si puede, si no, por software.
Si ejecutamos veremos la pelotita botar por la pantalla, ahora necesitamos las raquetas …
* Descargar imagen oficial de la bola: aquÃ
* Descargar el código fuente hecho hasta ahora: aquÃ
7. REACCIONANDO A LOS CONTROLES
Vamos a crear la clase pala, que contendrá el movimiento de la pala, tanto de la del jugador, como la del CPU.
class pala(pygame.sprite.Sprite):
def __init__(self, x):
pygame.sprite.Sprite.__init__(self)
self.image, self.rect = load_image('pala.png', 1)
self.rect.centerx = x
self.rect.centery = SCREEN_HEIGHT / 2
def mover_raton(self):
pos = pygame.mouse.get_pos()
self.rect.centery = pos[1]
if self.rect.bottom >= SCREEN_HEIGHT: self.rect.bottom = SCREEN_HEIGHT
elif self.rect.top < =0: self.rect.top = 0
def mover_cpu(self, objetivo):
self.rect.centery = objetivo.rect.centery
if self.rect.bottom >= SCREEN_HEIGHT: self.rect.bottom = SCREEN_HEIGHT
elif self.rect.top < =0: self.rect.top = 0
Lo unico nuevo en el constructor, es que le pasaremos una variable para colocar la pala en la posición x que nos llegue, por lo demas, todo igual que en la bola.
Despues definimos la función mover_raton que lo que hace es capturar la posición del ratón y colocar el sprite en la posición y (altura) del cursor. Las dos últimas instrucciones es una corrección para que si la pala se “sale” de la pantalla, vuelve al máximo permitido.
La función mover_cpu es la inteligencia artificial de la pala controlada por el ordenador, en este sentido no nos quebraremos mucho la cabeza por ahora y simplemente haremos que “siga” la altura de la bola, que se la pasaremos como parámetro. Luego tenemos la corrección antes explicada.
Con esto ya tenemos definidas las palas, vamos a instanciarlas desde la función principal.
En la zona de inicialización de variables, donde instanciamos a la bola, debemos añadir las instancias a las palas y agrupar todos los sprites:
sbola = bola()
spala1p = pala(20)
spala2p = pala(SCREEN_WIDTH - 20)
gtodos = pygame.sprite.RenderPlain((sbola, spala1p, spala2p))
clock = pygame.time.Clock()
Lo único remarcable es que tenemos que mandar como parámetro la posición x donde dibujar la raqueta.
Ahora, en la función principal tenemos que darle movimiento a las palas:
pygame.event.pump()
spala1p.mover_raton()
spala2p.mover_cpu(sbola)
sbola.update()
La primera sentencia “recarga” los eventos de la libreria (ratón, teclado, ect…) para que esten disponibles y poder mover la pala.
Para ello añadimos las funciones que mueven las palas ANTES que la bola, el porque de añadirlo antes es por jugabilidad, si movemos antes la bola que la pala, podrÃa darse el caso que visualmente estemos bien colocados, pero para el sistema habriamos perdido, quien haya jugado se acordará de aquello de “¡¡ Pero si no me daba … !!”.
* Descargar imagen oficial de la pala: aquÃ
* Descargar código fuente realizado hasta ahora: aquÃ
8. DETECTANDO COLISIONES
Por último vamos a detectar las colisiones entre la bola y las palas, para ello añadiremos la siguiente función al objeto bola
def colision(self, objetivo):
if self.rect.colliderect(objetivo.rect): self.speed[0] = -self.speed[0]
A la cual le llega como parámetro el objetivo a chequear, en este caso seran las palas, más adelante veremos cómo.
Mediante la sentencia colliderect miramos si se “tocan” las imágenes, si es el caso, cambiamos el sentido horizontal de la bola.
En la función main, dentro del bucle infinito, debemos mirar si la bola ha colisionado ANTES de moverla, mediante las dos siguientes sentencias:
sbola.colision(spala1p)
sbola.colision(spala2p)
Que lo único que hace es comprobar la colisión con las dos raquetas.
Por último, quien haya seguido el ejemplo escribiendolo desde cero, se habrá dado cuenta de que no hay manera de “cerrar” la ventana. Para solucionar eso debemos incluir, despues de mover la bola, las siguientes sentencias:
pygame.event.pump()
keyinput = pygame.key.get_pressed()
if keyinput[K_ESCAPE] or pygame.event.peek(QUIT): raise SystemExit
Asi, si se detecta que ha pulsado escape, se cerrara la ventana.

* Descargar todo el código fuente: aquÃ
Con esto termina este tutorial, ya tendemos conocimientos suficientes como para hacer juegos sencillos que controlen pocos sprites, en la siguiente entrega aprenderemos a controlas muchos sprites de manera cómoda, le pondremos música a los juegos y veremos los controles desde teclado.
He intentado explicar todo lo mejor posible, aún asi, si hay algo que no se entiende o se quiere profundizar más en algún aspecto, os remito al foro de programación, o a los comentarios a este tutorial. Como siempre estoy abierto a cualquier corrección, mejora o sugerencia.
ESTE JUEGO AUN NO ESTÃ TERMINADO …
Este juego funciona, pero tiene bugs, por ejemplo, puedes atrapar la bola entre la pala y la pared, ¿podrias solucionar esto?
Esto es un poco más comlpicado …
La mecanica del juego es muy simple, ¿podrias mejorar el sistema de rebote de la bola?
PISTA: Podrias utilizar trigonometrÃa para controlar la bola, puedes apoyarte en esta web si tienes dudas.
NOTA: Para más información acerca de las funciones utilizadas, como siempre, podeis hojear la documentación de PYGAME
Para descargar todas las imagenes y códigos utilizados: aquÃ.
No perdais de vista este ejemplo, pues lo usaremos para probar la librerÃa python-2play y jugar en red en los últimos tutoriales !!!


August 25th, 2005 en 11:37 pm
Que pedazo de tutorial te está quedando dvl. Cuando termines le hacemos una portada, lo pasamos a PDF y le hacemos una sección especial en la web. Te he cambiado un par de enlaces a imágenes que no iban.
August 25th, 2005 en 11:48 pm
Muchas gracias Cromo, de verdad, se hace lo que se puede, por que tengo MUY poco tiempo libre … pero creo que esto ayudará a la gente que empieza a intentar colaborar/ayudar al mundo de los juegos en linux
Granito a granito se hace la montaña … y este es mi granito ;P
August 26th, 2005 en 12:13 am
Está genial esta segunda parte. Me lo voy a empapar de cabo a rabo a ver si domino el tema. Además me viene de perlas ya que estos dias me estoy liando con Python a marchas forzadas.
August 26th, 2005 en 1:43 am
Todos a los pies de dvl :PP, muy bueno, voy a seguirlo ahora que tengo ubuntu aqui en casa de mi novia.
PD: akademyyyyyyyyyyy
August 26th, 2005 en 11:54 am
Mi más sincera enhorabuena. Particularmente me gusta trastear con códigos y demás pero lo máximo que habÃa hecho era un juego de navecitas en ensamblador… De veras que acabas de despertar un gran interés en mà y en aprender phyton, parece un lenguaje majo. Seguiré estos tutoriales y ahora mismo voy a trastear con lo que has hecho.
Un saludo
August 28th, 2005 en 6:04 pm
En mi opinión pygame tiene sentido para pequeños juegos o, lo que es muchÃsimo más importante, para usarlo como lanzadera para opengl. Usando Opengl puedes hacer gráficos en 2D aprovechando las capacidades de las taretas gráficas, y no hablo de las últimas arjetas, hablo de tarjetas muy asequibles.
buen trabajo, un salludo
September 15th, 2005 en 3:52 pm
buen trabajo espero que cosas asà de buenas sigan saliendo podeis mandarme a mi correo más documentos sino es molestia es que soy novato en esto y quisiera empezar a sumergime en este maravilloso mundo saludos a todos y que viva nuestro sistema favorito Gnu/Linux escribanme a donaldoquintana@yahoo.es espero prontas colaboraciones.
September 15th, 2005 en 4:29 pm
Excelente tutorial
September 15th, 2005 en 7:55 pm
Para mi un muy buen tutorial, esperemos que el tutorial siga este progreso y que no se estanque,el nivel de explicacion la justa tampoco hay que cebarse a veces con un buen codigo basta,Felicidades voy a estar atento para las siguientes versiones
September 15th, 2005 en 10:06 pm
Me parece excelente !
Parece que no hay pretexto para portar todos los juegos que tengo hechos en DOS a Linux con graficos. . .
Por lo que he visto la base es la misma que uso en borland C. Asi que lo veo sencillo.
p.d. Alguien en particular puede ayudarme a echar andar mi linux con python ? uso Red hat pero si es necesario lo quito y pongo el necesario.
September 15th, 2005 en 10:53 pm
me parecen geniales los tutoriales, creo que es una manera muy buena para aprender python!!
September 16th, 2005 en 3:39 pm
[…] aprender los fundamentos de python e incluso atreveros a programar juegos, hacedle clic a este enlace
[…]
September 16th, 2005 en 3:55 pm
Fantástico tuto ^^
September 16th, 2005 en 8:28 pm
Angel si no es mucha molestia, postea tus dudas en el foro, asà estará todo mejor organizado y será mas facil para posteriores consultas.
September 16th, 2005 en 11:33 pm
Bueno, como sabiamente dice cutOFF, las dudas las intentaré resolver en el foro. Pero bueno, como he estado un tiempo fuera y se me han amontonado comentarios haré aquà un repasillo.
javi, pygame utiliza SDL, y tambien puede usar openGL, pero el objetivo del tutorial es aprender desde lo básico, y creo que 3D no es aún muy básico, y python con pygame es ideal para esto, es un lenguaje sencillo y las funciones que usa son “genericas” para cualquier lenguaje que use SDL. (Si alguien ha usado directX o allegro verá que en el fondo es lo mismo).
Done, el uno de los objetivos del tutorial es que haya algo en español, ya que apenas encontre información en nuestro idioma, si quieres te puedo mandar info, pero en ingles.
xirex96, se estancó, por que estuve de vacaciones (que una vez al año no hace daño), y ademas tengo poco tiempo, pero aún asÃ, este domingo (18-09-2005) espero subir la tercera parte del tutorial, y seguir un ritmo de a semana o dos semanas por capitulo … pero el hombre propone y dios dispone …
Angel, en el foro, te voy a poner un post con un “install” paso a paso para red hat. Y si, podrás pasar todos esos juegos de DOS, y seguro que apenas te costará esfuerzo.
Venga, hasta pronto !!!
September 18th, 2005 en 4:11 pm
Estupendisimo tutorial, com otu has dicho el juego n oestá terminado, le añado una par de funcionalidades que tu mismo has nombrado, un meno, para 1 u dos jugadores, y cuando hables de lo de la red pues posivilidad de jugar online, ke solo jugaré yo y el tipo al ke obligue por cansino pero está wapo
y una vez bien empachado de pong me paso al de la nave ke ya está publicado.
September 19th, 2005 en 11:09 pm
wuuuuaaaaooo es la primera vez que me meto con python y esta de pelos, no se mucho de progra pero la verdad es que este tutorial le ayuda bastante a auno a abrir el apetito por la informatica y mejor aun por la comunidad. los felicito a todos por tan excelente trabajo, de verdad que cuesta encontrar informacion en español. Una vez mas mis felicitaciones. Espero que todos esten en disposicion de ayudar………….. miauuuuuu……………………..
September 22nd, 2005 en 9:04 pm
dvl, de verdad que te has sobrado, soy novato, pero como no serlo si en toda parte ve uno el puto guindos y nada para linux
, agradezco que me colabores esta bien mandame la informaciòn que tratare de traducirla al español, les cuento que estudio sistemas en la UdeA (Colombia) colaboradme que entre el mundo GNU no puede exister el egoismo.
cualquier documento que me queraÃs enviar se los agradeceria muchisimo: donaldoquintana@yahoo.es
September 24th, 2005 en 6:51 am
Excelente tutorial!!
En mi casa tengo ubuntu y window$, asi que de cualquier manera puedo probar los ejemplos este en un sistema u otro jejeje. Dvl, tengo una duda: ¿pygame, hace uso de las capacidades de la tarjeta grafica directamente, ya sea en 2D con sprites o en 3D con poligonos? ¿o usa la memoria del sistema (no para graficos)? DirectX, aunque se trabaje con sprites y graficos 2D, hace uso de la tarjeta grafica directamente, en pygame es lo mismo? (o similar).
Te hago esta consulta porque me interesa para saber si los juegos se ejecutan eficientemente gracias a que se trabaja directamente con la tarjeta grafica, como lo hace directX u openGL.
Un saludo.
October 1st, 2005 en 10:31 am
DanielGT, pygame usa SDL, y SDL si usa la tarjeta gráfica, de hecho, en el capitulo 3 le decimos explicitamente que use la tarjeta gráfica.
October 13th, 2005 en 5:04 pm
Hola amigos:
de q sirve un en el q nunca pierdes, asi q heche mano del codigo q nos dio dvl, gracias por estos tutoriales, hice algunas modificacions y logre el q juego funcione creo algo mejor y ahora nos sale el puntaje en la pantalla
Me encanto el tutorial lo segui con muy interes pero cuando lo termine el juego no perdia nunca
A continuacion explica nada una de mis modificaciones:
Primero importe el modulo font para poder tener el texto dela puntuacion:
import pygame.font
from pygame.font import *
La clase bola
Modificamos la funcion update:
Añadimos:
if self.rect.left SCREEN_WIDTH: self.speed[0] = -self.speed[0]
if self.rect.top SCREEN_HEIGTH: self.speed[1] = -self.speed[1]
if self.rect.left
January 15th, 2006 en 8:24 pm
oe sabes que no hagas cosas fantaciosas ps ya noseas fantacioso
ya
January 28th, 2006 en 6:35 pm
grandiiisimo trbajo, para cuando el tercer turorial?
April 27th, 2006 en 3:20 am
bn g nasdhh het hite hite nhdfmm .jnnx
April 27th, 2006 en 3:21 am
waaaea c v fv r bvv fr bv b
September 4th, 2006 en 2:26 am
Excelente tutorial…!!! Felicidades.
September 17th, 2006 en 6:00 am
Tuve barios problemas para poder programar este juego, y aun no pude hacerlo.
¿Podrìan darme algunos consejos y pasos a seguir?.
Desde ya, GRACIAS.
September 21st, 2006 en 1:01 am
holas , tengo serios problemas con este juego es la primera ves q intento hacer esto , y la verdad
no pude p`rogramarlo es la 9 ves q lo intento i nada , lres pido ayuda
, desde ya gracias allex88_80@hotmail.com
January 12th, 2007 en 10:08 pm
Tengo Python 2.5 cuando juego al pong me dice que no existe ninguna libreria llamada pygame!!
Pueden ayudarme gracias
February 17th, 2007 en 6:34 pm
La libreria pygame te la puedes descargar desde http://www.pygame.org/download.shtml e incluso creo que hay un paquete de instalación.
A alex le aconsejo que pruebe a instalar la última version de Python, (o al menos la 2.4, http://www.python.org/2.4). Despues lo mismo que a StoneIMP. Instala el paquete de pygame y vuelve a probar.
El tutarial es muy bueno. sobre todo, si no tienes mucha idea de como utilizar la libreria pygame.
Un saludo
March 1st, 2007 en 9:04 am
Quise bajar los fuentes, pero cuando hago click en el enlace me envÃa a una página 500 Internal Server Error
May 13th, 2007 en 3:07 am
[…] Empece leyendo unos tutoriales y pude hacer juegos en un par de horas, es super veloz, mi conocimiento de python era nulo. Pueden leer los algunos tutoriales de linuxjuegos o leer algunos articulos de loserjuegos que son re importantes. […]
November 23rd, 2007 en 4:37 pm
Excelente tutorial!!!
MUY claro y completo.
saludos!!
February 4th, 2008 en 7:27 pm
Felicitaciones por el tutorial, es muy buen resumen, tanto asi que me gustaria linkearlos de mi pagina, pues hace poco empeze a hacer un blog sobre programacion de video juegos y me voy a enfocar principalmente en python y pygame y aunque todavia el blog esta en pañales me gustaria tener sus comentarios para poder asi mejorarlo.
aqui les dejo el link.
http://www.creatusjuegos.blogspot.com/
de antemano muchas gracias
August 27th, 2008 en 7:22 pm
son todos gggggggggggggggggaaaaaaaaaaaaaaaaaayyyyyyyyyyyyyyyyy