Inicio > Programing > Aceitunas vs Estrellas usando Pilas

Aceitunas vs Estrellas usando Pilas


Y cuando hay energía no hay que desperdiciarla, seguiremos codeando hasta que el cuerpo aguante y ya iniciado, seguiré conociendo a Pilas.

Ahora toca el turno de seguir el tuto para hacer un juego donde unas aceitunas tienen que escapar de ser hechas pomada por una bombas terriblemente maléficas! (nota: hacer pomada algo en la gerga mexicana significa hacerlo pedazos ok!) y como eso de meléficas me suena a diabólico y yo soy un angel!!, he decidido que las aceitunas no tengan que huir de bombas, sino de unas santas y agradables estrellas, que además quieren poblar el cielo de aceituas (así o más angelical el asunto).

Si lo que necesitas es instalar Pilas, entonces puedes seguir el anteior post sobre Haciendo funcionar Pilas en Linuxmint 12

Teclas a la obra!

Lo primero creamos una carpeta llamada AceitunasVsEstrellas y dentro creamos un archivo llamado aceituasvsestrellas.py y lo abrimos con cualquier editor de texto, yo usaré gedit!

La primera parte del código será la siguiente

import pilas
pilas.iniciar()
fondo = pilas.fondos.Noche()
aceituna = pilas.actores.Aceituna()
aceituna.aprender(pilas.habilidad.SeguirAlMouse)

Ahora en una terminal se ejecuta el script de la siguiente manera

AceitunasVsEstrellas $ python aceitunasvsestrellas.py

y deberíamos de obtener un resultado similar al siguiente:

Creando a los enemigos las estrellas

Ahora hay que agregar varias estrellas, eso lo podríamos hacer muy facilmente creando un actor estrella y luego multiplicándolo, pero se necesita que cada estrella se mueva por la pantalla persiguiendo a nuestra aceituna, por lo que se tiene que dotar de movimiento.

Para realizar lo anterior se tiene que crear una nueva clase llamada EstrellaConMovimiento basada en la clase Estrella como sigue

clase EstrellaConMovimiento(pilas.actores.Estrella)
    def __init__(self, x=0, y=0):
        pilas.actores.Estrella.__init__(self, x, y)

lo anterior hace que si no se pasan valores, la estrella se posiciona al centro de la pantalla, pero lo que se necesita es que la estrella se vaya desplazando así que se tiene que agregar un método especial llamado actualizar, este método es llamado de forma automática por el motor de Pilas, así que se ejecuta en todo momento.

En actualizar tenemos que hacer que las coordenadas se la estrella se vayan modificando poco a poco haciendo que la estrella se desplace y se vea un efecto de que la estrella se mueve. El método actualizar quedaría algo así:

# Esto hace que la estrella se vaya moviendo
def actualizar(self):
        # La posición se actualiza sólo en 0.5 ¿xq?
	self.x += 0.5
	self.y += 0.5
	# Se examina si la aceituna ya se estampó en el límite derecho de la ventana
	# Si 320 es la mitad de la ventana, entonces toda la ventana tiene 640
	if self.x > 320:
	     self.x = -320
	# Lo mismo para y, sólo que en este caso se tiene 480
	if self.y > 240:
	     self.y = -240

algo que no me queda muy claro de momento es porque la posición de la aceituna se actualiza sólo en 0.5, pienso que es un valor algo pequeño, pero tendré que esperar a ejecutarlo para ver el resultado.

Otra duda! veo que se valida que la aceituna no se estampe en el límite derecho de la ventana revisando en casa caso que la coordenada en x no sea mayor a 320, por lo que asumo que la ventana a lo ancho tiene 640.

Ejecuto nuevamente el script y obtengo lo siguiente

Las observaciones al resultado obtenido son las siguientes:

  • La estrella en verdad se mueve, peor su velocidad es considerablemente lenta, posiblemente para un primer nivel estaría bien, pero no para un experto.
  • El movimiento de la estrella es de forma inclinada hacia arriba, es un poco estraño ver que una estrella suba al cielo o ¿nooo?, así que voy a cambiar el incremento en la coordenada en y por un decremento.
  • Cuando la estrella llega a alguno de los límites, desaparece y reaparece en el límite contrario, podría tener un mejor efecto que la estrella se dejara de ver por completo antes de aparecer al otro lado, habría que hacer algunas pruebas.

Corrigiendo decremento en la coordenada en y, listo!

Ahora a gregar más estrellas, que tal unas cinco, el código sería como sigue

# Se crean tres estrellas
estrella1 = EstrellaConMovimiento()
estrella2 = EstrellaConMovimiento(x=200, y=0)
estrella3 = EstrellaConMovimiento(x=0, y=200)
estrella4 = EstrellaConMovimiento(x=-200, y=200)
estrella5 = EstrellaConMovimiento(x=-100, y=50)

