Programar Juegos Arcade con Python y Pygame

Programar Juegos Arcade
con Python y Pygame

Chapter 1: Crear una Calculadora Personal

(¡Hola! Si aún no tienes una máquina con Python y Pygame instalado, entonces regresa a la sección “anterior” para descargar e instalarlos para que puedas empezar.)

1.1 Introducción

fig.trajectory

Una de las cosas más simples que se pueden hacer con Python es usarlo como una sofisticada calculadora. Pero espera, una calculadora no es un juego. ¿Por qué estamos hablando de calculadoras? Me aburro....

Ten paciencia, para calcular objetos cayendo y balas volando, así como las puntuaciones, necesitamos cálculos. Además, ¡cualquier geek auténtico considera una calculadora más como un juguete que como un dispositivo de tortura! Vamos a empezar nuestro aprendizaje de juegos con calculadoras. No te preocupes, comenzaremos con los gráficos en el capítulo 5.

Un sencillo programa calculadora puede ser usado para pedir información al usuario, y luego calcular cosas aburridas como pagos de hipotecas, o cosas más excitantes como la trayectoria de bolas de barro al ser lanzadas al aire.

Como primer ejemplo calcularemos la energía cinética, algo que necesitaremos hacer como parte de un motor de juego de física.

fig.kinetic_energy
Figure 1.1: Usando Python Para Calcular La Energía Cinética

Lo mejor de hacer esto como un programa, es la habilidad de ocultar las complejidades de una ecuación. Todo lo que el usuario necesita hacer es dar la información y él o ella, podrá obtener el resultado en un formato fácil de entender. Cualquier aplicación del tipo calculadora podría funcionar en un smartphone, permitiendo a cualquier persona, llevar a cabo fácilmente cálculos en cualquier lugar.

1.2 Imprimir

1.2.1 Imprimir Texto

¿Cómo imprime un programa algo en pantalla?

print("Hola Mundo.")
fig.printing_calculator

Este programa imprime “Hola Mundo” en pantalla. Continúa e introdúcelo en el prompt del IDLE, y mira como funciona. Intenta imprimir otras palabras y frases. Por lo general, el ordenador imprimirá cualquier cosa que quieras, sea verdad o no.

¿Cómo sería el programa “Hola Mundo” en otros lenguajes de programación? Compruébalo en la Wikipedia. En ella se muestran una buena cantidad de programas de “Hola Mundo” escritos en varios lenguajes de programación distintos:
http://es.wikipedia.org/wiki/Hola_mundo

Es interesante ver cuántos lenguajes de programación distintos existen. Puedes hacerte una idea de lo complejo que es un lenguaje viendo la forma de programar “Hola Mundo”.

Vídeo: La función print

Recuerda, el comando para imprimir en Python es fácil. Simplemente escribe print. Después del comando print hay un par de paréntesis ( ). Dentro de estos paréntesis está lo que debería ser imprimido por pantalla. El usar paréntesis para pasar información a una función es una práctica habitual en matemáticas y lenguajes de programación.

Los estudiantes de matemáticas aprenden a usar paréntesis evaluando expresiones como $seno(\theta)=coseno(\frac{\pi}{2}-\theta)$. $seno$ y $coseno$ son funciones. Los datos pasados a estas funciones están entre los paréntesis. Nuestro caso difiere en que la información pasada es texto.

Fíjate que hay comillas dobles rodeando el texto a ser imprimido. Si una declaración de print tiene comillas rodeando el texto, el ordenador lo imprimirá tal cual está escrito. Por ejemplo, este programa imprimirá 2+3:

print("2 + 3")

1.2.2 Imprimir Resultados de Operaciones

El siguiente programa no tiene comillas rodeando $2+3$, y el ordenador lo evaluará como una expresión matemática. Imprimirá 5 en vez de 2+3.

print(2 + 3)

El código siguiente provocará un error porque el ordenador intentará evaluar “Hola Mundo” como una expresión matemática y eso no funcionará:

print(Hola Mundo)

El código anterior imprimirá un error del tipo SyntaxError: invalid syntax, que es la manera en que expresa el ordenador su desconocimiento de “Hola” y “Mundo”.

