Oct 20

Cuando el compilador de FlexBuilder nos lanza un error en tiempo de ejecución, automáticamente veremos una pila de lineas relacionadas con dicho error. Digamos que tenemos la siguiente estructura de objetos:

Clase Main alberga > clase Menú que alberga > clase Boton

Si uno de los botones genera un error, FlexBuilder nos dirá que en la línea x de la clase Botón hay un error, y seguidamente, nos mostrará el “camino” que ha seguido la aplicación para llegar a dicho error. En este caso el camino sería algo así (pseudo error imaginario claro):

Se ha intentado acceder a un objeto nulo: clase Boton, linea 27
[....] Menu, linea 69
[....] Main, linea 10

Pues bién, esta forma de mostrar los errores no es una característica de Flex Builder. En realidad es un método de la clase “Error” de ActionScript 3. Concretamente el método “getStackTrace()“.

¿Que para qué me sirve saber esto?
Pues resulta que si compilas con Eclipse FDT (por ejemplo), desgraciadamente los errores no vienen seguidos de su stack trace, y es mucho más dificil captarlos, o saber de dónde vienen.

Todavía no he descubierto la manera de que esto sea automático, pero en su lugar hago mucho uso de las sentencias try-catch, con las que podemos simular lo que os contaba:

try
{
    trace("Esto podría generar un error:", objeto.HacerAlgo());
 
}catch(e:Error)
{
    trace(e.getStackTrace()); // esto nos lanza todo el stack trace si se produce un error
}

Espero que os sirva si trabajáis con FDT, y si por casualidad alguien sabe cómo hacer que esto salga por defecto como en Flex Builder, soy todo orejas. Yo he preguntado en el foro de FDT, pero nadie me conesta =(

Oct 20

Solo un apunte rápido. De toda mi experiencia de AS3 hasta la fecha, me acabo de dar cuenta (mira qué luces tengo!), de que la mayoría de errores “en tiempo de ejecución” (sí, eso que pasa después de compilar =), son por la misma causa. Porque estoy intentando manejar un objeto que no existe, ya sea llamándolo directamente, lo cuál es más facil de detectar, o llamándo a un método o propiedad de dicho objeto.

El error típico suele ser:
“TypeError [n]: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo”.

Si compilas con flex builder te dirá exactamente la línea del error. Pero lo que hago casi siempre para solucionarlo es una traza de cada una de las propiedades del objeto. Para ello tengo un método estático en una clase típica de útiles, de esta manera:

public static function TraceProps(o:*):void
{
	for ( var i:* in o)
	{
		trace(">", i, ":", o[i]);
	}
}

Así veremos el nombre y valor de cada propiedad del objeto, y podremos detectar más fácilmente nuestro error.

Jul 25

En una larga charla con Juan Muro, sobre los diferentes hábitos de hacer las cosas en lo que se refiere a proyectos ActionScript, llegamos a la conclusión de que muchos flasheros no dan el salto a utilizar otro editor de código que no sea FlashCS3, y mucho menos a compilar (publicar), por desconocimiento, poca información clara al respecto y confusión entre conceptos tales como Flex, FlexBuilder, Eclipse, FDT, classpath, swc, y diversos términos relacionados con la programación orientada a objetos (POO), etc.

La razón es sencilla. Estamos arraigados a Flash hasta la médula, y nos cuesta cambiar nuestras maneras, que buenas o malas, siempre nos han funcionado.

Con este post me gustaría aclarar dudas que se plantean a cualquier flashero con poca o mediana experiencia a la hora de afrontar un PROYECTO ACTIONSCRIPT con otra cosa que no sea FlashCS3. Continue reading »

Jul 22

Nos encontramos con una aplicación de tantas en la que debemos cargar contenidos externos por demanda del usuarío: una galería de fotos, un catálogo de productos, etc, etc.

Vamos cargando esas imágenes o swf´s en nuestra aplicación y todo es muy bonito y fabuloso… hasta que algo empieza a fallar, se ralentiza o simplemente deja de funcionar. !Mierda! mi pc no vale para nada! Lo tiras por la ventana y te compras uno nuevo… pero a ver, si en mi ordenador que es un pepino, no funciona, los clientes lo van a flipar más aún.

Fuera de bromas, todo esto pasa porque lo que vamos cargando se almacena en memoria, y cuando hacemos desaparecer un contenido, no lo estamos aniquilando debidamente.
Resulta que el típico MovieClip.unloadMovie() de AS2 ha desaparecido en el olvido. Ese método se cargaba cualquier cosa que hubiera cargado externamente, liberando así la memoria y haciéndonos más felices y contentos. En cambio, en AS3 la cosa se complica mucho. Según leo en el blog de gSkinner, éstos son los motivos del problema, y por los cuáles sería imposible “descargar” algo:

  • Cualquier listener, timer, o variable que haga referencia al contenido cargado
  • Un contenido cargado con la línea de tiempo reproduciéndose
  • Un contenido cargado con algún listener que se refiera al stage, o a cualquier cosa fuera de su ámbito

Y creo que no podría explicarlo mejor que gskinner en este párrafo:

In AS3, calling Loader.unload() simply removes the reference to the loaded movie. If any other references exist to the loaded content, it will not be unloaded. Even when all references are removed, it only frees the content for collection by the garbage collector at some indeterminate point in the future. This means that even if everything worked as expected the loaded content will continue to execute, and remain in memory for an indeterminate amount of time after you unload it. This is problematic in many ways, but it is made worse by a bug in the player.

Parece mentira que a estas alturas con un señor Flash Player 9 y el tan supuestamente mejorado y todo poderoso ActionScript 3.0, nos encontremos con que la gestión de memoria es lo más decadente que nos podamos echar encima.

Aunque no todo es feo y negativo. Por lo visto con Flash Player 10 está medio resuelto el problema, y esperemos que este player se extienda rápido para poder producir con él.

Otro buen artículo sobre gestión de recursos, tambien de Grant Skinner.

Ala! a disfrutar con Adobe

Jul 21

Acabo de hacer una prueba con esta clase y me ha parecido de lo más útil. Hace poco hice una clase similar por no saber que existía (creo que por entonces no existía). Es una cámara que usamos en lugar de “Camera3D”, que nos da total control sobre ella, mediante movimientos de ratón (pinchar y arrastrar) y mediante el teclado.

Me parece idónea para movernos por la escena y explorarla desde todas las vistas posibles cuando estamos desarrollando con Papervision3D. Además podemos explorar en tiempo real, propiedades muy importantes como “fov”, “near plane” y “far plane” para el manejo del frustum culling (la explicación de todo esto vendrá en nuevo post), lo que nos evitará tener que cambiar y probar con numeritos “mágicos” tropecientas veces hasta que los objetos se vean como queremos.

La clase se encuentra en el mismo package de las cámaras (org.papervision3d.cameras).
Si no la encuentras hazle un “update” a tu repositorio, que lo más seguro es que tengas una versión desactualizada.

Aquí va una prueba sencilla de lo que estoy contando: Continue reading »

Jul 16

Basándonos en el ejemplo anterior de cómo crear una aplicación mediante el “BasicView”, vamos a utilizar todas las primitivas de Papervision3D (package objects.primitives).

De momento usaremos solamente un material, el WireframeMaterial, ya que el uso de materiales se detallará debídamente en otro post.

Aunque no es una primitiva tambien usaremos la clase UCS (objects.special), que no es sino un eje de coordenadas 3D visibles formadas por líneas (core.geom.Lines3D), que nos pueden ser muy útiles en algunos casos.

También aprovecho para implementar un movimiento de cámara con tweenings, de una primitiva a otra, y una navegación mediante botones fuera de la escena de Papervision, que servirán para navegar. Los botones son de la clase “ItemButton”, de los cuáles podéis ver la referencia en este post, aunque lógicamente sirve cualquiera. Continue reading »

Jul 15

Como bién dice en la documentación de Papervision3D (traduzco), el BasicView es una clase que nos brinda una plantilla para configurar rápidamente un proyecto de Papervision, creando automáticamente un viewport, escena, cámara y renderer (bucle de renderización). Como BasicView es una subclase de Sprite, la podemos añadir a cualquier DisplayObject.

En resumen: te facilita la vida para proyectos sencillos, evitando instanciar y declarar unas cuantas cosas.
La clase la podéis encontrar dentro del package “view” de Papervision3D Great White.

Veamos el mismo ejemplo del post “Papervision3D y Flex Builder: Primeros pasos“, pero ahora usando la clase “BasicView”. He quitado todos los comentarios que no vienen al caso para centrarnos en lo importante: Continue reading »

Jul 15

Esta clase es un simple controlador de caché. Un array que almacena datos cargados. Si nuestra aplicación carga datos bajo demanda, por ejemplo de una base de datos, tal vez queramos almacenar los datos en una caché interna, de manera que solo hará falta una petición al servidor para mostrar el mismo dato o consulta.

Ejemplo:

Tenemos un catálogo de productos, el usuario pincha un botón del producto con “id=x”
Hacemos una consulta a la base de datos que nos devuelve todos los datos de ese producto, que parseamos creando un objeto.
El usuario continua navegando por otros contenidos. Acto seguido vuelve a reclamar el producto mostrado anteriormente. ¿Por qué volver a hacer la petición al servidor si previamente podíamos almecenar esa información?

Pues esa situación es la que resuelve esta clase.
Admite cualquier tipo de datos. Continue reading »

May 10

 

Hola a todos, os dejo un listado de las ultimas api´s en as3 que he encontrado últimamente. Sirven para acceder diréctamente desde ActionScript (bueno, para según qué cosas hace falta código del lado del servidor) a servicios conocidos como YouTube, Facebook, Flickr, etc.
Os recomiendo que descarguéis los archivos (normalmente son repositorios de subversion) y que vayáis probando. Suelen ser bastante sencillos en cuanto a funciones básicas.

Picasa albums:
http://code.google.com/apis/picasaweb/overview.html

Flickr:
http://code.google.com/p/as3flickrlib/

YouTube:
http://code.google.com/p/as3-youtube-data-api/

Facebook:
http://code.google.com/p/facebook-actionscript-api/
http://code.google.com/p/as3facebooklib/

Last FM:
http://code.google.com/p/lastfm-as3/

Y si en esta lista no hay nada que os llame la atención, todavía os queda el buscador de google code!

Apr 18

Acabo de solucionar un problema con texto dinámico que me ha dado más de un día de quebraderos de cabeza en el trabajo.

El caso

Resulta que los contenidos de un frame en concreto (que no sea el 1) de la línea de tiempo (me refiero a cualquier instancia colocada en el escenario), NO están disponibles, o mejor dicho, NO existen nada más llegar al frame.
Por ejemplo:
- Crea una peli nueva
- Pon un movieClip en el frame 5 con nombre de instancia “prueba”
- Ahora vuelve al frame 1 y en panel de acciones escribe este código:

stop();
gotoAndStop(5);
trace(prueba); // null

El resultado del trace nos da “null” !!!!!
Esto no pasaba en as2, y me fastidia que en algunos aspectos as3 va hacia atrás en lugar de mejorar las cosas (y eso que no puedo vivir sin él).

Solución

Para solucionar esto hay que programar un método que busque periódicamente el movieClip “prueba” hasta que ya esté disponible. ¿Cómo?, pues con un Timer por ejemplo:

stop();
gotoAndStop(5);
trace(prueba); // null
 
var timer:Timer = new Timer(10, 0); // se repite cada 10 milisegundos indefinidamente
timer.addEventListener(TimerEvent.TIMER, AccessContent);
timer.start();
 
function AccessContent(event:TimerEvent):void
{
    if(prueba != null)
    {
        Timer(event.target).stop();
        trace("ya tenemos acceso a prueba: ", prueba)
    }
}

Yo personalmente preferiría no tener que hacer esto nunca, ya que me parece una guarrería, pero a veces, por como está montado el proyecto, (o cómo nos lo han dado), o vete a saber qué cosas, pues tenemos que hacer ñapas como estas.
De todas formas, no se si esto es “lógico” o es un bug.

Saludos

Mar 17

A través de uno de los foros de adobe (”macromedia.espana”), veo que uno de sus integrantes hizo un componente en Flash con el que se pueden ver videos de youTube. Mi sorpresa no ha sido pequeña, ya que hace algunos meses me propuse hacer algo parecido para la web de un amigo, y nunca lo conseguí, debido a la limitación que por aquél entonces tenia youTube y su “crossdomain”. Cuando conseguía cargar el video, éste se escalaba de forma inesperada y su posición no se podía controlar (estoy hablando desde Flash lógicamente).

Muchos pensarán que siempre ha sido muy fácil hacer esto, pero no es asi, os lo aseguro. Embeber el player de youTube en una página html es un juego de niños, pero al intentarlo mediante ActionScript, la cosa cambiaba.

Enseguida busqué en el blog de youTube, cuando me encontré con esto:
http://code.google.com/apis/youtube/overview.html

Donde podréis encontrar toda la documentación y API´s para desarrollar clientes de youTube en varios lenguajes como PHP, Flash, .NET, Rubi, Java, etc. En este link hay un listado de recursos muy interesante, y más concretamente, la as3-youtube-data-api, que es lo primero que busqué al empezar a ver todo este tema.

imagen-1.png

Las API´s no se limitan a la visualización de vídeos. Con ellas podemos acceder a una lista larga de webservices muy interesantes:

Introduction

This library connects to the http://gdata.youtube.com host to collect publicly available information on the YouTube Data API Feeds. You can search for videos, and get data for: standard video feeds, video responses, video comments, user profiles, user subscriptions, user favorites, and playlists.

Y genial, ahora podemos hacernos nuestra propia platarforma de video a costa de YouTube, y sin publicidad de ningún tipo y, desde un montón de lenguajes distintos. Ya nadie tiene escusa =)

Posibilidades infinitas. Creo que esto va a dar mucho de qué hablar, y creo que muchas empresas del sector de hosting de streaming se verán muy afectadas, y otros muchos beneficiados (como es mi caso ).

Mar 04

Estoy metido en un proyecto donde los “artes” han dictaminado que nuestra aplicación Flash (un juego) irá a 12 FPS(frames por segundo). Los motivos no vienen al caso.

Resulta que yo siempre he testado a 31 FPS, por lo que mis animaciones con Tweening (Tweener de Caurina) iban de lujo. Cuando puse el swf a 12 FPS menuda cagadilla, todo a saltos y horrible. Y claro, es que la mayoría de las librerias de Tweening usan el evento ENTER_FRAME para renderizar el movimiento, por lo tanto, a menor tasa de frames por segundo, menos fluidas serán nuestras animaciones, al igual que ocurre con animaciones en timeline.

Buscando por ahí encontré este paquete de animaciones que permite elegir el modo de renderizado entre ENTER_FRAME y un TIMER, además de otra serie de características que me han gustado bastante. Problema del framerate arreglado ! Incluso a 1 FPS la animación rula bién.

Felicitación y gracias al máquina que las hizo (boostworthy.com).
Os animo que que os bajeis el paquete, que viene con documentación, y que la probéis. No tiene desperdicio.

Jan 20

Haciendo de las mías en AS3, lo primero que eché en falta fueron los delegates de AS2 que podían pasar parámetros:
[as]unboton.onRelease = Delegate.create(ambito, ambito.funcion, param1, param2,….paramN);[/as]

o también…

unboton.addEventListener("evento", Delegate.create(ambito, ambito.funcion, param1, param2,....paramN) );

Pues algo tan sencillo no he podido hacer en AS3, y vi que existían otras maneras de hacerlo, pero ninguna tan clara y fácil como la forma que usábamos en as2. Hasta que encontré esta maravillosa página donde dan la solución al problema con una simple clase “Callback” que sirve exactamente para estos menesteres. A partir de ahora, la utilizaré siempre ;)

Un ejemplo de uso en as3:

package
{
import xFramework.utils.Callback;
 
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.MouseEvent;
import flash.events.Event;
 
public class CallbackTest extends Sprite
{
public function CallbackTest()
{
var s:Shape = new Shape();
s.graphics.beginFill(0x000000);
s.graphics.drawCircle(100, 100, 10);
s.graphics.endFill();
var cont : Sprite = new Sprite();
cont.addChild(s);
cont.addEventListener(MouseEvent.CLICK, Callback.create(onClicked, cont, "esto funciona"));
addChild(cont);
}
private function onClicked(event:Event, cont:Sprite, str2:String):void
{
trace(cont, str2);
}
}
}
Jan 20

Acabo de entrar en gotoandlearn.com y veo que Lee Brimelow ha lanzado hace unos días la versión 2. Os animo a que entréis y echéis un ojo, vais a poder encontrar tutoriales que ya conocéis y otros realmente interesantes.