Creo que el código en este caso se explica sólo si o ¿siii?, en caso contrario por favor decidme y le hago una nota!

Pero una captura del resultado es

Observaciones:

  • Ya se ve lindo y las estrellas se mueven (diría una amiga!)
  • Todas las estrellas se mueven a la misma velocidad. Hacer que cada estrella se mueva a velocidad no implica muchos cambios o ¿siii? ¿quien dice yo?
  • Ahorita son sólo cinco estrellas, pero si fueran más, entonces hay que usar una lista para poder controlar de mejor manera cuantas estrellas se necesiten.

Haciendo estrellas con movimientos más “inteligentes”

Aunque la IA (Inteligence Artifial) ya eswtá muy desarrollada, no podremos por el momento crear estrellas super inteligentes, pero si podemos hacer que sus movimientos no sean tan predecibles o por lo menos lineales.

Según la documentación, Pilas cuenta con un motor de física que podría permitir agregar comportamientos reales a nuestros objetos y lo que se busca ahora es que nuestras estrellas se comporten como si fueran una pelota, para que reboten por toda la pantalla e incluso reboten entre ellas mismas.

Pa lograr lo anterior lo primero es indicar que no hay gravedad cambiando la siguiente línea:

pilas.iniciar(gravedad=(0, 0))

Luego en la clase EstrellaConMovimiento() se elimina el método actualizar y se modifica el contructor (metodo __init__) como sigue

# Esto hace que la estrella se coloque al centro si no se indica otra posición
def __init__(self, x=0, y=0):
    pilas.actores.Estrella.__init__(self, x, y)
# Se crea un área circular de colisión con ciertas propiedades que definen
# el comportamiento de la estrella
    self.circulo = pilas.fisica.Circulo(x, y, 30, restitucion=1, friccion=0, amortiguacion=0)
# Ahora se hace que la estrella se comporte como el círculo creado<br />
    self.imitar(self.circulo)
# Y finalmente queremos que cuando haya una colisión, la estrella rebote<br />
    self._empujar()

me parece que lo documentación del código es suficiente… o ¿no?… ok ok!!

Lo actores en Pilas tienen una propiedad o método que se llama imitar, lo que hace que la estrella se comporte como si fuera un objeto circular con las propiedades antes definidas.

Luego hay un método _empujar() que todavía no ha sido definido, pero lo hago a continuación

# Se encarga de definir el comportamiento de la estrella cuando esta colisiona
# con algún objeto
def _empujar(self):
    # Determina la dirección del movimiento inicial de la estrella
    dx = 1
    dy = 1
    self.circulo.impulsar(dx * 100000, dy * 100000)

Ahora a ejecutarlo y el resultado es

Observaciones:

  • En realidad la estrellas se han vuelto locas! Se mueven para todos lados rebotando en los límites de la ventana y entre ellas mismas
  • A este paso ya no me será suficiente colocar imágenes, requeriré de video
  • He presionado F11 para observar el radio del círculo y algunos valores extras.

Haciendo explotar a nuestra aceituna

Lo primero es que la aceituna pueda explotar, pero al pareser es una habilidad que el actor Aceituna por si mismo no tiene, así que es una habilidad que tendrá que aprender el actor aceituna y el código queda así

# Se crea el personaje de la aceituna
aceituna = pilas.actores.Aceituna(x=0,y=-200)
aceituna.aprender(pilas.habilidades.SeguirAlMouse)
aceituna.aprender(pilas.habilidades.PuedeExplotar)

Ahora lo que sigue es activar las colisiones entre las estrellas y la aceituna, lo que se hace agregando al final el siguiente código:

# Se crea una lista de estrellas
lista_de_estrellas = [estrella1, estrella2, estrella3, estrella4, estrella5]
# Se crea una función que define la acción de lo que pasa cuando una
# estrella cocha con la aceituna
def cuando_colisionan(aceituna, estrella):
    aceituna.eliminar()
# Por último se relacionan agregando una definición de colisión a pilas
pilas.mundo.colisiones.agregar(aceituna, lista_de_estrellas, cuando_colisionan)

Y el resultado es como sigue:

Wow!!!, esto ya se pone más interesante y Si!! definitavmente necesito hacer un video

Observaciones

  • Me gustaría colocar un retardo al final, pero todavía no se como!
  • Revisando algún otro tutorial, sería interesante que cada 6 segundos apareciera otra estrella, de esta forma el nivel de dificultad aumenta minuto a minuto je je!
  • Lo que falta es modularizar el código, un archivo para las estrellas, uno para la aceituna y otro que llame a los demás o el main. También para esto ¿quién dice yo?

