Stratos

Temas: HTML5 Stratos
Juan Mellado, 3 Enero, 2012 - 18:27

PlayN es una librería multiplataforma de Google para desarrollar juegos. El nombre viene de "... for N>=4 platforms", aunque a día de hoy más bien es "N>=3", ya que sólo compila para Java, HTML5 y Android. La cuarta plataforma que faltaría es Flash, que está desarrollada, pero actualmente no funciona.

En la Google I/O del año pasado la presentaron con el nombre de "ForPlay":


Con el nuevo nombre de la librería hicieron hace poco una nueva presentación, entrando más en detalle con un ejemplo más concreto explicando como portaron "Angry Birds" a HTML5. No está colgada en YouTube, pero el vídeo y las diapositivas se pueden ver (no muy bien) en Angry Birds on HTML5. Para los que tengan curiosidad, el juego está online y se puede jugar en http://chrome.angrybirds.com/.

Respecto a la librería, comentar que está montada sobre GWT, por lo que el código se escribe en Java. Y a través de Eclipse, con los plugins correspondientes, se genera el código para la plataforma destino preferida. Ofrece una abstracción del bucle principal habitual de un juego, leyendo la entrada del usuario, actualizando el mundo y renderizándolo. Además de dar soporte para los componentes básicos, como gráficos, sonidos, red, física (Box2D embebido), gestión de recursos, ...

El proyecto está en desarrollo todavía, es ambicioso, y GWT no ha acabado de terminar de cuajar entre el gran público. En cualquier caso la idea no es mala. Pero es lo de siempre, un mismo código que pueda ejecutarse en todas partes.

Juan Mellado, 9 Diciembre, 2011 - 09:12

www.experimentalgameplay.com es una web que propone un tema nuevo cada mes e invita a la gente a crear un juego basado en dicho tema propuesto. La única condición es que lo haga una única persona en menos de una semana, aunque tampoco se controla, es ya cuestión de cada cual cumplirla o reconocer que no lo ha hecho. Este mes sin embargo han cambiado las reglas.

experimentalgameplay.com

Hasta ahora la participación ha sido muy variada, hay meses que han alcanzado hasta casi cincuenta juegos y el mes pasado por ejemplo apenas llegaron a cinco. No hay premio, sólo la recompensa a nivel individual que cada uno quiera atribuirse.

Sin embargo en la última convocatoria han cambiado las reglas. Han dado dos meses de plazo (diciembre y enero), y el tema propuesto es crear un juego que funcione con cinco botones, concretamente con las teclas que van del "1" al "5". Han llamado 5 BUTTONS al tema.

La gracia es que van a utilizar una instalación creada a propósito en una sala de exposiciones para exhibir el juego ganador con un proyector y cinco grandes botones de 80cmx80cm, de forma que en vez pulsarlos lo que se hará en realidad será saltar sobre ellos.

Para rematar la faena han añadido premios en metálico:
- Primer lugar: 1200 €
- Segundo lugar: 600 €
- Tercer lugar: 200 €

Y han confirmado que el juego se expondrá en un evento mayor.

Juan Mellado, 30 Noviembre, 2011 - 15:37

Al Independent Games Festival del año que viene, más conocido como IGF 2012, se han presentado a la competición principal casi 570 juegos para todo tipo de plataformas. Desde la organización han montado una página con el detalle de cada uno, incluyendo sinopsis, imagen y vídeo.

IGF 2012

Dedicando apenas un minuto a cada uno de ellos llevaría del orden de unas diez horas echarles un vistazo rápido a todos. Y a ese tiempo habría que sumar además el necesario para revisar los casi 300 trabajos presentados en la competición de juegos realizados por estudiantes, que también tiene su página correspondiente.

Mucho que ver ahí, con paciencia. No es de esperar que todos y cada uno de ellos sean originales, pero siempre puede haber alguna sorpresa. "Los buenos artistas copian, los grandes artistas roban" dijo Picasso.

No envidio al jurado.

Temas: Flash Stratos
Juan Mellado, 22 Noviembre, 2011 - 22:51

WebGL Cheat SheetEl lanzamiento de la versión definitiva de Flash 11 hace unas pocas semanas trajo consigo el tan esperado Stage3D, anteriormente conocido como Molehill. O lo que es lo mismo, la posibilidad de aprovechar las capacidades de las GPUs desde Flash. En principio es una alternativa más a otras opciones disponibles actualmente como WebGL, aunque el anuncio por parte de Adobe de renunciar a seguir desarrollando Flash para móviles en favor de su plataforma AIR nos ha dejado despistados a un montón de gente. Pero decisiones empresariales aparte, el API está ahí fuera y es hora de echarle un vistazo.

Siguiendo mi costumbre, he elaborado una pequeña cheat sheet para que me sirva de referencia, igual que la que hice para WebGL.

Lo primero que llama la atención es que es una API de muy bajo nivel. Los que hayan utilizado alguna vez OpenGL, WebGL o DirectX se sentirán cómodos. Pero sinceramente, me esperaba una jerarquía de clases que ofreciera una funcionalidad de más alto nivel para la gestión de escenas, cámaras, colisiones o carga de modelos. Pero no, las clases que hay son para el acceso a bastante bajo nivel. De hecho, ni siquiera han incluido en el runtime el compilador de shaders.

Pero vayamos por partes, las clases básicas de entrada al API son Stage3D y Context3D. La primera clase representa la superficie sobre la que se dibuja, de forma similar al Stage de toda la vida, y que permite además instanciar la segunda clase a través de un evento (para las situaciones de pérdida de contexto). El contexto 3D es el que permite instanciar al resto de clases como los buffers de índices, vértices, texturas o shaders.

public class Example extends Sprite{
  private var stage3D:Stage3D;
  private var context3D:Context3D;

  public function Example(){
    stage3D = this.stage.stage3Ds[0];
    stage3D.addEventListener(Event.CONTEXT3D_CREATE, onContext3DCreate);
    stage3D.requestContext3D(Context3DRenderMode.AUTO);
  }

  private function onContext3DCreated(event:Event):void{
    context3D = Stage3D(event.target).context3D;
  }
...

Context3D es la clase base, muy similar a otras APIs, y permite, entre cosas, establecer el estado del render con las clásicas opciones de configuración del z-buffer, blending o stencil, y el envío al driver de la orden de dibujado de triángulos.

Otras clases básicas son VertexBuffer3D, IndexBuffer3D, Texture, CubeTexture y Program3D. Pero tienen muy poca funcionalidad, apenas dos o tres métodos para inicializar su contenido desde fuentes de distintos tipos como arrays o matrices. El resto de clases son básicamente enumerados con las constantes típicas como Context3DTextureFormat, Context3DVertexBufferFormat, Context3DBlendFactor o Context3DStencilAction. En total son unas nueve clases de este último tipo, pero no ofrecen mayor funcionalidad aparte de exponer las constantes.

var triangles:Vector.<uint> = Vector.<uint>( [ ... ] );
...
indexList = context3D.createIndexBuffer(triangles.length);
indexList.uploadFromVector(triangles, 0, triangles.length);
...           
context3D.setCulling(Context3DTriangleFace.BACK);
...

Por lo que respecta a los shaders, Adobe ha definido un lenguaje propio (otro más) de muy bajo nivel llamado AGAL (Adobe Graphics Assembly Language). Es realmente ensamblador, por lo que las operaciones son de muy bajo nivel. Las instrucciones son opcodes que manipulan directamente los distintos tipos de registros habituales (attribute, constant, temporary, output, varying, sampler).

private const VERTEX_SHADER:String =
  "mov v0, va1"; //Color (v0: varying 0 <= va1: attribute 1)
  "m44 op, va0, vc0 \n" + //Perspectiva (op: output position, vc0: constant 0)
       
private const FRAGMENT_SHADER:String =
  "mov oc, v0"; //oc: output color

El array de bytecodes correspondiente a un shader puede generarse en tiempo de diseño mediante Pixel Bender 3D, que es una ampliación de la versión 2D de Pixel Bender, una tecnología de Adobe para el procesamiento óptimo de imágenes y vídeos independiente de la plataforma hardware utilizada basada en el uso de ficheros XML. Aunque afortunadamente los shaders también pueden compilarse de una forma más conveniente en tiempo de ejecución mediante una clase de utilidad externa llamada AGALMiniAssembler.

private var vertexAssembly:AGALMiniAssembler = new AGALMiniAssembler();
private var fragmentAssembly:AGALMiniAssembler = new AGALMiniAssembler();
private var programPair:Program3D;
...
vertexAssembly.assemble(Context3DProgramType.VERTEX, VERTEX_SHADER, false);
fragmentAssembly.assemble(Context3DProgramType.FRAGMENT, FRAGMENT_SHADER, false);
...
programPair = renderContext.createProgram();
programPair.upload(vertexAssembly.agalcode, fragmentAssembly.agalcode);

Por lo que respecta al bucle principal habitual de Flash, no parece requerir modificación, pudiéndose seguir utilizando el evento ENTER_FRAME por ejemplo.

  ...
  this.stage.addEventListener(Event.ENTER_FRAME, render);
}

private function render(event:Event):void{
  ...
  context3D.drawTriangles(indexList, 0, 12);
  context3D.present();
}

En definitiva, una API más, una opción más a tener en cuenta a la hora de representar 3D en el navegador. Quizás de muy bajo nivel para el concepto que suele tenerse en la cabeza de Flash, percepción que la aparición de ActionScript 3 empezó a modificar y que Stage3D no hace más que confirmar.

Para terminar, revisando la web de Flash, he encontrado un enlace a un proyecto de la propia Adobe llamado Proscenium. Una librería gráfica de alto nivel, a modo de engine 3D, que están desarrollando sobre Stage3D. El inconveniente es que está aún en fase de desarrollo y no tiene soporte, aunque ya permite crear primitivas básicas, cargar modelos de objetos, e incluso gestionar colisiones. No sé como acabará, pero supongo que pretenderá ser una alternativa a motores desarrollados de forma independiente, como por ejemplo el popular Away3D y otros, que la propia Adobe parece estar apoyando.

Juan Mellado, 21 Noviembre, 2011 - 16:50

Opera lanzó hace unas semanas un build especial de su navegador que habilitaba el uso de la función getUserMedia de JavaScript. Esta función permite acceder a la webcam directamente desde JavaScript de forma nativa. He creado una nueva demo de js-aruco, mi detector de marcadores de realidad aumentada, usando esta versión para conseguir que todo el proceso sea 100% JavaScript evitando Flash para la captura de la webcam.


Demo online:
www.inmensia.com/files/aruco/getusermedia/getusermedia.html

Para que la demo funcione hay que realizar dos pasos:

1) Instalar la versión especial del navegador de Opera que se encuentra en el siguiente enlace:
http://labs.opera.com/news/2011/10/19/

2) Permitir el acceso del navegador a la webcam a través de las opciones de configuración a través del siguiente enlace:
opera:config#SecurityPrefs|AllowCameraToCanvasCopy

Por motivos de seguridad, el navegador debería pedir permiso a los usuarios antes de acceder a la webcam, pero este funcionamiento no está todavía implementado. Lo que si está desarrollado es que no se pueda acceder por código. Si se intenta acceder con la función getImageData al contenido del canvas se produce una excepción de seguridad.