Tutoriales no image

Publicado el 25-08-2005 | por admin

37

Programación de juegos en Python – Tutorial 2

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.

Tutorial 22. 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().

Tutorial 24. 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.

Tutorial 2
* 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 !!!


Sobre el autor



37 respuestas a Programación de juegos en Python – Tutorial 2

  1. Cromo says:

    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.

  2. dvl says:

    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

  3. cut0ff says:

    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.

  4. Fox says:

    Todos a los pies de dvl :PP, muy bueno, voy a seguirlo ahora que tengo ubuntu aqui en casa de mi novia.

    PD: akademyyyyyyyyyyy 😛

  5. amuchamu says:

    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 😀

  6. javi says:

    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

  7. Done says:

    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.

  8. Marc says:

    Excelente tutorial

  9. xirex96 says:

    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

  10. Angel says:

    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.

  11. biquillo says:

    me parecen geniales los tutoriales, creo que es una manera muy buena para aprender python!!

  12. Pingback: AcenTiLLo

  13. cut0ff says:

    Angel si no es mucha molestia, postea tus dudas en el foro, así estará todo mejor organizado y será mas facil para posteriores consultas.

  14. dvl says:

    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 !!!

  15. ceritium says:

    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.

  16. felinito14 says:

    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……………………..

  17. Done says:

    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

  18. DanielGT says:

    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.

  19. dvl says:

    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.

  20. |3 0 |2 1 S says:

    Hola amigos:
    Me encanto el tutorial lo segui con muy interes pero cuando lo termine el juego no perdia nunca 🙁 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
    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

  21. hoobert says:

    oe sabes que no hagas cosas fantaciosas ps ya noseas fantacioso
    ya

  22. David Snake says:

    grandiiisimo trbajo, para cuando el tercer turorial?

  23. bn g nasdhh het hite hite nhdfmm .jnnx

  24. waaaea c v fv r bvv fr bv b

  25. Polainas says:

    Excelente tutorial…!!! Felicidades.

  26. Lalo says:

    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.

  27. alex pinto says:

    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

  28. StoneIMP says:

    Tengo Python 2.5 cuando juego al pong me dice que no existe ninguna libreria llamada pygame!!

    Pueden ayudarme gracias

  29. Xil says:

    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

  30. pepe says:

    Quise bajar los fuentes, pero cuando hago click en el enlace me envía a una página 500 Internal Server Error

  31. Pingback: Pygame « Mi blog (que original)

  32. alejo says:

    Excelente tutorial!!!

    MUY claro y completo. 😉

    saludos!!

  33. 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

  34. caca says:

    son todos gggggggggggggggggaaaaaaaaaaaaaaaaaayyyyyyyyyyyyyyyyy

  35. Juan Oviedo says:

    Muy bueno este tuto también!! y muy buena la documentación extra que se encuentra siguiendo los links! Ahora me voy al 3er tuto…

  36. Pingback: Tutorial Pygame 3: creando un videojuego (el clasico pong) « Python Mania

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Back to Top ↑