Desarrollo de Videojuego en Pygame
Desarrollo de Videojuego en Pygame
Docentes
Alicia Benesch
Ximena Ebertz
Omar Javier Argañaras
ÍNDICE
Índice___..............................................................................................................................................1
Introducción........................................................................................................................................2
Funciones obligatorias........................................................................................................................3
Funciones no obligatorias...................................................................................................................6
Clases ............................................................................................................................................12
Sonidos...............................................................................................................................17
Íconos................................................................................................................................. 17
Puntero................................................................................................................................17
Teclado...............................................................................................................................18
Lemarios y dificultades...................................................................................................... 18
Pifies ............................................................................................................................................20
Titileo en títulos..................................................................................................................20
Mostrar récords...................................................................................................................20
Conclusiones.....................................................................................................................................22
Anexos ............................................................................................................................................23
Principal..............................................................................................................................23
FuncionesVACIAS.............................................................................................................26
Extras..................................................................................................................................40
Configuración.....................................................................................................................60
Clases..................................................................................................................................60
1. INTRODUCCIÓN
1
mediante el teclado y el mouse (según mi experiencia siempre es mejor asegurarse, dado que a veces las
mascotas o les mismes usuaries muerden los cables de los periféricos, los rompen y dejan de funcionar).
principal,
funcionesVACIAS,
extras,
configuración,
clases
Los primeros cuatro estaban por defecto en el código sin completar que se nos suministró. El quinto
archivo lo incorporé luego de aprender a mover y colisionar imágenes. Pasar todas las figuras e imágenes
móviles a clases me permitió ordenar un poco los ríos y ríos de código antes de que todo se desborde por
cantidad y desorden.
En los siguientes apartados se describirá el código y las decisiones tomadas en el fragor de la lucha por
hacer funcionar el videojuego con una amplia esperanza de que el berenjenal le sea leve a quién lo lea.
También se detallará qué funcionó, qué no funcionó y qué funcionó a medias. A modo de conclusiones se
presentan algunos comentarios cortos y bonitos sobre todo lo que se aprendió con este desafío y sobre
partes del videojuego que se pueden perfeccionar o pulir un poco más. Por último, en anexos se encuentra
el código completo.
Tras largas semanas el código fue sufriendo cambios que obedecieron a diferentes estilos. Diferentes
soluciones encontradas en diferentes páginas web. Diferentes estilos gráficos que se me fueron ocurriendo
y diferentes musicalizaciones. Diferentes momentos de luchar contra un código que crecía en desorden y
dificultad. Diferentes problemas y desafíos propuestos en la consigna. Por todo ello se me hace difícil
encontrar un hilo lógico y completamente ameno para describir todo el trabajo hecho. Así que, antes de
avanzar, están ustedes advertides estimades lectores. Sin más dilaciones comenzamos.
2
2. FUNCIONES OBLIGATORIAS
Se comentarán las tres funciones obligatorias y mínimas para que corra el video juego (llamadas
nuevaPalabra, lectura y revisión). Para la tercera función se crearon otras tres funciones auxiliares que
también serán comentadas.
Esta función toma como argumento una lista de palabras y retorna de ella una única palabra al azar.
Previamente debe importarse la librería random para que funcione la función [Link]().
def nuevaPalabra(lista):
return [Link](lista)
La segunda función tiene tres argumentos. Previamente se abrió un archivo de texto (en modo lectura) en
la variable archivo. Cada línea del archivo se guarda en la lista salida pero se quita el último carácter de
cada línea (así se guardan las letras de cada palabra y se quita el salto de línea). La lista salida no se crea
con todas las palabras del archivo sino que únicamente almacena las palabras que tienen un determinado
largo.
La tercera función es un poco más larga y requiere de otras cuatro funciones auxiliares que luego se
detallan. Principalmente hace dos cosas. Primero evalúa si una palabra (que previamente ingresaron les
usuaries) coincide con la palabra correcta que retorna la primera función obligatoria (si se cumple
devuelve un True). Segundo evalúa cada letra de esa palabra para determinar si tiene letras correctas,
incorrectas o casi según se definen en las consignas del trabajo práctico.
3
if palabra == palabraCorrecta:
return True
else:
return False (lista)
Las cuatro funciones auxiliares se copian a continuación. La primera evalúa si una letra no se encuentra
en la palabra correcta y arma una lista con las letras incorrectas. La segunda chequea si una letra se
encuentra en la palabra correcta y además chequea que coincida la posición, luego crea una lista de letras
correctas. La tercera chequea si una letra se encuentra en la palabra correcta pero en diferente posición y
crea a lista llamada casi con esas letras.
Las tres listas luego se utilizarán para colorear el abecedario en la pantalla e indicarle a les usuaries qué
letras son correctas, incorrectas o casi. Además se tuvo el cuidado de incorporar sólo una única vez cada
letra correcta a la lista correspondiente porque en otra parte del código la cantidad de letras correctas
servirá para asignar puntajes. En las demás listas también se guarda una vez cada letra que corresponda
pero quedó así por inercia (creo que no corrompe el programa si en alguna de estas dos listas se guardara
una misma letra más de una vez).
4
Verde, naranja y rojo para las letras correctas, casi e incorrectas. En este ejemplo la palabra correcta es cobra.
Apretar la tecla enter por error dispara el comentario lo siento =(. Las palabras que no están en el lemario se
colorean de gris.
5
3. FUNCIONES NO OBLIGATORIAS
En este apartado no se comentan todas las funciones no obligatorias porque algunas de ellas son
presentadas en otras partes del informe.
El videojuego no acepta cualquier palabra ingresada por les usuaries. Primero el programa evalúa que se
cumplan dos condiciones :
Una vez pasado este filtro y sólo si se cumplen las dos condiciones el juego continúa. Evalúa si la
palabra es correcta y evalúa sus letras. Esa parte del código ya fue comentada en el apartado de
Funciones Obligatorias.
La siguiente función determina si la palabra ingresada es la correcta, es decir, si les usuaries ganaron.
Saber si ganaron me permite modificar una variable booleana que cierra el ciclo while en el que, iteración
tras iteración, se toma la palabra ingresada y se la evalúa.
Para guardar los récords necesito guardar el nombre de quién acaba de jugar. La verdad es que quién
acaba de jugar puede ingresar todos los caracteres que quiere para escribir su nombre pero sólo tomé los
primeros cuatro caracteres que ingresa. No sé por qué, fue una decisión tomada al principio, momento en
el que le estaba dando una onda retro al juego. Como en los antiguos juegos que uno almacenaba tan sólo
tres caracteres para grabar el récord. Tomé el recaudo de agregar símbolos @ hasta completar cuatro
caracteres si se ingresan menos de cuatro letras. Esta decisión obedece principalmente a dos razones. La
primera es que queda todo más parejo al ser presentado en pantalla (no es una razón de peso). La segunda
es que facilita mucho separar el nombre del puntaje dado que ambos datos son guardados en una misma
6
línea en el archivo [Link] (tampoco es una razón de peso pero fue la manera en todo resultó ¡pasaron
cosas!)
def completarCaracteres(palabra):
if len(palabra) == 0:
palabra += "@@@@"
if len(palabra) == 1:
palabra += "@@@"
if len(palabra) == 2:
palabra += "@@"
if len(palabra) == 3:
palabra += "@"
palabra = palabra[0:4]
return palabra
A continuación presento la función con la que creo una lista en la que cada elemento es una línea del
archivo records (que guarda en cada linea cuatro letras + un espacio + puntaje).
La verdad pensé que venía pisteando como un campeón pero rápidamente me quedé sin nombres para
tantas funciones (creadas rápida y brillantemente por cierto). En pos de ordenar de mayor a menor los
récords creé dos listas: una de nombres y otra con los puntajes correspondientes a cada nombre.
A continuación ordené los puntajes con el método de burbuja. Cada vez que ordenaba los elementos de la
lista de puntajes hacía lo mismo con los elementos correspondientes de la lista de nombres. Así me
quedaron dos listas ordenadas en las que los nombres y los puntajes concuerdan.
7
listaAuxNombres = listaNombres[:]
salida = []
auxiliar = listaAuxNombres[i]
listaAuxNombres[i] = listaAuxNombres[i-1]
listaAuxNombres[i-1] = auxiliar
Me queda la sensación de que debe haber muchas maneras más sencillas de resolver estas
funciones pero éstas son las que me salieron a mi. No es pobre el que poco tiene sino el que mucho
anela, cantaba un tango.
En este apartado comento aquellas funciones que están en el archivo [Link]. En la parte del
código que nos vino por defecto ya se encontraba la función menu que mostraba el menú. No sólo
le hice varios cambios sino que la copié y pegué para crear nuevas funciones. Cada una de ellas la
utilicé para diferentes pantallas del juegos, de ese modo pude mostrar rectángulos, títulos,
opciones, colorear palabras y letras, colorear el tiempo, mostrar palabras ingresadas, mostrar letras
que se van tipeando, mostrar línea, utilizar fuentes de diferente tamaño, mostrar puntaje, entre
otras cosas.
Como ejemplo muestro a continuación la función menu, en anexos figura todo el código completo
del archivo [Link].
#rectangulos
rectangulos = Rectangulos()
[Link](screen, 80, COLOR_RECTANGULOS) #screen, cantidad de rectángulos, altura
8
y2 += 80
if i < len(opcionesMenu) - 1 and i > 0:
[Link]([Link](opcionesMenu[i], 1, COLOR_BLANCO), (ANCHO/2-
(len(opcionesMenu[i])/2)*TAMANNO_LETRA_NORMAL/2, y2))
y2 += 80
if i == len(opcionesMenu) - 1:
y2 += 6
9
4. LIBRERÍAS Y OTRAS YERBAS
Gran parte de estas librerías estaba por defecto en el trabajo práctico. La librería time no recuerdo si ya
estaba o la incorporé para poder hacer pausas muy breves entre diferentes pantallas y para esperar que
terminen de reproducirse algunos sonidos y no se superpongan con otros, de tal modo que se no escuchen
horriblemente ambos a la vez.
Las funciones randint y uniform de la librería random retornan un número entero entre cierto rango y un
número con decimales entre algún rango, respectivamente. La primera la utilicé para generar gotas de
agua cuyo tamaño vertical en pixeles se determinó adecuadamente entre dos valores enteros, es decir, las
gotas se pueden ver a simple vista en la pantalla. En cambio, para determinar la velocidad de caída de las
gotas no pude utilizar valores enteros dado que el valor más bajo (el uno) producía una velocidad muy
alta (y el cero las frenaba). El uso de valores decimales aleatorios entre [0.5, 1] permitió una velocidad de
caída adecuada. A continuación muestro cómo utilicé las dos funciones mencionadas en un pedacito de
código.
[Link] = uniform(0.5, 1)
[Link] = randint(25, 35)
Pueden verse las gotas de agua mencionadas. Pantalla creada para practicar un poco más y porque no había nada
para comer en casa.
Esta pantalla de tormenta alterna dos fondos, uno gris oscuro (el que se muestra) y otro gris claro para dar
la sensación de relámpagos. Todo el tiempo fue una pantalla de prueba que me permitió incorporar
imágenes, moverlas, utilizar clases, incorporar sonidos continuos, utilizar el mouse, ingresar valores por
10
teclado para activar sonidos o para volver al menú principal del juego, hacer que los objetos reboten en
los bordes de pantalla o en otros lugares, etc.
En algún momento tuve la idea de hacer un minijuego dentro del juego atrapando o esquivando con los
gatitos las letras del título pero me faltan habilidades para lograrlo.
11
5. CLASES
Al principio incorporé al juego muchas imágenes y con el esfuerzo de muchos días pude incluso
moverlas por la pantalla. Mi vida cambió luego de ver la sencillez de un tutorial en el que utilizaban
clases y colisionaban una imagen contra los bordes de la ventana. Todas las imágenes que pude las pasé
a clases. Antes de eso cada imagen se movía gracias a interminables líneas de código con muchas
variables y contadores que cambiaban la posición de la imagen. No sólo resultaba engorroso mover una
sola imagen sino que además se enquilombaba (si es que existe el verbo) el main y las otras funciones
principales que muestran las diferentes pantallas.
Les llame clases porque así las denominaban en un tutorial de You Tube. Si son en realidad clases o
sprites no es algo en lo que me voy a meter aquí.
La clase Gota() (ya comentada en el aparatado anterior) me vino bien para simular una lluvia en una
pantalla que tuvo la intención de ser un minijuego dentro del juego. Pero el proyecto fue abandonado y
practique el movimiento de imágenes, las colisiones, la alternancia de imágenes parecidas (como en un
GIF), la alternancia de fondos de pantalla, etc.
Para lograr el efecto de lluvia se definen una variable x aleatoria (las gotas cubrirán todo el ancho de
pantalla) y una variable y aleatoria (las gotas aparecerán en cualquier altura de la pantalla). Las funciones
uniform y randint fueron comentadas en el apartado Librerías, en particular, se aclara por qué se utilizó
una variable entera y una decimal para el tamaño y para la velocidad vertical respectivamente.
En caída se les da movimiento a las gotas, a la variable y se le suma la velocidad de tal modo que cada
gota tendrá una aceleración diferente. Una vez que la posición vertical de la gota llega casi al borde
inferior de la pantalla se reinicia la altura y la velocidad, es decir, aparece otra gota.
Por último cada gota es dibujada como una línea vertical de color negro y de un fino espesor.
class Gota():
def __init__(self):
self.x = randint(0, 800)
self.y = randint(-200, 600)
[Link] = uniform(0.5, 1)
[Link] = randint(25, 35)
def caida(self):
self.y += [Link]
[Link] += 0.005
Carey y Potter son mis gatitos. La función [Link].get_rect() es una maravilla porque toma las
dimensiones de una imagen y luego permite llamar a otras funciones útiles para mover esa imagen. Por
ejemplo, [Link]() que mueve la imagen de acuerdo a parámetros que se ingresan en el
argumento de la función. Luego la función [Link]() recibe dos argumentos, una imagen y la posición
para mostrarla.
Hay dos condicionales if que invierten una de las componentes de la velocidad si la imagen choca contra
alguno de los bordes de pantalla.
12
Además hay otros dos condicionales if que alternan entre dos imágenes de acuerdo a un contador externo
a la clases. La alternancia de las dos imágenes hace que parezca animada.
class Carey():
def __init__(self):
self.carey1 = [Link]("imagen_carey1.png")
[Link] = [Link]("imagen_carey.png")
[Link] = [Link].get_rect()
[Link] = [1, 1]
[Link].move_ip(710, 200)
class Potter():
def __init__(self):
self.potito2 = [Link]("imagen_potito2.png")
self.potito1 = [Link]("imagen_potito1.png")
[Link] = self.potito1.get_rect()
[Link] = [1, 1]
[Link].move_ip(90, 450)
Para dar una apariencia de lluvia o tormenta se alternan dos fondos de pantalla en la clase FondoLluvia(),
uno de tonos grises claros y otros de tonos grises muy oscuros. La clase requiere de un contador externo
para alternan los dos fondos de pantalla.
class FondoLluvia():
def __init__(self):
self.lluvia1 = [Link]("imagen_background_lluvia.png")
self.lluvia2 = [Link]("imagen_background_trueno.png")
13
if contador > 8 and contador <= 16:
[Link](self.lluvia2,(0,0))
Las nubes son tres. Dos de ellas colisionan en la parte superior de la pantalla y una se mueve de izquierda
a derecha en línea recta. Las tres clases son parecidas a las de los gatitos ya comentadas.
class Nube1():
def __init__(self):
[Link] = [Link]("imagen_nube.png")
[Link] = [Link].get_rect()
[Link] = [1, 1]
[Link].move_ip(90, 50)
[Link] = [Link]([Link])
[Link]([Link], [Link])
class Nube2():
def __init__(self):
[Link] = [Link]("imagen_nube.png")
[Link] = [Link].get_rect()
[Link] = [1, 1]
[Link].move_ip(680, 30)
[Link] = [Link]([Link])
[Link]([Link], [Link])
class Nube3():
def __init__(self):
[Link] = [Link]("imagen_nube.png")
[Link] = [Link].get_rect()
[Link] = [1, 0]
[Link].move_ip(400, 30)
[Link] = [Link]([Link])
[Link]([Link], [Link])
14
Las nubes -dice el poeta- nos ofrecen el espectáculo de la vida. La existencia, ¿qué es sino un juego de nubes?
La clase rectángulo me sirvió para reducir muchas líneas de código. Utilicé un ciclo for para imprimir en
pantalla seis rectángulo iguales e igualmente espaciados que utilicé en varios menús. Por defecto, el
código tenía la instrucción polygon (para graficar alguna línea o rectángulo, ya no recuerdo) y lo cambié
por rect porque me resultó más sencillo. Creo que polygon requiere entre otros argumentos cuatro pares
de valores para la posición del rectángulo y polygon requiere sólo cuatro valores (cuatro coordenadas de
los bordes del rectángulo) para lo mismo.
class Rectangulos():
def __init__(self):
self.posX1 = 20*ANCHO/100
self.posX2 = ANCHO-(2*self.posX1)
self.posY1 = 12*ALTO/100
self.posY2 = 10*ALTO/100
[Link] = 0
15
Pueden verse los seis rectángulos que resaltan el menú.
La última clase que tengo listada es una imagen de un farolito. No requiere de mayores comentarios.
class Farol():
def __init__(self):
[Link] = [Link]("imagen_farol.png")
16
6. SONIDOS, ÍCONO, PUNTERO, TECLADO, LEMARIOS,
DIFICULTADES Y OTROS BÁRTULOS
6. 1. Sonidos
Lo que sobró de los apartados anteriores, debería llamarse este apartado. Para utilizar sonidos hay que
iniciar el mixer, luego cargar cada sonido con [Link]() y finalmente llamar al sonido con
[Link]() en la que utilicé dos argumentos. El primero es el sonido a lanzar y el segundo
permite reproducirlo una vez si se deja vacío o, como en el ejemplo, continuamente si se le asigna el
valor -1. Utilicé música de fondo en partes del juego y varios sonidos para enfatizar cuando se gana,
cuando se acierta una palabra, cuando se termina el tiempo sin acertar palabra, etc. A continuación un
pedacito de código:
[Link]()
sonido_mario = [Link]("audio_mario.wav")
[Link](sonido_mario, -1)
sonido_edu = [Link]("audio_edu.mp3")
sonido_marcho = [Link]("audio_marcho.mp3")
sonido_boing = [Link]("audio_boing.mp3")
6. 2. Ícono
icono = [Link]("[Link]")
[Link].set_icon(icono)
6. 3. Puntero
También cambié el puntero. Con la primera línea oculto el puntero común de Windows. Luego cargué
una imagen que voy a usar de puntero y creé dos variables (x, y) que más adelante utilizaré para la
ubicación del puntero.
[Link].set_visible(False)
puntero = [Link]("imagen_mouse.png")
x, y = 0, 0
Ahora solicito las coordenadas actuales del puntero. Les asigno las dos coordenadas en las variables x, y.
Finalmente muestro el puntero con [Link](puntero, [x, y]).
mouse_pos = [Link].get_pos()
x = mouse_pos[0]
y = mouse_pos[1]
[Link](puntero, [x, y])
La ventaja de solicitar las coordenadas del puntero es que puede desencardenarse eventos (como llamar
funciones o reproducir sonidos) si se hace un click en ciertas partes de la ventana. En el siguiente
ejemplo, se reproducen sonidos, se detienen otros sonidos, se hace una brevísima pausa y se cambia de
17
pantalla con la función pantallaComenzar(screen, archivoElegido), si se hace un click en cierto
rectángulo de la pantalla definido por los valores dentro del condicional if.
if y < 212 and y > 152 and x > 160 and x < 640:
if [Link] == [Link]:
[Link](sonido_mario)
[Link](sonido_boing)
[Link](0.2)
[Link]()
pantallaComenzar(screen, archivoElegido)
6. 4. Teclado
También se puede jugar completamente con el teclado. Las mismas sentencias del código anterior se
lanzan si se presiona la tecla a en el teclado.
if [Link] == KEYDOWN:
if [Link] == KEYDOWN:
letra = dameLetraApretada([Link])
if letra == "a":
[Link](sonido_mario)
[Link](sonido_boing)
[Link](0.2)
[Link]()
pantallaComenzar(screen, archivoElegido)
6. 5. Lemarios y dificultades
Se utilizó el lemario que nos dieron por defecto y se crearon otros tres lemarios mucho menos
extensos que el original. Se creó uno de animales de cinco letras, otro de nombres de seis letras y otro
de verbos de siete letras. Se armaron a mano copiando y pegando palabras de la web. Para que
resulten funcionales y no rompan el juego en todos los lemarios se eliminaron las tildes y las letras ñ
reemplazando letras con el Block de Notas de Windows. Para quitar las letras mayúsculas de los
lemarios se creó una función que armaba una lista con las palabras del lemario convertidas a
minúsculas y las guardaba en un nuevo archivo. Esa función se creó ad hoc y se eliminó.
Hay cinco dificultades en el juego. Por defecto, si no se elige ninguna dificultad se juega con palabras
de cinco letras del lemario original extenso. Las restantes cuatro dificultades en el juego se muestran
en la siguiente imagen.
18
Cuatro de las cinco dificultades del juego.
19
7. PIFIES
7. 1. Titileo en títulos
La pantalla Dificultades y la pantalla Récords tienen títulos que hago titilar mostrando alternadamente dos
pantallas que difieren sólo en el color de dichos títulos. Para que la alternancia no resulte muy rápida y el
ojo humano pueda captarla incluí un contador y cada 15 ciclos while (aproximadamente) alterno entre una
y otra pantalla. ¿Cuánto dura un ciclo while? Obviamente la respuesta es depende.
Al principio de todo, cuando las líneas de código eran muy pocas, no tuve problemas con hacer titilar los
títulos. A medida que el código creció en complejidad y los ciclos while crecieron en tamaño comencé a
notar, o ojo, algunas variaciones de frecuencia en el titileo. No es un problema fundamental pero marca la
impronta del videojuego. Fue creado a los tumbos, me daba mañana para hacerlo y lo hacía, sin buscar
alguna propuesta quizás más profesional en la web.
7. 1. Mostrar récords
Me volvió loco, un poco más de lo que estoy. Grabar el nombre de les usuaries y sus puntajes para luego
mostrarlos en pantalla fue algo que resolví (como casi todo) a los palazos, como se dice en el barrio.
Funcionaba en algunos testeos pero crasheaba (¿existe la palabra?) en otros.
El inconveniente más grande se producía al cerrar el videojuego justo en la pantalla de grabar récords
(justito después de terminar el juego habiendo ganado o perdido). Como consecuencia no se grababa el
nombre ni el puntaje sino un simple salto de línea al final de archivo [Link]. Por supuesto que no eso
no es problemático pero las funciones que construí no podían mostrar la pantalla de los récords si eso
sucedía. Dichas funciones separan cada línea del archivo [Link] en strings y enteros. Pero fallaban
rotundamente al encontrarse con una línea con un simple carácter como el salto de línea \n.
Durante semanas le di vueltas al asunto parchando y creando un código demasiado enrevesado. Creaba
nuevas funciones que trataban de evitar la generación de saltos de línea innecesarios cuando se cerraba el
juego abruptamente sin haber grabado nombre y puntaje. Esas funciones las coloqué por acá y por allá.
Probé un sinfín de variantes. Todas malas por cierto. Pero no claudiqué, qué mejor que morir de pie y no
de rodillas.
La solución vino un día mientras dormía o mientras me despertaba. Una solución sencilla. Para mostrar
los mayores puntajes en pantalla generé una lista con cada línea del archivo [Link], excluyendo a
todas aquellas líneas que únicamente tengan el carácter \n. Tan sencillo que me avergonzó.
El punto no es el ejemplo puntual que acabo de contar. Sino saber que esas cosas suceden, sobre todo a
mi y hay estar atentxs para evitarlas. ¿Cómo? Aún no lo sé, seguramente con mayor experiencia,
conocimientos y práctica saldrán mejor las cosas.
20
7. CONCLUSIONES
Principalmente el juego funciona. Ese objetivo se cumplió. Mientras que hacer un código más simple y
agregar nuevo contenido al juego es algo que me quedó pendiente y que escapa a mis posibilidades hoy
en día. De todos modos el desarrollo del video juego me permitió repasar la gran mayoría de los
contenidos de la materia Introducción a la Programación y entender el tenor y las instrucciones básicas de
la librería Pygame.
Algunas detalles que me quedaron en el tintero fueron comentados en el apartado anterior llamado Pifies.
Todo es perfectible, más aún este programa que hice. Existe una modificación al juego que puede hacer
más amable jugarlo, que me quedó en el tintero y creo que no comenté antes. La modificación consiste en
colorear las letras correctas, incorrectas y casi en las palabras que se ingresaron y no en el abecedario.
Sería más fácil visualizar la posición correcta de las letras.
21
7. ANEXOS
El código se copia completo a continuación, no sé si tiene sentido. Son decenas de páginas y al copiar y
pegar se distorsiona un poco el formato por lo que tuve que arreglarlo a mano línea por línea
7. 1. principal
#! /usr/bin/env Python
import os, random, sys, math, pygame, time
#Funcion principal
def main():
#[Link]()
[Link]()
22
[Link]()
sonido_mario = [Link]("audio_mario.wav")
[Link](sonido_mario, -1)
sonido_edu = [Link]("audio_edu.mp3")
sonido_marcho = [Link]("audio_marcho.mp3")
sonido_boing = [Link]("audio_boing.mp3")
#Preparar la ventana
[Link].set_caption("La escondida...")
screen = [Link].set_mode((ANCHO, ALTO))
#fondo, icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
contadorGatitx = 0
carey = Carey()
potter = Potter()
#Mouse
[Link].set_visible(False) #Oculto puntero, luego muestro imagen
puntero = [Link]("imagen_mouse.png")
x, y = 0, 0
letra = ""
menu(screen, letra)
archivoElegido = "lemario"
while True:
#Buscar la tecla apretada del modulo de eventos de pygame
for e in [Link]():
23
if [Link] == [Link]:
[Link](sonido_mario)
[Link](sonido_boing)
[Link](0.2)
[Link]()
archivoElegido = pantallaMostrarDificultad(screen, archivoElegido)
if y < 464 and y > 392 and x > 160 and x < 640:
if [Link] == [Link]:
[Link](sonido_mario)
[Link](0.2)
[Link]()
menuLluvia(screen)
if y < 544 and y > 472 and x > 160 and x < 640:
if [Link] == [Link]:
[Link](sonido_mario)
[Link](sonido_marcho)
[Link](1.5)
[Link]()
return()
24
mouse_pos = [Link].get_pos()
x = mouse_pos[0]
y = mouse_pos[1]
[Link](puntero, [x, y])
[Link](screen, contadorGatitx)
[Link](screen, contadorGatitx)
#Para alternar las imágenes de cada gatitx
contadorGatitx += 1
if contadorGatitx == 51:
contadorGatitx = 0
menu(screen, letra)
[Link]()
while 1:
#Esperar el QUIT del usuario
for e in [Link]():
if [Link] == QUIT:
[Link]
return
[Link]()
#Programa Principal ejecuta Main
if __name__ == "__main__":
main()
7. 2. funcionesVACIAS
return salida
25
#revisa y guarda en lista las letras correctas
def revisionCorrectas(letra, palabraCorrecta, indice, lista):
if encontrarLetra(palabraCorrecta, letra) and (letra == palabraCorrecta[indice]): #si la letra SI se
encuentra en la palabraCorrecta pero NO coincide posición
if not encontrarLetra(lista, letra): #verifico para agregar la letra a la lista correctas una sola vez
[Link](letra)
#busca letra
def encontrarLetra(cadena, caracter):
for letra in cadena:
if caracter == letra:
return True
else:
return False
26
#Hizo un afunción gano para poder llamarla desde varios módulos
def gano(palabraCorrecta, palabraUsuario, correctas, incorrectas, casi):
return revision(palabraCorrecta, palabraUsuario, correctas, incorrectas, casi)
return palabra
return nuevaLista
27
listaAuxNombres = listaNombres[:]
salida = []
auxiliar = listaAuxNombres[i]
listaAuxNombres[i] = listaAuxNombres[i-1]
listaAuxNombres[i-1] = auxiliar
#sonidos
sonido_victory = [Link]("audio_victory.mp3")
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
puntos = 0
palabraUsuario = ""
listaPalabrasDiccionario = []
listaDePalabrasUsuario = []
correctas = []
incorrectas = []
casi = []
gano = False
intentos = 5
pasarAPantallaFinalGanador = False
pasarAPantallaFinalNoGanador = False
archivo = open("[Link]", "r")
extra_puntos = 1.6
28
while segundos > fps/1000 and intentos > 0 and not gano:
# 1 frame cada 1/fps segundos
[Link](fps)
totaltime += gameClock.get_time()
if True:
fps = 3
if gano:
#asigna puntaje para quien gana
puntos = puntos + len(correctas) * 2 * extra_puntos
#lectura del diccionario
lectura(archivo, listaPalabrasDiccionario, LARGO)
#elige una al azar
palabraCorrecta = nuevaPalabra(listaPalabrasDiccionario)
totalmentePorTiempo(screen, listaDePalabrasUsuario, palabraUsuario, puntos,
segundos, gano, correctas, incorrectas, casi, LARGO, listaPalabrasDiccionario)
print(palabraCorrecta)
listaDePalabrasUsuario = []
correctas = []
incorrectas = []
casi = []
gano = False
[Link](palabraUsuario)
palabraUsuario = ""
else:
[Link](palabraUsuario)
palabraUsuario = "" #si pifia en longitud o fuera de diccionario sigue probando sin
descontar intento
#ni contabilizar correctas, ni incorrectas ni casi
29
#Limpiar pantalla anterior
[Link](fondo,(0,0))
#Reinicio reloj
[Link]()
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
puntos = 0
palabraUsuario = ""
listaPalabrasDiccionario = []
listaDePalabrasUsuario = []
correctas = []
incorrectas = []
casi = []
gano = False
intentos = 5
pasarAPantallaFinalGanador = False
pasarAPantallaFinalNoGanador = False
archivo = open("[Link]", "r")
acumulador = 0
LARGO = 5
if archivoElegido == "lemario":
archivo = open("[Link]", "r")
extra_puntos = 1.3
if archivoElegido == "animales":
archivo = open("[Link]", "r")
LARGO = 5
30
extra_puntos = 1
if archivoElegido == "nombres":
archivo = open("[Link]", "r")
LARGO = 6
extra_puntos = 1.2
if archivoElegido == "verbos":
archivo = open("[Link]", "r")
extra_puntos = 1.4
LARGO = 7
if archivoElegido == "totalmente_por_tiempo":
pantallaTotalmentePorTiempo()()
gano = True
while segundos > fps/1000 and intentos > 0 and not gano:
# 1 frame cada 1/fps segundos
[Link](fps)
totaltime += gameClock.get_time()
if True:
fps = 3
31
[Link](palabraUsuario)
palabraUsuario = ""
intentos -= 1
else:
[Link](palabraUsuario)
palabraUsuario = "" #si pifia en longitud o fuera de diccionario sigue probando sin
descontar intento
#ni contabilizar correctas, ni incorrectas ni casi
#asigna puntaje a quien pierde
if intentos == 0:
puntos = len(correctas) * 2
pasarAPantallaFinalNoGanador = True
#Reinicio reloj
[Link]()
#sonidos
sonido_victory = [Link]("audio_victory.mp3")
[Link](sonido_victory)
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
pasarAModuloMenuInicial = False
palabraIngresada = ""
archivoRecords = open("[Link]","a")
saludoGanador(screen, puntos, segundos, correctas, incorrectas, casi, intentos, palabraIngresada)
32
while not pasarAModuloMenuInicial:
#Buscar la tecla apretada del modulo de eventos de pygame
for e in [Link]():
[Link]()
#sonidos
sonido_defeat = [Link]("audio_defeat.mp3")
[Link](sonido_defeat)
33
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
pasarAModuloMenuInicial = False
palabraIngresada = ""
archivoRecords = open("[Link]","a")
saludoNoGanador(screen, puntos, segundos, correctas, incorrectas, casi, intentos,
palabraIngresada)
while not pasarAModuloMenuInicial:
#Buscar la tecla apretada del modulo de eventos de pygame
for e in [Link]():
#QUIT es apretar la X en la ventana
if [Link] == QUIT:
[Link]()
return()
[Link]()
34
#Funcion muestra los mayores records
def pantallaMostrarRecords(screen):
#sonidos
sonido_boing = [Link]("audio_boing.mp3")
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
contadorTitilaRecords = 1
pasarAModuloMenuInicial = False
palabraIngresada = ""
archivoRecords = open("[Link]","a")
mostrarRecords(screen, contadorTitilaRecords)
[Link](sonido_boing)
[Link](0.2)
letra = ""
#sonidos
sonido_boing = [Link]("audio_boing.mp3")
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
35
[Link].set_icon(icono)
letra = ""
contadorTitilaDificultad = 1
dificultad(screen, letra, contadorTitilaDificultad)
seguirEnDificultad = True
contadorTitilaDificultad = 1
#Mouse
[Link].set_visible(False) #Oculto puntero, luego muestro imagen
puntero = [Link]("imagen_mouse.png")
x, y = 0, 0
while seguirEnDificultad:
#Buscar la tecla apretada del modulo de eventos de pygame
for e in [Link]():
#QUIT es apretar la X en la ventana
if [Link] == QUIT:
[Link]()
return()
archivoElegido = "animales"
seguirEnDificultad = False
if letra == "b":
archivoElegido = "nombres"
seguirEnDificultad = False
if letra == "c":
archivoElegido = "verbos"
36
seguirEnDificultad = False
if letra == "d":
archivoElegido = "totalmente_por_tiempo"
seguirEnDificultad = False
if [Link] == K_x or [Link] == K_SPACE:
seguirEnDificultad = False
letra = ""
[Link](sonido_boing)
[Link](0.2)
mouse_pos = [Link].get_pos()
x = mouse_pos[0]
y = mouse_pos[1]
[Link](puntero, [x, y])
return archivoElegido
#[Link]()
sonido_lluvia = [Link]("audio_lluvia.mp3")
sonido_trueno = [Link]("audio_truenos.mp3")
sonido_trueno2 = [Link]("audio_truenos2.mp3")
sonido_mau = [Link]("audio_mau.mp3")
sonido_maullido = [Link]("audio_maullido.mp3")
[Link](sonido_lluvia, -1)
[Link](sonido_trueno, -1)
[Link](sonido_trueno2, -1)
contador_fondo_lluvia = 0
gotas = [Gota() for _ in range(100)]
fondo_lluvia = FondoLluvia()
nube1 = Nube1()
nube2 = Nube2()
nube3 = Nube3()
carey = Carey()
potter = Potter()
farol = Farol()
contadorGatitx = 0
pasarAMenu = False
letra = ""
menuTormenta(screen, letra)
37
#Mouse
[Link].set_visible(False) #Oculto puntero, luego muestro imagen
puntero = [Link]("imagen_mouse.png")
x, y = 0, 0
#mostrar fondo, mover gatito, alternar gatito, mostrar menu, mostar lluvia
menuTormenta(screen, letra)
mouse_pos = [Link].get_pos()
x = mouse_pos[0]
y = mouse_pos[1]
[Link](puntero, [x, y])
38
#Mover nubes
[Link](screen)
[Link](screen)
[Link](screen)
[Link](screen)
menuTormenta(screen, letra)
for gota in gotas:
[Link]()
[Link](screen)
[Link](screen, contadorGatitx)
[Link](screen, contadorGatitx)
contadorGatitx += 1
if contadorGatitx == 51:
contadorGatitx = 0
[Link]()
6. 4. extras
def dameLetraApretada(key):
if key == K_a:
return("a")
elif key == K_b:
return("b")
elif key == K_c:
return("c")
elif key == K_d:
return("d")
elif key == K_e:
return("e")
elif key == K_f:
return("f")
elif key == K_g:
return("g")
elif key == K_h:
return("h")
39
elif key == K_i:
return("i")
elif key == K_j:
return("j")
elif key == K_k:
return("k")
elif key == K_l:
return("l")
elif key == K_m:
return("m")
elif key == K_n:
return("n")
elif key == K_o:
return("o")
elif key == K_p:
return("p")
elif key == K_q:
return("q")
elif key == K_r:
return("r")
elif key == K_s:
return("s")
elif key == K_t:
return("t")
elif key == K_u:
return("u")
elif key == K_v:
return("v")
elif key == K_w:
return("w")
elif key == K_x:
return("x")
elif key == K_y:
return("y")
elif key == K_z:
return("z")
elif key == K_SLASH:
return("-")
#Linea Horizontal
[Link](screen, (255,255,255), (0, ALTO-70) , (ANCHO, ALTO-70), 5)
40
#muestra lo que escribe el jugador
[Link]([Link](palabraUsuario, 1, COLOR_TEXTO), (ANCHO//2-
len(palabraUsuario)*TAMANNO_LETRA//4, 555))
#muestra el puntaje
[Link]([Link]("Puntos: " + str(puntos), 1, COLOR_TEXTO), (640, 10))
x += TAMANNO_LETRA
if encontrarLetra(correctas, [Link]()):
color = COLOR_LETRAS_CORRECTAS
elif encontrarLetra(incorrectas, [Link]()):
color = COLOR_LETRAS_INCORRECTAS
elif encontrarLetra(casi, [Link]()):
color = COLOR_LETRAS_CASI
else:
color = COLOR_LETRAS_ABCDARIO
[Link]([Link](letra, 1, color), (10 + x, ALTO/1.5 + y))
41
#Linea Horizontal
[Link](screen, (255,255,255), (0, ALTO-70) , (ANCHO, ALTO-70), 5)
#muestra el puntaje
[Link]([Link]("Puntos: " + str(puntos), 1, COLOR_TEXTO), (640, 10))
pos += 1
42
def menu(screen, palabraUsuario):
defaultFontNormal= [Link]( [Link].get_default_font(), TAMANNO_LETRA_NORMAL)
defaultFontPequenna= [Link]( [Link].get_default_font(), TAMANNO_LETRA_PEQUENNA)
defaultFont= [Link]( [Link].get_default_font(), TAMANNO_LETRA)
defaultFontTitulo= [Link]( [Link].get_default_font(), TAMANNO_LETRA_TITULO)
#rectangulos
rectangulos = Rectangulos()
[Link](screen, 80, COLOR_RECTANGULOS) #screen, cantidad de rectángulos, altura
#Linea Horizontal
[Link](screen, (255,255,255), (0, ALTO-70) , (ANCHO, ALTO-70), 5)
#muestra el puntaje
[Link]([Link]("Puntos: " + str(puntos), 1, COLOR_TEXTO), (640, 10))
43
ren = [Link]("Tiempo: " + str(int(segundos)), 1, COLOR_TEXTO)
[Link](ren, (10, 10))
#rectangulo
color = (46,211,189)
puntos = [(80,2*ALTO/5),(ANCHO-80,2*ALTO/5),(ANCHO-80,3*ALTO/5),(80,3*ALTO/5)]
[Link](screen,color,puntos)
#Linea Horizontal
[Link](screen, (255,255,255), (0, ALTO-70) , (ANCHO, ALTO-70), 5)
#muestra el puntaje
[Link]([Link]("Puntos: " + str(puntos), 1, COLOR_TEXTO), (640, 10))
44
else:
ren = [Link]("Tiempo: " + str(int(segundos)), 1, COLOR_TEXTO)
[Link](ren, (10, 10))
#rectangulo
color = (46,211,189)
puntos = [(80,2*ALTO/5),(ANCHO-80,2*ALTO/5),(ANCHO-80,3*ALTO/5),(80,3*ALTO/5)]
[Link](screen,color,puntos)
#rectangulos
color = (46,211,189)
x1 = 20*ANCHO/100
y1, y2 = 12*ALTO/100, 76*ALTO/100
[Link](screen,color,[Link](x1, y1, ANCHO-(2*x1), y2), 2, 3) #cambié de polygon a
rect
#Título
titulo = "RECORDS "
if contadorTitilaRecords % 2 == 0:
[Link]([Link](titulo, 1, COLOR_BLANCO), (ANCHO//2-
len(titulo)*TAMANNO_LETRA_GRANDE//5, 90))
else:
[Link]([Link](titulo, 1, COLOR_GRIS), (ANCHO//2-
len(titulo)*TAMANNO_LETRA_GRANDE//5, 90))
45
#Lee archivo [Link]
archivoRecords = open("[Link]","r")
listaRecords = []
listaNombres = []
listaPuntajes = []
listaPuntajesOrdenados = []
listaNombresOrdenados = []
listaAuxPuntajes = []
listaAuxNombres = []
listaAuxPuntajes, listaAuxNombres = ordenarPuntajes(listaPuntajes, listaNombres)
y = 125
espacio = 40
#Muestra los 9 máximos puntjaes, sino hay aún nueve records cargados muestra menos
if len(listaAuxPuntajes) < 9:
maximo = len(listaAuxPuntajes)
else:
maximo = 9
#rectangulos
rectangulos = Rectangulos()
[Link](screen, 80, COLOR_RECTANGULOS) #screen, cantidad de rectángulos, altura,
cardinal(en qué rectángulo comenzar a dibujar), borde
46
#palabras del menú
y2 = 14*ALTO/100
opcionesMenu = ["DIFICULTADES ", "a - Animales 5 letras ", "b - Nombres 6 letras ", "c - Verbos 7
letras", "d - Totalmente por tiempo ","x - Volver, con la frente marchita"] #me encanta esta manera de
centrar palabras
for i in range(0, len(opcionesMenu), 1):
if i == 0:
if contadorTitilaDificultad % 2 == 0:
[Link]([Link](opcionesMenu[i], 1, COLOR_BLANCO), (ANCHO//2-
(len(opcionesMenu[i])-2)*TAMANNO_LETRA_NORMAL//4, y2))
y2 += 86
else:
[Link]([Link](opcionesMenu[i], 1, COLOR_GRIS), (ANCHO//2-
(len(opcionesMenu[i])-2)*TAMANNO_LETRA_NORMAL//4, y2))
y2 += 86
if i > 0:
[Link]([Link](opcionesMenu[i], 1, COLOR_BLANCO), (ANCHO//2-
(len(opcionesMenu[i])-2)*TAMANNO_LETRA_PEQUENNA//4, y2))
y2 += 80
#rectangulos
rectangulos = Rectangulos()
[Link](screen, 80, COLOR_RECTANGULOS) #screen, cantidad de rectángulos, altura,
cardinal(en qué rectángulo comenzar a dibujar), borde
47
#muestra lo que escribe el jugador
[Link]([Link](palabraUsuario, 1, COLOR_BLANCO), (ANCHO//2-
LARGO*TAMANNO_LETRA//4, 550))
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
puntos = 0
palabraUsuario = ""
listaPalabrasDiccionario = []
listaDePalabrasUsuario = []
correctas = []
incorrectas = []
casi = []
gano = False
intentos = 5
pasarAPantallaFinalGanador = False
pasarAPantallaFinalNoGanador = False
archivo = open("[Link]", "r")
extra_puntos = 1.6
while segundos > fps/1000 and intentos > 0 and not gano:
# 1 frame cada 1/fps segundos
[Link](fps)
totaltime += gameClock.get_time()
if True:
fps = 3
48
#Ver si fue apretada alguna tecla
if [Link] == KEYDOWN:
letra = dameLetraApretada([Link])
palabraUsuario += letra #es la palabra que escribe el usuario
if [Link] == K_BACKSPACE:
palabraUsuario = palabraUsuario[0:len(palabraUsuario)-1]
if [Link] == K_RETURN:
#falta hacer un control para que sea una palabra de la longitud deseada
#falta controlar que la palabra este en el diccionario
if controlarPalabraIngresada (palabraUsuario, LARGO, listaPalabrasDiccionario):
gano = revision(palabraCorrecta, palabraUsuario, correctas, incorrectas, casi)
if gano:
#asigna puntaje para quien gana
puntos = puntos + len(correctas) * 2 * extra_puntos
#lectura del diccionario
lectura(archivo, listaPalabrasDiccionario, LARGO)
#elige una al azar
palabraCorrecta = nuevaPalabra(listaPalabrasDiccionario)
totalmentePorTiempo(screen, listaDePalabrasUsuario, palabraUsuario, puntos,
segundos, gano, correctas, incorrectas, casi, LARGO, listaPalabrasDiccionario)
print(palabraCorrecta)
listaDePalabrasUsuario = []
correctas = []
incorrectas = []
casi = []
gano = False
[Link](palabraUsuario)
palabraUsuario = ""
else:
[Link](palabraUsuario)
palabraUsuario = "" #si pifia en longitud o fuera de diccionario sigue probando sin
descontar intento
#ni contabilizar correctas, ni incorrectas ni casi
49
#Reinicio reloj
[Link]()
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
puntos = 0
palabraUsuario = ""
listaPalabrasDiccionario = []
listaDePalabrasUsuario = []
correctas = []
incorrectas = []
casi = []
gano = False
intentos = 5
pasarAPantallaFinalGanador = False
pasarAPantallaFinalNoGanador = False
archivo = open("[Link]", "r")
acumulador = 0
LARGO = 5
if archivoElegido == "lemario":
archivo = open("[Link]", "r")
extra_puntos = 1.3
if archivoElegido == "animales":
archivo = open("[Link]", "r")
LARGO = 5
extra_puntos = 1
if archivoElegido == "nombres":
archivo = open("[Link]", "r")
LARGO = 6
extra_puntos = 1.2
if archivoElegido == "verbos":
archivo = open("[Link]", "r")
extra_puntos = 1.4
LARGO = 7
50
print(palabraCorrecta)
if archivoElegido == "totalmente_por_tiempo":
pantallaTotalmentePorTiempo()()
gano = True
while segundos > fps/1000 and intentos > 0 and not gano:
# 1 frame cada 1/fps segundos
[Link](fps)
totaltime += gameClock.get_time()
if True:
fps = 3
[Link](palabraUsuario)
palabraUsuario = ""
intentos -= 1
else:
[Link](palabraUsuario)
palabraUsuario = "" #si pifia en longitud o fuera de diccionario sigue probando sin
descontar intento #ni contabilizar correctas, ni incorrectas ni casi
51
pantallaFinalGanador(screen, listaDePalabrasUsuario, puntos, segundos, gano,
correctas, incorrectas, casi, intentos, LARGO, archivo, listaPalabrasDiccionario)
gano = True
if pasarAPantallaFinalNoGanador:
[Link](0.2)
pantallaFinalNoGanador(screen, listaDePalabrasUsuario, puntos, segundos, gano,
correctas, incorrectas, casi, intentos, LARGO, archivo, listaPalabrasDiccionario)
else:
dibujar(screen, listaDePalabrasUsuario, palabraUsuario, puntos, segundos, gano,
correctas, incorrectas, casi, intentos, LARGO, listaPalabrasDiccionario)
[Link]()
#Reinicio reloj
[Link]()
#sonidos
sonido_victory = [Link]("audio_victory.mp3")
[Link](sonido_victory)
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
pasarAModuloMenuInicial = False
palabraIngresada = ""
archivoRecords = open("[Link]","a")
saludoGanador(screen, puntos, segundos, correctas, incorrectas, casi, intentos, palabraIngresada)
while not pasarAModuloMenuInicial:
#Buscar la tecla apretada del modulo de eventos de pygame
for e in [Link]():
#QUIT es apretar la X en la ventana
if [Link] == QUIT:
[Link]()
return()
52
#Guardo las primeras cuatro letras si el nombre es largo
palabraIngresada = palabraIngresada[0:4]
pasarAModuloMenuInicial = True
[Link]()
#sonidos
sonido_defeat = [Link]("audio_defeat.mp3")
[Link](sonido_defeat)
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
pasarAModuloMenuInicial = False
palabraIngresada = ""
archivoRecords = open("[Link]","a")
53
#Recorto y completo caracteres
if len(palabraIngresada) == 0:
palabraIngresada += "@@@@"
if len(palabraIngresada) == 1:
palabraIngresada += "@@@"
if len(palabraIngresada) == 2:
palabraIngresada += "@@"
if len(palabraIngresada) == 3:
palabraIngresada += "@"
pasarAModuloMenuInicial = True
[Link]()
#sonidos
sonido_boing = [Link]("audio_boing.mp3")
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
contadorTitilaRecords = 1
pasarAModuloMenuInicial = False
palabraIngresada = ""
archivoRecords = open("[Link]","a")
mostrarRecords(screen, contadorTitilaRecords)
#Mouse
[Link].set_visible(False) #Oculto puntero, luego muestro imagen
puntero = [Link]("imagen_mouse.png")
x, y = 0, 0
54
#QUIT es apretar la X en la ventana
if [Link] == QUIT:
[Link]()
return()
if y < 600 and y > 456 and x > 160 and x < 640:
if [Link] == [Link]:
pasarAModuloMenuInicial = True
if [Link] == KEYDOWN:
letra = dameLetraApretada([Link])
if [Link] == K_x or [Link] == K_SPACE:
pasarAModuloMenuInicial = True
[Link](sonido_boing)
[Link](0.2)
letra = ""
mouse_pos = [Link].get_pos()
x = mouse_pos[0]
y = mouse_pos[1]
[Link](puntero, [x, y])
[Link]()
#sonidos
sonido_boing = [Link]("audio_boing.mp3")
#fondo e icono
fondo = [Link]("[Link]")
icono = [Link]("[Link]")
[Link].set_icon(icono)
letra = ""
contadorTitilaDificultad = 1
dificultad(screen, letra, contadorTitilaDificultad)
seguirEnDificultad = True
contadorTitilaDificultad = 1
#Mouse
[Link].set_visible(False) #Oculto puntero, luego muestro imagen
puntero = [Link]("imagen_mouse.png")
x, y = 0, 0
while seguirEnDificultad:
55
#Buscar la tecla apretada del modulo de eventos de pygame
for e in [Link]():
#QUIT es apretar la X en la ventana
if [Link] == QUIT:
[Link]()
return()
if letra == "a":
archivoElegido = "animales"
seguirEnDificultad = False
if letra == "b":
archivoElegido = "nombres"
seguirEnDificultad = False
if letra == "c":
archivoElegido = "verbos"
seguirEnDificultad = False
if letra == "d":
archivoElegido = "totalmente_por_tiempo"
seguirEnDificultad = False
if [Link] == K_x or [Link] == K_SPACE:
seguirEnDificultad = False
letra = ""
[Link](sonido_boing)
[Link](0.2)
56
x = mouse_pos[0]
y = mouse_pos[1]
[Link](puntero, [x, y])
#[Link]()
sonido_lluvia = [Link]("audio_lluvia.mp3")
sonido_trueno = [Link]("audio_truenos.mp3")
sonido_trueno2 = [Link]("audio_truenos2.mp3")
sonido_mau = [Link]("audio_mau.mp3")
sonido_maullido = [Link]("audio_maullido.mp3")
[Link](sonido_lluvia, -1)
[Link](sonido_trueno, -1)
[Link](sonido_trueno2, -1)
contador_fondo_lluvia = 0
gotas = [Gota() for _ in range(100)]
fondo_lluvia = FondoLluvia()
nube1 = Nube1()
nube2 = Nube2()
nube3 = Nube3()
carey = Carey()
potter = Potter()
farol = Farol()
contadorGatitx = 0
pasarAMenu = False
letra = ""
menuTormenta(screen, letra)
#Mouse
[Link].set_visible(False) #Oculto puntero, luego muestro imagen
puntero = [Link]("imagen_mouse.png")
x, y = 0, 0
57
[Link](sonido_lluvia)
[Link](sonido_trueno)
[Link](sonido_trueno2)
#mostrar fondo, mover gatito, alternar gatito, mostrar menu, mostar lluvia
menuTormenta(screen, letra)
for gota in gotas:
[Link]()
[Link](screen)
fondo_lluvia.show(screen, contador_fondo_lluvia)
if contador_fondo_lluvia == 17:
contador_fondo_lluvia = 0
contador_fondo_lluvia += 1
mouse_pos = [Link].get_pos()
x = mouse_pos[0]
y = mouse_pos[1]
[Link](puntero, [x, y])
#Mover nubes
[Link](screen)
[Link](screen)
[Link](screen)
[Link](screen)
menuTormenta(screen, letra)
[Link]()
6. 4. configuracion
58
TAMANNO_LETRA_MINI = 14
TAMANNO_LETRA_PEQUENNA = 21
TAMANNO_LETRA = 23
TAMANNO_LETRA_TITULO = 36
TAMANNO_LETRA_NORMAL = 40
TAMANNO_LETRA_GRANDE = 62
FPS_inicial = 3
TIEMPO_MAX = 151
ANCHO = 800
ALTO = 600
LARGO = 5
6. 4. clases
def caida(self):
self.y += [Link]
[Link] += 0.005
59
def show(self, screen):
[Link](screen, (0,0,0), (self.x, self.y), (self.x, (self.y)+[Link]), 2)
#Gatita
class Carey():
def __init__(self):
self.carey1 = [Link]("imagen_carey1.png")
[Link] = [Link]("imagen_carey.png")
[Link] = [Link].get_rect()
[Link] = [1, 1]
[Link].move_ip(710, 200)
#Gatito
class Potter():
def __init__(self):
self.potito2 = [Link]("imagen_potito2.png")
self.potito1 = [Link]("imagen_potito1.png")
[Link] = self.potito1.get_rect()
[Link] = [1, 1]
[Link].move_ip(90, 450)
60
if contador > 8 and contador <= 16:
[Link](self.lluvia2,(0,0))
#Nubes de tormenta
class Nube1():
def __init__(self):
[Link] = [Link]("imagen_nube.png")
[Link] = [Link].get_rect()
[Link] = [1, 1]
[Link].move_ip(90, 50)
class Nube2():
def __init__(self):
[Link] = [Link]("imagen_nube.png")
[Link] = [Link].get_rect()
[Link] = [1, 1]
[Link].move_ip(680, 30)
class Nube3():
def __init__(self):
[Link] = [Link]("imagen_nube.png")
[Link] = [Link].get_rect()
[Link] = [1, 0]
[Link].move_ip(400, 30)
61
def __init__(self):
self.posX1 = 20*ANCHO/100
self.posX2 = ANCHO-(2*self.posX1)
self.posY1 = 12*ALTO/100
self.posY2 = 10*ALTO/100
[Link] = 0
#Farolito
class Farol():
def __init__(self):
[Link] = [Link]("imagen_farol.png")
62