Ten en cuenta, también, que esto es una comilla simple: ' y esto una doble: " Si pido una comilla doble es un error común escribir "" que realmente es una doble doble comilla.

1.2.3 Imprimir Múltiples Elementos

Una declaración print puede sacar múltiples cosas a la vez, cada elemento separado por una coma. Por ejemplo, este código imprimirá Tu nueva puntuación es 1040

print("Tu nueva puntuación es ", 1030 + 10)

La próxima línea de código imprimirá Tu nueva puntuación es 1030+10. Los números no se suman porque están entre comillas. Cualquier cosa entre comillas es tratada por el ordenador como texto. El ordenador piensa que cualquier cosa fuera de ellas es una declaración matemática o código.

print("Tu nueva puntuación es ", "1030 + 10")
La coma, ¿va dentro o fuera de las comillas?

El siguiente código de ejemplo no funciona de ninguna manera. Esto es porque no hay una coma separando el texto que está entre comillas y el 1030+10. A primera vista puede parecer que hay una coma, pero la coma está dentro de las comillas. La coma que separa los elementos a imprimir debe estar fuera de las comillas. Si el programador quiere imprimir una coma, ésta debe estar entre las comillas:

print("Tu nueva puntuación es," 1030 + 10)

El próximo ejemplo sí funciona, porque hay una coma separando los elementos. Imprime:
Tu nueva puntuación es, 1040
Fíjate que solo imprime una coma. Las comas fuera de las comillas separan elementos, las comas dentro de las comillas son imprimidas. La primera coma es imprimida, la segunda es usada para separar los elementos.

print("Tu nueva puntuación es,", 1030 + 10)

1.3 Códigos de Escape

Si se usan comillas para indicarle al ordenador el comienzo y el final de la cadena de texto que deseas imprimir, ¿cómo conseguimos que un programa imprima un conjunto de comillas dobles? Por ejemplo:

print("Quiero imprimir comillas dobles " por alguna razón.")

Este código no funcionará. El ordenador se fija en las comillas del centro de la cadena y piensa que es el final del texto. Por ello no sabe qué hacer con el comando por alguna razón y las comillas del final de la cadena confunden al ordenador todavía más.

Es necesario decirle al ordenador que queremos tratar las comillas dobles del medio como texto, no como las comillas finales de una cadena. Esto es fácil, simplemente coloca una contrabarra (o barra inversa) delante de las comillas para decirle al ordenador que son parte de una cadena y no un caracter que finaliza una cadena. Por ejemplo:

print("Quiero imprimir una comilla doble \" por alguna razón.")
fig.escape_codes

Esta combinación de dos caracteres \" se conoce como código de escape. Casi todos los lenguajes los tienen. Debido a que la contrabarra se usa como código de escape, la propia contrabarra debe ser precedida por un código de escape. Por ejemplo, este código no funcionará correctamente:

print("El archivo está guardado en C:\nueva carpeta")

¿Por qué? Porque \n es un código de escape. Para imprimir la contrabarra es necesario usar el código de escape de la siguiente manera:

print("El archivo está guardado en C:\\nueva carpeta")

Tenemos que aprender unos cuantos códigos de escape importantes más. Esta es la tabla de los más importantes:
Código de escapeDescripción
\'Comilla simple
\"Comilla doble
\tTabulador
\rCR: Retorno de Carro (mover a la izquierda)
\nLF: Salto de línea (mover abajo)

¿Qué es un “Retorno de Carro” y qué un “Salto de línea”? Intenta este ejemplo:

print("Este\nes\nmi\nejemplo.")

La salida de este comando es:

Este
es
mi
ejemplo.

La \n es un salto de línea. Mueve el “cursor” una línea más abajo y ahí será donde el ordenador imprimirá. El ordenador almacena todo el texto en una gran línea. El ordenador entiende cómo mostrar el texto en diferentes líneas debido al uso de los caracteres \n.

Para complicar las cosas, cada sistema operativo tiene diferentes estándares para acabar una línea.
Códigos de escapeDescripción
\r\nCR+LF: Microsoft Windows
\nLF: sistemas basados en UNIX, y los Macs más modernos.
\rCR: sistemas basados en Mac antiguos

Normalmente tu editor de texto se encargará de esto por ti. El Bloc de Notas de Microsoft no lo hace, y los archivos de UNIX abiertos en el bloc de notas aparecen horribles porque los finales de línea no se muestran o aparecen como cajas negras.

1.4 Comentarios

Los comentarios son importantes (incluso si los ignora el ordenador)

A veces, el código necesita algunas explicaciones adicionales para la persona que lo lee. Por esto añadimos “comentarios” al código. Los comentarios son para que los lean los humanos y no el ordenador.

Hay dos maneras de poner comentarios. La primera es usar el simbolo #. El ordenador ignorará cualquier texto en un programa de Python que esté detras de #. Por ejemplo:

# Esto es un comentario que comienza con el signo # 
# y el compilador lo ignorará.

print("Esto no es un comentario, el ordenador")
print("ejecutará esto y lo imprimirá.")

El signo # entre comillas no es tratado como un comentario. Un programador puede deshabilitar una línea de código poniendo # delante de ella. También es posible poner un comentario al final de una línea.

print("Un signo # entre comillas no es un comentario.")

# print("Esto es un comentario, incluso si es código.") 

print("Hola") # Esto es un comentario al final de una línea

Es posible comentar múltiples líneas de código usando tres comillas simples en una fila para delimitar los comentarios.

print("Hola")
'''
Esto es
un
comentario
de
múltiples
líneas. Nada
de lo que esté
entre estas comillas
se ejecutará.
print("Allí")
'''
print("Hecho")

La mayoría de los programadores profesionales de Python solo usan este tipo de comentarios multilínea en los llamados docstrings. Los docstrings permiten escribir la documentación a lo largo del código y luego extraerla automáticamente como documentación impresa, páginas web, y en Entornos de Desarrollo Integrados (IDEs). Para los comentarios genéricos es mejor usar el símbolo #.

Incluso si tú eres el único que va a leer el código que escribes, los comentarios pueden ayudarte a ahorrar tiempo. Añadiendo un comentario como “Manejar bombas alien” te permitirá recordar rápidamente qué hace esa sección de código sin tener que leerla y descifrarla.

1.5 Operadores de Asignación

Vídeo: El Operador de Asignación

¿Cómo almacenamos la puntuación en nuestro juego? ¿Cómo controlamos la resistencia del enemigo? Lo que tenemos que hacer es usar un operador de asignación. (Un operador es un símbolo como + o -.) Esto almacena un valor en una variable para ser usado luego. El código de abajo asignará 10 a la variable x, y luego imprimirá el valor almacenado en x.

Observa el siguiente ejemplo. Haz click en el botón “Inicio” para ver cómo funciona el código.
# Crea la variable x
# Almacena el valor de 10 en ella.
x = 10

# Imprime el valor almacenado en x.
print(x)

# Imprime la letra x, pero no el valor contenido en x
print("x")

# Imprime "x= 10"
print("x=", x)
Variables:
x=
Salida:
10
x
x= 10

Las variables van fuera de las comillas.

Observación: El listado de arriba también demuestra la diferencia entre imprimir una x dentro de comillas y una x fuera de ellas. Si una x está entre comillas, entonces el ordenador imprime x. Si una x está fuera de las comillas, entonces el ordenador imprimirá el valor de x. La confusión entre “dentro o fuera de las comillas” es muy común para aquellos que empiezan a programar.

fig.pi

Una sentencia de asignación (una línea de código usando el operador =) es diferente a la igualdad algebráica que aprendiste en matemáticas. No te confundas, no pienses que son la misma cosa. En la parte de la izquierda de un operador de asignación sólo debe haber una variable. ¡Y nada más!

A la derecha del símbolo igual/operador de asignación hay una expresión. Una expresión es algo que evalúa un valor. Examina el siguiente código:

x = x + 1

Obviamente, el código anterior no puede ser una igualdad algebraica. Pero para el ordenador es válido ya que es una sentencia de asignación. Las ecuaciones matemáticas son diferentes a las sentencias de asignación, incluso si tienen variables, números y un signo de igual.

El código anterior toma el valor actual de x, le añade una unidad y almacena el nuevo resultado en x.

Ampliando nuestro ejemplo, la sentencia siguiente imprimirá el número 6.

x = 5
x = x + 1
print(x)

Las sentencias son ejecutadas secuencialmente. El ordenador no “ve el futuro.” En el código siguiente, el ordenador imprimirá un 5 en la línea 2 y un 6 en la línea 4. Esto es porque en la línea 2, el código para añadir una unidad a x aún no se ha ejecutado.

x = 5
print(x) # Imprime 5
x = x + 1
print(x) # Imprime 6

La siguiente sentencia es válida y se ejecutará, pero no tiene sentido. El ordenador añadirá una unidad a x, pero el resultado nunca se almacenará o imprimirá.

x + 1

El código de abajo imprimirá 5 en vez de 6 porque el programador olvidó almacenar el resultado de x + 1 en la variable x.

x = 5
x + 1
print(x)

La siguiente sentencia no es válida porque a la izquierda del signo igual hay más de una variable:

x + 1 = x

Python tiene otros tipos de operadores de asignación, permiten al programador modificar fácilmente una variable. Por ejemplo:

x += 1

La sentencia anterior es equivalente a escribir el siguiente código:

x = x + 1

También hay operadores de asignación para restar, multiplicar y dividir.

1.6 Variables

Las variables empiezan con una letra minúscula.

Las variables deberían empezar siempre con una letra minúscula. Las variables pueden empezar con una letra mayúscula o un guión bajo, pero esos son casos especiales y no deberían usarse de forma habitual. Después de la primera letra minúscula, la variable puede incluir mayúsculas y minúsculas. Las variables no pueden contener espacios.

Las variables son sensibles a las minúsculas y mayúsculas. Esto puede ser confuso si el programador no lo espera. En el siguiente código, la salida será 6 en lugar de 5 porque hay dos variables distintas, x y X.

x = 6
X = 5
print(x)

La guía de estilo de Python (sí, los programadores escribieron un libro de estilo) dice que las variables con nombres formados por varias palabras en Python deberían estar separadas por guiones bajos. Por ejemplo, usaríamos estilo_peinado en lugar de estiloPeinado. Personalmente, si eres uno de mis alumnos, no me importa mucho esta regla porque el siguiente lenguaje que damos, Java, tiene exactamente la regla de estilo opuesta. Yo solía enseñar reglas de estilo de Java en esta clase pero comencé a recibir cartas de odio de los amantes de Python. Estas personas visitaron mi página web y quedaron conmocionados, tal como te lo digo, conmocionados, con mi pobre estilo.

Renuncié y ahora intento usar guías de estilo apropiadas.

Aquí hay algunos ejemplos de nombres de variables que son correctos y otros que no:
Nombres de variables legales Nombres de variables ilegales Legales pero no correctas
primer_nombre primer nombre PrimerNombre
distancia 9ds primerNombre
ds9 %correcto X

Todos los nombres de variables en mayúsculas como MAX_VELOCIDAD están permitidas solo en circunstancias donde el valor de la variable nunca cambia. Una variable que no cambia se llama constante.

1.7 Operadores

Para operaciones matemáticas más complejas contamos con los operadores matemáticos comunes, junto con otros no tan comunes:
operador operación ejemplo de ecuación ejemplo de código
+ suma $3 + 2$ a = 3 + 2
- resta $3 - 2$ a = 3 - 2
* multiplicación $3 \cdot 2$ a = 3 * 2
/ división $\frac{10}{2}$ a = 10 / 2
// división parte entera (cociente) N/A a = 10 // 3
** potencia $2^3$ a = 2 ** 3
% módulo (resto) N/A a = 8 % 3

Vídeo: Operadores

“División parte entera” siempre redondeará el resultado hacia el entero menor más cercano. Por ejemplo, 11//2 será 5, no 5.5, y 99//100 será igual a 0.

La multiplicación por yuxtaposición no funciona en Python. Las siguientes dos líneas de código no funcionarán:

# Esto no funcionará
x = 5y
x = 5(3/2)

Es necesario usar el operador de multiplicación para conseguir que funcionen estas líneas de código:

# Esto funciona
x = 5 * y
x = 5 * (3 / 2)

1.7.1 Espacios entre Operadores

Antes y después de un operador puede haber cualquier cantidad de espacios y el ordenador lo entenderá. Por ejemplo, cualquiera de estas líneas son equivalentes:

x=5*(3/2)
x = 5 * ( 3 / 2 )
x      =5     *(    3/   2)

La guía oficial de estilo de Python dice que debería haber un espacio antes y después de cada operador. (A que te estás muriendo por saberlo, ¿verdad?. De acuerdo, la guía oficial de estilo de código Python está aquí: PEP-8.) De las tres líneas de código anteriores, la más “estilosa” sería la línea 2.

1.8 Orden de Operaciones

Python evaluará las expresiones usando el mismo orden de operaciones que se esperan en las expresiones matemáticas estándar. Por ejemplo, esta ecuación no calcula correctamente la media:

media = 90 + 86 + 71 + 100 + 98 / 5


La primera operación que se hace es 98/5. El ordenador calcula:

$90+86+71+100+\frac{98}{5}$
en lugar del que necesitamos:

$\dfrac{90+86+71+100+98}{5}$

Este problema se resuelve usando paréntesis:
media = (90 + 86 + 71 + 100 + 98) / 5

1.9 Funciones Trigonométricas

Las funciones trigonométricas se usan para calcular el seno y coseno en ecuaciones. Por defecto, Python no sabe calcular el seno y coseno, pero lo hace una vez que se ha importado la biblioteca correspondiente. Las unidades están en radianes.

# Importar la biblioteca math
# Esta linea se usa una sola vez y al principio del
# del programa.
from math import *

# Calcular x usando seno y coseno
x = sin(0) + cos(0)

1.10 Cálculo de Ecuaciones Personales

Un programa puede usar Python para calcular el consumo por unidad distancia de un coche que recorrió 294 millas con 10.5 galones de gasolina.

m = 294 / 10.5
print(m)

Podemos mejorar este programa usando variables. Esto nos permitirá cambiar fácilmente los valores en el código sin modificar la ecuación.

m = 294
g = 10.5
m2 = m/ g # Aquí empleamos variables
print(m2)
Es importante nombrar bien las variables

Por sí solo, este programa es difícil de entender. Las variables m y g no significan nada sin algún contexto. El programa puede ser más fácil de entender usando variables nombradas apropiadamente:

millas_recorridas = 294
galones_usados = 10.5
mpg = millas_recorridas / galones_usados
print(mpg)

Con esto, incluso una persona que no sea programadora, puede ver el programa y hacerse una idea de qué es lo que hace. Otro ejemplo de un uso correcto de los nombres para una variable, frente a uno malo, sería:

# Difícil de entender
ir = 0.12
b = 12123.34
i = ir * b

# Fácil de entender
tasa_interes = 0.12
balance_cuenta = 12123.34
capital_final = tasa_interes * balance_cuenta
Vídeo: Creando un programa de cálculo personalizado

En el editor IDLE es posible editar una línea anterior sin reescribirla. Sitúa el cursor en la línea a editar y pulsa la tecla “enter”. La línea en cuestión será copiada a la línea actual.

Introducir código en el prompt >>> es lento y solamente podemos hacer una línea cada vez. Tampoco es posible guardar el código para que otra persona pueda ejecutarlo. Por suerte hay otra manera mejor de introducir código en Python.

El código Python se puede introducir usando un script. Un script es una serie de líneas de código de Python que se ejecutarán todas a la vez. Para crear un script, abre una nueva ventana como se muestra en la Figura 1.2.

fig.entering_a_script
Figure 1.2: Introduciendo un script

Introduce el programa de Python para calcular el consumo de gasolina por millas y guarda el archivo. Guarda el archivo en una unidad flash, unidad de red, o en cualquier otro dispositivo de tu elección. Los programas en Python deberían acabar siempre con la extensión .py. Ver Figura 1.3.

fig.saving_mpg_calculator
Figure 1.3: Guardando un script

Ejecuta el programa escrito haciendo click sobre el menu “Run” y seleccionando “Run Module”. Prueba a actualizar el programa con distintos valores para las millas recorridas y los galones consumidos.

Cuidado, ¡Error habitual!

De ahora en adelante, casi todo el código debería ser introducido en un script/módulo. No escribas tu programa en el prompt >>> del IDLE. El código escrito aquí no se guarda. Si haces eso, será necesario comenzar de nuevo. Es un error muy habitual en los programadores novatos.

Este programa sería más útil si interactuase con el usuario y le preguntase por las millas recorridas y los galones consumidos. Esto puede hacerse con la sentencia input. Mira el siguiente código:

# Este código casi funciona
millas_recorridas = input("Introduce las millas recorridas:")
galones_usados = input("Introduce los galones usados:")
mpg = millas_recorridas / galones_usados
print("Millas por galón:", mpg)

Al ejecutar este programa, se le preguntará al usuario por las millas y los galones, pero generará un extraño error tal y como se muestra en la Figura 1.4.

fig.mpg_program_error
Figure 1.4: Error ejecutando programa KPL

El motivo de este error puede verse cambiando un poco el programa:

millas_recorridas = input("Introduce las millas recorridas:")
galones_usados = input("Introduce los galones usados:")
x = millas_recorridas + galones_usados
print("Suma de m + g:", x)

Al ejecutar el programa anterior se observa el resultado que muestra la Figura 1.5.

fig.mpg_incorrect_addition
Figure 1.5: Suma incorrecta

El programa no suma los dos números, los pone uno a continuación del otro. Esto es porque no sabe que el usuario esta introduciendo números. El usuario podría introducir “Bob” y “Mary”, sumar esas dos variables, obteniendo “BobMary”, lo que tendría más sentido.

La entrada debe ser transformada a números.

Para decirle al ordenador que son números, es necesario envolver la función de input con un int( ) o un float( ). Usamos la primera opción para números enteros y la segunda para números con decimales.

El programa definitivo será:

# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# Vídeo explicativo: http://youtu.be/JK5ht5_m6Mk

# Calcular las millas por galon
print("Este programa calcula mpg.")

# Obtener del usuario las millas recorridas
millas_recorridas = input("Introduce las millas recorridas: ")
# Convertimos el texto introducido a
# número en coma flotante (número real)
millas_recorridas = float(millas_recorridas)

#Obtener del usuario los galones consumidos
galones_usados = input("Introduce los galones usados: ")
# Convertimos el texto introducido a
# número en coma flotante (número real)
galones_usados = float(galones_usados)

# Calculamos e imprimimos la respuesta
mpg = millas_recorridas / galones_usados
print ("Millas por galon:",mpg)

Variables:
millasRecorridas=
galonesUsados=
mpg=
Salida:
Este programa calcula las millas por galón.
Introducir las millas recorridas: 288
Introducir los galones consumidos: 15
Millas por galón: 19.2

Otro ejemplo, calcular la energía cinética de un objeto:

# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# Calcula la Energía Cinética de un objeto

print("Este programa calcula la energía cinética para un objeto en movimiento.")
m_string = input("Introduce la masa del objeto en kilogramos: ")
m = float(m_string)
v_string = input("Introduce la velocidad en metros por segundo: ")
v = float(v_string)

e = 0.5 * m * v * v
print("El objeto tiene " + str(e) + " joules de energía.")

Para simplificar un programa es posible anidar la sentencia input dentro de la sentencia float. Por ejemplo, estas líneas de código:

 
millas_recorridas = input("Introduce las millas recorridas:")
millas_recorridas = float(millas_recorridas)

Hacen lo mismo que esta línea:

millas_recorridas = float(input("Introduce las millas recorridas:"))

En este caso, la salida de la función input se introduce directamente en la función float. Ambas funcionan y es cuestión del programador decidir cuáles de las dos opciones elegir. Sin embargo, sí que es importante entender ambas formas.

1.11 Repaso

1.11.1 Test

Haz click para ir al Test.

1.11.2 Ejercicios

Haz click para ir a los Ejercicios.

1.11.3 Taller

Haz click para ir al Taller.


You are not logged in. Log in here and track your progress.