jueves, 15 de noviembre de 2012

Texturas Naturales

La idea es tratar de imitar la textura de cierto pedazo de aglomerado (una variedad de madera que une diferentes residuos y los prensan con pegamento ).
Parecido a esto:



Lo que se hace en el código es edición de imágenes con la librería de PIL para python, primero creando una imagen en blanco o tomando una imagen en blanco como referencia (en formato RGB), posteriormente se obtienen los valores de los colores de cada pixel (en RGB) y se modifican siguiendo cierto criterio, que como ya todos saben la madera tiene un patrón de líneas (semi-paralelas).

Así que lo primera idea es la de imitar este patron de líneas usando diferentes tonos de cafes/negros y amarillos para simular las lineas.

Este es el código, se usa la la libreria PIL para edición de imágenes:

import random 
from Tkinter import * 
import Image, ImageTk

negros = [(0,0,0), (139,69,19), (160,82,45) (210,105,30)] 
amarillos = [(255,215,0), (218,165,32), (184,134,11), (205,133,63)] 

im = Image.new("RGB",(350,350))
pixels = im.load()

for i in range (0, 350):
 for j in range(0, 350):
  if(i%2==0):
   pixels[i,j] = random.choice(amarillos)
  else:
   pixels[i,j] = random.choice(negros)

im.save("textura.bmp")
tk= Tk()
tkimage = ImageTk.PhotoImage(im)
label = Label(tk, image=tkimage).pack()

tk.mainloop()


Una imágen de la textura lograda:



Otra con zoom:



Aunque, tal ves puede pasar tambien como una textura de una especie de corcho o incluso tela :P.


__________________________________________________________________________________
Enlaces:
Documentación de PIL

jueves, 8 de noviembre de 2012

Respuestas visuales, auditivas y táctiles

En esta entrada la idea era mostrar una especie de interacción entre el usuario y la maquina (donde se ejecuta una aplicación/juego). Como el curso esta orientado a la creación de un juego, estas interacciones se pueden obtener como respuestas por parte de la aplicación a acciones que realice el usuario, que pueden ser visuales, sonoras o hasta táctiles.

En el mundo de los videojuegos estas respuestas son imprescindibles:
  • Las visuales, son las más presentes en todos los videojuegos, ya que cualquier situación, acción o cambio que el usuario realice, se vera reflejada en una respuesta visual, como por ejemplo al disparar una arma, una respuesta visual puede ser el humo o la pequeña explosión que se emite. 

  • Las sonoras, son tambien muy presentes, ya casi en cualquier acciones que se realice y en la que se trate de imitar la realidad, lo mas natural es que se escuche algo, como ejemplo podemos retomar el disparo de una pistola, que al suceder esto se debe de emitir un sonido que emule la explosión de ésta o al quebrar un cristal, o incluso se puede tomar como respuesta sonora, la música de ambientación ya que se encuentra en constante cambio y depende de la situación en la que se encuentre el personaje o cierta acción que se realice.

  • Las táctiles son un poco más recientes (según yo, su primera aparición fué en los controles del nintendo 64, añadiendo un aditamento), y su mayor uso es en las consolas de juegos, ya que se encuentran en los controles como pequeños motores que los hacen vibrar en diversas situaciones, como al disparar, golpear, recibir daño, etc.
Para tratar de explicar un poco mejor esto, realice una pequeña implementación usando un arduino, botones, leds, un piezo/speaker/buzzer y muchos cables :P.

La idea que se me ocurrió fue la de hacer juego de reacción (tratando de imitar un juego de unos topos que se golpean con un mazo) donde tengo 3 leds y 3 botones, los led prenden aleatoriamente y la meta es presionar el boton del led que esta encendido.
El jugador tiene 1/2 segundo para reaccionar, si el jugador atina se enciende un led de aprobación (verde) y se emite un sonido agudo, de lo contrario o si no se presiona nada se enciene un led de error (rojo) y se emite un sonido grave.

Aquí las respuestas a las acciones del jugador son visuales y auditivas, donde las visuales son en las que encienden los leds (aprobación y error)  y las sonoras son en las que se emiten los sonidos (agudos y graves).

Sin más, aquí dejo la imágen del diagrama hecho con Fritzing para las conexiones:




Aquí unas fotos del circuito real:




El código para el arduino esta muy simple, se hace uso de conexión serial, encendido y apagado de pines digitales, lecturas de pines digitales y de random para encender los leds aleatoriamente:

