Intro Pygame Capitulo 6

28
Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys [email protected] Programación de Juegos con PyGame Capitulo 6: Sonidos, Sprites y Animaciones 1

description

Capitulo 6 del curso

Transcript of Intro Pygame Capitulo 6

Page 1: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

Programación de Juegos con PyGame

Capitulo 6: Sonidos, Sprites y Animaciones

1

Page 2: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

pygame.mixerBueno ya teniamos casi todos los Modulos y herramientas para programar juegos, la

unica cosa que nos hacia falta era poder reproducir sonidos y bueno aqui es donde toma importancia este modulo, ya que su utilidad es exactamente esa, brindarnos clases y funciones para poder reproducir audio.

Este módulo contiene clases para crear objetos Sound y controlar la reproducción de audio. El módulo mixer es opcional y depende de SDL_MIXER Antes de usar este módulo su programa debería verificar si el módulo pygame.mixer está disponible.

El módulo mixer tiene un número limitado de canales para reproducir sonidos. Generalmente los programas le piden a pygame que comience a reproducir un sonido y pygame selecciona un canal de audio disponible de forma automática. Por defecto hay 8 canales simultáneos, aunque los programas complejos pueden obtener un control mas preciso de la cantidad de canales y utilizarlos.

Toda la reproducción de sonido se realiza en segundo plano (en hilos diferentes). Cuando comienza a reproducir un objeto Sound, esta llamada retornará inmediatamente mientras el sonido continúa sonando. Un objeto Sound también se puede reproducir varias veces.

También tiene un canal de streaming que se utiliza para reproducir música y se accede a él a través del módulo pygame.mixer.music.

El módulo mixer se debe inicializar como los otros módulos de pygame, aunque tiene algunas condiciones adicionales. La función pygame.mixer.init() toma varios argumentos opcionales para controlar la frecuencia de reproducción. pygame colocará por defecto valores razonables, aunque no realizará conversión de frecuencias, por lo tanto mixer debería iniciarse para coincidir con la frecuencia y calidad de los recursos de audio.

init

Inicializar el módulo mixer para cargar y reproducir sonido. Los valores por defecto de los argumentos se pueden reemplazar utilizando atributos de audio específicos. El argumento size representa cuantos bits se usarán para cada muestra de audio. Se usarán valores de muestra con signo si se especifica un valor negativo, en otro caso se usarán muestras de audio sin signo.

El argumento channels se usa para especificar cuando usar el modo estéreo y cuando el modo mono. 1 indica mono y 2 estéreo. No se permiten otros valores.

El argumento buffer controla el número de muestras internas que se usarán en el mezclador de sonido. El valor por defecto debería funcionar en la mayoría de los casos. Este valor se puede reducir para disminuir la latencia, aunque podría ocurrir una pérdida de calidad en el sonido. También se puede aumentar para asegurarse que la reproducción nunca se detenga, aunque esto impone latencia. El valor de buffer debe ser potencia de dos.

Algunos equipos necesitan que el módulo pygame.mixer se inicialice después de los módulos de video. El módulo de orden superior tiene precaución de esto automáticamente, pero no envía ningún argumento especial la iniciar mixer. Para resolver esto, el módulo mixer tiene una función llamada pygame.mixer.pre_init() para definir los valores por defecto antes

2

Page 3: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

de llamar a pygame.init

sintaxispygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=3072):

return None

pre_init

Define con anterioridad los argumentos de mixer.init.

sintaxis:pygame.mixer.pre_init(frequency=0, size=0, channels=0, buffersize=0):

return None

quit

Deshabilita el módulo pygame.mixer. Se detendrá toda la reproducción de audio y los objetos Sound cargados podrían ser incompatibles con el mezclador si éste se modifica luego.

sintaxis:pygame.mixer.quit(): return None

get_init

Consulta si se ha inicializado el módulo mixer. adicionalmete retornara los argumentos con los que fue o sera inicializado, el modulo.

sintaxis:pygame.mixer.get_init(): return (frequency, format, channels)

stop

Detiene la reproducción de todos los canales de sonido.

sintaxis:pygame.mixer.stop(): return None

pause

Detendrá de forma temporal todas las reproducciones en los canales del mezclador activos. La reproducción de sonido se puede reanudar mas tarde llamando a la función pygame.mixer.unpause().

sintaxis:pygame.mixer.pause(): return None

3

Page 4: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

unpause

Reanuda la reproducción de audio que se encuentre en pausa.

sintaxis:pygame.mixer.unpause(): return None

fadeout

Deducirá el volumen de todos los canales de sonidos en el tiempo indicado por por el argumento milliseconds. El sonido se detendrá una vez que el volumen llegue a su menor valor.

sintaxis:pygame.mixer.fadeout(time): return None

set_num_channels

Define el número de canales disponibles para el mezclador. El valor por defecto es 8 y depende de la cantidad de canales que soporte su placa de sonido. Puede aumentar o disminuir este valor. Se reduce este valor todos los sonidos que estén sonando en los canales a eliminar se detendrán.

sintaxis:pygame.mixer.set_num_channels(count): return None

get_num_channels

Obtiene el número total de canales de reproducion activos.

sintaxis:pygame.mixer.get_num_channels(): return count

set_reserved

El módulo mixer puede preservar cualquier número de canales para que no se seleccionen automáticamente al reproducir Sonidos. No se detendrán los sonidos que actualmente estén sonando en los canales reservados.

Esto permite a la aplicación reservar un número específico de canales para sonidos importantes que no deberían interrumpirse y tener garantizado un canal para reproducirse.

sintaxis:pygame.mixer.set_reserved(count): return None

4

Page 5: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

find_channel

Encuentra y retorna un objeto Channel inactivo. Si no hay canales inactivos retornará None. Si no hay canales inactivos y el argumento foce vale True entonces encontrará el canal que tiene el sonido que mas tiempo se a reproducido y lo retornará.

Si el módulo tiene canales reservados de la función pygame.mixer.set_reserved() entonces esos canales no se retornarán aquí.

sintaxis:pygame.mixer.find_channel(force=False): return Channel

get_busy

Retorna True si el módulo está reproduciendo en alguno de los canales. Retornará False si el mezclador está libre.

sintaxis:pygame.mixer.get_busy(): return bool

MusicEl módulo music está muy relacionado con el módulo pygame.mixer. Use el módulo

music para controlar la reproducción de música en el módulo mixer.

La diferencia entre la reproducción de música y la reproducción de un sonido es que la música se reproduce mientras se carga, y nunca se carga completamente de una vez. El módulo mixer soporta solamente la reproducción de una música a la vez.

load

Cargará el archivo de música y lo preparará para reproducir. Se detendrá cualquier música si se estaba reproduciendo. Esta función no comenzará a reproducir la música.

Tenga en cuenta que la música solo se puede cargar a partir del nombre de un archivo, no se puede cargar desde objetos file como las otras funciones para cargar recursos de pygame.

sintaxis:pygame.mixer.music.load(filename): return None

play

Reproducirá la música que se ha cargado. Si la música ya estaba sonando entonces se reiniciará. El argumento loops controla el número de veces que se debe reproducir la canción. Por ejemplo, play(5) causará que la canción suene una vez y luego se repita 5

5

Page 6: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

veces; es decir, unas 6 veces. Si el argumento loop vale -1 se repetirá la reproducción indefinidamente.

El argumento de posición start controla a partir de donde comenzará a reproducirse. La posición de inicio depende del formato de música utilizado. Los formatos MP3 y OGG utilizan la posición como tiempo medido en segundos. La música en formato MOD usará start como el número de patrón. Si no se puede definir la posición de inicio se lanzará la excepción NotImplementedError.

sintaxis:pygame.mixer.music.play(loops=0, start=0.0): return None

rewind

Reinicia la reproducción de la música actual para iniciar desde el principio.

sintaxis:pygame.mixer.music.rewind(): return None

stop

Detiene la reproducción de música si se está reproduciendo.

sintaxis:pygame.mixer.music.stop(): return None

pause

Detiene de forma temporal la reproducción de música. Con la función pygame.mixer.music.unpause() puede continuar la reproducción.

sintaxis:pygame.mixer.music.pause(): return None

unpause

Continúa la reproducción de una canción luego de que esta se ha pausado.

sintaxis:pygame.mixer.music.unpause(): return None

fadeout

Detendrá la reproducción de música luego de haber reducido el volumen en el tiempo especificado (en milisegundos).

6

Page 7: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

sintaxis:pygame.mixer.music.fadeout(time): return None

Nota: esta función puede bloquear el programa mientras altera el volumen.

set_volume

Define el volumen de la reproducción de música. El argumento value es un número entre 0.0 y 1.0. Se redefine el nivel de volumen cuando se carga una nueva música.

sintaxis:pygame.mixer.music.set_volume(value): return None

get_volume

Obtiene el volumen de la música. Retorna el volumen actual para el mezclador. El valor debe estar entre 0.0 y 1.0.

sintaxis:pygame.mixer.music.get_volume(): return value

get_busy

Consulta si se está reproduciendo música.

sintaxis:pygame.mixer.music.get_busy(): return bool

get_pos

Obtiene el número de milisegundos desde que el módulo ha comenzado a reproducir música. El tiempo que se retorna solo representa cuanto tiempo a estado reproduciendo música, este valor no tiene en cuenta cualquier desplazamiento de posición inicial.

sintaixs:pygame.mixer.music.get_pos(): return time

queue

Esta función carga un archivo de música y lo pone en una cola. Un archivo que se encuentra en la cola comenzará a sonar cuando la música actual termine normalmente. La cola de canciones se perderá si la música actual se interrumpe o intercambia.

sintaxispygame.mixer.music.queue(filename): return None

7

Page 8: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

set_endevent

Esta función hace que pygame emita una señal (con ayuda de la cola de eventos) cuando el módulo termine de reproducir. El argumento determina que tipo de evento se quiere emite. El evento se emitirá cada vez que una canción termine, no solo la primera vez. Para anular la emisión de eventos llame a esta función sin argumentos.

sintaxis:pygame.mixer.music.set_endevent(): return Nonepygame.mixer.music.set_endevent(type): return None

get_endevent

Obtiene el evento que un canal emite cuando termina de reproducir.

sintaxis:pygame.mixer.music.get_endevent(): return type

SoundCarga un nuevo sonido a partir de un nombre de archivo, un archivo de python o un

objeto de almacenamiento que se pueda leer. Se realizará un ajuste limitado de frecuencia para que coincida con los argumentos de inicialización del módulo mixer.

El objeto Sound representa los datos de sonido actual. Los métodos que cambian el estado del objeto de sonido lo harán en todas las instancias de ese objeto. El sonido puede cargarse desde un archivo de audio OGG o desde un archivo WAV sin compresión.

sintaixs:pygame.mixer.Sound(filename): return Soundpygame.mixer.Sound(buffer): return Soundpygame.mixer.Sound(object): return Sound

Nota: La memoria asignada para los datos se copiará internamente, dada de información será compartida entre el archivo y el objeto de sonido.

play

Comienza a reproducir el sonido en un canal disponible (por ejemplo, en los parlantes de la computadora). Se elegirá de forma forzada el canal, por lo tanto la reproducción se podría detener el sonido en curso si es necesario.

El argumento loops controla cuantas veces de deberá repetir el sonido luego de haber sonado por primera vez. Un valor como 5 significa que el sonido será reproducido una vez, y luego se repetirá cinco veces mas, por lo tanto sonará seis veces en total. El valor por defecto (cero) significa que el sonido no se repetirá, y solo sonará una vez. Si loops se define a -1 el sonido se repetirá constantemente (aunque podrá llamar a stop() para detenerlo).

8

Page 9: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

El argumento maxtime se puede usar para detener la reproducción luego del numero de milisegundos indicado.

El argumento fade_ms hará que el sonido comience a reproducirse desde el valor de volumen 0 y aumente de volumen hasta el máximo valor en el tiempo indicado. Note que el sonido podría termina antes de que el aumento de volumen se complete. Este método retornará un objeto Channel con el canal que ha sido seleccionado.

sintaxis:Sound.play(loops=0, maxtime=0, fade_ms=0): return Channel

get_num_channels

Retorna el numero de canales activos donde se está reproduciendo este sonido.

sintaxis:Sound.get_num_channels(): return count

get_length

Obtiene la longitud del sonido. Retorna la longitud del sonido en segundos.

sintaxis:Sound.get_length(): return seconds

get_buffer

Obtiene un objeto de almacenamiento para modificar el sonido. Retorna un objeto de almacenamiento para modificar el sonido. Este objeto se puede usar para acceso directo y manipulación.

sintaxis:Sound.get_buffer(): return BufferProxy

stop, fadeout, set_volume, get_volume, set_volume

Para no aburrirlos este metodos hacen exactamente lo mismos que los metodos de las otras clases, por lo que evitare comentarlos.

ChannelRetorna un objeto Channel para uno de los canales actuales. El argumento id debe ser

un valor entre 0 y el valor que devuelve pygame.mixer.get_num_channels().

El objeto Channel se puede usar para obtener un control preciso sobre la reproducción

9

Page 10: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

de sonidos. Un canal solo puede reproducir un objeto Sound a la vez. Como pygame por defecto maneja por su cuenta estos objetos, utilizarlos es completamente opcional.

sintaxis:pygame.mixer.Channel(id): return Channel

play

Comenzará a reproducir un sonido en un canal específico. Se interrumpirá cualquier sonido que esté sonando en este canal.

El argumento loops tiene el mismo significado que en Sound.play(): es el número de veces que se repetirá el sonido luego de sonar la primera vez. Si vale 3, entonces el sonido se reproducirá 4 veces (la primera y luego 3 veces mas). Si loops vale -1, entonces el sonido se repetirá indefinidamente.

Como en Sound.play(), el argumento maxtime se puede usar para detener la reproducción de sonido luego de un tiempo determinado (indicado en milisegundos).

sintaxis:Channel.play(Sound, loops=0, maxtime=0, fade_ms=0): return None

Nota: Al igual que Sound.play(), el argumento fade_ms se puede usar para alterar progresivamente el volumen de un sonido.

Stop

Detiene la reproducción de sonido en el canal. Luego de interrumpir la reproducción el canal quedará disponible para que nuevos sonidos puedan sonar en él.

sintaxis:Channel.stop(): return None

pause

Detiene de forma temporal la reproducción de sonido en un canal. Este sonido se puede reanudar nuevamente mediante la función Channel.unpause().

sintaxis:Channel.pause(): return None

unpause

Continúa la reproducción en un canal que está en pausa.

sintaxis:Channel.unpause(): return None

10

Page 11: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

fadeout

Detiene la reproducción de un canal luego de reducir progresivamente el volumen de un sonido en el tiempo indicado por el argumento time (en milisegundos).

sintaixs:Channel.fadeout(time): return None

set_volume

Define el volumen, o latencia, de un sonido. El nivel de volumen se reinicia cuando un canal comienza a reproducir nuevamente. Esta función solo afecta al sonido actual. El argument value debe ser un número entre 0.0 y 1.0

Si se pasa un solo argumento, este se interpretará como el volumen de ambos parlantes. Si se pasan dos argumento y el módulo mixer usa el modo estéreo, entonces el primer argumento será el volumen del parlante izquierdo y el segundo argumento será el volumen del parlante derecho. (Si el segundo argumento es None, entonces el primer argumento se interpretará como el volumen de ambos parlantes.)

sintaxis:Channel.set_volume(value): return NoneChannel.set_volume(left, right): return None

get_volume

Retorna el volumen del canal para el sonido que es está reproduciendo. Esta función no tiene en cuenta la separación estéreo que se ha utilizado en Channel.set_volume. El objeto Sound también tiene su propio volumen que se mezcla con el del canal.

sintaxis:Channel.get_volume(): return value

get_busy

Consulta si el canal está activo.

sintaxis:Channel.get_busy(): return bool

get_sound

Obtiene el sonido que se está reproduciendo actualmente. Retorna el objeto Sound que se está reproduciendo en este canal. Retornará None si el canal está inactivo.

sintaxis:

11

Page 12: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

Channel.get_sound(): return Sound

queue

Un objeto Sound comienza a reproducirse inmediatamente después de otro si se coloca en la cola de reproducción del canal. Cada canal solo puede tener un sonido en cola al mismo tiempo. El sonido en cola solo se reproducirá si el sonido actual finaliza normalmente. En otro caso, si se llama a Channel.stop() o Channel.play(), el sonido en cola se cancelará. El sonido comenzará a reproducirse inmediatamente si no hay otro sonido en curso.

sintaxis:Channel.queue(Sound): return None

get_queue

Se retornará el sonido que esté en cola para este canal. Una vez que el sonido comienza a reproducirse ya no estará en la cola de reproducción.

sintaxis:Channel.get_queue(): return Sound

set_endevent

Hace que el canal envíe un evento cuando la reproducción finalice. Cuando se define un evento de terminación para el canal, se enviará un evento a la cola de eventos cada vez que un sonido termine de reproducirse en este canal (no solo la primera vez). Use la función pygame.event.get() para recibir el evento de terminación una vez que halla sido enviado.

Note que si ha llamado a Sound.play(n) o Channel.play(sound, n), el evento de terminación se enviará una sola vez, luego de reproducirse “n+1” veces (vea la documentación de Sound.play).

Se enviará el evento de terminación inmediatamente si se llama a Channel.stop() o Channel.play() mientras el sonido está en reproducción.

El argumento type indica el identificador de evento para enviar a la cola de eventos. Puede ser válido usar cualquier tipo de evento, aunque una buena elección debería ser optar por un valor entre pygame.locals.USEREVENT y pygame.locals.NUMEVENTS.

sintaxis:Channel.set_endevent(): return NoneChannel.set_endevent(type): return None

El canal dejará de enviar eventos si se llama a esta función sin argumentos.

get_endevent

12

Page 13: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

Obtiene el evento que un canal emite cuando finaliza la reproducción. Retorna el tipo de evento que se enviará cada vez que el canal termina de reproducir un objeto Sound. Esta función retornará pygame.NOEVENT si el canal no tiene asignado un evento para emitir.

sintaxis:Channel.get_endevent(): return type

La verdad de la Milanesa :P Traducido significa lo que en verdad nos tiene que interesar si son como yo y no

tienen conocimientos avanzados sobre audio pero aun asi les interesa agregar sonidos a sus juegos.

En resumen, pygame.mixer nos brinda los controles generales sobre el resto de los modulos de niveles inferiores en el manejo de audio, Ademas nos da 2 posibilidadeso formas para reproducir sonidos, la primera es directa y mas sencilla utiliza el modulo pygame.mixer.music pero tiene la dificultad de que solo puede reproducir un sonido o tema a la ves, a lo sumo los diferentes sonidos se podrian ir agregando a la cola de reproducion, el unico problema es que es necesario cargar desde archivo cada ves que se quiere reproducir.

Bien ahora un poco de codigo de ejemplo sobre pygame.mixer.music, pero este sera un poco interactivo para no tener que escribir demasiado.

>>> import pygame>>> pygame.init() #inicializamos la mayoria de los modulos entre ellos mixer(6, 0)>>> pygame.mixer.music.load('after_in_the_dark.ogg') #al archivo lo tengo en el path de python por eso no pongo la ruta>>> pygame.mixer.music.play(2) #el tema se reproducira 3 veses >>> pygame.mixer.music.queue('nirvana_seigyo_fortnoug.ogg') #agregamos el archivo a la cola de reproducion

En fin lo que hicimos fue, primero como siempre importar e inicializar pygame, con ello tanbien automaticamente logramos inicializar pygame.mixer con los parametros por defecto.

Lo siguiente fue cargar un tema en OGG (por algun motivo con este metodo cuando intento cargar otra cosa que no sea un OGG como un WAV me da error, me dice que no lo puede cargar).

Luego le decimos que reprodusca el tema actual, si queremos que se reprodusca 1 vez pasamos 0, si queremos que se reprodusca 2 veses pasaremos un 1 y haci sucesivamente, si quisieramos que se reprodujera el tema indefinidamente tendriamos que pasar -1 como parametro.

por ultimo agregamos otro archivo a la cola de reproducion, este comenzara a reproducirse automaticamente despues de que el ultimo archivo termine de reproducirse.

La segunda forma, diria la recomendada (Usar los Objectos Chanels Solo si saben como hacerlo, sino estaran apostando a su suerte :P) es reproducir los sonidos que emita nuestro juego mediante el uso de objectos Sound y dejar que pygame se encargue del manejo de de los canales osea los objectos Chanels, su manejo basico es sencillo y se crean de la siguiente manera:

13

Page 14: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

back = pygame.mixer.Sound('background.ogg') #suponer que este es el sonido de fondosound1 = pygame.mixer.Sound('sound.wav') #sonidos para los efectos#.... otros sonido que quieran agregar

Sonido de Fondo (Background)

Es el sonido que se reproducira todo el tiempo para anbientizarnos con el ecenario, es el mas sencillo de implementar, al comienzo del bucle principal (antes de entrar en el) del juego solo tendrian que comenzar a reproducir indefinidamente el sonido de fondo, seria razonable que la duracion del sonido que usaremos como fondo sea dentro de todo larga.

back.play(-1) #reproducir indefinidamenteloop = Truewhile lopp:

screen.fill(BLANCO)....

por ende al salir de dicho bucle llamar al metodo stop() para detener su reproducion

back.stop()

Efectos de Sonidos

Los efectos de sonido normalmente son lanzados por ejemplos cuando una pelota coliciona con la parede, aceleramos un auto, un diparo coliciona contra un tanque y por ejemplo tenemos que lanzar la animacion de una explosion junto con el sonido, en fin podemos hacer varias cosas, definer los efectos de sonido por cada objecto, cosa que no es muy logico ya que eston objectos no son unicos en el juego y tenderan a repetirse, la otra solucion es tener un mini modulo donde precargariamos todos nuestros efectos de sonidos por ejemplo en un dicionario, creariamos una sencilla funcion que reproduciria un sonido determinado por una cadena de caracteres que por ejemplo coincidiria con la clave (en el dicionario) del objecto sonido que queremos reproducir en fin algo como:

SONIDOS = { 'shoot' : pygame.mixer.Sound('sonidos/shoot.wav'), 'explode' : pygame.mixer.Sound('sonidos/explocion.wav'), 'clic' : pygame.mixer.Sound('sonidos/clic.wav'), # etc...}

def reproducir(tema): SONIDOS[key].play()

Despues solo importariamos el mini modulo dentro del archivo donde por ejemplo definiriamos la clase que maneje a nuestro personaje, y cuando querramos reproducir un sonido determinado por ejemplo siguiendo con la explocion:

#extracto de codigo de lo que podria ser una clase que maneje los objectos disparo, esto es solo para ejemplificar

14

Page 15: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

def colicion(self, target):if self.colliderect(target.rect):

self.explode() #lanza la animacion de explocionself.enable = False#reproducimos el sonidoreproducir("explode")

Otra opcion mas elegante seria que cuando ocurra algo como esto, lancemos un evento (para algo esta pygame.event y no es un simple modulo que comente por comentar) de la siguiente forma:

#creamos un evento personalizadoevt = pygame.event.Event(pygame.USEREVENT, {'play':'explode'}) pygame.event.post(evt) #lo colocamos dentro de la cola

Nota: En los eventos creados por el usauario podemos aceder al dicionario de parametros mediante el atributo 'dict'

Luego en la secion donde normalmente leemos todos los eventos en busca de algun evento pygame.QUIT podriamos agregar unas cuantas lineas para que esta secion se encargue de reproducir todos los sonidos, osea capturar lo eventos del tipo pygame.USEREVENT y reproducir el tema definido por play:

for evento in pygame.event.get():#capturamos los eventos creados

if evento.type == pygame.USEREVENT: reproducir(evento.dict['play']) elif evento.type == pygame.QUIT: loop =False

pygame.spriteBueno el ultimo modulo de pygame que veremos en este capitulo se llama

pygame.sprite el cual a rasgo generales nos permite manejar grupos de objecto, y que son esos objectos que mencionamos, bueno este termino no se refiere explicitamente a la POO sino al manejo de Objectos Sprites osea todos los elementos que interactuan en nuestro juego.

El uso de este modulo es opcional, particularmente no lo uso por que prefiero escribir mis propias clases para manejo de Sprites, esto no es reinventar la rueda, solo es hacer soluciones a medida.

Se espera que la clase Sprite se utilice como clase base para los diferentes tipos de objetos en el juego. También hay una clase Group básica que simplemente almacena sprites. Un juego podría crear nuevos tipos de clases Group que operen sobre instancias de objetos Sprite personalizadas.

La clase Sprite básica puede dibujar los sprites que contiene sobre una superficie. El método Group.draw() requiere que cada que cada Sprite tenga los atributos image y

15

Page 16: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

rect. El método Group.clear() requiere estos mismos atributos para poder borrar todos los sprites con fondo de pantalla. También hay grupos mas avanzados, por ejemplo pygame.sprite.RenderUpdates() y pygame.sprite.OrderedUpdates().

Los sprites y los grupos manejan sus relaciones con los métodos add() y remove()'. Estos métodos pueden aceptar una o varias instancias de objetos. Los inicializadores para estas clases también aceptan uno o varios objetos para insertar. Es seguro agregar y eliminar el mismo Sprite de un grupo.

Mientras es posible diseñar clases de sprite y grupos que no deriven desde las clases Sprite y AbstractGroup de mas arriba, es extremadamente que herede de ellas cuando agregue una clase de grupo o sprite. Los sprites no son seguros para operar desde diferentes hilos, por lo tanto debe bloquearlos usted mismo si está usando hilos.

spritecollide

Encuentra sprites en el grupo que están en contacto con otro sprite. Retorna una lista que contiene todos los sprites en un grupo que están colisionando con otro sprite. La intersección se determina comparando el atributo Sprite.rect de cada sprite.

El argumento dokill es un valor booleando. Si vale True todos los sprites que colisionan se eliminarán del grupo.

El argumento collided es una función que se utiliza para calcular si dos sprites están en contacto, esta función debería tomar dos sprites como agumentos y retornar un valor True o False indicado si están colisionando. Si no se especifica el valor para el argumento, todos los sprites deberán tener un valor rect, que es el rectángulo del área de sprite, que se usará para calcular la colisión.

Funciones de colisión:• collide_rect• collide_rect_ratio• collide_circle• collide_circle_ratio• collide_mask

sintaxis:pygame.sprite.spritecollide(sprite, group, dokill, collided = None):

return Sprite_list

collide_rect

Consulta la colisión entre dos sprites. Usa la función colliderect del módulo rect para calcular la colisión. Está diseñada para ser enviada como una función de colisión a las funciones generales de colisión. Los sprites deben tener atributos rect.

sintaxispygame.sprite.collide_rect(left, right): return bool

collide_rect_ratio

16

Page 17: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

Verifica colisiones entre dos sprites usando usa versión reducida de los rectángulos de sprite. Se generan con un radio, y la instancia retornada está diseñada para ser enviada como una función de colisión a las funciones generales de colisión. El argumento ratio es un número real, 1.0 indica que será del mismo tamaño, 2.0 es el doble de grande y 0.5 es de la mitad de tamaño.

sintaixis:pygame.sprite.collide_rect_ratio(ratio): return collided_callable

collide_circle

Verifica la colisión entre dos sprites, verificando si dos círculos centrados en los sprites están en contacto. Si el sprite tiene un atributo radius este se usará para crear en círculo, en caso de que no exista se creará un círculo lo suficientemente grande para contener todo el rectángulo del sprite indicado por el atributo rect. Esta función está diseñada para ser enviada como función de colisión a las funciones generales de colisión. Los sprites deben tener los atributos rect y radius

sintaixis:pygame.sprite.collide_circle(left, right): return bool

collide_circle_ratio

Verifica colisiones entre dos sprites usando usa versión reducida de los círculos de sprite. Se generan con un radio, y la instancia retornada está diseñada para ser enviada como una función de colisión a las funciones generales de colisión. El argumento ratio es un número real, 1.0 indica que será del mismo tamaño, 2.0 es el doble de grande y 0.5 es de la mitad de tamaño.

El objeto creado verifica la existencia de colisión entre dos sprites, comprobando si los dos círculos con centro en los sprites están en contacto luego de haberlos alterado de tamaño. Lo los sprites tienen un atributo radius este se usará para crear el círculo, en otro caso se creará un círculo lo suficientemente grande grande para contener por completo el rectángulo de sprite según su atributo rect. Está diseñada para ser enviada como función de colisión a las funciones generales de colisión. Los sprites deben tener los atributos rect y radius (este último es opcional).

sintaixis:pygame.sprite.collide_circle_ratio(ratio): return collided_callable

collide_mask

Verifica la colisión entre dos sprites, probando si sus máscaras de bits se superponen. Si el sprite tiene un atributo mask, este atributo se usará como máscara, en otro caso se creará la máscara a partir de la imagen del sprite. Esta función está diseñada para ser enviada como función de colisión a las funciones generales de colisión. Los sprites deben tener un atributo rect y un atributo opcional de nombre mask.

17

Page 18: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

sintaixis:pygame.sprite.collide_mask(SpriteLeft, SpriteRight): return bool

groupcollide

Esta función encontrará intersecciones entre todos los sprites de dos grupos. Las intersecciones se determinan comparando los atributos Sprite.rect de cada Sprite. Cada sprite dentro del grupo group1 se agrega al diccionario de retorno como clave. El valor de cada elemento será una lista de los sprites del grupo group2 que colisionan con el primero.

sintaixis:pygame.sprite.groupcollide(group1, group2, dokill1, dokill2): return

Sprite_dict

spritecollideany

Consulta si el sprite dado colisiona con algún sprite en el grupo. La intersección se determina comparando el atributo Sprite.rect de cada sprite. Esta prueba de colisión puede ser mas rápida que pygame.sprite.spritecollideany() dado que tiene menos trabajo para hacer. Retornará al encontrar la primer colisión.

sintaixis:pygame.sprite.spritecollideany(sprite, group): return bool

SpriteComo comente arriba, pygame.sprite.Sprite es la clase base de cualquier objecto en

un juego, por defecto esta clase posee 2 atributos image y rect. sobre-escribirán el método Sprite.update() y asignarán un valor a los atributos Sprite.image y Sprite.rect. El constructor puede aceptar cualquier número de objetos Group a donde se insertará el objeto.

sintaxis:pygame.sprite.Sprite(*groups): return Sprite

update

La implementación por defecto de este método no hace nada; es solo un hueco conveniente que puede sobreescribir. Este método se llama desde Group.update() con cualquier argumento que se le envíe.

sintaxis:Sprite.update(*args): #tiene que redefinirse este metodo

18

Page 19: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

add

Inserta el sprite a los grupos.

sintaixis:Sprite.add(*groups): return None

remove

Elimina un sprite de los grupos.

sintaixis:Sprite.remove(*groups): return None

kill

Elimina el Sprite de todos los grupos. El Sprite será eliminado de todos los grupos a los que pertenezca. No se cambiará nada acerca del estado del Sprite. Es posible continuar usando el Sprite luego de haber llamado a este método, incluyendo agregarlo a otros grupos.

sintaixis:Sprite.kill() return None

alive

Consulta si el sprite pertenece a algún grupo.

sintaxis:Sprite.alive(): return bool

groups

Lista los grupos que contienen este sprite.

sintaixis:Sprite.groups(): return group_list

GroupUn contenedor simple para objetos Sprite, es el mas basico de todos los grupos

contenedores que posee pygame.sptrite. Se puede heredar de esta clase para crear contenedores que tengan comportamiento mas específico. El constructor toma cualquier número de sprites para agregar en el grupo. El grupo soporta las siguientes operaciones estándar de python: in, len, bool iter

19

Page 20: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

sintaixis:pygame.sprite.Group(*sprites): return Group

sprites

Retorna una lista con todos los sprites contenidos en el grupo. También puede obtener un iterador para el grupo, aunque no podrá iterar en el grupo mientras lo modifica.

sintaixis:Group.sprites(): return sprite_list

copy

Duplica el grupo. crea una copia en ves de una referencia del grupo.

sintaixis:Group.copy(): return Group

add

Agrega cualquier número de sprites a este grupo. Esta función solo agregará sprites que aún no sean miembros del grupo.

sintaixis:Group.add(*sprites): return None

remove

Elimina cualquier número de sprites del grupo. Esta función solo elimina sprites que son miembros actuales del grupo.

sintaxis:Group.remove(*sprites): return None

has

Consulta si un grupo contiene sprites.

sintaixis:Group.has(*sprites): return None

update

Llama al método update()) en todos los sprites incluidos en el grupo. La clase base Sprite tiene un método update que toma cualquier número de argumentos y no hace nada.

20

Page 21: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

Los argumento que se pasan a Group.update() se pasarán a cada Sprite.

sintaixis:Group.update(*args): return None

draw

Dibuja los sprites contenidos sobre el argumento Surface. Para ello utiliza el atributo Sprite.image para la superficie fuente y Sprite.rect para la posición. El grupo no almacena los sprites en orden, por lo tanto el orden al momento de dibujar es arbitrario.

sintaixis:Group.draw(Surface): return None

clear

Borra los sprites usados en la última llamada a Group.draw(). La superficie destino se limpia pintando con el fondo de pantalla sobre las posición anterior del sprite.

El fondo de pantalla es generalmente una Superficie que tiene las mismas dimensiones que la superficie destino. De todas formas, también puede ser un nombre de función que tome dos argumentos, la superficie destino y un area a limpia. La función background se llamará varias veces para limpiar la pantalla.

sintaixis:Group.clear(Surface_dest, background): return None

empty

Elimina todos los sprites de este grupo.

sintaixis:Group.empty(): return None

Grupos Avanzados de Sprites Ademas de la clase basica Group, pygame provee un grupo de clases especificas para

manejar distintos tipos de sprites, todos ellos heredan los atributos y metodos basicos que heredan de Group, estos son:

GroupSingle

Grupo contenedor que almacena un solo Sprite, para que sirve, es simple este es el grupo que almacenara al Heroe. Existe una propiedad especial, GroupSingle.sprite, que accede al sprite que un grupo contiene. Puede ser None cuando el grupo está vacío. Incluso

21

Page 22: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

la propiedad se puede utilizar para asignarle un sprite y que éste se almacene dentro del contenedor GroupSingle.

LayeredDirty

El grupo LayeredDirty está diseñado para objetos DirtySprite que es una subclase con algunas cosas mas que Sprite, osea trabaja con sprites que utilizan la tecnica de rectangulo Sucio, y es subclase de LayeredUpdates. Este grupo utiliza una técnica de marcas dirty, por lo tanto es mas rápido que los grupos pygame.sprite.RenderUpdates si usted tiene varios sprites estáticos. Además cambia automáticamente entre dos modalidades de actualización: pantalla completa o actualización dirty rectangles, por lo tanto no tendrá que preocuparse de que tendría que ser mas rápido.

LayeredUpdates

Grupo que pemite dibujar los Sprites mediante capas, osea se define el orden de dibujo de cada sprite usando el argumento para indicar a que capa pertenece.

Si el sprite que se agrega al grupo tiene un atributo de nombre layer, entonces se utilizará ese atributo para determinar en que capa se va a agregar el sprite. Si el argumento kwarg contiene el parámetro layer entonces los sprites se agregarán a esa capa (ignorando el atributo sprite.layer). Se utilizará la capa por defecto para insertar los sprites si no se utiliza ninguna de las formas descritas mas arriba.

RenderUpdates

Clase de grupo que utiliza el procedimiento 'dirty rectangles'. Dibuja las imágenes de objetos Sprite y guarda información de las áreas modificadas.

Dibuja todos los objetos Sprite en la superficie, al igual que Group.draw(). Aunque este método retorna una lista de áreas rectangulares de la pantalla que han sido modificadas. Los cambios devueltos incluyen áreas de la pantalla que han sido afectadas por llamadas previas a Group.clear

La lista de objetos Rect devuelta se podría utilizar para llamar a pygame.display.update. Esto ayudará a mejorar el rendimiento del programa en modos de video gestionados por software. Este tipo de actualización solamente es útil en pantallas sin fondos animados.

OrderedUpdates

Esta clase deriva de pygame.sprite.RenderUpdates(). Mantiene el orden en que se agregaron los objetos Sprite al grupo para imprimirlos. Esto produce que agregar y eliminar objetos del grupo sea un poco mas lento que en los Grupos normales.

Bueno los ejemplos de trabajo con Sprites y Grupos son sencillos, yo los dejo para que los vean mas abajo, cuando muestre el codigo de como crear animacion sencilla.

22

Page 23: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

Animacion de SpritesEsto es bastante simple, aquí aparece el concepto de frame o cuadro, que

corresponde a una de las imágenes que forman la animación completa de un sprite. Podemos pensar en una secuencia de imágenes que son dibujadas rápidamente, que engañan al ojo humano dando el efecto de un movimiento fluido. Es el mismo método que se utiliza para los dibujos animados. Si alguna ves trabajaron con Flash o hicieron un gif animado creo que sabran de que estamos ablando.

El número de frames dibujados en un periodo de tiempo se conoce como frame rate (tasa de frames), siendo un aspecto muy importante en la animación, ya que de esto depende la calidad de animación que obtendremos. Si cada uno de los frames se muestra muy rápido o muy lento, la ilusión del movimiento se perderá y el usuario verá cada uno de los frames como una imagen separada. Una animación muy común puede ser la de un personaje caminando, saltando, o realizando cualquier otra acción.

Esto también debe ser representado de alguna forma inteligente en nuestro videojuego, utilizando algún tipo de estructura de datos adecuada, como un vector o lista. Normalmente el sprite tendrá como atributo una lista de animaciones (las acciones del personaje, enemigo, etc.),donde cada animación corresponderá a otra lista con cada uno de los frames. La totalidad de los frames que forman un personaje, suele lmacenarse en un solo archivo de imagen, a esto se le llama sprite sheet, es decir, una imagen donde tenemos secuencias de frames para las diferentes acciones que puede realizar un personaje en un videojuego. La siguiente imagen lo ilustra claramente.

23

Page 24: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

¿Que es un Frame (Cuadro)?

Durante todo este tiempo estubimos ablando de Frame Rate o Cuadros por Segundo, un Frame vendria a ser el estado de una animacion (en este caso nuestro juego) en un momento de tiempo determinado, para mayor sencilles un frame es un estado de la ecena (en este caso nuestro personaje) que es remplazada tan rapidamente que no hace parecer que tenemos un efecto de fluides en el movimento del personaje. A modo de ejemplo los frames vendrian a ser las capturas de los diferentes estados de una imagen como la de mas abajo, si los vemos por separados no tiene sentiedo, pero si los juntamos y hacemos que cambie cada determinado intervalo de tiempo lograremos un efecto de animacion en la pelota.

Animacion Completa vs Animacion Limitada

En el cine existe un estándar de 24 imágenes por segundo. Esa es la tasa a la que graban las cámaras y proyectan los proyectores. Se toma una fotografía de la imagen cada veinticuatroavo de segundo.

En la animación, sin embargo, las imágenes no se toman sino que se producen individualmente, y por ello no tienen que cumplir necesariamente con el estándar del cine. Una película de animación tiene siempre 24 fotogramas por segundo, pero no necesariamente todos esos fotogramas muestran imágenes diferentes: en la animación, las imágenes suelen repetirse en varios fotogramas.

Así pues, tenemos varias tasas de animación:

• En unos: cada imagen es diferente, sin repetición. 24 imágenes por segundo, 1 imagen cada fotograma.

• En doses: cada imagen se repite dos veces. 12 imágenes por segundo, 1 imagen cada 2 fotogramas.

• En treses: cada imagen se repite tres veces. 8 imágenes por segundo, 1 imagen cada 3 fotogramas.

Se ha calculado que el umbral visual por debajo del que ya no se capta un movimiento sino imágenes individuales es de 7 imágenes por segundo.

Animación completa es cuando se anima en unos o en doses. Es el estándar de la animación estadounidense para salas de cine, principalmente las películas de Walt Disney, y

24

Page 25: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

también los largometrajes europeos. Generalmente, se animan las escenas con muchos movimientos rápidos en unos, y el resto en doses (la pérdida de calidad es imperceptible).

Animación limitada es cuando se anima en una tasa inferior. El estándar del animé japonés es animación en treses. La pérdida de calidad ya es perceptible si se es observador. El concepto de animación limitada también afecta a otros aspectos diferentes de la tasa. Por ejemplo, es animación limitada cuando se repiten ciclos: pensemos en Pedro Picapiedra corriendo mientras al fondo aparecen una y otra vez las mismas casas en el mismo orden.

Hay que tener en cuenta que diferentes elementos de la imagen (un personaje, otro personaje, un objeto móvil, un plano del fondo, otro plano del fondo) se animan por separado, y que por tanto dentro de la misma escena puede haber elementos con diferentes tasas de animación.

Un Ejemplo Sencillo

Veremos como almacenar varios cuadros de animación en un solo archivo para realizar una animación muy simple (como mencionamos arriba). Esto nos resultará de utilidad para manejar animaciones y comprender los próximos artículos. Creando los gráficos del personaje

Para mostrar una animación tendremos que imprimir uno a uno varios cuadros de animación. Nos resultará de mucha utilidad almacenar cada uno de estos cuadros en un único fichero gráfico.

Cuando nos queramos referir a la imagen que contiene todos los cuadros le llamaremos grilla, porque contiene varios rectángulos de igual tamaño con los cuadros de animación de nuestro personaje.

Aunque no todos los cuadros y o capturas de nuestro personaje obligatoriamete tienen que tener el mismo grosor, pero al hacerlo nos evitaremos complicaciones en el codigo, bien las imagen con todos los cuadros que usaremos para este ejemplo es un poco reducida (solo unos poco cuadros).

Como vemos nuestro ejemplo contendra 5 cuadros, para claridad los enumeraremos de 0 a 4 (por que de 0 a 4 y no de 1 a 5, es simple cuando animemos y hagamos desplazamiento nos sera mas sencillo).

Para dibujar algunos de los cuadros necesitamos al menos conocer la siguiente información:

• Cantidad total de Filas y Columnas, en nuestro caso 1, fila y 5 columnas• El ancho y alto Completo de la imagen, en este ejemplo 240x35 pixels

Con estos datos ya podemos calcular el ancho y alto de cada cuadro:

frame_ancho = imagen_ancho // num_filasframe_alto = imagen_alto // num_columnas

25

Page 26: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

en nuestro caso:

frame_ancho = 240 // 5 # 48frame_alto = 35 / 1 # 35

Ahora bien supongamos que queremos calcular el area a dibujar de un frame o cuadro en particular por ejemplo el frame 3 (vendria a ser el cuarto cuadro), conocemos el ancho y alto del frame solo nos falta conocer el desplazamiento vertical (en realidad en este ejemplo no hay osea es 0 ya que tenemos una sola fila) y horizontal, como todos los cuadros o frames son del mismo tamaño este calculo del desplazamiento es simple y solo tenemos que multiplicar el nro de frame actual por el ancho o alto dependiendo la situacion.

frame_num = 3 #para el ejemplody = 0 #como dijimos en este ejemplo no tenemos desplazamiento verticaldx = frame_num * frame_ancho # 3 * 48 = 144

Con eso ya tenemos el area de recorte para mostrar en pantalla y usando el metodo surface.blit seria:

area_recorte = pygame.Rect(dx, dy, frame_ancho, frame_alto)surface.blit(imagen, (x, y), area_recorte)

Por ultimo hay que definir un ciclo de animacion, en nuestro ejemplo el ciclo de animacion sera el siguiente:

0,1,2,3,4,5,0,1,2,3,4,5,1,2,3....

Bien ahora veamos el codigo completo de como se veria una clase Sprite basica que represente una animacion:

class SpriteAnimado(pygame.sprite.Sprite): def __init__(self, imagen, filas=1, columnas=1): pygame.sprite.Sprite.__init__(self) #grilla que contendra todos los cuadros o frames self.image = pygame.image.load(imagen) self.image.set_colorkey(MAGENTA)

#como tengo pocos cuadros tengo que agregar un contador #adicional para que los cuadros no pasen tan rapido self.cont = 0

self.filas = filas self.columnas = columnas self.frame_num = 0 self.frame_ancho = self.image.get_width() / self.columnas self.frame_alto = self.image.get_height() / self.filas

self.rect = pygame.Rect(0, 0, self.frame_ancho, self.frame_alto)

26

Page 27: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

def update(self, *argv): self.cont += 1 if self.cont > 10: self.frame_num += 1 self.cont = 0

if self.frame_num >= 5: self.frame_num = 0

def draw(self, surface): dx = self.frame_num * self.frame_ancho dy = 0 area_recorte = pygame.Rect(dx, dy, self.frame_ancho, self.frame_alto) surface.blit(self.image, self.rect, area_recorte)

A estas alturas no creo que sea necesario explicar el resto del codigo, y como veran este ejemplo ademas nos sirvio como ejemplo de como crear una clase derivada del modulo sprite.Sprite, como veran modifique ademas el metodo draw (habran notado que a lo largo de este curso use drawn en ves de draw para el metodo que dibuja el sprite sobre la superficie, se que esta mal expresado como lo escribo, pero diria que es solo una cuestion de gustos.) en fin aca tienen una captura del ejemplo corriendo:

(vease ejemplo_animacion.py)

Bueno con esto doy por finalizado este Modulo de Introducion a la Programacion de Juego, mas explicitamente al sub Curso Aprender a usar PyGame, Ahora bien el curso completo no termina aquí, le sigue el segundo modulo donde ya nos dedicaremos explicitamente al tema programacion de juegos, aunque seguiremos usando pygame, el uso o no de esta librería no tendra tanta relevancia, en fin algunos de los temas que vienen en la segunda parte de este curso, aunque no os digo que los publique en ese orden:

• IA (Inteligencia Artificial) Introducion a la Inteligencia Artificial aplicada a la programacion de Juegos

• Scroling (Mapas compuestos por tiles)

• Juegos en Red (como utilizar Sockets en nuestros juegos)

27

Page 28: Intro Pygame Capitulo 6

Curso de: Programación de Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → [email protected]

• mas...

Saludos, y nos vemos en la segunda parte del curso...

28