[OT] Shuffle art
Izquierda: Designed by Jack Williamson Sanz ( edad: 6 ).
Derecha: Designed bt Leah Williamson Sanz ( edad: 3 ).
« Enero 2005 | Inicio | Marzo 2005 »
Izquierda: Designed by Jack Williamson Sanz ( edad: 6 ).
Derecha: Designed bt Leah Williamson Sanz ( edad: 3 ).
La respuesta, en el artÌculo de Troy Holmes publicado en sys-com.
El autor explica los conceptos clave de esta metodologÌa de desarrollo, y da algunos consejos para llevarlos a la pr·ctica.
El link al artÌculo: http://sys-con.com/story/?storyid=48170&DE=1
Alguien que me quiere mucho, o que no me conoce lo suficiente, me ha enviado un iPod Shuffle. Y la verdad es que el juguetÌn es una cucada.
Seguro que ya habeÌs visto miles de fotos como Èstas, pero aquÌ va mi contribuciÛn a la secciÛn "he abierto una caja y he hecho 500 fotos".
La caja, que tiene un tacto my agradable:
La parte de atr·s de la caja. El texto en castellano no est· impreso en el cartÛn, sino en una pegatina.
Y aquÌ todos los contenidos de la caja. Me encantan las pegatinas:
Ahora mismo est· conectado al portatil, en proceso de carga.
Acabo de recibir un email de Richard Leggett, anunciando Flash Mobile Community.
La idea original de esta comunidad era permitir a los desarrolladores el intercambio de swf para que pudieran ser testeados en distintas plataformas, pero la idea ha crecido, y ahora se ha incluido un agregador de noticias, foros, etc.
Si est·s interesado en el desarrollo de aplicaciones mÛviles, puede ser un recurso fundamental. AquÌ est· el link: http://www.flashmobileforum.org/
Sabemos que se puede asignar una clase AS2 a cualquier movieclip que se encuentre en la librerÌa. Si esa clase extiende movieclip, cuando se atachea ( menudo palabro ) el clip se materializa una instancia de esa clase. Pero ni siquiera hace falta hacer el attachmovie. Con colocar el clip en el stage en tiempo de diseÒo es suficiente, la instancia de la clase se materializar· cuando el cabezal llegue a ese frame. Esto puede facilitar el trabajo cuando se est· creando una interfaz de usuario, no hay m·s que colocar el movieclip en el stage y *magia*, se tiene una instancia de la clase asociada.
Imaginemos que hay que crear un interfaz parecido a Èste:
Podemos escribir una clase como Èsta:
class MyButton extends MovieClip
{
function MyButton()
{
stop();
}
function onRollOver():Void
{
gotoAndStop(2);
}
function onPress():Void
{
gotoAndStop(3);
}
function onRollOut():Void
{
gotoAndStop(1);
}
}
Si asignamos el valor de la clase de AS2 del movieclip:
Entonces, en cuanto esos clips aparezcan en el stage, tendremos dos instancias de la clase MyButton. Muy bien. Hemos encontrado una forma facil te llevar el clip a su segundo frame cuando hagamos rollover, devolverlo al primero al hacer rollout.... Estupendo.
Pero nuestros botones no est·n solos, son parte de una aplicaciÛn. øQuÈ pasa cuando hacemos click en ellos?. øCÛmo interact˙an con el resto de la aplicaciÛn?
Recuerda: no hemos creado las instancias de MyButton a travÈs de su constructor, por lo que no les podemos pasar ning˙n par·metro. Entones, øcÛmo podemos manejar el click del botÛn?
Bueno, podrÌamos hacer que esta clase actuara como emisor de eventos. De este modo, podrÌamos emitir un evento al hacer click en el botÛn.
Supongamos que hay una clase en la que reside la lÛgica de la aplicaciÛn, o que sÛlo es la vista de la misma, da igual. LlamÈmosla AppInstance. Esa clase podrÌa ser instanciada, por ejemplo, en el primer frame del root.
Esa clase no sabe cu·ntos botones hay en el stage, entre otras cosas porque no los ha creado, y por tanto no puede registrarse como listener a los eventos que los botones pudieran emitir
øQuÈ podemos hacer, entonces?. Esos botones son movieclips que est·n colocados directamente en la lÌnea de tiempo principal, asÌ que podrÌamos aÒadir el siguiente mÈtodo a la clase MyButton:
function onRelease( )
{
this._parent.doWhatever( );
}
Si quisiÈramos ejecutar una funciÛn llamada doWhatever que estuviera definida en el root, o:
function onRelease( )
{
this._parent.appInstance.doWhatever( );
}
Para ejecutar el mÈtodo doWhatever de la clase appInstance.
Pero aquÌ est· el problema. Este cÛdigo huele fatal. øPor quÈ?. Por el _parent. Estamos atacando directamente una lÌnea de tiempo concreta. øQuÈ pasa si tenemos que cargar este swf desde otro?. øQuÈ pasa si la aplicaciÛn no se llama appInstance?. øQuÈ pasa si tenemos que pasar de alguna forma alg˙n indicativo del botÛn que se ha clickeado?. Este botÛn funcionar· sÛlo cuando estÈ colocado en una lÌnea de tiempo en la que haya una variable que se llame appInstance
La verdad, no hay mucha diferencia con la forma en la que se manejaban los botones hace tiempo, cuando se asignaban los handlers "on" directamente en un script asignado al botÛn o al movieclip.
Bueno, y entonces, øquÈ podemos hacer?. °Pues componer, en vez de heredar!.
Vamos a cambiar el cÛdigo de la clase MyButton:
class MyButton
{
private var timeline: MovieClip;
private var buttonId: String;
private var btMC: MovieClip
function MyButton( timeline: MovieClip, buttonId: String )
{
this.timeline = timeline;
this.buttonId = butonId;
this.btMC = this.timeline.attachMovie( this.buttonId, this.buttonId, this.timeline.getNextHighestDepth( ) );
this.initEvents( );
}
private function initEvents( )
{
var manager: MyButton = this;
this.btMC.onRollOver = function( )
{
this.gotoAndStop( 2 );
}
this.btMC.onRollOut = function( )
{
this.gotoAndStop( 1 );
}
this.btMC.onPress = function( )
{
this.gotoAndStop( 3 );
}
this.btMC.onRelease = function( )
{
manager.onRelease( );
}
}
private function onRelease( )
{
}
}
He atacheado el movieclip, pero podrÌa haber pasado una referencia al clip como par·metro, algo asÌ como:
function MyButton( btMC: MovieClip, buttonId: String )
{
this.buttonId = butonId;
this.btMC = btMC;
this.initEvents( );
}
Y por tanto, en mi otra clase AppInstance, podrÌa hacer algo asÌ:
var btOK: MyButton = new MyButton( this.btOK, "btOK" );
var btCancel: MyButton = new MyButton( this.btCancel, "btCancel" );
btOK.addEventListener( "click", this );
btCancel.addEventListener( "click", this );
Donde this.btOK y this.btCancel son las referencias a ambos clips. De esta manera puedo seguir colocando los clips en tiempo de diseÒo
Bien, los botones tienen que interactuar con el resto de la aplicaciÛn, asÌ que vamos a hacer que puedan emitir eventos.
Es m·s que probable que no sÛlo estos botones deban emitir eventos, por lo que vamos a encapsular esa funcionalidad en una clase base, de la que luego extender· MyButton
class EventDispatcherImpl
{
function dispatchEvent() {};
function addEventListener() {};
function removeEventListener() {};
function EventDispatcherImpl()
{
mx.events.EventDispatcher.initialize(this);
}
}
Y por tanto, el cÛdigo de MyButton ser·::
class MyButton extends EventDispatcherImpl
{
private var buttonId: String;
private var btMC: MovieClip
function MyButton( btMC: MovieClip, buttonId: String )
{
this.buttonId = buttonId;
this.btMC = btMC;
this.initEvents( );
}
private function initEvents( )
{
var manager: MyButton = this;
this.btMC.onRollOver = function( )
{
this.gotoAndStop( 2 );
}
this.btMC.onRollOut = function( )
{
this.gotoAndStop( 1 );
}
this.btMC.onPress = function( )
{
this.gotoAndStop( 3 );
}
this.btMC.onRelease = function( )
{
manager.onRelease( );
}
}
private function onRelease( )
{
var eventObject: Object={ target:this, type:'click'}
eventObject.buttonId=this.buttonId;
dispatchEvent(eventObject);
}
}
øY si no quiero que emita eventos?. Pues nada, le paso a las instancias de MyButton la referencia de la clase que las construye (serÌa a˙n mejor si le pasara sÛlo su interfaz, pero bueno ):
var btOK: MyButton = new MyButton( this.btOK, "btOK", this );
Ya nos ovlidamos de extender de EventDispatcherImpl. MyButton, por tanto, quedar· asÌ:
class MyButton
{
private var buttonId: String;
private var btMC: MovieClip
private var appRef: AppInstance;
function MyButton( btMC: MovieClip, buttonId: String, ref: AppInstance )
{
this.buttonId = butonId;
this.btMC = btMC;
this.appRef = ref;
this.initEvents( );
}
private function initEvents( )
{
var manager: MyButton = this;
this.btMC.onRollOver = function( )
{
this.gotoAndStop( 2 );
}
this.btMC.onRollOut = function( )
{
this.gotoAndStop( 1 );
}
this.btMC.onPress = function( )
{
this.gotoAndStop( 3 );
}
this.btMC.onRelease = function( )
{
manager.onRelease( );
}
}
private function onRelease( )
{
this.appRef.doWhatEver( );
}
}
Y ya est·. Hemos hecho el cÛdigo mucho m·s protable, f·cil de mantener, y mucho m·s encapsulado. Hay bastantes soluciones mucho mejores que extender de movieclip y dejar que flash haga el trabajo por nosotros.
øPor quÈ a algunos les molesta tanto que haya extranjeros en EspaÒa?. Es que no lo puedo entender.
Veamos, supongamos que soy una persona que vive en un paÌs que no es el suyo, que trabaja, paga sus impuestos ( no olvidemos que aquÌ, la carga fiscal est· en los impuestos indirectos, por cierto ), que compra la comida en los comercios del barrio, las medicinas en la farmacia, el periÛdico en el quiosco, que compra el abono transporte todos los meses para ir a trabajar, y que los domingos se va al Retiro ( es que mi extranjero-ejemplo vive en Madrid ) a pasar el dÌa.
Ahora supongamos que ya no soy una persona que vive en un paÌs que no es el suyo. Ahora soy un seÒor de Valladolid, que vive en Madrid desde hace unos aÒos. Un seÒor que trabaja, que paga sus impuestos ( no olvidemos que aquÌ, la carga fiscal est· en los impuestos indirectos, por cierto ), que compra la comida en los comercios del barrio, las medicinas en la farmacia, el periÛdico en el quiosco, que compra el abono transporte todos los meses para ir a trabajar, y que los domingos se va al Retiro ( es que mi vallisoletano-ejemplo vive en Madrid ) a pasar el dÌa.
Vamos un poco m·s alla. Ahora ya no soy un vallisoletano que vive en Madrid desde hace unos aÒos. Ahora soy un madrileÒo de toda la vida. Trabajo, pago mis impuestos, ( indirectos, claro ), compro en el barrio, voy a la farmacia a por las aspirinas, compro el abono transporte y los domingos me doy una vuelta por el Retiro y el Rastro ( que soy muy madrileÒo ).
øAlguien me puede explicar cu·l es la diferencia entre los tres?. Pues eso.
Nokia acaba de publicar el documento definitivo con la especificaciÛn de la API para gr·ficos vectoriales en 2D. El objetivo de esta especificaciÛn es definir una API opcional para renderizar gr·ficos vectoriales en 2D, incluyendo el tratamiento de im·genes externas en formato SVG.
De los documentos de la especificaciÛn:
Los casos de uso principales de esta API incluyen:
ïVisualizaciÛn de mapas
ïIconos escalables
ïAnimaciones ( en aplicaciones de mensajerÌa )
ïIlustraciones tÈcnicas
Los documentos pueden bajarse de aquÌ
Una vez m·s, parece que J2ME y Flashlite corren en paralelo. Yo, sinceramente, no sÈ si esto supone un avance o una amenaza, en lo que se refiere a Flashlite. Alguna idea?
Hoy se ha publicado en theserverside.com un artÌculo sobre J2ME escrito por Dan Moore, que puede resultar muy interesante no sÛlo para los que estamos empezando con J2ME, sino para todos los que estamos interesados en el desarrollo de aplicaciones en dispositivos mÛviles en general.
El autor plantea los pros y contras de las aplicaciones mÛviles, y a continuaciÛn hace una introducciÛn bastante extensa a J2ME, en la que explica, desde las herramientas de desarrollo, a las limitaciones propias de los dispositivos.
El link est· aquÌ: working with J2ME ( inglÈs )