int led1 = 2;
int led2 = 3;
int led3 = 4;
int boton1 = 5;
int boton2 = 6;
int boton3 = 7;
int ok = 8;
int error = 9;
int bocina = 10;


void setup(){
Serial.begin(115200);

pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(ok, OUTPUT);
pinMode(bocina, OUTPUT);
pinMode(error, OUTPUT);
pinMode(boton1, INPUT);
pinMode(boton2, INPUT);
pinMode(boton3, INPUT);

}

void loop(){
   
    int led = random(2, 5);
  
    digitalWrite(led, HIGH);
    Serial.print(led-1);
    delay(500);
    
    int boton = led + 3;
    
    int estado = digitalRead(boton);
    delay(500);
    if (estado == HIGH){
      digitalWrite(ok, HIGH);
      tone(bocina, 900, 250);
      delay(500);
      Serial.print(boton-4);
      Serial.print(1);
    }
    else{
      digitalWrite(error, HIGH);
      tone(bocina, 400, 250);
      delay(500);
      Serial.print(0);
      Serial.print(0); 
    }     
  
  digitalWrite(led, LOW);
  digitalWrite(ok, LOW);
  digitalWrite(error, LOW);  
  delay(250);
}



  • Al principio se establecen que pines se usaran y como se usarán, entradas o salidas.
  • Ya en la parte de ejecución del programa, primero se usa random, para obtener un entero y usar este para encender cierto led.
  • Ya encendido el led, se usa un delay(500) para tener oportunidad de ver al led encendido.
  • Se busca que se presione el botón correspondiente, esto sumando 3 al entero que se uso para encender led y ya con este número de pin se hace la lectura con digitalRead().
  • Se usa un delay(500), que equivale a 1/2 segundo para esperar a que reaccione el jugador.
  • Con la lectura obtenida, se entra al if, si se presiona se enciende el led ok(verde) y la bocina emite un sonido agudo, usando la función tone, que tiene como parametros (pin, frecuencia(MHz), duración(milisegundos)), entre más alta la frecuencia mas agudo el sonido. si no se presiona sucede todo lo contrario, se enciende el led error (rojo) y se emite un sonido grave.
  • Al final se apagan todos los leds encendidos, la bocina se apaga sola al terminar la duración de su sonido, se puso un pequeño delay(250) para darle un tiempo al arduino antes de que se vuelva a repetir todo el proceso.

También, como el código de arduino usa conexión serial, elabore un pequeño programa en python que usa esta comunicación serial y usa los datos recibidos para mostrar una forma de puntuación en pantalla, además de indicar cuando se acierta o falla en el juego.

import serial

s=serial.Serial(2,115200)

def main():

 marcador, total = 0, 0

 while (True):
  l = int(s.read())
  b = int(s.read())
  r = int(s.read())
  print "Led #", l, " Boton #", b

  total +=1 

  if(r == 1): 
   marcador += 1
   print "Acertaste!!"

  else:
   print "Fallaste!!"

 
  print "Tu puntuacion -->> ", marcador, "/", total

main()  



  • Se usa la librería pyserial, se importa como import serial.
  • Se crea un objeto tipo serial con los parametros (puerto, baudrate), se pueden usar más, pero con estos son suficientes para este propósito. el puerto es asignado por windows para el arduino es COM3 o 3, pero debido a que la librería pyserial los enumera desde 0, por eso se estableció 2, (en Ubuntu el manejo de los puertos es de manera diferente).
  •  Con el objeto serial, se hacen las lecturas de la información enviada por el arduino, mediante la función read().
  • Se usa un while infinito para que siempre que el arduino envíe datos este leyendo.
  • Las variables, l se usa para el valor de led encendido, b para el boton presionado y r para el resultado de si se presiono o no el correcto, y se convierten todos a enteros.
  • Si r arroja un 1, quiere decir que se acertó y se suma uno al puntaje.
  • Al final se muestra el puntaje,en el formato de, cuantas veces que se acertó de cuantas posibles y se repite todo el proceso.


Una captura del programa de python:



Aquí dejo un video de como funciona el juego:




____________________________________________________________________________________
Enlace Útiles:




jueves, 1 de noviembre de 2012

Investigación de Usabilidad en Sistemas Inteligentes

El artículo que yo elegí, su nombre es: USABILITY OF INTELLIGENT AGENT SYSTEMS IN URBAN TRAFFIC CONTROL algo como Usabilidad de Sistemas de Agentes Inteligentes en Control de Tráfico Urbano. Es na investigación realizada por Danko A. Roozemond & Peter van der Veer del departamento de Informática de Ingeniería Civil en la Universidad de Tecnología de Delft, en Delft, Países Bajos.

El link del documento de la investigación esta aquí (en pdf e inglés).

Al principio del documento mencionan que la investigación se centra en el manejo inteligente y dinámico del tráfico de vehículos y como esto puede adaptarse y responder a las condiciones del tráfico en tiempo real. Por lo que su investigación se centra en que tan difícil (usabilidad) puede resultar la implementación de agentes inteligentes que ayuden a controlar el tráfico y la aplicabilidad de esto para mantener niveles altos de precisión y facilidad de uso de estos sistemas dinámicos para controlar satisfactoriamente el tráfico vehicular.

En pocas palabras, ellos buscan saber que tan complicado puede resultar implementar un sistema de este tipo y su grado de usabilidad si se implementara esto.

Esta parte me recordo a una pequeña práctica que realizamos en el laboratorio de sistemas adaptativos, en la que se buscaba agilizar el tráfico de vehículos mediante semáforos que cambiaban dependiendo de que tanto tráfico había en una calle, consiguiendo con esto que una calle con más tráfico que otra tuviera prioridad para desahogar el su flujo de vehículos y que fuera capaz de detectar todo esto en tiempo real y estar cambiando constantemente.

Estos tipos para su investigación buscaron recursos dentro del uso de agentes inteligentes, redes neuronales o sistemas de computo distribuido.

Hablan de que la mayoría de las personas pasa mucho de su tiempo manejando en carreteras/caminos/avenidas y que en la mayoría de los casos estos trayectos se realizan en horas donde la demanda de estos caminos o avenidas es mucha (salidas del trabajo, escuelas, etc.), por estos hechos las dependencias correspondientes (en México la SCT) se ven obligadas a construir más y más tramos de carretera, pero con el tiempo se vuelven otra vez avenidad saturadas.
Todos estos inconvenientes influyen en el desarrollo de sistemas inteligentes o IDTMIS (Dynamic Traffic Management and Information System) como ellos lo llaman (esto proviene de una investigación anterior), que trabajaran como un grupo multi-disciplinario, incorporando todos los sistemas necesarios para el control y el manejo del tráfico para solucionar esta problemática.

Se centran mucho en el desarrollo de sistemas de agentes inteligentes, mencionando que la idea es que cada agente sea autónomo y cuanto más grande sea este nivel de autonomía mas eficiente puede resultar ya que también se reduciría la intervención de personas(humanos) en los procesos de automatización y estas personas pueden ser requeridas en otros campos donde se realicen procesos más complejos y aportando ideas en procesos como tomas de decisiones o proveer asistencia técnica a estos agentes. (Ya que no se tiene previsto que un agente tenga la capacidad de "reparar" a otro.)
Esto hace que las tareas más básicas puedan realizarlas los agentes y asi convertirlas en procesos automatizados para obtener un mejor performance en estas tareas, además de que estos procesos automatizados se pueden combinar más facilmente para en un dado caso realizar otra tarea un poco más compleja y obtener como ya se dijo un buen performance.

Otro aspecto que se trata en la investigación es que el tráfico vehicular de las ciudades modernas es por mucho muy variado (autos, camionetas, bicicletas, peatones, camiones, etc), esto puede complicar las cosas al momento de tratar de que los agentes identifiquen vehiculos para realizar acciones o tomar decisiones por si solos.
Debido a esto el sistema de agentes inteligentes no solo debe de ser algo que se adapte en tiempo real, si no que ademas de esto, es necesario que el sistema tenga la capacidad de estar aprendiendo constantemente para facilitar las tareas de identificación de los agentes.

Una parte muy importante en la implementación de este tipo de sistemas es la comunicación, ya que una pequeño flujo constante de información hacia el sistema puede ayudar a que funcione correctamente, ya que si en algún momento puede ocurrir algún accidente en X lugar, esta información se envía al sistema y el sistema puede tomar la decisión de desviar el tráfico en algunas partes para agilizarlo y también poder así apoyar a los cuerpos de seguridad/rescate.

En este aspecto las redes de comunicación juegan un papel muy importante ya que debido a esto puede establecerse de manera más facil y eficiente el tráfico de la información, usando diferentes estadares internacionales para facilitar aún más las cosas.

En resumen, toda esta investigación esta centrada en la solución al gran problema del tráfico vehicular y ellos buscan la manera de ofrecer una solución diferente este problema. Hacieno uso de la tecnología con la que se cuenta actualmente y encaminandose a algo tal vez un poco mas futurista, pero que solucionaría este problema, la menos en un determinado tiempo.

En cuanto a la usabilidad de este sistema, se buscaría que los agentes cuenten con muchas capacidades automatizadas, que la intervención de los hombres sea las más mínima en estos procesos y que si en algún momento es necesario que estos agentes interactúen con usuarios comúnes (persona sin conocimientos sobre esto) sean de la manera más facil, usando interfaces muy intuitivas y buscando siempre, que estos agentes den solución a las dudas de los usuarios.
Todo esto debe de ir en constante perfeccionamiento ya que se buscaría que el sistema sea capaz de adaptarse y aprender constantemente.


____________________________________________________________________
Enlaces:





jueves, 25 de octubre de 2012

Animación con Blender...

En esta ocasión el trabajo a realizar fué el de realizar una animación con objetos o modelos en 3D, existen varias maneras de realizarlo y la que yo elegí es llamada "Camera Tracking" su traducción sería algo como seguimiento de camara.

Para continuar con la entrada anterior, la idea era formar algo parecido a un bosque donde la camara se paseara por el lugar dando diferentes vistas desde diferentes ángulos. Con esto se puede apreciar las diferentes condiciones de iluminación para cada objeto.

Para comenzar, lo primero que se hizo fue tomar el arbol que ya se había modelado anteriormente:


                                                      
   
Se comenzó a duplicar para crear un mini-bosque y se estableció una especie de suelo a la que se agregó una textura de hojas y tierra para que fuera algo parecido a la realidad en un bosque:




Ya con esto, ahora seguimos con la parte de la animación de la cámara, que ya se había mencionado, se conoce como camera tracking, esto debido que sigue un camino previamente establecido.

Primero tenemos que establecer el camino a seguir por la cámara, esto se hace añadiendolo desde el menú Add->Curve->Path y se agregará el camino, ahora hay que modificarlo según se la ruta que se quiera seguir.

Después ya con el camino a seguir establecido, se tiene que linkear la cámara al camino y esto se hace,  estando en la opción Object Mode, seleccionamos el camino y la cámara, después se presionan las teclas Ctrl+P y se selecciona la opción Follow Path.

Con esto la cámara ya esta linkeada al camino, ahora el inconveniente es que cuando se ejecute la animación, la cámara visualizará cualquier cosa y no siempre lo que nosotros queramos. Esto se arregla centrando la cámara en un punto, que en este caso será fijo, añadimos un objeto nulo desde Add->Empty y lo situamos en el lugar donde queremos que la cámara apunte.

Ahora estando en la opción Object Mode seleccionamos el objeto nulo y la cámara, se presionan las teclas Ctrl+T y se escoge la opción Track to Constraint. Aparecerá una línea azul que va desde la cámara hasta el objeto.





Para checar la animación se puede reproducir con las botones de "play" que se sitúan en la barra de herramientas inferior:

Para renderizar animaciones se usan las teclas Ctrl+F12, con esto se muestra la animación con texturas, colores y demás retoques que se hayan hecho a los objetos, pero unicamente desde la perspectiva de la cámara.

Aqui dejo los videos que pude crear con esta animación:




Aporte para el proyecto:

Ahora un plus para que puedan salvar sus animaciones como video, que puede servir si es que se quisieran incluir cinematics en el juego al realizar una acción o al llegar a algún lado, o también la especie de animaciones/comerciales que aparecen cuando los juegos comienzan:

1.- Vamos a la barra de herramientas que aparece a la derecha de la pantalla (donde aparecen las opciones de materiales, texturas,etc.) y nos situamos en pestaña de Render.

2.-Buscamos la opción de Output, casi esta al final.



3.-Cambiamos en la ruta de salida, por default es temp.

4.-Y elegimos el formato, por defecto es un formato de imágenes asi que seleccionamos uno para videos y eso es todo, cuando rendericemos con Ctrl+F12 se creará en la ruta que elegimos un video con las animaciones que creamos. 



Un poco más abajo aparecen una opción de Encoding que servirá si queremos tocar las opciones de decodificación del video.