Algo que he encontrado es que algunos de los métodos no están dentro del árbol que según le corresponde y he tenido a veces que ir buscando hasta dar con el, por ejemplo la función de agregar() para colisiones, resulta que está dentro de pilas.mundo, cuando en los tutos indica que está en pilas.colisiones.agregar().

Revisando en la página del proyecto de Pilas, están solicitando ayuda para dar mantenimiento a la documentación, a ver quien se anima.

Mi código final lo dejo aquí por si alguien está interesando en hacer una revisión completa y además de poder corrborar que todo esto en tan sólo 67 líneas de código! Genial!

<br />
#/usr/bin/python<br />
# -*- coding: utf-8 -*-</p>
<p># Módulo necesario para poder usar pilas<br />
import pilas</p>
<p># Así se inicia el motor de pilas<br />
#   Con gravedad=(0, 0) se hace que los objetos se comporten como si estubieran<br />
#   en el espacio<br />
pilas.iniciar(gravedad=(0, 0))</p>
<p># Se adiciona un fondo al escenario<br />
fondo = pilas.fondos.Noche()</p>
<p># Se crea el personaje de la aceituna<br />
aceituna = pilas.actores.Aceituna(x=0,y=-200)<br />
aceituna.aprender(pilas.habilidades.SeguirAlMouse)<br />
aceituna.aprender(pilas.habilidades.PuedeExplotar)</p>
<p># Se crea a los enemigos que en este caso son estrellas<br />
class EstrellaConMovimiento(pilas.actores.Estrella):</p>
<p>	 # Esto hace que la estrella se coloque al centro si no se indica otra posición<br />
    def __init__(self, x=0, y=0):<br />
        pilas.actores.Estrella.__init__(self, x, y)</p>
<p>        # Se crea un área circular de colisión con ciertas propiedades que definen<br />
        # el comportamiento de la estrella<br />
        self.circulo = pilas.fisica.Circulo(x, y, 30, restitucion=1, friccion=0, amortiguacion=0)</p>
<p>        # Ahora se hace que la estrella se comporte como el círculo creado<br />
        self.imitar(self.circulo)</p>
<p>        # Y finalmente queremos que cuando haya una colisión, la estrella rebote<br />
        self._empujar()</p>
<p>	# Se encarga de definir el comportamiento de la estrella cuando esta colisiona<br />
	# con algún objeto<br />
    def _empujar(self):<br />
    	# Determina la dirección del movimiento inicial de la estrella<br />
    	dx = 1<br />
    	dy = 1</p>
<p>        self.circulo.impulsar(dx * 100000, dy * 100000)</p>
<p># Se crean cinco estrellas<br />
estrella1 = EstrellaConMovimiento()<br />
estrella2 = EstrellaConMovimiento(x=200, y=0)<br />
estrella3 = EstrellaConMovimiento(x=0, y=200)<br />
estrella4 = EstrellaConMovimiento(x=-200, y=200)<br />
estrella5 = EstrellaConMovimiento(x=-100, y=50)</p>
<p># Se crea una lista de estrellas<br />
lista_de_estrellas = [estrella1, estrella2, estrella3, estrella4, estrella5]</p>
<p># Se crea una función que define la acción de lo que pasa cuando una<br />
# estrella cocha con la aceituna<br />
def cuando_colisionan(aceituna, estrella):<br />
    aceituna.eliminar()<br />
#    pilas.terminar()</p>
<p># Por último se relacionan agregando una definición de colisión a pilas<br />
pilas.mundo.colisiones.agregar(aceituna, lista_de_estrellas, cuando_colisionan)</p>
<p># Se mantiene el programa corriendo<br />
pilas.ejecutar()<br />
Anuncios
Categorías:Programing Etiquetas: , , ,
  1. 28 mayo, 2012 en 08:52

    Wow, que buen artículo. Muchisimas gracias!!!

  2. 28 mayo, 2012 en 18:49

    bueno, este es el segundo y todavía no está terminado ya que sólo es un avance porque hay una colega involucrada y sobre todo interesada 😉

    gracias por dejar tu huella!!

  3. 9 julio, 2012 en 10:40

    Hola Ricardo!
    Soy Cris, cambié mi sitio web y mi twitter, ya te sigo, espero me sigas 😀 @nenatuits

    • 9 julio, 2012 en 12:49

      Hola Cris!

      Ya tenía tiempo que no te dejabas leer!

      animo con ese blog, todvaía se ve algo vacío, espero pronto esté muy habitado!

      Un abrazo!

  4. 9 julio, 2012 en 12:53

    Re.vacío pero ya se irá viendo mejor de a poco 😉 gracias!

  1. 3 febrero, 2013 en 04:16

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

PiKon

3D Printing + Raspberry Pi Camera = PiKon Telescope

gvSIG blog

gvSIG project blog

Python Adventures

Welcome to the Jungle!

A %d blogueros les gusta esto: