Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Programación de Juegos 
con PyGame 
Capitulo 4: Modulos Key, 
Image, Surface, Rect 
1
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
pygame.key 
Modulo que permite gestionar el disposito del teclado (Si no saben cual es el teclado 
miren hacia abajo y lo veran :P) 
Como ya vimos en el capitulo anterior la cola de eventos obtiene eventos como 
pygame.KEYDOWN y pygame.KEYUP cuando se pulsan o sueltan las teclas del teclado 
respectivamente. Cada evento tiene una atributo llamado key que es un identificador en 
entero que representa cada tecla del teclado. 
El evento pygame.KEYDOWN tiene un atributo adicional llamado unicode, y otro 
scancode. unicode representa un único caracter que es la traducción completa del caracter 
ingresado por teclado. Teniendo en cuenta las teclas de composición y mayúsculas. scancode 
representa el código de tecla específico de la plataforma. Este código podría ser diferente de 
un teclado a otro, aunque es útil para la selección de teclas raras como las teclas multimedia. 
Existen muchas constantes de teclado que se utilizadan para representar teclas. La 
siguiente es una lista con todas esas constantes: 
Constante ASCII Nombre habitual 
K_BACKSPACE b backspace 
K_TAB t tab 
K_CLEAR clear 
K_RETURN r return 
K_PAUSE pause 
K_ESCAPE escape 
K_SPACE space 
K_EXCLAIM ! exclaim 
K_QUOTEDBL ” quotedbl 
K_HASH # hash 
K_DOLLAR $ dollar 
K_AMPERSAND & ampersand 
K_QUOTE quote 
K_LEFTPAREN ( left parenthesis 
K_RIGHTPAREN ) right parenthesis 
K_ASTERISK * asterisk 
K_PLUS + plus sign 
K_COMMA , comma 
K_MINUS - minus sign 
K_PERIOD . period 
K_SLASH / forward slash 
K_0 0 0 
K_1 1 1 
K_2 2 2 
K_3 3 3 
K_4 4 4 
K_5 5 5 
K_6 6 6 
K_7 7 7 
K_8 8 8 
K_9 9 9 
K_COLON : colon 
K_SEMICOLON ; semicolon 
K_LESS < less-than sign 
K_EQUALS = equals sign 
K_GREATER > greater-than sign 
2
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
K_QUESTION ? question mark 
K_AT @ at 
K_LEFTBRACKET [ left bracket 
K_BACKSLASH  backslash 
K_RIGHTBRACKET ] right bracket 
K_CARET caret 
K_UNDERSCORE _ underscore 
K_BACKQUOTE ` grave 
K_a a a 
K_b b b 
K_c c c 
K_d d d 
K_e e e 
K_f f f 
K_g g g 
K_h h h 
K_i i i 
K_j j j 
K_k k k 
K_l l l 
K_m m m 
K_n n n 
K_o o o 
K_p p p 
K_q q q 
K_r r r 
K_s s s 
K_t t t 
K_u u u 
K_v v v 
K_w w w 
K_x x x 
K_y y y 
K_z z z 
K_DELETE delete 
K_KP0 keypad 0 
K_KP1 keypad 1 
K_KP2 keypad 2 
K_KP3 keypad 3 
K_KP4 keypad 4 
K_KP5 keypad 5 
K_KP6 keypad 6 
K_KP7 keypad 7 
K_KP8 keypad 8 
K_KP9 keypad 9 
K_KP_PERIOD . keypad period 
K_KP_DIVIDE / keypad divide 
K_KP_MULTIPLY * keypad multiply 
K_KP_MINUS - keypad minus 
K_KP_PLUS + keypad plus 
K_KP_ENTER r keypad enter 
K_KP_EQUALS = keypad equals 
K_UP up arrow 
K_DOWN down arrow 
K_RIGHT right arrow 
K_LEFT left arrow 
K_INSERT insert 
K_HOME home 
3
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
K_END end 
K_PAGEUP page up 
K_PAGEDOWN page down 
K_F1 F1 
K_F2 F2 
K_F3 F3 
K_F4 F4 
K_F5 F5 
K_F6 F6 
K_F7 F7 
K_F8 F8 
K_F9 F9 
K_F10 F10 
K_F11 F11 
K_F12 F12 
K_F13 F13 
K_F14 F14 
K_F15 F15 
K_NUMLOCK numlock 
K_CAPSLOCK capslock 
K_SCROLLOCK scrollock 
K_RSHIFT right shift 
K_LSHIFT left shift 
K_RCTRL right ctrl 
K_LCTRL left ctrl 
K_RALT right alt 
K_LALT left alt 
K_RMETA right meta 
K_LMETA left meta 
K_LSUPER left windows key 
K_RSUPER right windows key 
K_MODE mode shift 
K_HELP help 
K_PRINT print screen 
K_SYSREQ sysrq 
K_BREAK break 
K_MENU menu 
K_POWER power 
K_EURO euro 
El teclado tambien tiene una lista de estados de combinaciones que pueden ser 
montados a través de una lógica binaria. 
KMOD_NONE 
KMOD_LSHIFT 
KMOD_RSHIFT 
KMOD_SHIFT 
KMOD_CAPS 
KMOD_LCTRL 
KMOD_RCTRL 
KMOD_CTRL 
KMOD_LALT 
KMOD_RALT 
KMOD_ALT 
KMOD_LMETA 
KMOD_RMETA 
KMOD_META 
KMOD_NUM 
4
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
KMOD_MODE 
get_focused 
Esta función devolvera verdadero cuando la ventana de visualización contiene el foco 
del teclado. Si se necesita que la ventana no pierda el foco del teclado, se puede utilizar 
pygame.event.set_grab para capturar todas las entradas de teclado. 
sintaxis: 
pygame.key.get_focused() -> return bool 
get_pressed 
Devuelve una secuencia de valores lógicos (booleans) representando el estado de 
cada tecla en el teclado. Utilice los valores de constante de tecla como índice de la secuencia. 
Un valor verdadero significa que el botón esta presionado. 
Tenga en cuenta que obtener la lista de las teclas pulsadas con esta función no es la 
forma apropiada de gestionar la entrada de texto por parte del usuario. No hay forma de 
conocer el orden de las teclas pulsadas, y las pulsaciones muy rápidas de teclas pueden 
pasar desapercibidas entre dos llamadas a get_pressed. Tampoco hay forma de trasladar las 
teclas pulsadas a un valor de caracter completamente imprimible por lo que para un mejor 
manejo de las entradas de teclado por parte de usuario se recomienda realizar un manejo 
mediante la cola de eventos con los eventos pygame.KEYDOWN. 
sintaxis: 
pygame.key.get_pressed() -> return bools 
get_mods 
Devuelve un entero representando una mascara con todos las teclas que estan siendo 
presionadas. Utilizando lógica binaria puedes verificar si una tecla como shift está pulsada, el 
estado de capslock y más. 
sintaxis: 
pygame.key.get_mods() -> return int 
set_mods 
Crea una mascara binaria con las constantes de las teclas que deseas imponer sobre 
tu programa. 
sintaxis: 
pygame.key.set_mods(int) -> return None 
set_repeat 
5
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Cuando la funcionalidad de repetición de teclas está habilitada en el teclado, las teclas 
que quedan presionadas generan múltiples eventos de tipo pygame.KEYDOWN. El 
parrámetro delay (tiempo de retraso) es el número de milisegundos transcurridos antes de 
enviar el primer evento. Luego el resto de los eventos se enviarán en ese intervalo de 
milisegundos. 
Si no especifica argumentos la repetición de teclas quedará deshabilitada. 
sintaxis: 
pygame.key.set_repeat() -> return None 
pygame.key.set_repeat(delay, interval) -> return None 
Nota: Cuando se inicializa pygame la repetición de teclas está deshabilitada. 
get_repeat 
Esta función cumple una tarea similar a set_repeat, solo que nos muestra el intervalo de 
milisegundos en lugar de definirlo. 
sintaxis: 
pygame.key.get_repeat() -> return (delay, interval) 
name 
Devuelve el nombre descriptivo de la constante del telclado, ya que no todas los caracteres 
se pueden representar (en realidad todos los caracteres se pueden representar mediente su 
codigo). 
sintaxis: 
pygame.key.name(key) -> return string 
pygame.image 
Es el Módulo de pygame encargador de la transferencia (leer/grabar imagenes desde 
ficheros) de imagen. 
El módulo image contiene funciones para leer y grabar imágenes, como así también 
para transferir superficies a formatos accesibles para otros paquetes. 
Note que no hay una clase Image, todas la imagenes se cargan como objetos Surface. 
La clase Surface es la que se encarga de su manipulacion, la misma permite operaciones 
como dibujar lineas, pintar pixeles, capturar regiones, etc. 
El módulo image es una dependencia importante de pygame, aunque el soporte 
extendido a formatos es opcional. Por defecto solo puede cargar imágenes BMP sin 
compresión; pero cuando pygame se provee con soporte de imágenes completo, la función 
pygame.image.load() puede interpretar los siguientes formatos: 
6
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
JPG 
PNG 
GIF(sin animación) 
BMP 
PCX 
TGA (sin compresión) 
TIF 
LBM (y PBM) 
PBM (y PGM, PPM) 
XPM 
La funcionalidad de guardado imágenes solo soporta un conjunto reducido de estos 
formatos. Puede grabar o almacenar imagenes en los siguientes formatos: 
BMP 
TGA 
PNG 
JPEG 
Aun asi la ide de PyGame no es especificamete cargar imagenes, por ello el grupo 
reducido de formatos de imagenes soportados por la API para cargar y guardar imagenes 
desde ficheros, aun asi no estamos del todo perdidos ya que la funcionalidad de este modulo 
se puede extender utilizando la liberia PIL junto con PyGame. 
load 
Funcion para cargar una nueva imagen desde un archivo. se puede pasar como 
parametro tanto la ruta del archivo como un objecto file de python. 
Pygame determina automaticamente el tipo de formato archivo (por ejemplo, si es un 
gif o bmp) y generará un nuevo objeto Surface de acuerdo a esa información. En algunos 
casos necesitará conocer la extensión del archivo (por ejemplo las imagenes GIF deberían 
terminar en ”.gif”). Si utiliza un objeto archivo en formato crudo, seguramente necesitará 
enviar el nombre original del archivo como el argumento namehint. 
La superficie retornada contendrá el mismo formato de color, colores clave o 
transparencia alpha que el fichero del que proviene. Generalmente cuando cargue imagenes 
que uilicen algun algoritmo de comprecion o canal alfa devera llamar al metodo 
Surface.convert() sin argumentos para crear una copia que se pueda imprimir mas rápido en 
pantalla. 
Para imágenes con transparencia alpha, como en las imágenes .png, use el método 
convert_alpha() luego de cargar la imágen, así la superficie resultante también tendrá 
transparencia. 
Tener en Cuenta que PyGame no siempre tendrá soporte para todos los formatos. 
Como mínimo soportará el formato BMP sin compresión. Si pygame.image.get_extended() 
retorna True, usted podría ser capaz de cargar la mayoría de las imágenes, incluyendo png, 
jpg y gif. 
sintaxis: 
pygame.image.load(filename): return Surface 
pygame.image.load(fileobj, namehint=""): return Surface 
7
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
save 
Permite guardar o almacenar una imagen en el disco. 
Como ya se mencion pygame solo puede guardar la superficie como algunos de los 
posibles tipos de formato de imagen BMP, TGA, PNG o JPEG. Si la extensión del nombre de 
archivo no se reconoce, se utilizará por defecto .TGA. Tanto los formatos TGA como BMP 
generan archivos sin compresión. 
sintaxis: 
pygame.image.save(Surface, filename): return None 
get_extended 
Consulta si se pueden cargar los formatos de imagen extendidos. 
Si el paquete de pygame fue construido (Compilado Recordar que PyGame aunque 
extiende muchas cosas internamente sigue siendo un envoltorio de la Libreria SDL) con los 
formatos de imagen extendido esta función retornará True. Aún así no es posible determinar 
que formatos estarán disponibles, generalmente en la mayoria de los paquetes podrá 
manipular todos los formatos. 
sintaxis: 
pygame.image.get_extended(): return bool 
tostring 
Transfiere una imagen a una cadena de texto string. 
Genera una cadena que pude transferirse con el método fromstring en otros paquetes 
de imágenes de python. Algunos paquetes de imagen de python prefieren sus imágenes en 
el formato “de abajo hacia arriba”, por ejemplo el paquete PyOpenGL). Se invertirá 
verticalmente la cadena retorno si envía True como valor para el argumento flipped. 
El argumento format es una cadena con uno de los siguiente valores. Note que solo 
las superficies de 8 bits pueden usar el formato “P”. Los otros formatos funcionarán con 
cualquier superficie. Ademas note que otros paquetes de imágenes de python suportan mas 
formatos que pygame. 
Cadena Formato Superficie 
P superficies de 8 bits con paleta. 
RGB imagen de 24 bits. 
RGBX imagen de 32 bits con un espacio sin utilizar. 
RGBA imagen de 32 bits con un canal alpha (transparencia). 
ARGB imagen de 32 bits con canal alpha en primer lugar. 
RGBA_PREMULT imagen de 32 bits bajo la escala del canal alpha. 
ARGB_PREMULT imagen de 32 bits bajo la escala del canal alpha en primer 
lugar. 
sintaxis: 
8
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
pygame.image.tostring(Surface, format, flipped=False): return string 
fromstring 
Genera una nueva superficie desde una cadena. 
Esta función toma argumentos similares a pygame.image.tostring(). El argumento 
size es una tupla con números que representan el ancho y alto. Puede destruir la cadena 
original una vez que la nueva superficie se ha creado. 
El formato y tamaño de la imagen debe coincidir exactamente con el mismo tamaño 
de la cadena. Se lanzará una excepción en caso contrario. 
sintaxis: 
pygame.image.fromstring(string, size, format, flipped=False): return 
Surface 
frombuffer 
Genera una nueva superficie que comparte los datos dentro de una cadena. 
Genera una nueva superficie que comparte los datos de los pixeles directamente 
desde la cadena. Esta función toma los mismos argumentos que pygame.image.fromstring(), 
pero no puede invertir verticalmente los datos de origen. 
Esta Funcion Funcionará mucho mas rápido que pygame.image.fromstring dado que 
no se alojan o copian datos de pixeles. 
sintaxis: 
pygame.image.frombuffer(string, size, format): return Surface 
Surface 
Objecto que pygame utiliza para representar y trabajar con las superficies (Imagenes 
en memoria del programa o script) 
Un objeto Surface de pygame se utiliza para representar cualquier imagen. La 
superficie tiene un formato de pixel y resolución fija. Las superficies con pixeles de 8 bits 
usan una paleta de 256 colores. 
Invoque pygame.Surface() para crear un nuevo objeto image. La superficie será 
completamente negra. El único argumento requerido es el tamaño. La superficie se creará 
con el formato que mejor coincida con la pantalla actual si no se especifican los argumentos 
adicionales. 
El formato de pixel se puede controlar especificando la profundidad de colores o una 
superficie existente. El argumento flags es una combinación de características adiciones para 
la superficie. Puede utilizar cualquier combinación de estas: 
9
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
HWSURFACE: Genera la imagen en la memoria de video. 
SRCALPHA: El formato de pixel incluirá transparencias por pixel. 
Ambas opciones son solo una solicitud, tal vez no sea posible para todos los modos de video 
Los usuarios avanzados pueden combinar un conjunto de opciones con un valor 
depth. El argumento masks es un conjunto de 4 números enteros que especifica cuales bits 
representan a cada color en el pixel. Las superficies normales no requieren el argumento 
mask. 
Las superficies pueden tener varios atributos adicionales como planos alpha, colores 
clave o recortes. Estas funciones afectan principalmente a la forma en que se imprime la 
superficie sobre otra. Las rutinas blit intentarán usar aceleración de hardware cuando sea 
posible, en caso contrario usarán métodos de impresión por software muy optimizados. 
Existen tres tipos de transparencia en pygame: colores clave, transparencia de 
superficie, y transparencia de pixel. La transparencia de superficie se puede combinar con 
colores clave, pero las imágenes con transparencia de pixel no puede usar los otros modos. 
La transparencia por color clave hace transparente un solo color. No se imprimirán los pixeles 
que coincidan con el color clave. La transparencia de superficie es un valor individual que 
cambia la transparencia de la imagen completa. Una transparencia de superficie de 255 será 
opaca mientras que un valor de 0 será completamente transparente. 
La transparencia de pixel es diferente porque se almacena el valor de transparencia 
de cada pixel. Esto permite crear efectos de transparencia mas precisos, pero es algo mas 
lento. La transparencia de pixel no se puede mezclar con los otros tipos de transparencia. 
Existe soporte para acceder a los pixels de la superficie. El acceso pixels en superficies 
de hardware es lento y no se recomienda. Estos métodos son adecuados para acceso simple, 
pero serán considerablemente lentos cuando realice mucho trabajo de pixels con ellos. Si 
planea realizar mucho trabajo a nivel de pixels se recomienda usar el módulo 
pygame.surfarray que puede tratar a las superficies como vectores de varias dimensiones (y 
es bastante veses mas rapido rápido). 
Cualquier función que acceda directamente a los datos de pixels de la superficie 
necesitarán que la superficie esté bloqueada. Estas funciones pueden bloquear (block()) o 
desbloquear (unlock()) las superficies por ellas mismas si ayuda, pero, si habrá una 
sobrecarga muy grande de múltiples bloqueos o desbloqueos si se llama a esta función 
muchas veces. Es mejor bloquear manualmente la superficie antes de llamar a las funciones 
muchas veces, y luego desbloquear la superficie cuando se halla finalizado. Todas las 
funciones que necesitan bloquear la superficie lo indican en la documentación. Recuerde 
dejar la superficie bloqueada solo mientras sea necesario. 
Los pixels de la superficie se almacenan internamente como un número individual que 
tiene todos los colores agrupados. Use las funciones Surface.map_rgb() y 
Surface.unmap_rgb() para convertir entre valores individuales (rojo, verde y azul) en colores 
agrupados para la superficie. 
Las superficies también pueden ser una referencia a una sección de otra superficie. Se 
generan con el método Surface.subsurface(). Cualquier cambio en alguna de las dos 
superficie que verá reflejado en ambas. 
Cada superficie contiene un área de recorte. Por defecto el área de recorte cubre la 
superficie entera. Si esta área de modifica, todas las operaciones de dibujado solo afectarán 
10
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
un área mas pequeña. 
sintaxis: 
pygame.Surface( (width, height), flags=0, depth=0, masks=None): return 
Surface 
pygame.Surface( (width, height), flags=0, Surface): return Surface 
blit 
La operacion mas comun en todo juego diria yo, que es la de copiar una imagen o 
parte de una imagen y pegarla o imprimirla sobre otra superficie, este metodo lo realiza o 
deve llamarlo la superficie destino (superficie donde quiero imprimir imagen) casi siempre 
sera la superficie que representa la pantalla osea screen que es el nombre como la vine 
llamando durante todo este curso. El metodo tiene varios argumentos que a continuacion 
listare de acuerdo a como deven ser colocados y explicare su funcion, el unico obligatorio es 
source el resto son opcionales: 
source: Se refiere a la superficie origen osea de la que se quiere copiar la superficie 
completa o parte de ella, este deve ser un atributo de tipo Surface. 
dest: Este atributo puede ser tanto una tupla (x, y), como un objecto Rect, 
representa en que posicion de la superficie destino se dibujara (comenzara a dibuar) la 
superficie origen, como referencia es donde aparecera dibujada la esquina superior 
izquierda de la superfice origen, si no se pasa argumento a este parametro asumira 
como posicion destino a los valores (0, 0). 
area: Este argumento es opcional, y representa la porcion rectangular de imagen que 
queremos copiar, si el parametro es None se copiara toda la imagen. El parametro area 
puede ser algunos de los siguientes: 
rect 
(x, y, w, h) 
((x, y), (w, h)) 
Donde x,y son la posicion x,y desde donde se empezara a copiar, w(width) es el 
ancho y h (height) es el alto del area de recorte. opcionalmete se puede utilizar un objecto 
rect para pasar estos parametros. 
Special_flags: La opción special_flags puede tomar los siguientes valores: 
BLEND_ADD 
BLEND_SUB 
BLEND_MULT 
BLEND_MIN 
BLEND_MAX 
BLEND_RGBA_ADD 
BLEND_RGBA_SUB 
BLEND_RGBA_MULT 
BLEND_RGBA_MIN 
BLEND_RGBA_MAX 
BLEND_RGB_ADD 
BLEND_RGB_SUB 
BLEND_RGB_MULT 
11
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
BLEND_RGB_MIN 
BLEND_RGB_MAX 
Nota: tal vez se agreguen mas opciones de impresión en el futuro. El rectángulo retornado 
representa el área de los pixels afectados, excluyendo cualquier pixel fuera de la superficie 
destino o el área de recorte. Ademas Se ignorarán los pixels alpha cuando se imprima sobre 
una superficie de 8 bits. 
sintaxis: 
surface.blit(source, dest, area=None, special_flags = 0): return Rect 
Aqui muestro algunos codigo de ejemplo para terminar de aclarar la situacion y evitar 
confuciones en el Futuro: 
Suponer que tenemos 2 superfices, por sinplicidad las llamaremos sup_origen y 
sup_destino (que en el codigo fuente sera screen) ambas de 400x300 pixeles osea para 
quien no leyo el capitulo 1, 400 pixeles de ancho por 300 pixeles de alto, Nota las imagenes 
podrian ser de cualquier tamaño en fin estas son mis superficies (imagenes en memoria): 
sup_origen 
12
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
sup_destino 
El color con tono semi amarillo es a proposito para que puedan diferenciar la 
superficie de la Hoja. ahora vamos a proponer varios problemas sencillos (que resolvere y 
mostrare el resultado), todas estas pruevas seran via consola, a no preocuparse si a primera 
vista la pantalla de pygame parece estar tildada o no responder, lo que pasa es que no 
actualizamos los eventos. 
Antes de todo, importar e inicializar pygame 
>>> import os 
>>> import pygame 
>>> from pygame.locals import * 
>>> pygame.init() 
(6, 0) 
Crear la superficie que representa la pantalla y cargar las imagenes 
>>> screen = pygame.display.set_mode((400, 300)) 
>>> path = 'D:CursosJuegosCurso PyGame' 
Nota: la variable path es el directorio donde actualmente tengo las imagenes, como veran 
estoy en windows, en linux pondriamos lo siguiente suponiendo que las imagenes esten 
en /home/username/fotos/. path seria: 
>>> path = '/home/username/fotos' 
>>> sup_origen = pygame.image.load(os.path.join(path, 'l2c5.bmp')) 
>>> sup_destino = pygame.image.load(os.path.join(path, 'blank.bmp')) 
para ver que estas son las superficies cargadas las mostrare: 
>>> screen.blit(sup_origen, (0, 0)) 
<rect(0, 0, 400, 300)> 
>>> pygame.display.flip() 
13
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
>>> screen.blit(sup_destino, (0, 0)) 
<rect(0, 0, 400, 300)> 
>>> pygame.display.flip() 
Ya vimos como copiar la imagen completamente Ahora supongamos que queremos 
copiar (lo correcto a decir es blitear) al sup_origen sobre la sup_destino en la posicion 
central osea en la pos 200, 150 
>>> sup_destino.blit(sup_origen, (200, 150)) 
<rect(200, 150, 200, 150)> 
>>> pygame.display.flip() 
14
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Si quisieramos copiar solo una porcion por ejemplo el area (150, 0, 100, 100) 
>>> screen.blit(sup_origen, (200, 150), (150, 0, 100, 100)) 
<rect(200, 150, 100, 100)> 
>>> pygame.display.flip() 
convert 
15
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Cambia el formato de pixel de una imagen. 
Genera una nueva copia de la superficie con un formato de pixel modificado. El nuevo 
formato de pixel se puede determinar a partir de otra superficie existente. Otra posibilidad es 
especificar los argumentos depth, flags y mask, de manera similar a pygame.Surface() 
La superficie nueva tendrá el mismo formato de pixel de la pantalla si no envía ningún 
argumento. Este formato será el mas rápido de imprimir. Es una buena idea convertir todas 
las superficies antes de imprimirlas varias veces. 
La superficie convertida podría no tener pixels alpha, dado que serán eliminados si la 
superficie original los tenía. Vea la función Surface.convert_alpha() para crear o preservar 
superficies con canal alpha. 
sintaxis: 
Surface.convert(Surface): return Surface 
Surface.convert(depth, flags=0): return Surface 
Surface.convert(masks, flags=0): return Surface 
Surface.convert(): return Surface 
convert_alpha 
Genera una nueva copia de la superficie con el formato de pixel deseado. La superficie 
nueva tendrá un formato adecuado para imprimirse mas rápidamente el formato indicado 
con canal alpha. Si no se especifica el argumento surface, la nueva superficie se optimizará 
para el formato de pantalla actual. 
A diferencia del método Surface.convert(), el formato de pixel para la imagen nueva 
podría no ser exactamente el mismo que se pide, aunque se optimizará para imprimirse 
sobre la superficie destino. 
sintaxis: 
Surface.convert_alpha(Surface): return Surface 
Surface.convert_alpha(): return Surface 
Nota: tanto al usar convert() como convert_alfa() adaptamos la superficie para que obtimize 
su manejo, pero esto avese trae perdida de definicion en algunos formatos de imagenes. 
copy 
Genera una nueva copia de la superficie. 
Hace una copia duplicada de un superficie. La superficie nueva tendrá el mismo 
formato de pixel, paletas de colores y configuración de transparencia que la original. 
sintaxis: 
Surface.copy(): return Surface 
fill 
16
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Pinta la superficie con un color solido. Se pintará la superficie entera si no se 
especifica el argumento rect. El argumento rect limitará la modificación al área especificada. 
La operación de pintado también se limitará por el área de recorte de la superficie. 
El argumento color puede ser una secuencia RGB, RGBA o un índice de una paleta de 
colores. Si usa el formato RGB se ignorará el componente alpha (una parte de RGBA) a 
menos que la superficie use transparencia por pixel (atributo SRCALPHA). 
BLEND_ADD 
BLEND_SUB 
BLEND_MULT 
BLEND_MIN 
BLEND_MAX 
BLEND_RGBA_ADD 
BLEND_RGBA_SUB 
BLEND_RGBA_MULT 
BLEND_RGBA_MIN 
BLEND_RGBA_MAX 
BLEND_RGB_ADD 
BLEND_RGB_SUB 
BLEND_RGB_MULT 
BLEND_RGB_MIN 
BLEND_RGB_MAX 
sintaxis: 
Surface.fill(color, rect=None, special_flags=0): return Rect 
Esta función retornará el área afectada de la superficie. 
set_colorkey 
Define el color clave de transparencia. 
Define el color clave para la superficie. Cuando imprima esta superficie sobre otra, 
cualquier pixel que tenga el mismo color que el color clave no se imprimirá. El argumento 
color puede ser un color RGB o un indice de una paleta de colores. Si se envía None como 
argumento entonces se deshabilitará el color clave. 
Se ignorará el color clave si la superficie tiene un formato para usar valores alpha por 
pixel. La transparencia por color clave se puede mezclar con la transparencia a nivel de 
superficie. 
Se puede definir el argumento opcional flags a pygame.RLEACCEL para obtener mejor 
rendimiento en pantallas que no tengan aceleración de video. Una superficie RLEACCEL 
puede ser mas lenta de modificar, pero se imprimirá mas rápido. 
El color que mas comunmente se usa como canal Alfa es el MAGENTA por ser raro que 
aparesca en pantalla. aca muestro como se vera una misma imagen sin y con color_key(). 
Sintaxis: 
Surface.set_colorkey(Color, flags=0): return None 
Surface.set_colorkey(None): return None 
17
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
(ejemplo_01.py) 
get_colorkey 
Obtiene el color clave de transparencia actual. Retorna el color clave actual de la 
superficie. Si la superficie no tiene color clave la función retornará None. 
sintaxis: 
Surface.get_colorkey(): return RGB or None 
set_alpha 
Define el valor de transparencia para la superficie. Cuando se imprima esta superficie 
sobre otra los pixels se dibujarán ligeramente transparentes. El valor de transparencia es un 
número entero de 0 a 255, 0 representa completamente transparente y 255 completamente 
opaco. Se deshabilitará la transparencia de la superficie si se pasa None como valor de 
transparencia. 
Esta transparencia es diferente a la transparencia por pixel. Se ignorará este valor de 
transparencia si la superficie contiene pixels con transparencia. Si la superficie contiene 
transparencia por pixel, cuando llame a esta función con el argumento None se deshabilitará 
esa transparencia por pixel. 
El argumento adicional flags se puede definir como pygame.RLEACCEL para obtener 
mayor rendimiento en pantallas que no tengan aceleración de video. Una superficie 
RLEACCEL será mas lenta de modificar, aunque será mas rápido imprimirla sobre otra. 
sintaxis: 
Surface.set_alpha(value, flags=0): return None 
Surface.set_alpha(None): return None 
(ejemplo_02.py) 
get_alpha 
18
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Obtiene el valor de transparencia de la superficie, Retorna el valor de transparencia actual 
para la superficie. Se retornará None si el valor de transparencia no está definido. 
sintaxis: 
Surface.get_alpha(): return int_value or None 
lock 
Bloquea los datos de pixel de una superficie para acceder a ellos. En la superficies 
aceleradas, los datos de pixels podrían estar almacenados en memoria de video volátil o en 
formas no lineales bajo compresión. Cuando se bloquea una superficie la información de 
pixels se convierte en un formato accesible. El código que lee o escribe valores de pixels 
necesitará que la superficie se bloquee para realizar esas tareas. 
Las superficies no deberían permanecer bloqueadas mas de lo necesario. Una 
superficie bloqueada podría no mostrarse o ser manipulada por pygame. 
No todas las superficies necesitan bloquease. El método Surface.mustlock() puede 
determinar si la superficie requiere bloquease. De todas formas, no hay desventaja al 
bloquear o desbloquear una superficie que no lo necesita. 
Todas las funciones de pygame bloquearán o desbloquearán automáticamente los 
datos de la superficie si es necesario. Si una sección de código hace varias llamas para 
modificar la superficie, entonces se bloqueará y desbloqueará muchas veces la superficie. Por 
este motivo, es mucho mas útil bloquear la superficie manualmente, luego modificarla 
muchas veces y luego desbloquearla manualmente. 
Es seguro anidar llamas para bloquear y desbloquear. La superficie solo se desbloqueará 
después de soltar el último bloqueo. 
sintaxis: 
Surface.lock(): return None 
unlock 
Desbloquea los datos de pixels de la superficie luego de que ha sido bloqueada. La 
superficie desbloqueada podrá imprimirse nuevamente por pygame. Vea la documentación 
de Surface.lock() para mas detalles. 
Todas las funciones de pygame bloquearán o desbloquearán automáticamente los 
datos de la superficie si es necesario. Si una sección de código hace varias llamas para 
modificar la superficie, entonces se bloqueará y desbloqueará muchas veces la superficie. Por 
este motivo, es mucho mas útil bloquear la superficie manualmente, luego modificarla 
muchas veces y luego desbloquearla manualmente. 
Es seguro anidar llamas para bloquear y desbloquear. La superficie solo se desbloqueará 
después de soltar el último bloqueo. 
sintaxis: 
Surface.unlock(): return None 
19
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
mustlock 
Verifica si la superficie necesita bloquearse., Retorna True si la superficie se debe 
bloquear para acceder a sus datos de pixel. Usualmente las superficies de software pura no 
necesitan bloquease. Este método no se usa con frecuencia, dado que es seguro y mas 
rápido directamente bloquear todas las superficies como sea necesario. 
Todas las funciones de pygame bloquearán o desbloquearán automáticamente los 
datos de la superficie si es necesario. Si una sección de código hace varias llamas para 
modificar la superficie, entonces se bloqueará y desbloqueará muchas veces la superficie. Por 
este motivo, es mucho mas útil bloquear la superficie manualmente, luego modificarla 
muchas veces y luego desbloquearla manualmente. 
sintaxis: 
Surface.mustlock(): return bool 
get_locked 
Consulta si la superficie está bloqueada, Retorna True cuando la superficie está 
bloqueada. Esta función no se fija o preocupa sobre cuantas veces se ha bloqueado la 
superficie. 
sintaxis: 
Surface.get_locked(): return bool 
get_locks 
Obtiene los bloqueos de la superficie. Retorna los bloqueos existentes para la 
superficie. 
sintaxis: 
Surface.get_locks(): return tuple 
get_at 
Retorna el valor de color RGBA en la posición indicada. Si la superficie no tiene 
transparencia por pixel, entonces el valor alpha del color será siempre 255 (completamente 
opaco). Se lanzará una excepción IndexError si la posición del pixel está fuera del área de la 
superficie. 
Obtener y definir los pixels de a uno a la vez es una tarea generalmente lenta para 
ser utilizada en un juego o una situación de tiempo real. Esta función bloqueará y 
desbloqueará la superficie temporalmente como sea necesario. 
sintaxis: 
Surface.get_at( (x, y) ): return Color 
20
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
set_at 
Define el valor de color RGBA o entero (si utiliza paleta) de un pixel. Si la superficie 
no tiene transparencia por pixel, entonces el valor alpha se ignorará. No tendrá ningún efecto 
definir pixels fuera del área total o el área de recorte de la superficie. 
Obtener y definir los pixels de a uno a la vez es una tarea generalmente lenta para 
ser utilizada en un juego o una situación de tiempo real. Esta función bloqueará y 
desbloqueará la superficie temporalmente como sea necesario. 
sintaxis: 
Surface.set_at( (x, y), Color): return None 
set_clip 
Define el área de recorte para la superficie. Cada superficie tiene una área de recorte 
activa. Este recorte es un rectángulo que representa a los pixels que se pueden modificar en 
una superficie. Toda la superficie se podrá modificar si se pasa None como área de recorte. 
El área de recorte está siempre limitada al área de la superficie en sí misma. Si el 
rectángulo de recorte es mas grande, entonces se encogerá para caber dentro de la 
superficie. 
sintaxis: 
Surface.set_clip(rect): return None 
Surface.set_clip(None): return None 
get_clip 
Obtiene el área de recorte actual de la superficie. Retorna una rectángulo que 
representa el área de recorte. La superficie siempre retornará un rectángulo válido que 
nunca estará por afuera de los bordes de la superficie. La superficie retornará el área 
completa de la misma si no se ha definido un área de recorte. 
sintaxis: 
Surface.get_clip(): return Rect 
subsurface 
Retorna una nueva superficie que comparte sus pixels con su superficie pariente. La 
nueva superficie se considera hija de la original. Las modificaciones a los pixels de cualquier 
de las dos superficies afectará a la otra. La información de la superficie como el área de 
recorte o los colores clave son únicos para cada superficie. 
La nueva superficie heredará la paleta, colores clave y configuración de transparencia 
de su padre. 
21
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Es posible tener cualquier número de sub-superficies y sub-sub-superficies de una 
superficie. También es posible tener una sub-superficie de la pantalla principal si el modo de 
video no está acelerado por software. 
sintaxis: 
Surface.subsurface(Rect): return Surface 
get_size 
Obtiene las dimensiones de una superficie. Retorna el ancho y alto de una superficie 
medida en pixels. 
sintaxis: 
Surface.get_size(): return (width, height) 
get_width 
Obtiene el ancho de una superficie. Retorna el ancho de una superficie medida en 
pixels. 
sintaxis: 
Surface.get_width(): return width 
get_height 
Obtiene la altura de una superficie.Retorna la altura de una superficies medida en 
pixels. 
sintaxis: 
Surface.get_height(): return height 
get_rect 
Obtiene el área rectangular de una superficie. Retorna un nuevo rectángulo que cubre 
la superficie entera. Este rectángulo siempre comenzará en la posición (0, 0) y tendrá el 
ancho y alto idéntico al tamaño de la imagen. 
Puede pasar valores clave como argumentos a esta función. Estos argumentos se 
aplicarán a los atributos del rectángulo antes de ser retornado. Un ejemplo podría ser 
mysurf.get_rect(center=(100,100)) para crear un rectángulo de la superficie con centro en la 
posición (100, 100). 
sintaxis: 
Surface.get_rect(**kwargs): return Rect 
22
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
get_bitsize 
Obtiene la profundidad de colores en bits del formato de pixel de la superficie. 
Retorna el número de bits utilizados para representar cada pixel. Este valor podría no 
coincidir exactamente con el número de bytes usados por pixel. Por ejemplo, una superficie 
de 15 bits requiere 2 bytes completos. 
sintaxis: 
Surface.get_bitsize(): return int 
get_bytesize 
Obtiene el número de bytes utilizados por pixel de la superficie. Retorna el número de 
bytes utilizados por pixel. 
sintaxis: 
Surface.get_bytesize(): return int 
get_flags 
Obtiene las opciones adicionales utilizadas por la superficie. Retorna el conjunto de 
propiedades de la superficie. Cada propiedad es un bit en la máscara de bits flags. Las 
propiedades habituales son HWSURFACE, RLEACCEL, SRCALPHA y SRCCOLORKEY. La lista 
completa de estas propiedades se puede encontrar en el archivo sdl_video.h. 
sintaxis: 
Surface.get_flags(): return int 
get_masks 
Obtiene la máscara de bits necesaria para convertir entre un color RGB y un color 
empaquetado. Retorna la máscara de bits que se utiliza para empaquetar cada color en un 
número entero. Este valor no se necesita para el uso normal de pygame. 
sintaxis: 
Surface.get_masks(): return (R, G, B, A) 
set_masks 
Define la máscara de bits necesaria para convertir entre un color RGB en un color en 
formato empaquetado. Esta función no se necesita para el uso habitual de pygame. 
sintaxis: 
Surface.set_masks( (r,g,b,a) ): return None 
23
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
get_buffer 
Obtiene un objeto buffer para los pixels de la superficie. Retorna un objeto buffer para 
los pixels de la superficie. El buffer se puede usar para acceder y manipular directamente los 
pixels. 
Este método bloquea y desbloquea la superficie de forma implícita. El bloqueo a la 
superficie se anulará una vez que el objeto BufferProxy sea eliminado. 
sintaxis: 
Surface.get_buffer(): return BufferProxy 
Otros metodos que pertenecen a este modulo que no fueron explicados por considerar 
que no son metodos de mucha relevancia o importancia. 
get_palette 
get_palette_at 
set_palette 
set_palette_at 
map_rgb 
unmap_rgb 
get_parent 
get_abs_parent 
get_offset 
get_abs_offset 
get_pitch 
get_shifts 
set_shifts 
get_losses 
get_bounding_rect 
Rect 
Pygame utiliza objetos Rect para almacenar y manipular areas rectangulares 
(Normalmente superficies). Un objeto Rect se puede crear a partir de una combinación de 
valores izquierda, arriba, ancho y alto. También se pueden crear desde objetos python que 
ya sean un objeto Rect o tengan un atributo de nombre rect. 
Cualquier función de pygame que requiera un argumento Rect también acepta 
cualquiera de eso valores para construir un rectángulo. Esto hace mas sencillo crear objetos 
Rect en el aire como argumentos a funciones. 
Los métodos de Rect que cambian la posición o el tamaño del rectángulo retornan una 
nueva copia del objeto con los cambios realizados. El rectángulo original no se modifica. 
Algunos métodos tiene una versión alternativa de estas funcionalidades pero que actúan 
sobre el objeto mismo y retornan None. Estos métodos alternativos se denotan con el sufijo 
“ip”. 
El objeto Rect tiene varios atributos virtuales que se pueden usar para mover ,alinear o 
simplemente consultar de un rectángulo. 
24
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
top, left, bottom, right 
topleft, bottomleft, topright, bottomright 
midtop, midleft, midbottom, midright 
center, centerx, centery 
size, width, height 
w,h 
Todos estos atributos se pueden consultar y asignar de la siguiente manera: 
rect1.right = 10 
rect2.center = (20, 30) 
rect.width = 140 #es equivalente a rect.w = 140 
Asignar un valor a size, width o height (tambien a w, h) cambia las dimensiones del 
rectángulo, todas las otras asignaciones mueven el rectángulo pero sin alterar el tamaño. 
Note que algunos atributos son números enteros y otros son pares de números enteros. 
Si un rectángulo tiene atributos width o height distintos de cero, entonces retornarán 
True por una consulta distinta de cero. Algunos métodos retornan un rectángulo con tamaño 
0 para representar un rectángulo inválido. 
Las coordenadas para objetos Rect siempre son números enteros. Los valores de 
tamaño se pueden programar para tener valores negativos, pero estos se consideran no 
válidos para la mayoría de las operaciones. 
Existen varios métodos para consultar colisiones con otros rectángulos. La mayoría de 
los contenedores de python se pueden utilizar para buscar colisiones entre varios rectángulos 
contra uno. 
El área cubierta por un rectángulo no incluye los pixeles que se encuentran en el 
límite inferior y derecho. Si el borde inferior de un rectángulo es igual al borde superior de 
otro rectángulo (por ejemplo rect1.bottom = rect2.top), los dos ocupan la misma linea en 
pantalla pero no se superponen, y la consulta a rect1.colliderect(rect2) retornará False. 
sintaxis: 
pygame.Rect(left, top, width, height): return Rect 
pygame.Rect((left, top), (width, height)): return Rect 
pygame.Rect(object): return Rect 
move 
Retorna una copia (copia no referencia) del rectángulo que está desplazado en la 
cantidad indicada. Los argumento dx e dy pueden ser cualquier valor entero, positivo o 
negativo. 
sintaxis 
Rect.move(dx, dy): return Rect 
move_ip 
permite mover al rectangulo las cantidades dx, dy. afecta al objeto receptor. 
25
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
sintaxis: 
Rect.move_ip(dx, dy): return None 
clamp 
Retorna una nuevo rectángulo desplazado para estar completamente dentro de otro 
rectángulo dado como parámetro. Si el rectángulo es demasiado grande para caber dentro 
del otro rectángulo, se posicionará en el mismo centro que el rectángulo del argumento, pero 
su tamaño no se cambiará. 
sintaxis: 
Rect.clamp(Rect): return Rect 
clamp_ip 
Similar al método clamp, pero afecta al objeto receptor. 
sintaxis: 
Rect.clamp_ip(Rect): return None 
clip 
Recorta un rectángulo dentro de otro. Retorna un nuevo rectángulo que se recorta 
para estar completamente dentro de otro indicado por parámetro. Si los dos rectángulos no 
están en colisión, se retornará un rectángulo de tamaño 0. 
sintaxis: 
Rect.clip(Rect): return Rect 
union 
Retorna un nuevo rectángulo que cubre completamente el área de otros dos 
rectángulos dados como parámetro. Pueden haber áreas dentro del nuevo rectángulo que no 
estén en el área de los originales. 
sintaxis: 
Rect.union(Rect): return Rect 
union_ip 
Similar al método union, pero que afecta al rectángulo receptor. 
sintaxis: 
Rect.union_ip(Rect): return None 
26
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
unionall 
Retorna la unión de un rectángulo con una secuencia de varios rectángulos. 
sintaxis: 
Rect.unionall(Rect_sequence): return Rect 
unionall_ip 
La unión de varios rectángulos, afectando al objeto receptor. Similar al método unionall. 
sintaxis: 
Rect.unionall_ip(Rect_sequence): return None 
fit 
Cambia el tamaño o mueve el rectángulo pero respetando su aspecto. Retorna un 
nuevo rectángulo desplazado y redimensionado para caber dentro de otro. Se preserva la 
proporción de aspecto del rectángulo original, por lo tanto el nuevo rectángulo puede ser 
mas pequeño que el ancho o alto del rectángulo final. 
sintaxis: 
Rect.fit(Rect): return Rect 
normalize 
Corrige los tamaños negativos. Invertirá el ancho o alto de un rectángulo si tiene 
algún tamaño negativo. El rectángulo conservará la misma posición, pero con los lados 
alternados. 
sintaxis: 
Rect.normalize(): return None 
contains 
Consulta si un rectángulo está dentro de otro. Retorna True cuando el argumento está 
completamente dentro del objeto receptor. 
sintaxis: 
Rect.contains(Rect): return bool 
collidepoint 
Consulta si un punto está dentro de un rectángulo. Retorna True si el punto dado está 
dentro del rectángulo. Un punto sobre el costado derecho o inferior del rectángulo no se 
27
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
considera que está dentro del rectángulo. 
sintaxis: 
Rect.collidepoint(x, y): return bool 
Rect.collidepoint((x, y)): return bool 
colliderect 
onsulta si dos rectángulos están en contacto Retorna True si cualquier parte de alguno 
de los rectángulos están en contacto (excepto los bordes superior+inferior o 
derecha+izquierda), es el metodo que normalmente se usara en el control de coliciones 
entre Sprites. 
sintaxis: 
Rect.colliderect(Rect): return bool 
collidelist 
Consulta si un rectángulo entra en contacto con una lista. onsulta si el rectángulo colisiona 
con otro de una secuencia de rectángulos. Se retorna el índice de la primer colisión que se 
encuentra. Se retorna el índice -1 si no se encuentran colisiones. 
sintaxis: 
Rect.collidelist(list): return index 
collidelistall 
dem a collidelist solo que retorna una lista con el indice de todos los rectangulos con 
los que coliciona: 
sintaxis: 
Rect.collidelistall(list): return indices 
collidedict, collidedictall 
Son Similares a collidelist y collidelistall en funcionamiento solo que estos toman 
como argumento un dicionario con rectangulos. 
sintaxis: 
Rect.collidedict(dict): return (key, value) 
Rect.collidedictall(dict): return [(key, value), ...] 
28
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Mi Primer Juego (Feo :P) un Pong 
Introducion 
Aunque este primer modulo apunta mas a aprender a usar la API PyGame para 
programar juegos y el curso en si se llama Programacion de Juegos con PyGame que 
seria de un curso de juego si lo unico que se esta haciendo es explicar que hacen los 
modulos a, b ,etc.. bueno ya explique la mayoria de los modulos importantes por lo que 
podemos avanzar un nivel mas y empezar a programar juegos, y que seria de un curso de 
programacion de juegos si como primer juego a programar no te colocaran un Pong, no es 
por que solo lo hagan en todos los cursos, yo lo hago mas como tributo al primer juego que 
revoluciono el mundo de las computadoras. 
En todo desarrollo de un videojuego siempre suelen trabajar un GRUPO de personas, 
unas que llevaran la parte grafica, otras que llevaran la parte de programacion, otras que 
llevaran el guion, otras que llevaran la parte de sonido... Lo que pretendo decir es que tu no 
tienes porque saber de todo porque normalmente si te dedicas a esto trabajaras con otra 
gente y no tu solo, por lo que si eres programador, buscate a alguien que sea grafista o sepa 
dibujar para que te haga unos buenos graficos y no te pases horas y horas intentando 
dibujar una cosilla cuando hay gente que la va a hacer mucho mejor y en mucho menos 
tiempo u sino busca en internet ya que hay varios Sitios donde te puedes bajar los sprites. 
Yo soy programador y no conozco a ningun grafista por lo que los graficos que 
utilizar‚ seran sacados de internet o dibujados por mi por lo que la calidad grafica no va ser 
excesiva (mas bien decepcionante, no tanto use formas basicas y un poco de degrado en 
Inskape para crearlas) enn fin haremos‚ lo que podamos. 
La Idea 
Como ya se menciono arriba vamos a hacer un juego sencillo llamdo pong o ping-pong, 
tenis o como quieran llamarle, en fin es un sencillo juego clasico, lo tomo como primer 
juego por ser dentro de todo sencillo de programar. Para los que no tengan idea de como es 
aca les dejo un captura de pantalla. 
El Objectivo 
El Objectivo del Juego va a ser marcar un gol, el primero de los participantes que 
meta 3 goles, sera declarado ganador y el juego acabara. Ahora analicemos los elementos 
que intervienen en el Juego: 
Paleta o Raqueta 
solo se podra mover en forma vertical entre los limites inferiores y superiores. 
Pelota 
Tendra un movimiento rectilineo (se movera en linea recta sin hacer ninguna curva 
estraña), aumentara su velocidad a medida de que rebota contra las raquetas, En funcion de 
29
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
la posicion en que golpee en las raquetas tomara una trayectoria u otra, es decir si se golpea 
con la parte superior tendera a ir hacia arriba y si es en la inferior tendera a ir hacia abajo. 
Los Graficos 
Como vimos es un juego sencillo que requiere solo 3 graficos (paleta_1, paleta_2 y 
pelota), a la cancha la dibujaremos mediante figuras basicas. aparte de eso necesitaremos 2 
imagenes mas 1 para la pantalla de presentacion y otra para el menu (aunque esa parte la 
realizaran ustedes como ejercicio). bueno por el momento yo me encargare de los graficos 
de las raquetas y las pelotas, para acelerar esto las dibuje mediante Inkscape usando formas 
basicas y algo de degradado. 
pueden verlas en la carpeta 'pong/imagenes/' 
Armazon Principal 
En Nuestro Juego deberiamos notar 2 bucles bien definidos el primero y mas externo 
visualizar la pantalla de presentacion hasta que se pulsa una tecla y en funcion de la tecla 
pulsada hace dos cosas: Empieza la partida o sale del juego. En el primer caso vemos el 
segundo bucle, que es la duracion de la partida, estara en ‚ el hasta que uno de los 
jugadores obtenga 3 puntos o se pulse la tecla ESCAPE. 
Por lo tanto y usando nuestra plantilla basica para aplicaciones en pygame (al menos 
yo lo hago siempre ustedes haganlo como deseen :P), los datos de pantallas y otras 
constanstes que utilizaremos a lo largo del juego estaran definidos en el fichero 
constantes.py otro modulo que usare y que notaran que solo posee un grupo de constantes 
que representan colores: 
#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import pygame 
from pygame.locals import * 
from colores import * 
from constantes import * 
def dibuja_cancha(surface): 
""" 
funcion que permite dibujar la cancha del juego utilizando funciones 
de dibujo basicas 
""" 
pygame.draw.rect(surface, VERDE_MEDIO, ((10,10),(ANCHO-20, ALTO-20)), 0) 
pygame.draw.rect(surface, BLANCO, ((30,30),(ANCHO-60, ALTO-60)), 2) 
pygame.draw.line(surface, BLANCO, (ANCHO/2,30), (ANCHO/2, ALTO-30), 2) 
def main(): 
""" 
funcion principal donde se implementara el Juego 
""" 
30
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
pygame.init() 
screen = pygame.display.set_mode(RESOLUCION) 
pygame.display.set_caption('Ping Pang Pong 0.0.1') 
titulo = pygame.image.load('imagenes/fondo.png').convert_alpha() 
jugando = False #bandera que avisa si se esta jugando la partida 
loop = True 
while loop: 
#screen.fill(NEGRO) 
screen.blit(titulo, (0, 0)) 
teclas = pygame.key.get_pressed() 
#si se preciona la tecla escape Finaliza el Juego del juego 
if teclas[K_ESCAPE]: 
loop = False 
jugando = False 
#estando en el bucle principal iniciara el juego 
elif teclas[K_RETURN]: 
jugando = True 
#loop de la partida 
while jugando: 
screen.fill(NEGRO) 
dibuja_cancha(screen) 
pygame.display.flip() 
for evento in pygame.event.get(): 
if evento.type == pygame.QUIT: 
loop = False 
pygame.display.flip() 
for evento in pygame.event.get(): 
if evento.type == pygame.QUIT: 
loop = False 
#finalizamos el juego antes de salir 
pygame.quit() 
if __name__ == '__main__': 
main() 
(vease el codigo en pong/paso_01.py) 
Como vemos ej juego posee una extructura sencilla, se destaca la utilizacion de 
modulo pygame.key para captura del teclado, otro punto importante es que a la cancha la 
dibujamos usando funciones de dibujo basicas. Por el momento nuestro juego no esta 
completo ya que solo tenemos el menu pero seguiremos avanzando. Una primera captura 
para ver el menu y la pantalla de juego: 
31
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
menu 
pantalla de juego 
Las Paletas o Raquetas 
En esta secion vamos a crear 1 clase paleta base y de ella derivaremos las clases que 
permitiran a los jugadores manejarlas, opcionalmente podriamos derivar una clase para 
implementar la AI del juego. En fin vamos a usar algunas herramientas de las que 
aprendimos hasta ahora de pygame. 
32
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
La Clase base Paleta: 
Nuestra clase base necesita tener todo lo necesario para manejar las paletas y las 
imagenes y demas objectos que las componen, ademas devemos definir algunos metodos 
que nos permitan controlarla, para no complicar la sintaxis definiremos las paletas en otro 
archivo distinto llamado paleta.py aqui coloco el constructor de la clase, el metodo de 
reinicio, el metodo para controlar que la paleta no se salga de pantalla, el metodo que 
permitira moverla, y el metodo para dibujarla. Ademas agregaremos algunas constantes 
mas: 
FRAME_RATE = 30 #cantidad de cuadros por segundo 
PALETA_SPEED = 5 #velocidad de la paleta 
MARGEN_SUP = 30 #limitante del margen superior de la cancha 
MARGEN_INF = ANCHO - 30 #limitante del margen inferior de la cancha 
ISO_ARRIBA = 0 #constante que define la direcion hacia arriba 
ISO_ABAJO = 1 #constante que define la direcion hacia abajo 
class Paleta: 
""" 
Clase base para definir las raquetas o paletas del juego 
""" 
def __init__(self, img): 
""" 
constructor de la clase, el unico parametro que recibe es el 
de la imagen que se usara. 
""" 
#cargamos la imagen y la convertimos (yo use unos *.png) para 
#representar todas las imagenes del juego 
self.imagen = pygame.image.load(img).convert_alpha() 
#obtenemos un objecto rect a partir de la imagen, el cual usaremos 
#para manipularla 
self.rect = self.imagen.get_rect() 
#variable que almacenara los goles del jugador 
self.puntaje = 0 
def init(self, pos): 
""" 
metodo que usaremos para inicializar las paletas antes de comensar 
cada partida nueva 
pos : tupla que representa la posicion (x,y) donde se centrara 
la imagen de la paleta y el rectangulo que maneja las coliciones 
""" 
self.rect.center = pos 
self.self.puntaje = 0 #reiniciamos la puntuacion 
def mover(self, dir): 
""" 
metodo que permite mover la paleta, tanto hacia arriba como hacia 
abajo, o arriba. 
dir : parametro donde se especifica la direcion los parametros 
validos son: ISO_ARRIBA o ISO_ABAJO 
""" 
if dir == ISO_ARRIBA: 
self.rect.y -= PALETA_SPEED 
33
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
elif dir == ISO_ABAJO: 
self.rect.y += PALETA_SPEED 
def controla(self): 
""" 
metodo que se usa para controlar que la paleta no se salga de 
la pantalla 
""" 
if self.rect.y < MARGEN_SUP: 
self.rect.y = MARGEN_SUP 
elif (self.rect.y + self.rect.h) > MARGEN_INF: 
self.rect.y = MARGEN_INF 
def update(self): 
pass 
def drawn(self, surface): 
""" 
metodo para dibujar la paleta sobre una superficie, normalmente 
esa superficie sera la pantalla principal. 
""" 
surface.blit(self.imagen, self.rect) 
Los Jugadores (Herenciando la Clase Paleta) 
Como habran notado el metodo update() (Actualizar) esta vacio, y eso se deve a que 
como mencionamos anteriormente se herenciara la clase paleta para definir las clases que 
manejaran los jugadores y alli es donde definiremos dicho metodo, las paletas solo necesitan 
ser controladas por 2 teclas cada una para controlar la paleta del jugador 1 usaremos las 
teclas (A;B) y para controlar la paleta del jugador 2 usaremos las teclas direcionales 
(ARRIBA;ABAJO). 
class Jugador1(Paleta): 
""" 
Clase que manipulara la paleta del jugador 1 
""" 
def update(self): 
""" 
metodo que permitira actualizar la posicion de las paletas 
""" 
#capturo todas las teclas que hayan sido pulsadas 
teclas = pygame.key.get_pressed() 
#mover arriba 
if teclas[K_q]: 
self.mover(ISO_ARRIBA) 
#mover abajo 
elif teclas[K_q]: 
self.mover(ISO_ABAJO) 
34
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
class Jugador2(Paleta): 
""" 
Clase que manipulara la paleta del jugador 2 
""" 
def update(self): 
""" 
metodo que permitira actualizar la posicion de las paletas 
""" 
#capturo todas las teclas que hayan sido pulsadas 
teclas = pygame.key.get_pressed() 
#mover arriba 
if teclas[K_UP]: 
self.mover(ISO_ARRIBA) 
#mover abajo 
elif teclas[K_DOWN]: 
self.mover(ISO_ABAJO) 
Ahora que tenemos implementadas las clases que manejaran las paletas (para mas 
detalle vease pong/paleta.py) procedamos a importarlas y probarlas junto con el esqueleto 
de juego que habiamos diseñado con anterioridad. 
#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import pygame 
from pygame.locals import * 
from colores import * 
from paleta import Jugador1, Jugador2 
from constantes import * 
def dibuja_cancha(surface): 
""" 
funcion que permite dibujar la cancha del juego utilizando funciones 
de dibujo basicas 
""" 
pygame.draw.rect(surface, VERDE_MEDIO, ((10,10),(ANCHO-20, ALTO-20)), 0) 
pygame.draw.rect(surface, BLANCO, ((30,30),(ANCHO-60, ALTO-60)), 2) 
pygame.draw.line(surface, BLANCO, (ANCHO/2,30), (ANCHO/2, ALTO-30), 2) 
def main(): 
""" 
funcion principal donde se implementara el Juego 
""" 
pygame.init() 
screen = pygame.display.set_mode(RESOLUCION) 
reloj = pygame.time.Clock() #temporizador del juego 
pygame.display.set_caption('Ping Pang Pong 0.0.1') 
#imagen del titulo 
titulo = pygame.image.load('imagenes/fondo.png').convert_alpha() 
#instanciamos los objectos que manejara las paletas 
35
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
pal_1 = Jugador1('imagenes/paleta_a.png') 
pal_2 = Jugador2('imagenes/paleta_b.png') 
jugando = False #bandera que avisa si se esta jugando la partida 
loop = True 
while loop: 
reloj.tick(FRAME_RATE) 
screen.blit(titulo, (0, 0)) 
teclas = pygame.key.get_pressed() 
#si se preciona la tecla escape Finaliza el Juego del juego 
if teclas[K_ESCAPE]: 
loop = False 
jugando = False 
#estando en el bucle principal iniciara el juego 
elif teclas[K_RETURN]: 
jugando = True 
#inicializamos las paletas 
pal_1.init((30, ALTO / 2)) 
pal_2.init((ANCHO - 30, ALTO/2 )) 
#loop de la partida 
while jugando: 
#~ reloj.tick(FRAME_RATE) 
screen.fill(NEGRO) 
dibuja_cancha(screen) 
#actualizamos los objectos 
pal_1.update() 
pal_2.update() 
#los dibujamos sobre la pantalla 
pal_1.drawn(screen) 
pal_2.drawn(screen) 
pygame.display.flip() 
for evento in pygame.event.get(): 
if evento.type == pygame.QUIT: 
loop = False 
pygame.display.flip() 
for evento in pygame.event.get(): 
if evento.type == pygame.QUIT: 
loop = False 
#finalizamos el juego antes de salir 
pygame.quit() 
if __name__ == '__main__': 
main() 
(vease pong/paso_02.py) 
36
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
Observar que ademas de agregar los 2 objectos paletas, en el bloque que pregunta si 
se preciono la tecla enter colocamos los metodos para resetear la poscicion de cada paleta, 
mas adelante agregaremos el metodo para resetear la pelota y por ultimo dentro del loop de 
juego introducio los metodos update() y drawn() para cada paleta, como vimos dichos 
metodos se encargan de mover y dibujar respectivamente las paletas. otro elemento agrega 
es el temporizador que aunque no he explicado todavia el modulo ya deven tener una idea 
de como funciona. Aca una captura de nuestro juego hasta el momento. 
La Pelota 
Bueno por lo visto el juego ya esta tomando forma solo nos esta faltando implementar 
el control de la pelota y sus coliciones con las paletas que es lo que trataremos en esta 
ultima parte de este capitulo. Programar la pelota es la parte mas complicada del juego por 
eso la deje para el final del mismo ya que tenemos que hacer que se mueva, cambie de 
direcion, aumente su velocidad, controlar si hace gol etc, lo bueno de esto es que no 
usaremos ninguna cosa estraña solo un poco de matematica simple. la clase aparte de 
contener la imagen y el rectangulo que la representara tendra los atributos x,y que 
representaran su poscion real (el rectangulo representara su posicion aproximada) y dos 
incrementadores dx y dy que definiran el incremento en cada una de las variables, los 
metodos tendran los mismos nombres que en las paletas pero su funcionamiento y 
argumentos diferiran un poco. Como siempre agregamos nuevas constantes: 
class Pelota: 
""" 
Clase que se utilizara para manejar la pelota. 
""" 
37
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
def __init__(self, imagen): 
""" 
constructor de la clase pelota el unico parametro que pide es 
la imagen que se usara para representar la pelota 
""" 
self.imagen = pygame.image.load(imagen).convert_alpha() 
self.rect = self.imagen.get_rect() 
#posicion exacta del centro de la pelota dentro de la pantalla 
self.x = 0.0 
self.y = 0.0 
#imcrementos en las direciones x,y 
self.dx = 0.0 
self.dy = 0.0 
def reset(self): 
""" 
reseteala posicion de la pelota en la pantalla, normalmente esta 
deberia iniciar en el centro de la misma 
""" 
#centro la pelota en el centro de la pantalla 
self.rect.center = (ANCHO / 2, ALTO / 2) 
self.x = float(ANCHO / 2) 
self.y = float(ALTO / 2) 
#calculo el incremento inicial de dy 
if random.random() > 0.5: 
self.dy = +1.5 
else: 
self.dy = -1.5 
#calculo el incremento inicial de dx 
if random.random() > 0.5: 
self.dx = +1.5 
else: 
self.dx = -1.5 
def controla(self, pal_a, pal_b): 
""" 
Esto no se deveria hacer (digo por lo de pasar una referencias a 
de las paletas ya que esto crea un enlace fuerte y ello se 
considera malo en la programacion orientada a objectos). En fin 
este metodo se encargara de controlar que la pelota no se salga 
de pantalla si choca con los bordes o las paletas ademas de 
incrementar su velocidad y cambiar su direcion. 
""" 
#pregunta si choco con la paleta A que esta a la izquierda 
if self.rect.colliderect(pal_a.rect): 
#compruebo si choco de la mitad para arriba 
if self.rect.centery < pal_a.rect.centery: 
self.dy -= 0.5 
#sino choco con la parte de abajo 
else: 
38
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
self.dy += 0.5 
#por ultimo invierto la direcion x y aumento la velocidad 
self.dx -= 0.5 
self.dx = -self.dx 
#ahora pregunta si choco con la paleta B que esta a la izquierda 
if self.rect.colliderect(pal_b.rect): 
#compruebo si choco de la mitad para arriba 
if self.rect.centery < pal_a.rect.centery: 
self.dy -= 0.5 
#sino choco con la parte de abajo 
else: 
self.dy += 0.5 
#por ultimo invierto la direcion x y aumento la velocidad 
self.dx += 0.5 
self.dx = -self.dx 
#ahora pregunto si choco con algunas de las paredes y cambio el 
#signo del incremento de y osea dy 
if self.rect.y < MARGEN_SUP or (self.rect.y + self.rect.h) > 
MARGEN_INF: 
self.dy = -self.dy 
#ahora por ultimo compruevo si se hizo un gol e incrementos el 
contador 
#goles del jugador rival y ademas hay que reiniciar la posicion de la 
#pelota 
#si la pelota toca el borde izquierdo de la pantalla implica que el 
#jugador B hizo un gol 
if self.rect.x < 0: 
# nota: los objectos son pasados por referencia por lo que la 
#siguiente operacion no se perdera 
pal_a.puntaje += 1 
self.reset() 
#si la pelota toca el borde izquierdo de la pantalla implica que el 
#jugador A hizo un gol 
elif (self.rect.x + self.rect.w) > ANCHO: 
# nota: los objectos son pasados por referencia por lo que la 
#siguiente operacion no se perdera 
pal_b.puntaje += 1 
self.reset() 
#en el titulo de la ventana colocaremos el puntaje de cada uno 
pygame.display.set_caption('Azul %d - Rojo %d' %(pal_a.puntaje, 
pal_b.puntaje)) 
def update(self, pal_a, pal_b): 
""" 
actualiza la posicion, velocidad y direcion y ademas devuelve 
el estado del juego: 
0 - el juego sigue 
1 - gano el jugador A 
39
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
2 - gano el jugador B 
""" 
self.controla(pal_a, pal_b) 
#actualizo la posicion de la pelota 
self.x += self.dx 
self.y += self.dy 
self.rect.center = int(self.x), int(self.y) 
#pregunto cuantos goles tiene cada jugador, si alguno tiene 3 o mas 
#retorno 1 o 2 avizando que el juego termino caso contrario devuelvo 0 
if pal_a.puntaje >= 3: 
return 1 
elif pal_b.puntaje >= 3: 
return 2 
else: 
return 0 
def drawn(self, surface): 
""" 
metodo para dibujar la pelota sobre una superficie, normalmente 
esa superficie sera la pantalla principal y ademas la pelota sera 
el ultimo objecto que se dibuje. 
""" 
surface.blit(self.imagen, self.rect) 
Bueno por ultimo hay que modificar el esqueleto principal y agregar la pelota. 
Despues de tanto sufrimiento tenemos un Juego Completo. Aca pueden ver una captura de 
pantalla del juego corriendo para jugarlo y ver el codigo del juego en su version final vea o 
ejecute el script pong/final.py 
Antes de de terminar: El juego se llama pong pero mientras escribia y documentaba 
el codigo de este juego se me ocurrio ponerle Ping, Pang, Pong el nombre no lo invente yo, 
40
Curso de: Programacion de Juegos con PyGame 
Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 
por si no saben era el nombre del Equipo de Bolos (Nada que ver con esto que 
supuestamente es un juego de tenis) de Homero en un capitulo de Los Simpson. Bue solo 
queria aclarar eso. 
Saludos 
41

Capitulo 4

  • 1.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Programación de Juegos con PyGame Capitulo 4: Modulos Key, Image, Surface, Rect 1
  • 2.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com pygame.key Modulo que permite gestionar el disposito del teclado (Si no saben cual es el teclado miren hacia abajo y lo veran :P) Como ya vimos en el capitulo anterior la cola de eventos obtiene eventos como pygame.KEYDOWN y pygame.KEYUP cuando se pulsan o sueltan las teclas del teclado respectivamente. Cada evento tiene una atributo llamado key que es un identificador en entero que representa cada tecla del teclado. El evento pygame.KEYDOWN tiene un atributo adicional llamado unicode, y otro scancode. unicode representa un único caracter que es la traducción completa del caracter ingresado por teclado. Teniendo en cuenta las teclas de composición y mayúsculas. scancode representa el código de tecla específico de la plataforma. Este código podría ser diferente de un teclado a otro, aunque es útil para la selección de teclas raras como las teclas multimedia. Existen muchas constantes de teclado que se utilizadan para representar teclas. La siguiente es una lista con todas esas constantes: Constante ASCII Nombre habitual K_BACKSPACE b backspace K_TAB t tab K_CLEAR clear K_RETURN r return K_PAUSE pause K_ESCAPE escape K_SPACE space K_EXCLAIM ! exclaim K_QUOTEDBL ” quotedbl K_HASH # hash K_DOLLAR $ dollar K_AMPERSAND & ampersand K_QUOTE quote K_LEFTPAREN ( left parenthesis K_RIGHTPAREN ) right parenthesis K_ASTERISK * asterisk K_PLUS + plus sign K_COMMA , comma K_MINUS - minus sign K_PERIOD . period K_SLASH / forward slash K_0 0 0 K_1 1 1 K_2 2 2 K_3 3 3 K_4 4 4 K_5 5 5 K_6 6 6 K_7 7 7 K_8 8 8 K_9 9 9 K_COLON : colon K_SEMICOLON ; semicolon K_LESS < less-than sign K_EQUALS = equals sign K_GREATER > greater-than sign 2
  • 3.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com K_QUESTION ? question mark K_AT @ at K_LEFTBRACKET [ left bracket K_BACKSLASH backslash K_RIGHTBRACKET ] right bracket K_CARET caret K_UNDERSCORE _ underscore K_BACKQUOTE ` grave K_a a a K_b b b K_c c c K_d d d K_e e e K_f f f K_g g g K_h h h K_i i i K_j j j K_k k k K_l l l K_m m m K_n n n K_o o o K_p p p K_q q q K_r r r K_s s s K_t t t K_u u u K_v v v K_w w w K_x x x K_y y y K_z z z K_DELETE delete K_KP0 keypad 0 K_KP1 keypad 1 K_KP2 keypad 2 K_KP3 keypad 3 K_KP4 keypad 4 K_KP5 keypad 5 K_KP6 keypad 6 K_KP7 keypad 7 K_KP8 keypad 8 K_KP9 keypad 9 K_KP_PERIOD . keypad period K_KP_DIVIDE / keypad divide K_KP_MULTIPLY * keypad multiply K_KP_MINUS - keypad minus K_KP_PLUS + keypad plus K_KP_ENTER r keypad enter K_KP_EQUALS = keypad equals K_UP up arrow K_DOWN down arrow K_RIGHT right arrow K_LEFT left arrow K_INSERT insert K_HOME home 3
  • 4.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com K_END end K_PAGEUP page up K_PAGEDOWN page down K_F1 F1 K_F2 F2 K_F3 F3 K_F4 F4 K_F5 F5 K_F6 F6 K_F7 F7 K_F8 F8 K_F9 F9 K_F10 F10 K_F11 F11 K_F12 F12 K_F13 F13 K_F14 F14 K_F15 F15 K_NUMLOCK numlock K_CAPSLOCK capslock K_SCROLLOCK scrollock K_RSHIFT right shift K_LSHIFT left shift K_RCTRL right ctrl K_LCTRL left ctrl K_RALT right alt K_LALT left alt K_RMETA right meta K_LMETA left meta K_LSUPER left windows key K_RSUPER right windows key K_MODE mode shift K_HELP help K_PRINT print screen K_SYSREQ sysrq K_BREAK break K_MENU menu K_POWER power K_EURO euro El teclado tambien tiene una lista de estados de combinaciones que pueden ser montados a través de una lógica binaria. KMOD_NONE KMOD_LSHIFT KMOD_RSHIFT KMOD_SHIFT KMOD_CAPS KMOD_LCTRL KMOD_RCTRL KMOD_CTRL KMOD_LALT KMOD_RALT KMOD_ALT KMOD_LMETA KMOD_RMETA KMOD_META KMOD_NUM 4
  • 5.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com KMOD_MODE get_focused Esta función devolvera verdadero cuando la ventana de visualización contiene el foco del teclado. Si se necesita que la ventana no pierda el foco del teclado, se puede utilizar pygame.event.set_grab para capturar todas las entradas de teclado. sintaxis: pygame.key.get_focused() -> return bool get_pressed Devuelve una secuencia de valores lógicos (booleans) representando el estado de cada tecla en el teclado. Utilice los valores de constante de tecla como índice de la secuencia. Un valor verdadero significa que el botón esta presionado. Tenga en cuenta que obtener la lista de las teclas pulsadas con esta función no es la forma apropiada de gestionar la entrada de texto por parte del usuario. No hay forma de conocer el orden de las teclas pulsadas, y las pulsaciones muy rápidas de teclas pueden pasar desapercibidas entre dos llamadas a get_pressed. Tampoco hay forma de trasladar las teclas pulsadas a un valor de caracter completamente imprimible por lo que para un mejor manejo de las entradas de teclado por parte de usuario se recomienda realizar un manejo mediante la cola de eventos con los eventos pygame.KEYDOWN. sintaxis: pygame.key.get_pressed() -> return bools get_mods Devuelve un entero representando una mascara con todos las teclas que estan siendo presionadas. Utilizando lógica binaria puedes verificar si una tecla como shift está pulsada, el estado de capslock y más. sintaxis: pygame.key.get_mods() -> return int set_mods Crea una mascara binaria con las constantes de las teclas que deseas imponer sobre tu programa. sintaxis: pygame.key.set_mods(int) -> return None set_repeat 5
  • 6.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Cuando la funcionalidad de repetición de teclas está habilitada en el teclado, las teclas que quedan presionadas generan múltiples eventos de tipo pygame.KEYDOWN. El parrámetro delay (tiempo de retraso) es el número de milisegundos transcurridos antes de enviar el primer evento. Luego el resto de los eventos se enviarán en ese intervalo de milisegundos. Si no especifica argumentos la repetición de teclas quedará deshabilitada. sintaxis: pygame.key.set_repeat() -> return None pygame.key.set_repeat(delay, interval) -> return None Nota: Cuando se inicializa pygame la repetición de teclas está deshabilitada. get_repeat Esta función cumple una tarea similar a set_repeat, solo que nos muestra el intervalo de milisegundos en lugar de definirlo. sintaxis: pygame.key.get_repeat() -> return (delay, interval) name Devuelve el nombre descriptivo de la constante del telclado, ya que no todas los caracteres se pueden representar (en realidad todos los caracteres se pueden representar mediente su codigo). sintaxis: pygame.key.name(key) -> return string pygame.image Es el Módulo de pygame encargador de la transferencia (leer/grabar imagenes desde ficheros) de imagen. El módulo image contiene funciones para leer y grabar imágenes, como así también para transferir superficies a formatos accesibles para otros paquetes. Note que no hay una clase Image, todas la imagenes se cargan como objetos Surface. La clase Surface es la que se encarga de su manipulacion, la misma permite operaciones como dibujar lineas, pintar pixeles, capturar regiones, etc. El módulo image es una dependencia importante de pygame, aunque el soporte extendido a formatos es opcional. Por defecto solo puede cargar imágenes BMP sin compresión; pero cuando pygame se provee con soporte de imágenes completo, la función pygame.image.load() puede interpretar los siguientes formatos: 6
  • 7.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com JPG PNG GIF(sin animación) BMP PCX TGA (sin compresión) TIF LBM (y PBM) PBM (y PGM, PPM) XPM La funcionalidad de guardado imágenes solo soporta un conjunto reducido de estos formatos. Puede grabar o almacenar imagenes en los siguientes formatos: BMP TGA PNG JPEG Aun asi la ide de PyGame no es especificamete cargar imagenes, por ello el grupo reducido de formatos de imagenes soportados por la API para cargar y guardar imagenes desde ficheros, aun asi no estamos del todo perdidos ya que la funcionalidad de este modulo se puede extender utilizando la liberia PIL junto con PyGame. load Funcion para cargar una nueva imagen desde un archivo. se puede pasar como parametro tanto la ruta del archivo como un objecto file de python. Pygame determina automaticamente el tipo de formato archivo (por ejemplo, si es un gif o bmp) y generará un nuevo objeto Surface de acuerdo a esa información. En algunos casos necesitará conocer la extensión del archivo (por ejemplo las imagenes GIF deberían terminar en ”.gif”). Si utiliza un objeto archivo en formato crudo, seguramente necesitará enviar el nombre original del archivo como el argumento namehint. La superficie retornada contendrá el mismo formato de color, colores clave o transparencia alpha que el fichero del que proviene. Generalmente cuando cargue imagenes que uilicen algun algoritmo de comprecion o canal alfa devera llamar al metodo Surface.convert() sin argumentos para crear una copia que se pueda imprimir mas rápido en pantalla. Para imágenes con transparencia alpha, como en las imágenes .png, use el método convert_alpha() luego de cargar la imágen, así la superficie resultante también tendrá transparencia. Tener en Cuenta que PyGame no siempre tendrá soporte para todos los formatos. Como mínimo soportará el formato BMP sin compresión. Si pygame.image.get_extended() retorna True, usted podría ser capaz de cargar la mayoría de las imágenes, incluyendo png, jpg y gif. sintaxis: pygame.image.load(filename): return Surface pygame.image.load(fileobj, namehint=""): return Surface 7
  • 8.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com save Permite guardar o almacenar una imagen en el disco. Como ya se mencion pygame solo puede guardar la superficie como algunos de los posibles tipos de formato de imagen BMP, TGA, PNG o JPEG. Si la extensión del nombre de archivo no se reconoce, se utilizará por defecto .TGA. Tanto los formatos TGA como BMP generan archivos sin compresión. sintaxis: pygame.image.save(Surface, filename): return None get_extended Consulta si se pueden cargar los formatos de imagen extendidos. Si el paquete de pygame fue construido (Compilado Recordar que PyGame aunque extiende muchas cosas internamente sigue siendo un envoltorio de la Libreria SDL) con los formatos de imagen extendido esta función retornará True. Aún así no es posible determinar que formatos estarán disponibles, generalmente en la mayoria de los paquetes podrá manipular todos los formatos. sintaxis: pygame.image.get_extended(): return bool tostring Transfiere una imagen a una cadena de texto string. Genera una cadena que pude transferirse con el método fromstring en otros paquetes de imágenes de python. Algunos paquetes de imagen de python prefieren sus imágenes en el formato “de abajo hacia arriba”, por ejemplo el paquete PyOpenGL). Se invertirá verticalmente la cadena retorno si envía True como valor para el argumento flipped. El argumento format es una cadena con uno de los siguiente valores. Note que solo las superficies de 8 bits pueden usar el formato “P”. Los otros formatos funcionarán con cualquier superficie. Ademas note que otros paquetes de imágenes de python suportan mas formatos que pygame. Cadena Formato Superficie P superficies de 8 bits con paleta. RGB imagen de 24 bits. RGBX imagen de 32 bits con un espacio sin utilizar. RGBA imagen de 32 bits con un canal alpha (transparencia). ARGB imagen de 32 bits con canal alpha en primer lugar. RGBA_PREMULT imagen de 32 bits bajo la escala del canal alpha. ARGB_PREMULT imagen de 32 bits bajo la escala del canal alpha en primer lugar. sintaxis: 8
  • 9.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com pygame.image.tostring(Surface, format, flipped=False): return string fromstring Genera una nueva superficie desde una cadena. Esta función toma argumentos similares a pygame.image.tostring(). El argumento size es una tupla con números que representan el ancho y alto. Puede destruir la cadena original una vez que la nueva superficie se ha creado. El formato y tamaño de la imagen debe coincidir exactamente con el mismo tamaño de la cadena. Se lanzará una excepción en caso contrario. sintaxis: pygame.image.fromstring(string, size, format, flipped=False): return Surface frombuffer Genera una nueva superficie que comparte los datos dentro de una cadena. Genera una nueva superficie que comparte los datos de los pixeles directamente desde la cadena. Esta función toma los mismos argumentos que pygame.image.fromstring(), pero no puede invertir verticalmente los datos de origen. Esta Funcion Funcionará mucho mas rápido que pygame.image.fromstring dado que no se alojan o copian datos de pixeles. sintaxis: pygame.image.frombuffer(string, size, format): return Surface Surface Objecto que pygame utiliza para representar y trabajar con las superficies (Imagenes en memoria del programa o script) Un objeto Surface de pygame se utiliza para representar cualquier imagen. La superficie tiene un formato de pixel y resolución fija. Las superficies con pixeles de 8 bits usan una paleta de 256 colores. Invoque pygame.Surface() para crear un nuevo objeto image. La superficie será completamente negra. El único argumento requerido es el tamaño. La superficie se creará con el formato que mejor coincida con la pantalla actual si no se especifican los argumentos adicionales. El formato de pixel se puede controlar especificando la profundidad de colores o una superficie existente. El argumento flags es una combinación de características adiciones para la superficie. Puede utilizar cualquier combinación de estas: 9
  • 10.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com HWSURFACE: Genera la imagen en la memoria de video. SRCALPHA: El formato de pixel incluirá transparencias por pixel. Ambas opciones son solo una solicitud, tal vez no sea posible para todos los modos de video Los usuarios avanzados pueden combinar un conjunto de opciones con un valor depth. El argumento masks es un conjunto de 4 números enteros que especifica cuales bits representan a cada color en el pixel. Las superficies normales no requieren el argumento mask. Las superficies pueden tener varios atributos adicionales como planos alpha, colores clave o recortes. Estas funciones afectan principalmente a la forma en que se imprime la superficie sobre otra. Las rutinas blit intentarán usar aceleración de hardware cuando sea posible, en caso contrario usarán métodos de impresión por software muy optimizados. Existen tres tipos de transparencia en pygame: colores clave, transparencia de superficie, y transparencia de pixel. La transparencia de superficie se puede combinar con colores clave, pero las imágenes con transparencia de pixel no puede usar los otros modos. La transparencia por color clave hace transparente un solo color. No se imprimirán los pixeles que coincidan con el color clave. La transparencia de superficie es un valor individual que cambia la transparencia de la imagen completa. Una transparencia de superficie de 255 será opaca mientras que un valor de 0 será completamente transparente. La transparencia de pixel es diferente porque se almacena el valor de transparencia de cada pixel. Esto permite crear efectos de transparencia mas precisos, pero es algo mas lento. La transparencia de pixel no se puede mezclar con los otros tipos de transparencia. Existe soporte para acceder a los pixels de la superficie. El acceso pixels en superficies de hardware es lento y no se recomienda. Estos métodos son adecuados para acceso simple, pero serán considerablemente lentos cuando realice mucho trabajo de pixels con ellos. Si planea realizar mucho trabajo a nivel de pixels se recomienda usar el módulo pygame.surfarray que puede tratar a las superficies como vectores de varias dimensiones (y es bastante veses mas rapido rápido). Cualquier función que acceda directamente a los datos de pixels de la superficie necesitarán que la superficie esté bloqueada. Estas funciones pueden bloquear (block()) o desbloquear (unlock()) las superficies por ellas mismas si ayuda, pero, si habrá una sobrecarga muy grande de múltiples bloqueos o desbloqueos si se llama a esta función muchas veces. Es mejor bloquear manualmente la superficie antes de llamar a las funciones muchas veces, y luego desbloquear la superficie cuando se halla finalizado. Todas las funciones que necesitan bloquear la superficie lo indican en la documentación. Recuerde dejar la superficie bloqueada solo mientras sea necesario. Los pixels de la superficie se almacenan internamente como un número individual que tiene todos los colores agrupados. Use las funciones Surface.map_rgb() y Surface.unmap_rgb() para convertir entre valores individuales (rojo, verde y azul) en colores agrupados para la superficie. Las superficies también pueden ser una referencia a una sección de otra superficie. Se generan con el método Surface.subsurface(). Cualquier cambio en alguna de las dos superficie que verá reflejado en ambas. Cada superficie contiene un área de recorte. Por defecto el área de recorte cubre la superficie entera. Si esta área de modifica, todas las operaciones de dibujado solo afectarán 10
  • 11.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com un área mas pequeña. sintaxis: pygame.Surface( (width, height), flags=0, depth=0, masks=None): return Surface pygame.Surface( (width, height), flags=0, Surface): return Surface blit La operacion mas comun en todo juego diria yo, que es la de copiar una imagen o parte de una imagen y pegarla o imprimirla sobre otra superficie, este metodo lo realiza o deve llamarlo la superficie destino (superficie donde quiero imprimir imagen) casi siempre sera la superficie que representa la pantalla osea screen que es el nombre como la vine llamando durante todo este curso. El metodo tiene varios argumentos que a continuacion listare de acuerdo a como deven ser colocados y explicare su funcion, el unico obligatorio es source el resto son opcionales: source: Se refiere a la superficie origen osea de la que se quiere copiar la superficie completa o parte de ella, este deve ser un atributo de tipo Surface. dest: Este atributo puede ser tanto una tupla (x, y), como un objecto Rect, representa en que posicion de la superficie destino se dibujara (comenzara a dibuar) la superficie origen, como referencia es donde aparecera dibujada la esquina superior izquierda de la superfice origen, si no se pasa argumento a este parametro asumira como posicion destino a los valores (0, 0). area: Este argumento es opcional, y representa la porcion rectangular de imagen que queremos copiar, si el parametro es None se copiara toda la imagen. El parametro area puede ser algunos de los siguientes: rect (x, y, w, h) ((x, y), (w, h)) Donde x,y son la posicion x,y desde donde se empezara a copiar, w(width) es el ancho y h (height) es el alto del area de recorte. opcionalmete se puede utilizar un objecto rect para pasar estos parametros. Special_flags: La opción special_flags puede tomar los siguientes valores: BLEND_ADD BLEND_SUB BLEND_MULT BLEND_MIN BLEND_MAX BLEND_RGBA_ADD BLEND_RGBA_SUB BLEND_RGBA_MULT BLEND_RGBA_MIN BLEND_RGBA_MAX BLEND_RGB_ADD BLEND_RGB_SUB BLEND_RGB_MULT 11
  • 12.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com BLEND_RGB_MIN BLEND_RGB_MAX Nota: tal vez se agreguen mas opciones de impresión en el futuro. El rectángulo retornado representa el área de los pixels afectados, excluyendo cualquier pixel fuera de la superficie destino o el área de recorte. Ademas Se ignorarán los pixels alpha cuando se imprima sobre una superficie de 8 bits. sintaxis: surface.blit(source, dest, area=None, special_flags = 0): return Rect Aqui muestro algunos codigo de ejemplo para terminar de aclarar la situacion y evitar confuciones en el Futuro: Suponer que tenemos 2 superfices, por sinplicidad las llamaremos sup_origen y sup_destino (que en el codigo fuente sera screen) ambas de 400x300 pixeles osea para quien no leyo el capitulo 1, 400 pixeles de ancho por 300 pixeles de alto, Nota las imagenes podrian ser de cualquier tamaño en fin estas son mis superficies (imagenes en memoria): sup_origen 12
  • 13.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com sup_destino El color con tono semi amarillo es a proposito para que puedan diferenciar la superficie de la Hoja. ahora vamos a proponer varios problemas sencillos (que resolvere y mostrare el resultado), todas estas pruevas seran via consola, a no preocuparse si a primera vista la pantalla de pygame parece estar tildada o no responder, lo que pasa es que no actualizamos los eventos. Antes de todo, importar e inicializar pygame >>> import os >>> import pygame >>> from pygame.locals import * >>> pygame.init() (6, 0) Crear la superficie que representa la pantalla y cargar las imagenes >>> screen = pygame.display.set_mode((400, 300)) >>> path = 'D:CursosJuegosCurso PyGame' Nota: la variable path es el directorio donde actualmente tengo las imagenes, como veran estoy en windows, en linux pondriamos lo siguiente suponiendo que las imagenes esten en /home/username/fotos/. path seria: >>> path = '/home/username/fotos' >>> sup_origen = pygame.image.load(os.path.join(path, 'l2c5.bmp')) >>> sup_destino = pygame.image.load(os.path.join(path, 'blank.bmp')) para ver que estas son las superficies cargadas las mostrare: >>> screen.blit(sup_origen, (0, 0)) <rect(0, 0, 400, 300)> >>> pygame.display.flip() 13
  • 14.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com >>> screen.blit(sup_destino, (0, 0)) <rect(0, 0, 400, 300)> >>> pygame.display.flip() Ya vimos como copiar la imagen completamente Ahora supongamos que queremos copiar (lo correcto a decir es blitear) al sup_origen sobre la sup_destino en la posicion central osea en la pos 200, 150 >>> sup_destino.blit(sup_origen, (200, 150)) <rect(200, 150, 200, 150)> >>> pygame.display.flip() 14
  • 15.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Si quisieramos copiar solo una porcion por ejemplo el area (150, 0, 100, 100) >>> screen.blit(sup_origen, (200, 150), (150, 0, 100, 100)) <rect(200, 150, 100, 100)> >>> pygame.display.flip() convert 15
  • 16.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Cambia el formato de pixel de una imagen. Genera una nueva copia de la superficie con un formato de pixel modificado. El nuevo formato de pixel se puede determinar a partir de otra superficie existente. Otra posibilidad es especificar los argumentos depth, flags y mask, de manera similar a pygame.Surface() La superficie nueva tendrá el mismo formato de pixel de la pantalla si no envía ningún argumento. Este formato será el mas rápido de imprimir. Es una buena idea convertir todas las superficies antes de imprimirlas varias veces. La superficie convertida podría no tener pixels alpha, dado que serán eliminados si la superficie original los tenía. Vea la función Surface.convert_alpha() para crear o preservar superficies con canal alpha. sintaxis: Surface.convert(Surface): return Surface Surface.convert(depth, flags=0): return Surface Surface.convert(masks, flags=0): return Surface Surface.convert(): return Surface convert_alpha Genera una nueva copia de la superficie con el formato de pixel deseado. La superficie nueva tendrá un formato adecuado para imprimirse mas rápidamente el formato indicado con canal alpha. Si no se especifica el argumento surface, la nueva superficie se optimizará para el formato de pantalla actual. A diferencia del método Surface.convert(), el formato de pixel para la imagen nueva podría no ser exactamente el mismo que se pide, aunque se optimizará para imprimirse sobre la superficie destino. sintaxis: Surface.convert_alpha(Surface): return Surface Surface.convert_alpha(): return Surface Nota: tanto al usar convert() como convert_alfa() adaptamos la superficie para que obtimize su manejo, pero esto avese trae perdida de definicion en algunos formatos de imagenes. copy Genera una nueva copia de la superficie. Hace una copia duplicada de un superficie. La superficie nueva tendrá el mismo formato de pixel, paletas de colores y configuración de transparencia que la original. sintaxis: Surface.copy(): return Surface fill 16
  • 17.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Pinta la superficie con un color solido. Se pintará la superficie entera si no se especifica el argumento rect. El argumento rect limitará la modificación al área especificada. La operación de pintado también se limitará por el área de recorte de la superficie. El argumento color puede ser una secuencia RGB, RGBA o un índice de una paleta de colores. Si usa el formato RGB se ignorará el componente alpha (una parte de RGBA) a menos que la superficie use transparencia por pixel (atributo SRCALPHA). BLEND_ADD BLEND_SUB BLEND_MULT BLEND_MIN BLEND_MAX BLEND_RGBA_ADD BLEND_RGBA_SUB BLEND_RGBA_MULT BLEND_RGBA_MIN BLEND_RGBA_MAX BLEND_RGB_ADD BLEND_RGB_SUB BLEND_RGB_MULT BLEND_RGB_MIN BLEND_RGB_MAX sintaxis: Surface.fill(color, rect=None, special_flags=0): return Rect Esta función retornará el área afectada de la superficie. set_colorkey Define el color clave de transparencia. Define el color clave para la superficie. Cuando imprima esta superficie sobre otra, cualquier pixel que tenga el mismo color que el color clave no se imprimirá. El argumento color puede ser un color RGB o un indice de una paleta de colores. Si se envía None como argumento entonces se deshabilitará el color clave. Se ignorará el color clave si la superficie tiene un formato para usar valores alpha por pixel. La transparencia por color clave se puede mezclar con la transparencia a nivel de superficie. Se puede definir el argumento opcional flags a pygame.RLEACCEL para obtener mejor rendimiento en pantallas que no tengan aceleración de video. Una superficie RLEACCEL puede ser mas lenta de modificar, pero se imprimirá mas rápido. El color que mas comunmente se usa como canal Alfa es el MAGENTA por ser raro que aparesca en pantalla. aca muestro como se vera una misma imagen sin y con color_key(). Sintaxis: Surface.set_colorkey(Color, flags=0): return None Surface.set_colorkey(None): return None 17
  • 18.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com (ejemplo_01.py) get_colorkey Obtiene el color clave de transparencia actual. Retorna el color clave actual de la superficie. Si la superficie no tiene color clave la función retornará None. sintaxis: Surface.get_colorkey(): return RGB or None set_alpha Define el valor de transparencia para la superficie. Cuando se imprima esta superficie sobre otra los pixels se dibujarán ligeramente transparentes. El valor de transparencia es un número entero de 0 a 255, 0 representa completamente transparente y 255 completamente opaco. Se deshabilitará la transparencia de la superficie si se pasa None como valor de transparencia. Esta transparencia es diferente a la transparencia por pixel. Se ignorará este valor de transparencia si la superficie contiene pixels con transparencia. Si la superficie contiene transparencia por pixel, cuando llame a esta función con el argumento None se deshabilitará esa transparencia por pixel. El argumento adicional flags se puede definir como pygame.RLEACCEL para obtener mayor rendimiento en pantallas que no tengan aceleración de video. Una superficie RLEACCEL será mas lenta de modificar, aunque será mas rápido imprimirla sobre otra. sintaxis: Surface.set_alpha(value, flags=0): return None Surface.set_alpha(None): return None (ejemplo_02.py) get_alpha 18
  • 19.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Obtiene el valor de transparencia de la superficie, Retorna el valor de transparencia actual para la superficie. Se retornará None si el valor de transparencia no está definido. sintaxis: Surface.get_alpha(): return int_value or None lock Bloquea los datos de pixel de una superficie para acceder a ellos. En la superficies aceleradas, los datos de pixels podrían estar almacenados en memoria de video volátil o en formas no lineales bajo compresión. Cuando se bloquea una superficie la información de pixels se convierte en un formato accesible. El código que lee o escribe valores de pixels necesitará que la superficie se bloquee para realizar esas tareas. Las superficies no deberían permanecer bloqueadas mas de lo necesario. Una superficie bloqueada podría no mostrarse o ser manipulada por pygame. No todas las superficies necesitan bloquease. El método Surface.mustlock() puede determinar si la superficie requiere bloquease. De todas formas, no hay desventaja al bloquear o desbloquear una superficie que no lo necesita. Todas las funciones de pygame bloquearán o desbloquearán automáticamente los datos de la superficie si es necesario. Si una sección de código hace varias llamas para modificar la superficie, entonces se bloqueará y desbloqueará muchas veces la superficie. Por este motivo, es mucho mas útil bloquear la superficie manualmente, luego modificarla muchas veces y luego desbloquearla manualmente. Es seguro anidar llamas para bloquear y desbloquear. La superficie solo se desbloqueará después de soltar el último bloqueo. sintaxis: Surface.lock(): return None unlock Desbloquea los datos de pixels de la superficie luego de que ha sido bloqueada. La superficie desbloqueada podrá imprimirse nuevamente por pygame. Vea la documentación de Surface.lock() para mas detalles. Todas las funciones de pygame bloquearán o desbloquearán automáticamente los datos de la superficie si es necesario. Si una sección de código hace varias llamas para modificar la superficie, entonces se bloqueará y desbloqueará muchas veces la superficie. Por este motivo, es mucho mas útil bloquear la superficie manualmente, luego modificarla muchas veces y luego desbloquearla manualmente. Es seguro anidar llamas para bloquear y desbloquear. La superficie solo se desbloqueará después de soltar el último bloqueo. sintaxis: Surface.unlock(): return None 19
  • 20.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com mustlock Verifica si la superficie necesita bloquearse., Retorna True si la superficie se debe bloquear para acceder a sus datos de pixel. Usualmente las superficies de software pura no necesitan bloquease. Este método no se usa con frecuencia, dado que es seguro y mas rápido directamente bloquear todas las superficies como sea necesario. Todas las funciones de pygame bloquearán o desbloquearán automáticamente los datos de la superficie si es necesario. Si una sección de código hace varias llamas para modificar la superficie, entonces se bloqueará y desbloqueará muchas veces la superficie. Por este motivo, es mucho mas útil bloquear la superficie manualmente, luego modificarla muchas veces y luego desbloquearla manualmente. sintaxis: Surface.mustlock(): return bool get_locked Consulta si la superficie está bloqueada, Retorna True cuando la superficie está bloqueada. Esta función no se fija o preocupa sobre cuantas veces se ha bloqueado la superficie. sintaxis: Surface.get_locked(): return bool get_locks Obtiene los bloqueos de la superficie. Retorna los bloqueos existentes para la superficie. sintaxis: Surface.get_locks(): return tuple get_at Retorna el valor de color RGBA en la posición indicada. Si la superficie no tiene transparencia por pixel, entonces el valor alpha del color será siempre 255 (completamente opaco). Se lanzará una excepción IndexError si la posición del pixel está fuera del área de la superficie. Obtener y definir los pixels de a uno a la vez es una tarea generalmente lenta para ser utilizada en un juego o una situación de tiempo real. Esta función bloqueará y desbloqueará la superficie temporalmente como sea necesario. sintaxis: Surface.get_at( (x, y) ): return Color 20
  • 21.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com set_at Define el valor de color RGBA o entero (si utiliza paleta) de un pixel. Si la superficie no tiene transparencia por pixel, entonces el valor alpha se ignorará. No tendrá ningún efecto definir pixels fuera del área total o el área de recorte de la superficie. Obtener y definir los pixels de a uno a la vez es una tarea generalmente lenta para ser utilizada en un juego o una situación de tiempo real. Esta función bloqueará y desbloqueará la superficie temporalmente como sea necesario. sintaxis: Surface.set_at( (x, y), Color): return None set_clip Define el área de recorte para la superficie. Cada superficie tiene una área de recorte activa. Este recorte es un rectángulo que representa a los pixels que se pueden modificar en una superficie. Toda la superficie se podrá modificar si se pasa None como área de recorte. El área de recorte está siempre limitada al área de la superficie en sí misma. Si el rectángulo de recorte es mas grande, entonces se encogerá para caber dentro de la superficie. sintaxis: Surface.set_clip(rect): return None Surface.set_clip(None): return None get_clip Obtiene el área de recorte actual de la superficie. Retorna una rectángulo que representa el área de recorte. La superficie siempre retornará un rectángulo válido que nunca estará por afuera de los bordes de la superficie. La superficie retornará el área completa de la misma si no se ha definido un área de recorte. sintaxis: Surface.get_clip(): return Rect subsurface Retorna una nueva superficie que comparte sus pixels con su superficie pariente. La nueva superficie se considera hija de la original. Las modificaciones a los pixels de cualquier de las dos superficies afectará a la otra. La información de la superficie como el área de recorte o los colores clave son únicos para cada superficie. La nueva superficie heredará la paleta, colores clave y configuración de transparencia de su padre. 21
  • 22.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Es posible tener cualquier número de sub-superficies y sub-sub-superficies de una superficie. También es posible tener una sub-superficie de la pantalla principal si el modo de video no está acelerado por software. sintaxis: Surface.subsurface(Rect): return Surface get_size Obtiene las dimensiones de una superficie. Retorna el ancho y alto de una superficie medida en pixels. sintaxis: Surface.get_size(): return (width, height) get_width Obtiene el ancho de una superficie. Retorna el ancho de una superficie medida en pixels. sintaxis: Surface.get_width(): return width get_height Obtiene la altura de una superficie.Retorna la altura de una superficies medida en pixels. sintaxis: Surface.get_height(): return height get_rect Obtiene el área rectangular de una superficie. Retorna un nuevo rectángulo que cubre la superficie entera. Este rectángulo siempre comenzará en la posición (0, 0) y tendrá el ancho y alto idéntico al tamaño de la imagen. Puede pasar valores clave como argumentos a esta función. Estos argumentos se aplicarán a los atributos del rectángulo antes de ser retornado. Un ejemplo podría ser mysurf.get_rect(center=(100,100)) para crear un rectángulo de la superficie con centro en la posición (100, 100). sintaxis: Surface.get_rect(**kwargs): return Rect 22
  • 23.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com get_bitsize Obtiene la profundidad de colores en bits del formato de pixel de la superficie. Retorna el número de bits utilizados para representar cada pixel. Este valor podría no coincidir exactamente con el número de bytes usados por pixel. Por ejemplo, una superficie de 15 bits requiere 2 bytes completos. sintaxis: Surface.get_bitsize(): return int get_bytesize Obtiene el número de bytes utilizados por pixel de la superficie. Retorna el número de bytes utilizados por pixel. sintaxis: Surface.get_bytesize(): return int get_flags Obtiene las opciones adicionales utilizadas por la superficie. Retorna el conjunto de propiedades de la superficie. Cada propiedad es un bit en la máscara de bits flags. Las propiedades habituales son HWSURFACE, RLEACCEL, SRCALPHA y SRCCOLORKEY. La lista completa de estas propiedades se puede encontrar en el archivo sdl_video.h. sintaxis: Surface.get_flags(): return int get_masks Obtiene la máscara de bits necesaria para convertir entre un color RGB y un color empaquetado. Retorna la máscara de bits que se utiliza para empaquetar cada color en un número entero. Este valor no se necesita para el uso normal de pygame. sintaxis: Surface.get_masks(): return (R, G, B, A) set_masks Define la máscara de bits necesaria para convertir entre un color RGB en un color en formato empaquetado. Esta función no se necesita para el uso habitual de pygame. sintaxis: Surface.set_masks( (r,g,b,a) ): return None 23
  • 24.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com get_buffer Obtiene un objeto buffer para los pixels de la superficie. Retorna un objeto buffer para los pixels de la superficie. El buffer se puede usar para acceder y manipular directamente los pixels. Este método bloquea y desbloquea la superficie de forma implícita. El bloqueo a la superficie se anulará una vez que el objeto BufferProxy sea eliminado. sintaxis: Surface.get_buffer(): return BufferProxy Otros metodos que pertenecen a este modulo que no fueron explicados por considerar que no son metodos de mucha relevancia o importancia. get_palette get_palette_at set_palette set_palette_at map_rgb unmap_rgb get_parent get_abs_parent get_offset get_abs_offset get_pitch get_shifts set_shifts get_losses get_bounding_rect Rect Pygame utiliza objetos Rect para almacenar y manipular areas rectangulares (Normalmente superficies). Un objeto Rect se puede crear a partir de una combinación de valores izquierda, arriba, ancho y alto. También se pueden crear desde objetos python que ya sean un objeto Rect o tengan un atributo de nombre rect. Cualquier función de pygame que requiera un argumento Rect también acepta cualquiera de eso valores para construir un rectángulo. Esto hace mas sencillo crear objetos Rect en el aire como argumentos a funciones. Los métodos de Rect que cambian la posición o el tamaño del rectángulo retornan una nueva copia del objeto con los cambios realizados. El rectángulo original no se modifica. Algunos métodos tiene una versión alternativa de estas funcionalidades pero que actúan sobre el objeto mismo y retornan None. Estos métodos alternativos se denotan con el sufijo “ip”. El objeto Rect tiene varios atributos virtuales que se pueden usar para mover ,alinear o simplemente consultar de un rectángulo. 24
  • 25.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com top, left, bottom, right topleft, bottomleft, topright, bottomright midtop, midleft, midbottom, midright center, centerx, centery size, width, height w,h Todos estos atributos se pueden consultar y asignar de la siguiente manera: rect1.right = 10 rect2.center = (20, 30) rect.width = 140 #es equivalente a rect.w = 140 Asignar un valor a size, width o height (tambien a w, h) cambia las dimensiones del rectángulo, todas las otras asignaciones mueven el rectángulo pero sin alterar el tamaño. Note que algunos atributos son números enteros y otros son pares de números enteros. Si un rectángulo tiene atributos width o height distintos de cero, entonces retornarán True por una consulta distinta de cero. Algunos métodos retornan un rectángulo con tamaño 0 para representar un rectángulo inválido. Las coordenadas para objetos Rect siempre son números enteros. Los valores de tamaño se pueden programar para tener valores negativos, pero estos se consideran no válidos para la mayoría de las operaciones. Existen varios métodos para consultar colisiones con otros rectángulos. La mayoría de los contenedores de python se pueden utilizar para buscar colisiones entre varios rectángulos contra uno. El área cubierta por un rectángulo no incluye los pixeles que se encuentran en el límite inferior y derecho. Si el borde inferior de un rectángulo es igual al borde superior de otro rectángulo (por ejemplo rect1.bottom = rect2.top), los dos ocupan la misma linea en pantalla pero no se superponen, y la consulta a rect1.colliderect(rect2) retornará False. sintaxis: pygame.Rect(left, top, width, height): return Rect pygame.Rect((left, top), (width, height)): return Rect pygame.Rect(object): return Rect move Retorna una copia (copia no referencia) del rectángulo que está desplazado en la cantidad indicada. Los argumento dx e dy pueden ser cualquier valor entero, positivo o negativo. sintaxis Rect.move(dx, dy): return Rect move_ip permite mover al rectangulo las cantidades dx, dy. afecta al objeto receptor. 25
  • 26.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com sintaxis: Rect.move_ip(dx, dy): return None clamp Retorna una nuevo rectángulo desplazado para estar completamente dentro de otro rectángulo dado como parámetro. Si el rectángulo es demasiado grande para caber dentro del otro rectángulo, se posicionará en el mismo centro que el rectángulo del argumento, pero su tamaño no se cambiará. sintaxis: Rect.clamp(Rect): return Rect clamp_ip Similar al método clamp, pero afecta al objeto receptor. sintaxis: Rect.clamp_ip(Rect): return None clip Recorta un rectángulo dentro de otro. Retorna un nuevo rectángulo que se recorta para estar completamente dentro de otro indicado por parámetro. Si los dos rectángulos no están en colisión, se retornará un rectángulo de tamaño 0. sintaxis: Rect.clip(Rect): return Rect union Retorna un nuevo rectángulo que cubre completamente el área de otros dos rectángulos dados como parámetro. Pueden haber áreas dentro del nuevo rectángulo que no estén en el área de los originales. sintaxis: Rect.union(Rect): return Rect union_ip Similar al método union, pero que afecta al rectángulo receptor. sintaxis: Rect.union_ip(Rect): return None 26
  • 27.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com unionall Retorna la unión de un rectángulo con una secuencia de varios rectángulos. sintaxis: Rect.unionall(Rect_sequence): return Rect unionall_ip La unión de varios rectángulos, afectando al objeto receptor. Similar al método unionall. sintaxis: Rect.unionall_ip(Rect_sequence): return None fit Cambia el tamaño o mueve el rectángulo pero respetando su aspecto. Retorna un nuevo rectángulo desplazado y redimensionado para caber dentro de otro. Se preserva la proporción de aspecto del rectángulo original, por lo tanto el nuevo rectángulo puede ser mas pequeño que el ancho o alto del rectángulo final. sintaxis: Rect.fit(Rect): return Rect normalize Corrige los tamaños negativos. Invertirá el ancho o alto de un rectángulo si tiene algún tamaño negativo. El rectángulo conservará la misma posición, pero con los lados alternados. sintaxis: Rect.normalize(): return None contains Consulta si un rectángulo está dentro de otro. Retorna True cuando el argumento está completamente dentro del objeto receptor. sintaxis: Rect.contains(Rect): return bool collidepoint Consulta si un punto está dentro de un rectángulo. Retorna True si el punto dado está dentro del rectángulo. Un punto sobre el costado derecho o inferior del rectángulo no se 27
  • 28.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com considera que está dentro del rectángulo. sintaxis: Rect.collidepoint(x, y): return bool Rect.collidepoint((x, y)): return bool colliderect onsulta si dos rectángulos están en contacto Retorna True si cualquier parte de alguno de los rectángulos están en contacto (excepto los bordes superior+inferior o derecha+izquierda), es el metodo que normalmente se usara en el control de coliciones entre Sprites. sintaxis: Rect.colliderect(Rect): return bool collidelist Consulta si un rectángulo entra en contacto con una lista. onsulta si el rectángulo colisiona con otro de una secuencia de rectángulos. Se retorna el índice de la primer colisión que se encuentra. Se retorna el índice -1 si no se encuentran colisiones. sintaxis: Rect.collidelist(list): return index collidelistall dem a collidelist solo que retorna una lista con el indice de todos los rectangulos con los que coliciona: sintaxis: Rect.collidelistall(list): return indices collidedict, collidedictall Son Similares a collidelist y collidelistall en funcionamiento solo que estos toman como argumento un dicionario con rectangulos. sintaxis: Rect.collidedict(dict): return (key, value) Rect.collidedictall(dict): return [(key, value), ...] 28
  • 29.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Mi Primer Juego (Feo :P) un Pong Introducion Aunque este primer modulo apunta mas a aprender a usar la API PyGame para programar juegos y el curso en si se llama Programacion de Juegos con PyGame que seria de un curso de juego si lo unico que se esta haciendo es explicar que hacen los modulos a, b ,etc.. bueno ya explique la mayoria de los modulos importantes por lo que podemos avanzar un nivel mas y empezar a programar juegos, y que seria de un curso de programacion de juegos si como primer juego a programar no te colocaran un Pong, no es por que solo lo hagan en todos los cursos, yo lo hago mas como tributo al primer juego que revoluciono el mundo de las computadoras. En todo desarrollo de un videojuego siempre suelen trabajar un GRUPO de personas, unas que llevaran la parte grafica, otras que llevaran la parte de programacion, otras que llevaran el guion, otras que llevaran la parte de sonido... Lo que pretendo decir es que tu no tienes porque saber de todo porque normalmente si te dedicas a esto trabajaras con otra gente y no tu solo, por lo que si eres programador, buscate a alguien que sea grafista o sepa dibujar para que te haga unos buenos graficos y no te pases horas y horas intentando dibujar una cosilla cuando hay gente que la va a hacer mucho mejor y en mucho menos tiempo u sino busca en internet ya que hay varios Sitios donde te puedes bajar los sprites. Yo soy programador y no conozco a ningun grafista por lo que los graficos que utilizar‚ seran sacados de internet o dibujados por mi por lo que la calidad grafica no va ser excesiva (mas bien decepcionante, no tanto use formas basicas y un poco de degrado en Inskape para crearlas) enn fin haremos‚ lo que podamos. La Idea Como ya se menciono arriba vamos a hacer un juego sencillo llamdo pong o ping-pong, tenis o como quieran llamarle, en fin es un sencillo juego clasico, lo tomo como primer juego por ser dentro de todo sencillo de programar. Para los que no tengan idea de como es aca les dejo un captura de pantalla. El Objectivo El Objectivo del Juego va a ser marcar un gol, el primero de los participantes que meta 3 goles, sera declarado ganador y el juego acabara. Ahora analicemos los elementos que intervienen en el Juego: Paleta o Raqueta solo se podra mover en forma vertical entre los limites inferiores y superiores. Pelota Tendra un movimiento rectilineo (se movera en linea recta sin hacer ninguna curva estraña), aumentara su velocidad a medida de que rebota contra las raquetas, En funcion de 29
  • 30.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com la posicion en que golpee en las raquetas tomara una trayectoria u otra, es decir si se golpea con la parte superior tendera a ir hacia arriba y si es en la inferior tendera a ir hacia abajo. Los Graficos Como vimos es un juego sencillo que requiere solo 3 graficos (paleta_1, paleta_2 y pelota), a la cancha la dibujaremos mediante figuras basicas. aparte de eso necesitaremos 2 imagenes mas 1 para la pantalla de presentacion y otra para el menu (aunque esa parte la realizaran ustedes como ejercicio). bueno por el momento yo me encargare de los graficos de las raquetas y las pelotas, para acelerar esto las dibuje mediante Inkscape usando formas basicas y algo de degradado. pueden verlas en la carpeta 'pong/imagenes/' Armazon Principal En Nuestro Juego deberiamos notar 2 bucles bien definidos el primero y mas externo visualizar la pantalla de presentacion hasta que se pulsa una tecla y en funcion de la tecla pulsada hace dos cosas: Empieza la partida o sale del juego. En el primer caso vemos el segundo bucle, que es la duracion de la partida, estara en ‚ el hasta que uno de los jugadores obtenga 3 puntos o se pulse la tecla ESCAPE. Por lo tanto y usando nuestra plantilla basica para aplicaciones en pygame (al menos yo lo hago siempre ustedes haganlo como deseen :P), los datos de pantallas y otras constanstes que utilizaremos a lo largo del juego estaran definidos en el fichero constantes.py otro modulo que usare y que notaran que solo posee un grupo de constantes que representan colores: #!/usr/bin/env python # -*- coding: utf-8 -*- import pygame from pygame.locals import * from colores import * from constantes import * def dibuja_cancha(surface): """ funcion que permite dibujar la cancha del juego utilizando funciones de dibujo basicas """ pygame.draw.rect(surface, VERDE_MEDIO, ((10,10),(ANCHO-20, ALTO-20)), 0) pygame.draw.rect(surface, BLANCO, ((30,30),(ANCHO-60, ALTO-60)), 2) pygame.draw.line(surface, BLANCO, (ANCHO/2,30), (ANCHO/2, ALTO-30), 2) def main(): """ funcion principal donde se implementara el Juego """ 30
  • 31.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com pygame.init() screen = pygame.display.set_mode(RESOLUCION) pygame.display.set_caption('Ping Pang Pong 0.0.1') titulo = pygame.image.load('imagenes/fondo.png').convert_alpha() jugando = False #bandera que avisa si se esta jugando la partida loop = True while loop: #screen.fill(NEGRO) screen.blit(titulo, (0, 0)) teclas = pygame.key.get_pressed() #si se preciona la tecla escape Finaliza el Juego del juego if teclas[K_ESCAPE]: loop = False jugando = False #estando en el bucle principal iniciara el juego elif teclas[K_RETURN]: jugando = True #loop de la partida while jugando: screen.fill(NEGRO) dibuja_cancha(screen) pygame.display.flip() for evento in pygame.event.get(): if evento.type == pygame.QUIT: loop = False pygame.display.flip() for evento in pygame.event.get(): if evento.type == pygame.QUIT: loop = False #finalizamos el juego antes de salir pygame.quit() if __name__ == '__main__': main() (vease el codigo en pong/paso_01.py) Como vemos ej juego posee una extructura sencilla, se destaca la utilizacion de modulo pygame.key para captura del teclado, otro punto importante es que a la cancha la dibujamos usando funciones de dibujo basicas. Por el momento nuestro juego no esta completo ya que solo tenemos el menu pero seguiremos avanzando. Una primera captura para ver el menu y la pantalla de juego: 31
  • 32.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com menu pantalla de juego Las Paletas o Raquetas En esta secion vamos a crear 1 clase paleta base y de ella derivaremos las clases que permitiran a los jugadores manejarlas, opcionalmente podriamos derivar una clase para implementar la AI del juego. En fin vamos a usar algunas herramientas de las que aprendimos hasta ahora de pygame. 32
  • 33.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com La Clase base Paleta: Nuestra clase base necesita tener todo lo necesario para manejar las paletas y las imagenes y demas objectos que las componen, ademas devemos definir algunos metodos que nos permitan controlarla, para no complicar la sintaxis definiremos las paletas en otro archivo distinto llamado paleta.py aqui coloco el constructor de la clase, el metodo de reinicio, el metodo para controlar que la paleta no se salga de pantalla, el metodo que permitira moverla, y el metodo para dibujarla. Ademas agregaremos algunas constantes mas: FRAME_RATE = 30 #cantidad de cuadros por segundo PALETA_SPEED = 5 #velocidad de la paleta MARGEN_SUP = 30 #limitante del margen superior de la cancha MARGEN_INF = ANCHO - 30 #limitante del margen inferior de la cancha ISO_ARRIBA = 0 #constante que define la direcion hacia arriba ISO_ABAJO = 1 #constante que define la direcion hacia abajo class Paleta: """ Clase base para definir las raquetas o paletas del juego """ def __init__(self, img): """ constructor de la clase, el unico parametro que recibe es el de la imagen que se usara. """ #cargamos la imagen y la convertimos (yo use unos *.png) para #representar todas las imagenes del juego self.imagen = pygame.image.load(img).convert_alpha() #obtenemos un objecto rect a partir de la imagen, el cual usaremos #para manipularla self.rect = self.imagen.get_rect() #variable que almacenara los goles del jugador self.puntaje = 0 def init(self, pos): """ metodo que usaremos para inicializar las paletas antes de comensar cada partida nueva pos : tupla que representa la posicion (x,y) donde se centrara la imagen de la paleta y el rectangulo que maneja las coliciones """ self.rect.center = pos self.self.puntaje = 0 #reiniciamos la puntuacion def mover(self, dir): """ metodo que permite mover la paleta, tanto hacia arriba como hacia abajo, o arriba. dir : parametro donde se especifica la direcion los parametros validos son: ISO_ARRIBA o ISO_ABAJO """ if dir == ISO_ARRIBA: self.rect.y -= PALETA_SPEED 33
  • 34.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com elif dir == ISO_ABAJO: self.rect.y += PALETA_SPEED def controla(self): """ metodo que se usa para controlar que la paleta no se salga de la pantalla """ if self.rect.y < MARGEN_SUP: self.rect.y = MARGEN_SUP elif (self.rect.y + self.rect.h) > MARGEN_INF: self.rect.y = MARGEN_INF def update(self): pass def drawn(self, surface): """ metodo para dibujar la paleta sobre una superficie, normalmente esa superficie sera la pantalla principal. """ surface.blit(self.imagen, self.rect) Los Jugadores (Herenciando la Clase Paleta) Como habran notado el metodo update() (Actualizar) esta vacio, y eso se deve a que como mencionamos anteriormente se herenciara la clase paleta para definir las clases que manejaran los jugadores y alli es donde definiremos dicho metodo, las paletas solo necesitan ser controladas por 2 teclas cada una para controlar la paleta del jugador 1 usaremos las teclas (A;B) y para controlar la paleta del jugador 2 usaremos las teclas direcionales (ARRIBA;ABAJO). class Jugador1(Paleta): """ Clase que manipulara la paleta del jugador 1 """ def update(self): """ metodo que permitira actualizar la posicion de las paletas """ #capturo todas las teclas que hayan sido pulsadas teclas = pygame.key.get_pressed() #mover arriba if teclas[K_q]: self.mover(ISO_ARRIBA) #mover abajo elif teclas[K_q]: self.mover(ISO_ABAJO) 34
  • 35.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com class Jugador2(Paleta): """ Clase que manipulara la paleta del jugador 2 """ def update(self): """ metodo que permitira actualizar la posicion de las paletas """ #capturo todas las teclas que hayan sido pulsadas teclas = pygame.key.get_pressed() #mover arriba if teclas[K_UP]: self.mover(ISO_ARRIBA) #mover abajo elif teclas[K_DOWN]: self.mover(ISO_ABAJO) Ahora que tenemos implementadas las clases que manejaran las paletas (para mas detalle vease pong/paleta.py) procedamos a importarlas y probarlas junto con el esqueleto de juego que habiamos diseñado con anterioridad. #!/usr/bin/env python # -*- coding: utf-8 -*- import pygame from pygame.locals import * from colores import * from paleta import Jugador1, Jugador2 from constantes import * def dibuja_cancha(surface): """ funcion que permite dibujar la cancha del juego utilizando funciones de dibujo basicas """ pygame.draw.rect(surface, VERDE_MEDIO, ((10,10),(ANCHO-20, ALTO-20)), 0) pygame.draw.rect(surface, BLANCO, ((30,30),(ANCHO-60, ALTO-60)), 2) pygame.draw.line(surface, BLANCO, (ANCHO/2,30), (ANCHO/2, ALTO-30), 2) def main(): """ funcion principal donde se implementara el Juego """ pygame.init() screen = pygame.display.set_mode(RESOLUCION) reloj = pygame.time.Clock() #temporizador del juego pygame.display.set_caption('Ping Pang Pong 0.0.1') #imagen del titulo titulo = pygame.image.load('imagenes/fondo.png').convert_alpha() #instanciamos los objectos que manejara las paletas 35
  • 36.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com pal_1 = Jugador1('imagenes/paleta_a.png') pal_2 = Jugador2('imagenes/paleta_b.png') jugando = False #bandera que avisa si se esta jugando la partida loop = True while loop: reloj.tick(FRAME_RATE) screen.blit(titulo, (0, 0)) teclas = pygame.key.get_pressed() #si se preciona la tecla escape Finaliza el Juego del juego if teclas[K_ESCAPE]: loop = False jugando = False #estando en el bucle principal iniciara el juego elif teclas[K_RETURN]: jugando = True #inicializamos las paletas pal_1.init((30, ALTO / 2)) pal_2.init((ANCHO - 30, ALTO/2 )) #loop de la partida while jugando: #~ reloj.tick(FRAME_RATE) screen.fill(NEGRO) dibuja_cancha(screen) #actualizamos los objectos pal_1.update() pal_2.update() #los dibujamos sobre la pantalla pal_1.drawn(screen) pal_2.drawn(screen) pygame.display.flip() for evento in pygame.event.get(): if evento.type == pygame.QUIT: loop = False pygame.display.flip() for evento in pygame.event.get(): if evento.type == pygame.QUIT: loop = False #finalizamos el juego antes de salir pygame.quit() if __name__ == '__main__': main() (vease pong/paso_02.py) 36
  • 37.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com Observar que ademas de agregar los 2 objectos paletas, en el bloque que pregunta si se preciono la tecla enter colocamos los metodos para resetear la poscicion de cada paleta, mas adelante agregaremos el metodo para resetear la pelota y por ultimo dentro del loop de juego introducio los metodos update() y drawn() para cada paleta, como vimos dichos metodos se encargan de mover y dibujar respectivamente las paletas. otro elemento agrega es el temporizador que aunque no he explicado todavia el modulo ya deven tener una idea de como funciona. Aca una captura de nuestro juego hasta el momento. La Pelota Bueno por lo visto el juego ya esta tomando forma solo nos esta faltando implementar el control de la pelota y sus coliciones con las paletas que es lo que trataremos en esta ultima parte de este capitulo. Programar la pelota es la parte mas complicada del juego por eso la deje para el final del mismo ya que tenemos que hacer que se mueva, cambie de direcion, aumente su velocidad, controlar si hace gol etc, lo bueno de esto es que no usaremos ninguna cosa estraña solo un poco de matematica simple. la clase aparte de contener la imagen y el rectangulo que la representara tendra los atributos x,y que representaran su poscion real (el rectangulo representara su posicion aproximada) y dos incrementadores dx y dy que definiran el incremento en cada una de las variables, los metodos tendran los mismos nombres que en las paletas pero su funcionamiento y argumentos diferiran un poco. Como siempre agregamos nuevas constantes: class Pelota: """ Clase que se utilizara para manejar la pelota. """ 37
  • 38.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com def __init__(self, imagen): """ constructor de la clase pelota el unico parametro que pide es la imagen que se usara para representar la pelota """ self.imagen = pygame.image.load(imagen).convert_alpha() self.rect = self.imagen.get_rect() #posicion exacta del centro de la pelota dentro de la pantalla self.x = 0.0 self.y = 0.0 #imcrementos en las direciones x,y self.dx = 0.0 self.dy = 0.0 def reset(self): """ reseteala posicion de la pelota en la pantalla, normalmente esta deberia iniciar en el centro de la misma """ #centro la pelota en el centro de la pantalla self.rect.center = (ANCHO / 2, ALTO / 2) self.x = float(ANCHO / 2) self.y = float(ALTO / 2) #calculo el incremento inicial de dy if random.random() > 0.5: self.dy = +1.5 else: self.dy = -1.5 #calculo el incremento inicial de dx if random.random() > 0.5: self.dx = +1.5 else: self.dx = -1.5 def controla(self, pal_a, pal_b): """ Esto no se deveria hacer (digo por lo de pasar una referencias a de las paletas ya que esto crea un enlace fuerte y ello se considera malo en la programacion orientada a objectos). En fin este metodo se encargara de controlar que la pelota no se salga de pantalla si choca con los bordes o las paletas ademas de incrementar su velocidad y cambiar su direcion. """ #pregunta si choco con la paleta A que esta a la izquierda if self.rect.colliderect(pal_a.rect): #compruebo si choco de la mitad para arriba if self.rect.centery < pal_a.rect.centery: self.dy -= 0.5 #sino choco con la parte de abajo else: 38
  • 39.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com self.dy += 0.5 #por ultimo invierto la direcion x y aumento la velocidad self.dx -= 0.5 self.dx = -self.dx #ahora pregunta si choco con la paleta B que esta a la izquierda if self.rect.colliderect(pal_b.rect): #compruebo si choco de la mitad para arriba if self.rect.centery < pal_a.rect.centery: self.dy -= 0.5 #sino choco con la parte de abajo else: self.dy += 0.5 #por ultimo invierto la direcion x y aumento la velocidad self.dx += 0.5 self.dx = -self.dx #ahora pregunto si choco con algunas de las paredes y cambio el #signo del incremento de y osea dy if self.rect.y < MARGEN_SUP or (self.rect.y + self.rect.h) > MARGEN_INF: self.dy = -self.dy #ahora por ultimo compruevo si se hizo un gol e incrementos el contador #goles del jugador rival y ademas hay que reiniciar la posicion de la #pelota #si la pelota toca el borde izquierdo de la pantalla implica que el #jugador B hizo un gol if self.rect.x < 0: # nota: los objectos son pasados por referencia por lo que la #siguiente operacion no se perdera pal_a.puntaje += 1 self.reset() #si la pelota toca el borde izquierdo de la pantalla implica que el #jugador A hizo un gol elif (self.rect.x + self.rect.w) > ANCHO: # nota: los objectos son pasados por referencia por lo que la #siguiente operacion no se perdera pal_b.puntaje += 1 self.reset() #en el titulo de la ventana colocaremos el puntaje de cada uno pygame.display.set_caption('Azul %d - Rojo %d' %(pal_a.puntaje, pal_b.puntaje)) def update(self, pal_a, pal_b): """ actualiza la posicion, velocidad y direcion y ademas devuelve el estado del juego: 0 - el juego sigue 1 - gano el jugador A 39
  • 40.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com 2 - gano el jugador B """ self.controla(pal_a, pal_b) #actualizo la posicion de la pelota self.x += self.dx self.y += self.dy self.rect.center = int(self.x), int(self.y) #pregunto cuantos goles tiene cada jugador, si alguno tiene 3 o mas #retorno 1 o 2 avizando que el juego termino caso contrario devuelvo 0 if pal_a.puntaje >= 3: return 1 elif pal_b.puntaje >= 3: return 2 else: return 0 def drawn(self, surface): """ metodo para dibujar la pelota sobre una superficie, normalmente esa superficie sera la pantalla principal y ademas la pelota sera el ultimo objecto que se dibuje. """ surface.blit(self.imagen, self.rect) Bueno por ultimo hay que modificar el esqueleto principal y agregar la pelota. Despues de tanto sufrimiento tenemos un Juego Completo. Aca pueden ver una captura de pantalla del juego corriendo para jugarlo y ver el codigo del juego en su version final vea o ejecute el script pong/final.py Antes de de terminar: El juego se llama pong pero mientras escribia y documentaba el codigo de este juego se me ocurrio ponerle Ping, Pang, Pong el nombre no lo invente yo, 40
  • 41.
    Curso de: Programacionde Juegos con PyGame Por: Ricardo D. Quiroga – L2Radamanthys → l2radamanthys@gmail.com por si no saben era el nombre del Equipo de Bolos (Nada que ver con esto que supuestamente es un juego de tenis) de Homero en un capitulo de Los Simpson. Bue solo queria aclarar eso. Saludos 41