Hay que tener cuidado con la opción de Overwrite ya que esta sobreescribira el video existente por uno nuevo cada que rendericemos, así que es recomendable desactivarla si es que queremos relizar comparaciones.

El resultado de esto son los videos que estan en la parte superior y hay que tener una computadora decente para poder lograr este tipo de renderizado, yo lo logré en una i5 de 4 núcleos a 2.4GHz con 4Gb de RAM, en mi netbook nada más no avanzó nada jaja.

jueves, 18 de octubre de 2012

Modelado 3D con Blender

Para esta entrada el objetivo era modelar algún objeto en 3D usando Blender, yo escogí hacer un árbol, un muy simple árbol con estilo de caricaturas que creo que lo vi en el juego de Megaman 8.

Para empezar a modelar el árbol, se crearon desde la opción: Add-> Mesh->
un cilindro y dos esferas (una mas grande que otra).

Obviamente el cilindro lo use para el tronco del árbol y las esferas son para crear una especie de copa de hojas del árbol.

La esfera mas grande es el centro de la copa del árbol y la esfera pequeña se va a ir duplicando y posiciondo sobre/en la esfera mas grande.

Al finalizar de juntar las esferas, seleccionamos todas las esferas presionando shift y seleccionando una por una o usando la tecla A para seleccionar todas las esferas.
Usamos una función de Blender llamada Join para juntar/crear un solo objeto todas las esferas seleccionadas.

Después de esto vamos con el cilindro y le damos las dimensiones deseadas para que paaresca el tronco y lo posicionamos debajo de la "copa del arbol" como debería de ser. 


Ahora seleccione los dos objetos (cilindro y la copa) y volvemos a usar la opción Join.

En este punto ya tenemos el arbol creado solo falta darle color o texturas.


Primero le di color, esto se hace añadiendo un tipo de material X al objeto y después a este material se le da el color.

Para tener diferentes zonas con diferentes colores hay que delimitar estas zonas, seleccionando las aristas que estan en esta frontera en el objeto y usando la función Mark Seam.

Ya con las areas delimitadas, se selecciona la que se quiera pintar, se añade un material nuevo para cada uno y se usa la opción assign para asignarla a cada área; ya después de esto solo se escogen los colores deseados.


También agregue texturas para que el árbol fuera un poco más "real".

Este procedimiento es el mismo que para colorear y como ya se tienen delimitadas las áreas se facilita.

Para la textura que imita las hojas del árbol, busque en google una imagen de un árbol X y recorte un recuadro donde aparecieran solo las hojas.




Este recuadro con hojas lo use lo añadí como textura, esto seleccionando la copa del arbol y modificando en el apartado de texturas, donde en la opción type (tipo de textura) escogí la opción image/video y cargue la imagen de las hojas.

Para la textura de madera, en el apartado de texturas, seleccione type->wood y comence a modificar(prueba y error :P) el color y los patrones de la textura.

Esta es la versión final de como quedó el árbol, esta imagen la cree renderizando el modelo con F12 para poder visualizar las texturas.


Avance:

Como avance para el proyecto podría usar esta especie de pseudo-árbol junto con los mapas y demás objetos que crearon los otros compañeros.

También se supone que modele la torre de rectoría, que podría ser usado como la entrada a un nivel especial o algo asi, pero al renderizar me marca error y no se muestran las texturas.


___________________________________________________________________________________
Enlaces:




miércoles, 19 de septiembre de 2012

Interacción con Voz y Texto

Esta semana la entrada trata de realizar una especie de juego/aplicación donde se pueda interactuar con ella mediante voz o texto.

Para el uso de la voz se puede realizar mediante comando ("predefinidos") y para el texto de igual forma, buscando siempre que el uso de estos "comandos" sean de una manera muy natural. Esto puede ayudar a minimizar la curva de aprendizaje de los usuarios, omitiendoles el paso en el que tienen que memorizar los "comandos" que se usan y que acción realiza cada uno.

Mediante el uso de la voz, a mi parecer resulta mas natural decir: "izquierda" y que cierto objeto en el juego se mueva hacia ese lado.
Mientras que en el texto, resulta mas comodo/natural escribir: "más rápido", que "aumentar la velocidad x veces".

Voz
Mi elección(la principal) fue la de mover cierto objeto, mediante el uso de la voz.

La parte del juego esta desarrollada con Pilas Engine (el motor que utilice en la entrada anterior) y prácticamente es lo mismo, solo cambia en la situación de que:
  • Los actores son diferentes, se agregaron un chango y platanos.
  • Ahora solo se mueve el chango.
  • Existen 2 tipos de colisiones, cuando choca con los platanos y cuando choca con las bombas.
  • Al chocar con los platanos, se los "come" y el chango se ríe.
  • Al chocar con las bombas, éstas "explotan" y el chango grita.

Para el apartado de la voz, me apoyé de la librería PySpeech, que hace uso del motor de reconocimiento de voz incluido en Windows (por lo que solo trabaja bajo Windows, una desventaja).
  • Por si les interesa probarla, les dejo el enlace para su descarga e instalación aquí. (en la página dice que solo funciona bajo python 2.4 o 2.5, pero yo estoy trabajando con python 2.6).
 
 Ya que se hace uso del motor de voz de Windows, tambien toca realizar la configuración de este para que trabaje de manera correcta, esto si no habían usado anteriormente esta herramienta.

Al parecer la combinación de esta librería y el motor de voz de Windows realizan un trabajo muy eficiente (tiene algunas deficiencias muy mínimas), tomando en cuenta que la mayoria de los programas/aplicaciones que usan apartados para el reconocimiento de voz estan entrenados o implementados para escuchar comandos en inglés, esta combinación resulto ser muy buena.


En el programa el uso que se le da a esta librería es:
  • Escuchar algún "comando" y pasarlo a texto, tambien hay la posibilidad de que la aplicación repita el comando que se dijo.
 
Ya después mediante condiciones, se valida el comando y la acción que se va a realizar, en este caso mover el chango en 4 direcciones por toda la ventana de la aplicación (actualizando los valores de las coordenadas de la posición del chango).

Aquí les dejo el código:

import pilas

import speech
import random

def comer(mono, banana):
 mono.sonreir()
 banana.eliminar()

def explotar(mono, bomba):
 mono.gritar()
 bomba.explotar()
 bomba.eliminar()

def comando_voz():
 comando = speech.input("Diga algo!!")
 print comando
 speech.say("You said, %s" % comando)
 return comando 

def movimiento(mono):
 comando = "nada"
 x = 0
     y = 0
 while (comando != "Salir"):
  comando = comando_voz()
  if (comando == "Uno"):
   mono.y = (y+5)
   y = mono.y
  elif (comando == "Dos"):
   mono.y = (y-5)
   y = mono.y
  elif (comando == "Izquierda"):
   mono.x = (x-5)
   x = mono.x
  elif (comando == "Derecha"):
   mono.x = (x+5)
   x = mono.x
  elif (comando == "Salir"):
   print "Saliendo.... "
   pilas.terminar()   
  else:
   print "Comando desconocido!!.."    

def main():

 bananas = []
 bombas = []

 pilas.iniciar()

 mono = pilas.actores.Mono()
 mono.x = 0
 mono.y = 0

 cantidad = 5
 for i in range(cantidad):
  bomba = pilas.actores.Bomba() #se crean las bombas
  bomba.x = random.randrange(-200, +200) #coordenadas aleatorias en x
  bomba.y = random.randrange(-200, +200) #coordenadas aleatorias en y
  bombas.append(bomba)  #se agregan las bombas al grupo 
  banana = pilas.actores.Banana() #se crean las bananas
  banana.x = random.randrange(-200, +200) #coordenadas aleatorias en x
  banana.y = random.randrange(-200, +200) #coordenadas aleatorias en y
  bananas.append(banana)  #se agregan las bananas al grupo
 
 mono.aprender(pilas.habilidades.Arrastrable)
 pilas.mundo.colisiones.agregar(mono, bananas, comer)
 pilas.mundo.colisiones.agregar(mono, bombas, explotar)

 movimiento(mono) 
 
 pilas.ejecutar()
 
main()



Un incoveniente con el que me tope (muy desagradable) fue el de que al tratar de usar la palabra/comando "arriba" o "abajo", el motor de voz lo interpreata como "activar la ventana que se encuentra por encima o por abajo de la ventana actual" por lo que la acción de mover al chango hacia arriba/abajo no se puede completar.

Debido a esto me vi en la necesidad de cambiar los comandos "Arriba/Abajo" por "Uno/Dos" respectivamente.

El video en esta parte va quedar pendiente, debido a que al ejecutar el juego y el programa de grabación la computadora se cuelga y no responde. (Más abajo pondre un video de esto mismo, pero ingresando los comandos por texto).

Texto
Esto lo realice antes de comenzar con la parte de la voz, lo hice a manera de checar como podía actualizar los valores de las coordenadas para la posición dle chango, ya después le agregue más cosillas.
Prácticamente esta versión hace lo mismo que la comentada arriba, solo con la diferencia de que los comandos se ingresan mediante texto (algo simple), tratandolo en cierta medida de hacerlo lo más natural posible.

Aquí esta el código:

import pilas
import random

def comer(mono, banana):
 mono.sonreir()
 banana.eliminar()

def explotar(mono, bomba):
 mono.gritar()
 bomba.explotar()
 bomba.eliminar()

def movimiento(mono):
 comando = "nada"
 comandos1 = ["arriba", "up", "y+", "subir", "lado1"]
 comandos2 = ["abajo", "down", "y-", "bajar", "lado2"]
 comandos3 = ["izquierda", "izq", "x-", "left", "lado3"]
 comandos4 = ["derecha", "der", "x+", "rigth", "lado4"]
 comandos5 = ["salir", "exit", "quit", "fin", "end"]

 x = 0
     y = 0
 while (comando != "Salir"):

  comando = raw_input("Diga algo!!  ") 

  if (comando in comandos1 ):
   mono.y = (y+5)
   y = mono.y
  elif (comando  in comandos2 ):
   mono.y = (y-5)
   y = mono.y
  elif (comando  in comandos3 ):
   mono.x = (x-5)
   x = mono.x
  elif (comando  in comandos4 ):
   mono.x = (x+5)
   x = mono.x
  elif (comando  in comandos5 ):
   print "Saliendo.... "
   pilas.terminar()   
  else:
   print "Comando desconocido!!.."    

def main():
 bananas = []
 bombas = []
 
        pilas.iniciar()
 
        mono = pilas.actores.Mono()
 mono.x = 0
 mono.y = 0

 cantidad = 5
 for i in range(cantidad):
  bomba = pilas.actores.Bomba() #se crean las bombas
  bomba.x = random.randrange(-200, +200) #coordenadas aleatorias en x
  bomba.y = random.randrange(-200, +200) #coordenadas aleatorias en y
  bombas.append(bomba)  #se agregan las bombas al grupo 
  banana = pilas.actores.Banana() #se crean las bananas
  banana.x = random.randrange(-200, +200) #coordenadas aleatorias en x
  banana.y = random.randrange(-200, +200) #coordenadas aleatorias en y
  bananas.append(banana)  #se agregan las bananas al grupo
 
 mono.aprender(pilas.habilidades.Arrastrable)
 pilas.mundo.colisiones.agregar(mono, bananas, comer)
 pilas.mundo.colisiones.agregar(mono, bombas, explotar)

 movimiento(mono) 
 
 pilas.ejecutar()

main()



En esta versión hay un poco más de libertad en los comando, estan almacenados en listas.
Una buena idea sería la de capturar el comando que ingrese el usuario y después dividirlo en palabras, posteriormente checar si una palabra de esas esta en las listas de los comandos soportados, pero eso no lo agregue ya que mi prioridad era la de la voz.

Aquí dejo el video, un poco lento y trabado, pero aquí esta:



__________________________________________________________________________________
Enlaces útiles:

jueves, 13 de septiembre de 2012

Colisiones (Interacción entre objetos)

En esta entrada realizaremos una pequeña demostración de la interación entre objetos dentro de nuestro juego.
El ejemplo no tiene nada relacionado con la temática del  videojuego, es solo una demostración.

A estas interaciónes, se les conoce como colisiones, debido a que se necesita que 2 o mas objetos choquen entre si para que se lance la acción a realizar.

Para esta entrada yo elegi un ejercicio donde se tiene una ventana con bombas, estas se pueden mover hacia cualquier lado dentro de la ventana, pero si llega a tocar una bomba con otra, las dos explotan, cuando esto sucede salen llamas, se escucha un sonido de explosión y obviamente las bombas que choquen desaparecen.



Este ejempo lo realice con ayuda del motor gráfico Pilas, que ya habia comentado en la primera entrada en este blog, donde se hablaba de las herramientas para creae videojuegos ( aquí la entrada ) .
Al realizarlo de esta manera el código es más simple, más supuesto mas entendible y por su puesto más fácil de implementar esto.

