Take A Photo – Demo

Hace unos meses publiqué un plugin para tomar fotos instantáneas desde una página web, usando Flash y un plugin para Ruby on Rails.

Hoy me puse un rato a jugar y armé un demo donde se pueden tomar fotos (ojo que todo es público :D) : TAP.

Las fotos se borran una vez por día y acepta un máximo de 50 fotos por día (para evitar que me llenen el disco). Tengo algunos TODOs que iré viendo de resolver en los tiempos libres (como cambiar el tamaño de la foto, recortar, aplicar efectos, etc).

Necesita Flash 9 o superior y una web cam para que tenga sentido :). Todavía sigo peleando con el Flash player de Linux y la camarita, sorry :S.

Les recomiendo verlo en Firefox, no me gasté en ver si en IE el CSS no se rompe y no creo que lo haga nunca.

El diario Escondido

Luego de muchos meses de mucho trabajo, remasterización, ajustes, pruebas y demás, finalmente pudimos terminar y poner online una de las campañas más ambiciosas que hemos hecho hasta ahora : El diario Escondido.

httpv://www.youtube.com/watch?v=MUI7FbMoNDw

Hasta el día del lanzamiento solo podrán ver el trailer, si lo juegan me gustaría que después se pasen y dejen opiniones sobre qué les pareció :).

PD: No, no estoy autorizado a decirles como pasar, sumarles puntos extra o hacerlos subir de ranking :D.

Take A Photo – Fotos instantáneas desde tu web

En la última semana estuve trabajando en agregar nuevas funcionalidades a un sitio de un cliente y entre los pedidos estaba una especie de Fotoblog para los usuarios (y bue, hay que pagar las cuentas a fin de mes :P).

La cosa salió rápido, usando Paperclip que guarda las imágenes que se suben, se muestra en orden, etc, nada del otro mundo. Pero hablando con el cliente surgió la idea de hacer que el usuario se pueda tomar una foto directamente desde la web usando su webcam, así que después de decir “si, se debe poder hacer” mentalmente me salió un “doh!, que dije!“. Lo último que se dijo en esa reunión fue “Lo quiero” :D.

Ya había visto juegos flash que utilizan la webcam así que empecé por ahí, para ver como sacaban un frame del video, lo cual era muy fácil. Lo siguiente era serializarla. A falta de algo mejor hice un serializador de imágenes muy pedorro, pero que anda (aunque es lento), que envía por POST la información de cada pixel.

La parte de Ruby fue fácil y decidí encapsularla en un plugin de Rails para poder reutilizarlo luego o por si a alguien más le sirve :). Además se puede integrar con Paperclip o AttachmentFu para hacer la persistencia de la imagen en donde sea.

La única parte que usa Flash es el capturador de la cámara, porque otra no quedaba, pero luego el botón para tomar la foto y los eventos se manejan todo por Javascript.

El plugin tiene varios TODOs, pero por si a alguien le sirve está en github.

Update : A falta de demo, algunas de las fotos tomadas con la aplicación de ejemplo que hice hoy durante Locos x rails.

MovieClip Factory en Flash

Para un videojuego que nos pidió un cliente tuve que solucionar un problema que me costó bastante y es por eso que lo comparto. Si bien no me gusta mucho escribir por acá sobre software privativo, en este caso encontré tan poca información que me pareció bueno compartirlo.

El juego en cuestión es un scroller horizontal, en donde van entrando chimeneas (mas bien techos con sus chimeneas) y Papá Noel tiene que hacer el delivery de regalos :). El problema apareció cuando empecé a agregar más y más techos al escenario.

La forma en que inicialmente lo manejaba era con un gran MovieClip que tenía adentro los techos en sus respectivas posiciones y luego moviendo el gran MovieClip movía todo. Simple, pero inefectivo. Según parece (aunque no hay nadie que lo confirme) Flash se lleva mal con las técnicas de clipping básicas y por eso el mover un MovieClip enorme (estamos hablando de 4000 o 5000px de ancho) le es costoso (algo así como consumir el 95% del CPU). Otra cosa que incrementaba el problema es que el juego tiene 3 layers para hacer un efecto de Parallax scrolling.

Esto hizo que empezara a investigar opciones, y la solución que mejor se adapta es crear los objetos antes de que entren en pantalla (unos pixels antes) y destruirlos al salir. Ahora bien, crear y destruir objetos on-the-fly es aún peor en muchos casos que el problema inicial :). La solución real al problema es reutilizar las instancias en lugar de eliminarlas. ¿Cómo?. Seguí leyendo.

La idea básica es que cuando un MovieClip sale de pantalla, en lugar de eliminarlo lo ocultamos. De esta forma Flash lo ignora al hacer el render. Si en algún momento necesitamos crear un objeto del mismo tipo, en lugar de crear uno nuevo, reutilizamos el que teníamos oculto y lo hacemos visible (previo acomodarlo donde corresponde). Ahora multipliquen esta idea por 10 tipos de objetos diferentes, y que además son generados al azar antes de empezar cada nivel (no puedo predecir cuantos de cada tipo necesito).

Esto hace que en lugar de tener una lista de MovieClips tengamos una lista de puntos, y solo movemos los puntos. En cada frame nos fijamos que puntos están por entrar a la pantalla y creamos el nuevo objeto y lo ponemos en la posición del punto. Mi código luce más o menos así :

// Crea los objetos que deben estar visibles
// en un momento dado.
while (i  (Stage.width+10)) {
    // Este punto está muy afuera y como
    // están ordenados, el resto también.
    break;
  }

  // Si estoy a 10 pixels de entrar lo creo
  var t:Techo = factory.create(o.techo, "techo"+last_id, 9000+last_id);
  // Acomodo el nuevo objeto, ya sea nuevo nuevo u obtenido del cache
  t._x = o.x;
  t._y = Stage.height - 125;
  // Esta lista tiene los Techos reales que estan visibles en pantalla
  techos.push(t);
  last_id++;
  ++i;
}
// Elimino los puntos que ya use
chimeneas = chimeneas.splice(i);

La solución que implementé fue esto que llamo “MovieClip Factory” que adjunto al final del post para quien quiera descargarla. La idea es que en lugar de crear un nuevo MovieClip con attachMovie, lo hago con la factory. Esta clase se encarga de manejar al lógica de caching de manera transparente.

Cuando no necesitamos más un objeto simplemente lo devolvemos a la fábrica y así esta lo deja a la espera de ser reusado. Un ejemplo de uso sería algo como sigue :

/* mc sería el MovieClip que queremos usar como padre */
factory = new Factory(mc);
factory.registerCode(1, "Techo01");

var t:MovieClip = factory.create(1, "un_id", 1);
// Devuelvo el objeto al factory.
factory.push(t);

/* A este punto t y u son el mismo objeto */
var u:MovieClip = factory.create(1, "un_id", 1);

Haciendo las cuentas, si en promedio mis techos miden 250px cada uno, de hacerlo de la manera inicial tendría que crear unos 16 techos para un escenario de 4000px de ancho. Usando el factory, suponiendo que más de 4 techos a la vez no puedo ver (por el ancho del área visible) en el peor de los casos tengo 4 de cada tipo de techo (2 completos y 2 mitades, una que entra y una que sale), es decir 20 objetos en memoria siendo el consumo mayor.

Sin embargo al generar el escenario en forma aleatoria yo valido que no toquen 2 iguales seguidos porque quedaban feos, por lo que la cuenta en realidad da 2 objetos simultáneos máximo de cada tipo, siendo 10 en total en memoria.

La otra ventaja es que puedo hacer el escenario infinitamente largo a costo constante de uso de memoria 🙂

Descargar MovieClip Factory

Flash Player 10 para Linux

Esta semana hice un update de mi Ubuntu Intrepid ya que tenía varias cosas en espera de actualización. Uno de los paquetes que entró fue el Flash Player (nonfree) 10 de Adobe. Como me pasa siempre que aparece una nueva versión del player para Linux, mi estado de ánimo fue pasando de “contento” a “frustrado” :).

Flash parece que se va a quedar un rato largo, es una realidad innegable. También es una realidad que debemos evitar que se propague a donde el contenido importa, pero no veo mal que si alguien quiere hacer una campaña de marketing se haga un mega sitio en Flash, es problema de esa empresa (y al final tal vez me pagan por hacerlo, así que está doblemente bien :P). Otro nicho de Flash son los juegos casuales. Yo, como ex “hardcore gamer”, migré a kongregate.com hace rato :).

Lo que más molesta es lo poco que hacen avanzar el plugin en cada release. En este caso se nota que lo único que agregaron es el soporte de los nuevos chiches (que dicho sea de paso el soporte de Bones para animar está muy groso para hacer videojuegos), pero no arreglaron ninguno de los problemas ni dan soporte a los “viejos chiches”. Un ejemplo, todavía no hay soporte de V4L para poder usar las webcams desde Linux, es muy frustrante, sobre todo cuando hay Webcam Games que para pasar el rato son entretenidos.

Los problemas de performance también siguen, es imposible usar el “Pantalla Completa”, sigue consumiendo mucho CPU, a veces el Firefox explota, etc. Historia conocida.