1. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
Programación de Juegos
con PyGame
Capitulo 6: Sonidos, Sprites
y Animaciones
1
2. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
pygame.mixer
Bueno 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
3. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
de llamar a pygame.init
sintaxis
pygame.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
4. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
5. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
Music
El 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
6. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
7. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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.
sintaxis
pygame.mixer.music.queue(filename): return None
7
8. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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 None
pygame.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
Sound
Carga 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 Sound
pygame.mixer.Sound(buffer): return Sound
pygame.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
9. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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.
Channel
Retorna 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
10. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
11. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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 None
Channel.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
12. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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 None
Channel.set_endevent(type): return None
El canal dejará de enviar eventos si se llama a esta función sin argumentos.
get_endevent
12
13. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
14. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
back = pygame.mixer.Sound('background.ogg') #suponer que este es el sonido de
fondo
sound1 = 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 indefinidamente
loop = True
while 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
15. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
def colicion(self, target):
if self.colliderect(target.rect):
self.explode() #lanza la animacion de explocion
self.enable = False
#reproducimos el sonido
reproducir("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 personalizado
evt = 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.sprite
Bueno 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
16. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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.
sintaxis
pygame.sprite.collide_rect(left, right): return bool
collide_rect_ratio
16
17. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
18. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
Sprite
Como 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
19. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
Group
Un 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
20. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
21. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
22. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
23. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
Animacion de Sprites
Esto 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
24. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
¿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
25. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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_filas
frame_alto = imagen_alto // num_columnas
25
26. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
en nuestro caso:
frame_ancho = 240 // 5 # 48
frame_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 ejemplo
dy = 0 #como dijimos en este ejemplo no tenemos desplazamiento vertical
dx = 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
27. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
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
28. Curso de: Programación de Juegos con PyGame
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com
• mas...
Saludos, y nos vemos en la segunda parte del curso...
28