Pilas Engine, hace uso de diferentes librerías, basicamente junta todas éstas y facilita su
uso, ya que pilas se encarga de su administración y todo lo necesario, por lo que no es necesario que conoscas las funciones de todas la librerías. Las mas importante son:
  • Pygame: para la manipulación de los personajes, imagenes, etc, 
  • Pyqt: para el manejo de las interfaces gráficas(ventanas, botones, etc) 
  • PyBox2d: para el manejo de la física de los juegos(gravedad, colisiones, etc.).
Si quieren probar Pilas Engine ( esta todo en español) :
  • Una guía de como instalarlo en Windows 7 está aquí.
  • Una guía de como instalarlo en Ubuntu 12.04 está aquí.
 ahí explican todo y ahí mismo estan los links para las cosas que se necesitan.

Sin más que decir, aquí esta el código :

import pilas
import random

def choque_explosion(bomba1, bomba2): # funcion para realizar la explosion y
 bomba1.explotar()      # la eliminacion de las bombas
 bomba1.eliminar()
 bomba2.explotar()
 bomba2.eliminar() 
 

def main():
 pilas.iniciar() #inicia pilas
 cantidad = 10
 bombas = pilas.grupo.Grupo()  #se crea un grupo para las bombas
 for i in range(cantidad):
  bomba = pilas.actores.Bomba() #se crean las bombas
  bomba.x = random.randrange(-200, +200) #coordenadas aleatorias en x
  bomba.y = random.randrange(-200, +200) #coordenadas aleatorias en y
  bombas.append(bomba)  #se agregan las bombas al grupo
 bombas.aprender(pilas.habilidades.Arrastrable) #se le agrega la posibilidad de
                                                       #ser arrastrable
  
 pilas.mundo.colisiones.agregar(bombas, bombas, choque_explosion) #se agrega la accion a realizar al motor de colisiones
 
 pilas.ejecutar()

main()


Se hace uso de las opciones que Pilas nos ofrece, donde el principal es el uso del motor de colisiones (que es controlado por el motor de física).
Lo que hace el programa a grandes rasgos:
  • Se inicia Pilas
  • Se crea un grupo para las bombas, donde un grupo es como una lista de objetos del mismo tipo, esto se hace para facilitar la manipulación de sus propiedades o personalización de los objetos de una manera mas fácil (en este caso es para esto, puede usarse para otros fines) y no estas agregando o modificando propiedades de objeto por objeto.´Hay una opción parecida a esta en PyGame o tal ves sea una derivada de ésta.
  • Se van creando las bombas, se les asignan coordenadas aleatorios y se agregan al grupo.
  • Se agrega la posibilidad de que cada bomba se pueda arrastrar independiente de las demás y moverse libremente dentro de la ventana.
  • Se hace uso del motor de colisiones de Pilas, donde se le pasan los objetos que interactuaran y la acción a realizar cuando estos colisionen. La acción se define en una función que se encarga de explotar las bombas (una propiedad de estas dentro de Pilas) y posteriormente eliminarlas (otra propiedad para los objetos en Pilas).
Dejo un video del funcionamiento de esto:


El video esta medio lento debido a que se el script consume algo de recursos y el progragra para grabar la pantalla consume una cantidad considerable de recursos, y como mi computadora no es muy rapida que digamos, pues ocurre esto.

También dejo una captura del script corriendo, pero con losmodos de Física, Colisiones y Posicion habilitados.


Cabe aclarar que los circulos verdes (producidos por el modo de Colisión) alrededor de las bombas, son los radios de colisión de cada objeto (bombas en este caso)  y que pueden ser modificables según sea necesario.
El centro de la pantalla es el origen del plano, por lo que las coordenadas negativas estan perimitidas.
El modo de Física muestras actualiza los valores mostrados de la posición de cada bomba al moverla.


La parte correspondiente al proyecto, en mi caso, es aportar al desarrollo de la física del juego.

Para esto se puede hacer uso de la librería PyBoxd2, la misma utilizada para el motor de fisica de Pilas Engine, ya que nuestro juego se desarrollara en un ambiente 2D.
Esta misma, puede proporcionarnos lo necesario para manejar las colisiones o interacciones entre varios objetos que ocurran en nuestro juego y también para establecer una gravedad dentro del juego, aunque creo  que esta no es muy necesaria debido a que practicamentee el juego es 2D.

_________________________________________________________________________
Referencias: