• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Programación con Pygame III
 

Programación con Pygame III

on

  • 6,392 views

Los archivos pueden encontrarse en

Los archivos pueden encontrarse en
http://sites.google.com/site/laislalibre/informatica/python/pygame

Statistics

Views

Total Views
6,392
Views on SlideShare
4,836
Embed Views
1,556

Actions

Likes
1
Downloads
413
Comments
0

15 Embeds 1,556

http://jabatogames.blogspot.com 845
http://jabatogames.blogspot.com.ar 246
http://jabatogames.blogspot.com.es 225
http://jabatogames.blogspot.mx 175
http://www.slideshare.net 28
http://jabatogames.blogspot.be 13
url_unknown 5
https://www.blogger.com 5
http://jabatogames.blogspot.com.br 5
https://jujo00obo2o234ungd3t8qjfcjrs3o6k-a-sites-opensocial.googleusercontent.com 3
http://jabatogames.blogspot.it 2
http://jabatogames.blogspot.de 1
http://jabatogames.blogspot.in 1
http://webcache.googleusercontent.com 1
https://bitacora-python.blogspot.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Programación con Pygame III Programación con Pygame III Document Transcript

    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO Animaciones Realistas Guy se pone a andar La animación es algo más que volcar una imagen en pantalla y moverla por ella. En realidad, para que las animaciones parezcan realistas, necesitamos mucho más; necesitamos que la propia imagen varíe a medida que la desplazamos. Para ilustrar la forma de hacerlo, vamos a usar un personaje famoso; Guybrush Threepwood, el protagonista de la saga de videojuegos Monkey Island (por cierto, si no la conoces te la aconsejo, es una de las sagas más famosas y entretenidas de la historia de los videojuegos). Conseguiremos algunas imágenes de nuestro personaje por Internet y trabajaremos hasta que la animación sea aceptable (no perfecta, pues las imágenes disponibles son limitadas; en un juego real, el ilustrador que trabaja con el programador dibuja cada una de las posiciones y los movimientos para que produzca un movimiento suave) ¡Escribamos código! PÁGINA 1 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy01.py El primer paso es, partiendo de una imagen de nuestro personaje, cargarla en memoria y hacer que se desplace por la pantalla. Sería algo así: # -*- coding: utf-8 -*- # En este primer ejemplo, ponemos la imagen de Guy en pantalla, # desplazándolo con las teclas 'a' y 's'. import pygame, sys from pygame.locals import * # Inicializar pygame pygame.init() # Crear la surface visor = pygame.display.set_mode((600, 600), 0, 32) # Poner el título de la ventana pygame.display.set_caption('Guy') # Cargar la imagen del hombre guy = pygame.image.load('guy.jpg').convert() # Variable que controla la posición de Guy pos = 100 # El bucle de eventos while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Modificar posición en función de la tecla pulsada teclasPulsadas = pygame.key.get_pressed() if teclasPulsadas[K_a]: pos = pos - 1 if teclasPulsadas[K_s]: pos = pos + 1 # Dibujar el fondo de color visor.fill((233,233,233)) # Dibujar a Guy visor.blit(guy, (pos,100)) # Volcar la surface en la ventana de pygame pygame.display.update() PÁGINA 2 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO Ya conocemos las técnicas necesarias para entender el código anterior. Sabemos cargar imágenes en memoria, comprobar si se ha pulsado una determinada tecla y desplazar objetos por la pantalla modificando sus coordenadas. Lo único matizable es que usamos una imagen sin transparencias. Si tuviera un fondo transparente, se nos movería por la pantalla sin problemas. Como no es el caso, para disimularlo, hemos elegido un color de fondo para la ventana similar al de la propia imagen (hay otros métodos, se puede indicar a PyGame que use determinado color como color transparente, pero entonces nos hemos asegurar que el propio fondo de la imagen es exactamente de ese color y no varía ningún pixel que se notaría con el movimiento; éste, por desgracia, es nuestro caso). PÁGINA 3 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy02.py Lo anterior queda muy artificial. ¿Acaso alguien va por la calle completamente rígido y deslizándose? Si queremos animaciones realistas, necesitamos que la imagen del protagonista vaya cambiando a medida que va andando; pies juntos, avanza el pie derecho, lo apoya, hace lo propio con el pie izquierdo, etc. Hay varias maneras de hacer esto, pero todas pasan por cargar diferentes imágenes del personaje que queremos animar y dibujarlas en los momentos apropiados. Pero antes de ello, ¿cómo conseguimos esas imágenes y cómo disponemos de ellas? Tanto si eres un buen dibujante como si buscas por Internet tus recursos (libres), una forma típica de tener archivadas las diferentes imágenes es en un solo archivo de sprite. Para que te hagas una idea, éste es el que vamos a usar: Esta única imagen contiene todos los pasos intermedios que va a dar nuestro protagonista (de paso puedes ver cómo era en la versión original del juego y cómo quedó en la nueva versión). Un aviso; como este trabajo es sólo con intención pedagógica, la animación no va a quedar del todo bien. En realidad necesitaríamos más fotogramas del movimiento o gestionar mejor la posición de como lo vamos a hacer (fíjate que el tamaño que ocupa cada fotograma es distinto). En cualquier caso, para aprender la técnica nos bastará. El código que simplemente extrae uno de los fotogramas de la imagen anterior es el siguiente: PÁGINA 4 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO # -*- coding: utf-8 -*- # En este segundo ejemplo, ponemos la imagen de Guy cargándola # desde el archivo de sprites que contiene todas las imágenes. import pygame, sys from pygame.locals import * # Inicializar pygame pygame.init() # Crear la surface visor = pygame.display.set_mode((600, 600), 0, 32) # Poner el título de la ventana pygame.display.set_caption('Guy') # Cargar la imagen de Guy guy = pygame.image.load('sprites.jpg').convert() # Variable que controla la posición de Guy pos = 100 # Posición de la parte de la imagen que se visualiza x = 130 y = 10 w = 120 h = 340 # El bucle de eventos while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Modificar posición en función de la tecla pulsada teclasPulsadas = pygame.key.get_pressed() if teclasPulsadas[K_a]: pos = pos - 1 if teclasPulsadas[K_s]: pos = pos + 1 # Dibujar el fondo de color visor.fill((233,233,233)) # Dibujar a Guy visor.blit(guy, (pos,100), (x,y,w,h)) # Volcar la surface en la ventana de pygame pygame.display.update() PÁGINA 5 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO La primera modificación, obviamente, es que al archivo de imagen que hemos de cargar en memoria es distinto: guy = pygame.image.load('sprites.jpg').convert() En la variable guy, por tanto, se almacenan todos los fotogramas de la animación del personaje. Para indicar cuál es el fotograma que queremos usar, necesitamos indicárselo con las coordenadas de un rect de PyGame (con cualquier programa de dibujo o retoque, como GIMP, podemos ver cuáles son). x = 130 y = 10 w = 120 h = 340 El significado, aunque debiera ser evidente, lo tenemos en la siguiente imagen: x y h w El resto es simplemente usar la función blit para indicar que se quiere volcar en pantalla sólo esta parte de la imagen: visor.blit(guy, (pos,100), (x,y,w,h)) En efecto, la última tupla (x,y,w,h), como puede verse en el documento de referencia de PyGame, indica que sólo debe dibujarse parte de una imagen. PÁGINA 6 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy03.py Aunque en las dos versiones anteriores el resultado es el mismo, hemos visto que el código hace cosas muy distintas. En la primera versión se carga una imagen que se mueve por la pantalla. En la segunda, se carga otra imagen y se mueve por la pantalla parte de esta. El resultado de este tercer paso va a ser el mismo también, pero de camino habremos cargado en memoria todos los fotogramas que forman la animación del personaje aunque sólo mostremos una. Éste es el código: # -*- coding: utf-8 -*- # En este tercer ejemplo, cargamos todas las imágenes de Guy desde # el archivo de sprites aunque solo mostramos una. import pygame, sys from pygame.locals import * # Inicializar pygame pygame.init() # Crear la surface visor = pygame.display.set_mode((600, 600), 0, 32) # Poner el título de la ventana pygame.display.set_caption('Guy') # Cargar la imagen de Guy fotogramas = pygame.image.load('sprites.jpg').convert() # Variable que controla la posición de Guy pos = 100 # Almacenamos las diferentes imágenes en un diccionario guy = {} guy[0] = (0, 10, 120, 340) guy[1] = (130, 10, 120, 340) guy[2] = (260, 10, 120, 340) guy[3] = (405, 10, 140, 340) guy[4] = (600, 10, 120, 340) guy[5] = (730, 10, 130, 340) guy[6] = (870, 10, 170, 340) # El bucle de eventos while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() PÁGINA 7 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO # Modificar posición en función de la tecla pulsada teclasPulsadas = pygame.key.get_pressed() if teclasPulsadas[K_a]: pos = pos - 1 if teclasPulsadas[K_s]: pos = pos + 1 # Dibujar el fondo de color visor.fill((233,233,233)) # Dibujar una imagen del hombre visor.blit(fotogramas, (pos,100), guy[1]) # Volcar la surface en la ventana de pygame pygame.display.update() Para empezar, hemos cambiado el nombre de la variable que contiene a la imagen de sprites, pues ahora es simplemente una variable intermedia. fotogramas = pygame.image.load('sprites.jpg').convert() El nombre de guy lo reservamos para la variable que contendrá todos los fotogramas. ¿Qué tipo de variable usar? ¿Una lista? Lo más flexible es, quizá, usar un diccionario: guy = {} guy[0] = (0, 10, 120, 340) guy[1] = (130, 10, 120, 340) guy[2] = (260, 10, 120, 340) guy[3] = (405, 10, 140, 340) guy[4] = (600, 10, 120, 340) guy[5] = (730, 10, 130, 340) guy[6] = (870, 10, 170, 340) Las claves del diccionario son, simplemente, números enteros que indican el orden del fotograma. Para cada una de ellas, almacenamos un rect que indica la posición del fotograma en la imagen de sprites (lo que antes poníamos como x, y,w y h). Observa que, de nuevo, debemos usar un programa de dibujo o retoque para mirar cuáles son las coordenadas de cada una de esas imágenes. Finalmente, sólo dibujamos una de ellas con visor.blit(fotogramas, (pos,100), guy[1]) PÁGINA 8 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy04.py Tres versiones y Guy aún no da ningún paso... Por fin ha llegado el momento de cambiar esto. En esta versión vamos a conseguir que, al mismo tiempo que nuestro personaje avance, su imagen vaya cambiando. Éste es el código: # -*- coding: utf-8 -*- # Y en el cuarto ejemplo, mostramos una imagen de la animación # distinta en cada paso. import pygame, sys from pygame.locals import * # Inicializar pygame pygame.init() # Crear la surface visor = pygame.display.set_mode((600, 600), 0, 32) # Poner el título de la ventana pygame.display.set_caption('Guy') # Cargar la imagen de Guy fotogramas = pygame.image.load('sprites.jpg').convert() # Variable que controla la posición de Guy pos = 100 # Almacenamos las diferentes imágenes en un diccionario guy = {} guy[0] = (0, 10, 120, 340) guy[1] = (130, 10, 120, 340) guy[2] = (260, 10, 120, 340) guy[3] = (405, 10, 140, 340) guy[4] = (600, 10, 120, 340) guy[5] = (730, 10, 130, 340) guy[6] = (870, 10, 170, 340) # Variable que controla qué imagen del hombre se muestra cual = 0 # El bucle de eventos while True: for event in pygame.event.get(): PÁGINA 9 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO if event.type == QUIT: pygame.quit() sys.exit() # Modificar posición en función de la tecla pulsada teclasPulsadas = pygame.key.get_pressed() if teclasPulsadas[K_a]: pos = pos - 1 if teclasPulsadas[K_s]: pos = pos + 1 cual = cual + 1 if cual > 6: cual = 0 # Dibujar el fondo de color visor.fill((233,233,233)) # Dibujar a Guy visor.blit(fotogramas, (pos,100), guy[cual]) # Volcar la surface en la ventana de pygame pygame.display.update() Observa que si ejecutas este programa verás que las cosas no salen como uno desea, ya que la imagen cambia excesivamente rápido y no da tiempo a verla. Pero para arreglar esto tendremos que esperar a la próxima versión... Ahora de lo que se trata es de ver cómo cambiar la imagen en cada paso. Vamos a hacerlo, primero, en una sola dirección (pongamos que hacia la derecha). Como es fácil de imaginar, primero necesitamos una variable que almacene cuál es la imagen que toca dibujar en cada momento. De ello se encarga cual: cual = 0 Recuerda que las imágenes (en realidad, la indicación de qué parte de la imagen de sprites hay que dibujar) están almacenadas en el diccionario guy. Como cual vale inicialmente 0, la expresión guy[cual] será en realidad guy[0], es decir, el primer fotograma de la animación del movimiento de nuestro protagonista. Sin más que cambiar el valor de la variable cual, la expresión anterior nos daría otro fotograma. ¿Dónde hacer el cambio de imagen? Acertaste, allí donde se mire si se ha pulsado la tecla s, cuando hay que desplazarse a la derecha y se aumenta la coordenada pos: if teclasPulsadas[K_s]: pos = pos + 1 cual = cual + 1 if cual > 6: cual = 0 PÁGINA 10 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO Como puedes ver en el if anterior, si se ha pulsado la tecla s primero se aumenta la variable pos (recuerda que allí se almacena la coordenada x del personaje) y luego aumentamos la variable cual para indicar, cuando más adelante se llegue al momento de dibujar, que hay que cambiar el fotograma de la animación. Hay que tener cuidado con el número de fotograma indicado. Fíjate que tenemos 7 imágenes para simular el movimiento, indicadas con las claves 0, 1, 2, 3, 4, 5 y 6. Eso quiere decir que, al aumentar la variable cual no nos debemos pasar de 6. De allí que se compruebe con un if y, en tal caso, la variable cual se ponga de nuevo a 0. Como hemos indicado antes, no todo es tan bonito como parece. Visto en movimiento, ¡Guy parece mover los pies a toda velocidad como alma que lleva el diablo! Hmmm... PÁGINA 11 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy05.py El problema que tenemos en la versión anterior de nuestra animación es que no controlamos la velocidad de ésta, con lo que en cada fotograma se cambia el dibujo de nuestro personaje; si el programa se ejecuta a 60 fotogramas por segundo, por ejemplo, Guy cambia de aspecto 60 veces cada segundo y de ahí la locura del movimiento de sus piernas... La manera de solucionarlo será ésta: # -*- coding: utf-8 -*- # Quinto ejemplo, controlamos la velocidad de la animación. import pygame, sys from pygame.locals import * import time # Inicializar pygame pygame.init() # Crear la surface visor = pygame.display.set_mode((600, 600), 0, 32) # Poner el título de la ventana pygame.display.set_caption('Guy') # Cargar la imagen de Guy fotogramas = pygame.image.load('sprites.jpg').convert() # Variable que controla la posición de Guy pos = 0 # Almacenamos las diferentes imágenes en un diccionario guy = {} guy[0] = (0, 10, 120, 340) guy[1] = (130, 10, 120, 340) guy[2] = (260, 10, 130, 340) guy[3] = (405, 10, 170, 340) guy[4] = (600, 10, 120, 340) guy[5] = (730, 10, 130, 340) guy[6] = (870, 10, 170, 340) # Variable que controla qué imagen de Guy se muestra cual = 0 # Controlando el tiempo cuanto = 100 tiempo = 0 PÁGINA 12 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO # El bucle de eventos while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Modificar posición en función de la tecla pulsada teclasPulsadas = pygame.key.get_pressed() if teclasPulsadas[K_a]: pos = pos - 1 if teclasPulsadas[K_s]: pos = pos + 1 if pygame.time.get_ticks()-tiempo > cuanto: tiempo = pygame.time.get_ticks() cual = cual + 1 if cual > 6: cual = 1 # Dibujar el fondo de color visor.fill((233,233,233)) # Dibujar al hombre visor.blit(fotogramas, (pos,100), guy[cual]) # Volcar la surface en la ventana de pygame pygame.display.update() La forma de controlar la velocidad a la que se cambia el aspecto del personaje es muy parecida a la que ya vimos cuando regulamos la velocidad en el juego del Pong. Para empezar, necesitamos dos variables que nos gestionen el tiempo de ejecución y el tiempo que hay que esperar: cuanto = 100 tiempo = 0 cuanto indica el número de milisegundos que hay que esperar para cambiar el dibujo. Los valores concretos que pongamos en esta variable y en otras similares dependerán de nosotros, de la velocidad que queramos y del número de dibujos que tengamos. La variable tiempo, recuerda, se encarga de almacenar el momento en el que se cambia el aspecto del fotograma, para poder comparar con este momento y ver si ha pasado el tiempo suficiente. Por supuesto, no olvides importar la librería que gestiona el tiempo import time ya que allí es donde reside la función pygame.time.get_ticks() que usamos para ver el tiempo que ha pasado: PÁGINA 13 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO if pygame.time.get_ticks()-tiempo > cuanto: tiempo = pygame.time.get_ticks() cual = cual + 1 if cual > 6: cual = 1 ¿Ves que es casi lo mismo que en el Pong? Aquí se mira si ha pasado el tiempo suficiente, en cuyo caso se cambia el fotograma. Y en caso contrario no se hace nada pues no se ejecuta ninguna de las instrucciones del bloque if. Otro matiz; habrás notado, quizá que hemos cambiado el número de fotograma en el que se vuelve a empezar la animación. Antes era cual = 0 y ahora cual = 1. ¿Adivinas por qué? En efecto, el fotograma número 0 es el que muestra a Guy parado y queda la animación muy rara al pasar el dibujo por allí cuando está en proceso de andar. Pruébalo: cambia el 1 por un 0 y ejecuta el programa. ¿Ves a lo que nos referimos? Claramente, el primer fotograma de la animación andadora ha de ser el 1. PÁGINA 14 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy06.py Hay un defecto evidente en la versión anterior de nuestro programa, y es que cuando dejamos de pulsar la tecla s el movimiento se para allí donde estuviera, incluido a mitad de paso.... Lo deseable es que al dejar de moverse, Guy quede esperando quieto, no en esa postura artificial. Otro ajuste que podemos hacer es con los dos fotogramas que abren el paso, pues las imágenes son más anchas que las demás (no es lo mismo estar con las piernas juntas que con las piernas abiertas). Veamos: # -*- coding: utf-8 -*- # Sexto ejemplo, ajustamos la animación para que tenga # un aspecto más realista. import pygame, sys from pygame.locals import * import time # Inicializar pygame pygame.init() # Crear la surface visor = pygame.display.set_mode((600, 600), 0, 32) # Poner el título de la ventana pygame.display.set_caption('Guy') # Cargar la imagen del hombre fotogramas = pygame.image.load('sprites.jpg').convert() # Variable que controla la posición de Guy pos = 0 # Almacenamos las diferentes imágenes en un diccionario guy = {} guy[0] = (0, 10, 120, 340) guy[1] = (130, 10, 120, 340) guy[2] = (260, 10, 130, 340) guy[3] = (405, 10, 170, 340) guy[4] = (600, 10, 120, 340) guy[5] = (730, 10, 130, 340) guy[6] = (870, 10, 170, 340) # Variable que controla qué imagen de Guy se muestra cual = 0 # Controlando el tiempo cuanto = 100 PÁGINA 15 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO tiempo = 0 # El bucle de eventos while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Modificar posición en función de la tecla pulsada teclasPulsadas = pygame.key.get_pressed() if teclasPulsadas[K_a]: pos = pos - 1 elif teclasPulsadas[K_s]: pos = pos + 1 if pygame.time.get_ticks()-tiempo > cuanto: tiempo = pygame.time.get_ticks() cual = cual + 1 if cual == 3 or cual == 6: pos = pos + 5 if cual > 6: cual = 1 else: cual = 0 # Dibujar el fondo de color visor.fill((233,233,233)) # Dibujar a Guy visor.blit(fotogramas, (pos,100), guy[cual]) # Volcar la surface en la ventana de pygame pygame.display.update() Lo primero es implementar la imagen de Guy parado. Ésa es precisamente la imagen 0 de nuestro diccionario. Así que cuando no se pulse ninguna tecla, tenemos que indicar que sea ésta y no otra la imagen que se dibuje cuando toque. Para ello, lo más sencillo es modificar los if que miran que tecla se ha pulsado en uno solo: if teclasPulsadas[K_a]: ... elif teclasPulsadas[K_s]: ... else: cual = 0 PÁGINA 16 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO Con una estructura de esta forma, se mira si se ha pulsado la tecla a, en caso contrario se mira si se ha pulsado la tecla s y si no se ha pulsado ninguna de las dos es cuando se pone la variable cual a 0 para indicar que se dibujará la imagen de Guy quieto. Lo siguiente es ajustar el desplazamiento con imágenes de diferentes tamaños. Vamos a hacerlo de manera sencilla, simplemente dando más desplazamiento en la posición cuando toca una de los fotogramas más anchos: if cual == 3 or cual == 6: pos = pos + 5 Como habrás notado, los fotogramas que en la imagen del sprite aparecen con las piernas abiertas son la 3 y la 6 (recuerda que la primera es la 0). La cantidad que añadamos a la variable pos dependerá del tamaño de la imagen y de cómo nos quede la animación al probarla. PÁGINA 17 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy07.py Llegamos al último paso. ¿Qué nos queda? El movimiento hacia la derecha está conseguido. Pero si pulsamos la tecla a para mover a Guy hacia la izquierda, veremos que éste se desliza. ¡Claro! No hemos implementado el movimiento en esa dirección. Además lo ideal sería tener otro sprite con los fotogramas del movimiento en la otra dirección, pero este no es nuestro caso... ¿Qué podemos hacer? El código fuente de nuestra versión definitiva será el siguiente: # -*- coding: utf-8 -*- # Séptimo y último ejemplo. Implementamos la animación # en sentido contrario. import pygame, sys from pygame.locals import * import time # Inicializar pygame pygame.init() # Crear la surface visor = pygame.display.set_mode((600, 600), 0, 32) # Poner el título de la ventana pygame.display.set_caption('Guy') # Variable que controla la posición de Guy pos = 0 # Cargar la imagen de Guy y su reflejo fotogramas = pygame.image.load('sprites.jpg').convert() fotogramas2 = pygame.transform.flip(fotogramas,True, False) # Almacenamos las diferentes imágenes en un diccionario guy = {} guy2 = {} guy[0] = (0, 10, 120, 340) guy2[0]= (941, 10, 120, 340) guy[1] = (130, 10, 120, 340) guy2[1]= (811, 10, 120, 340) guy[2] = (260, 10, 130, 340) guy2[2]= (671, 10, 130, 340) guy[3] = (405, 10, 170, 340) guy2[3]= (486, 10, 170, 340) guy[4] = (600, 10, 120, 340) guy2[4]= (341, 10, 120, 340) guy[5] = (730, 10, 130, 340) PÁGINA 18 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy2[5]= (201, 10, 130, 340) guy[6] = (870, 10, 170, 340) guy2[6]= (21, 10, 170, 340) # Controlando la dirección izquierda = True # Variable que controla qué imagen de Guy se muestra cual = 0 # Controlando el tiempo cuanto = 100 tiempo = 0 # Función que actualiza el fotograma def actualizar(): global cual, pos, tiempo if izquierda: pos = pos + 1 else: pos = pos - 1 if pygame.time.get_ticks()-tiempo > cuanto: tiempo = pygame.time.get_ticks() cual = cual + 1 if izquierda: if cual == 3 or cual == 6: pos = pos + 5 if cual > 6: cual = 1 else: if cual == 3 or cual == 6: pos = pos - 5 if cual > 6: cual = 1 # El bucle de eventos while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Modificar dirección en función de la tecla pulsada teclasPulsadas = pygame.key.get_pressed() if teclasPulsadas[K_a]: izquierda = False actualizar() elif teclasPulsadas[K_s]: izquierda = True actualizar() PÁGINA 19 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO else: cual = 0 # Dibujar el fondo de color visor.fill((233,233,233)) # Dibujar a Guy if izquierda: visor.blit(fotogramas, (pos,100), guy[cual]) else: visor.blit(fotogramas2, (pos,100), guy2[cual]) # Volcar la surface en la ventana de pygame pygame.display.update() En primer lugar necesitamos la imagen de los fotogramas del movimiento inverso al que hemos tratado. Es cierto, no la tenemos, pero PyGame es estupendo y dispone de una función que hace el trabajo por nosotros: fotogramas2 = pygame.transform.flip(fotogramas,True, False) La función pygame.transform.flip() toma como primer argumento una imagen y nos devuelve una nueva imagen invertida respecto a la anterior. La forma de invertirla depende de los dos argumentos siguientes. Si el primero de ellos es True intercambia izquierda y derecha (es decir, una reflexión respecto al eje vertical); si el segundo es True, hace lo propio con arriba y abajo (reflexión con respecto al eje horizontal). En nuestro caso sólo queremos lo primero y de ahí que pasemos True y False. (Podíamos haber cogido un programa de dibujo o de retoque y haber invertido la imagen, es cierto, pero al hacerlo así hemos aprendido una nueva técnica que a veces es útil). Lo siguiente es almacenar también las imágenes del nuevo sprite. Un nuevo diccionario viene a realizar la tarea: guy = {} guy2 = {} guy[0] = (0, 10, 120, 340) guy2[0]= (941, 10, 120, 340) guy[1] = (130, 10, 120, 340) guy2[1]= (811, 10, 120, 340) guy[2] = (260, 10, 130, 340) guy2[2]= (671, 10, 130, 340) guy[3] = (405, 10, 170, 340) guy2[3]= (486, 10, 170, 340) guy[4] = (600, 10, 120, 340) guy2[4]= (341, 10, 120, 340) guy[5] = (730, 10, 130, 340) guy2[5]= (201, 10, 130, 340) guy[6] = (870, 10, 170, 340) guy2[6]= (21, 10, 170, 340) PÁGINA 20 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO guy contiene los fotogramas del movimiento hacia la derecha y guy2 los de la izquierda. Los valores concretos que hay que poner, como antes, o los miramos con un programa de dibujo/retoque o hacemos algo de algebra teniendo encuenta el tamaño de la imagen y que los segundos son un reflejo de los primeros. Necesitamos también saber cual de los dos movimientos hay que dibujar, es decir, saber hacia dónde nos estamos moviendo: izquierda = True La variable booleana izquierda indica, si es True (como ocurre al principio de la ejecución del programa), que el movimiento es hacia la izquierda y si es False hacia la derecha. Esto es importante, pues sólo tendremos que modificar el valor de esta variable en el lugar apropiado de nuestro código para indicar qué imagen dibujar, siempre que modifiquemos la parte en la que dibujamos a nuestro protagonista a esto: if izquierda: visor.blit(fotogramas, (pos,100), guy[cual]) else: visor.blit(fotogramas2, (pos,100), guy2[cual]) ¿Entiendes la idea? Con un bloque if miramos el valor de la variable izquierda; cuando sea True dibujará un fotograma de guy y cuando sea False de guy2. Pasemos a seleccionar exactamente de qué fotograma se trata. Fíjate que hay que hacer prácticamente lo mismo en las dos direcciones, así que ¿por qué no definir una función que lo haga y así no repetimos el código? Llamemos a esa función actualizar(), ya que actualiza el dibujo de nuestro personaje. La parte que indica que hemos pulsado una tecla y hay que cambiar el dibujo quedará ahora así: if teclasPulsadas[K_a]: izquierda = False actualizar() elif teclasPulsadas[K_s]: izquierda = True actualizar() else: cual = 0 Observa que si no se ha pulsado ninguna tecla, cual se pone a 0 y, más adelante, gracias a nuestra modificación anterior, el programa dibujará el fotograma de parado correcta (hay dos distintas, una con Guy parado mirando hacia la derecha y otra mirando hacia la izquierda). Respecto al movimiento, si se ha pulsado la tecla a sabemos que hay que mover a Guy hacia la derecha, así que izquierda se pone a False y se llama a nuestra función actualizar() para que cambie el dibujo. Si se ha pulsado la tecla s, por su parte, el movimiento es hacia la izquierda, el valor correcto de la variable izquierda es ahora True y se llama de nuevo a nuestra función. Es el momento de abordar la implementación de la función actualizar(). Su código será el siguiente: PÁGINA 21 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO def actualizar(): global cual, pos, tiempo if izquierda: pos = pos + 1 else: pos = pos - 1 if pygame.time.get_ticks()-tiempo > cuanto: tiempo = pygame.time.get_ticks() cual = cual + 1 if izquierda: if cual == 3 or cual == 6: pos = pos + 5 if cual > 6: cual = 1 else: if cual == 3 or cual == 6: pos = pos - 5 if cual > 6: cual = 1 Un matiz no muy elegante y que cambiará por completo cuando veamos como trabaja de forma nativa PyGame con los sprites y la orientación a objetos, es la gestión de las variables externas a la función. Una función puede usar sus propias variables, definidas en su interior y también usar el valor de las variables que se han definido fuera de ella. Hasta aquí todo correcto. Pero en cuanto queremos cambiar el valor de una de estas últimas variables externas obtendremos un grosero error; Python protege las externas y piensa que son internas y, como no están definidas, la cosa no funciona. Para solucionarlo, existe la instrucción global. Las variables que pongamos a continuación de dicha instrucción se declaran como externas y Python nos permite modificarlas dentro del cuerpo de la función. En nuestro caso, vamos a modificar las variables cual, pos y tiempo. Lo siguiente que hay que hacer dentro de la función es modificar la posición de Guy. Aquí no hace falta que miremos si se ha pulsado el teclado, puesto que ya se ha hecho y se ha puesto la información en la variable izquierda. Basta poner, como vemos más arriba if izquierda: pos = pos + 1 else: pos = pos - 1 (¿Ves como modificamos la variable externa pos? De ahí el global al comienzo de la función). El resto también es similar a la versión anterior del programa, con las modificaciones correspondientes a las dos direcciones posibles. Simplemente miramos el valor de la variable izquierda y actuamos en consecuencia sumando o restando y cambiando el valor de la variable cual. Por supuesto, el código puede mejorarse, es algo redundante, pero para nuestros efectos, es suficiente: PÁGINA 22 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES
    • ASUNTO: PROGRAMACIÓN CON PYTHON Y PYGAME CURSO: 1º BACHILLERATO if pygame.time.get_ticks()-tiempo > cuanto: tiempo = pygame.time.get_ticks() cual = cual + 1 if izquierda: if cual == 3 or cual == 6: pos = pos + 5 if cual > 6: cual = 1 else: if cual == 3 or cual == 6: pos = pos - 5 if cual > 6: cual = 1 Con todos estos cambios, la animación funciona aceptablemente en las dos direcciones, como podemos comprobar si ejecutamos el programa. PÁGINA 23 DE 23 DURACIÓN: PERÍODOS DE DOS CLASES