Flash


Bienvenidos, en esta ocasión retomaremos el tema de los Paneles pero enfocado a su creación mediante Adobe Flex.

Antes o después de leer este tutorial sería interesante leer el este otro post sobre la introducción a la creación de Paneles.

INTRODUCCIÓN

La idea es crear un panel que nos ayude a modificar el fondo del documento FLA, pero más rápidamente, si, sé que cambiar el fondo del documento es muy fácil, pero soy un poco maniático y la verdad tener que abrir una ventana, seleccionar un color y luego dar click en aceptar son muchos pasos, me gustaría algo mucho más rápido, algo como hacer rollOver sobre un componente ColorPicker y listo.

DESARROLLO

Para ejecutar código JSFL en una película swf generada con Flex utilizaremos el método MMExecute que encontramos en el paquete adobe.utils por ejemplo:

import adobe.utils.MMExecute;
MMExecute("jsfl code");

El método MMExecute recibe un parámetro de tipo String en el cual indicaremos el código JSFL que deseamos ejecutar. Además devuelve un valor también de tipo String que es la representación en cadena del resultado de la ejecución del código.

Parte JSFL

Vale, ahora que sabemos como ejecutar código JSFL necesitamos saber que código ejecutar. Lo que queremos modificar es una propiedad del documento FLA, así es que antes que otra cosa debemos obtener una referencia al documento, esto lo hacemos con el siguiente código:

var oDoc = fl.getDocumentDOM();

Y para acceder y modificar el color de fondo utilizamos la propiedad backgroundColor que es de lectura y escritura:

oDoc.backgroundColor

Listo, por lo menos la parte de JSFL, ahora tenemos que integrar este código en una aplicación Flex.

Parte FLEX

Utilizaremos un componente ColorPicker este componente entre otras cosas emite los eventos:

  • change
  • close
  • itemRollOver
  • itemRollOut
  • open

Los que en nuestro caso nos interesan son los eventos change e itemRollOver así que como en cualquier otra aplicación utilizamos el siguiente código:

<mx:ColorPicker id="cpBackgroundColor" x="89" y="10" change="onChange(event);" itemRollOver="onItemRollOver(event);" />

Ahora simplemente en los métodos onChange y onItemRollOver es donde tendremos que utilizar el método MMExecute de la siguiente manera:

import mx.events.ColorPickerEvent;
import adobe.utils.MMExecute;

private function onChange(_oEvent:ColorPickerEvent):void
{
    if (this.isDocumentExists())
        MMExecute("fl.getDocumentDOM().backgroundColor = Number(" + _oEvent.color + ");");
}

private function onItemRollOver(_oEvent:ColorPickerEvent):void
{
    if (this.isDocumentExists())
        MMExecute("fl.getDocumentDOM().backgroundColor = Number(" + _oEvent.color + ");");
}

private function isDocumentExists():Boolean
{
    var ret:Boolean = false;
    if (MMExecute("fl.getDocumentDOM();") != "null")
        ret = true;

    return ret;
}

INSTALACIÓN

Listo, el resultado no lo podremos ver en ejecución a menos que llevemos el swf resultante a la carpeta de Paneles de Flash, es decir al directorio WindowSWF dentro del directorio Configuration de la instalación.

Según el sistema operativo:

Windows® VistaTM:

  • unidad de arranque\Users\nombre de usuario\Local Settings\Application Data\Adobe\Flash

CS4\idioma\Configuration\

Windows XP:

  • unidad de arranque\Documents and Settings\nombre de usuario\Local Settings\Application Data\Adobe\Flash CS4\idioma\Configuration\

Mac OS® X:

  • Macintosh HD/Usuarios/nombre de usuario/Librería/Application Support/Adobe/Flash

CS4/idioma/Configuration/

EJECUCIÓN

Para ejecutar el Panel debemos acceder al menú Ventana -> Otros paneles -> Change Background Color a continuación un ejemplo de como ejecutar y su funcionamiento:

Ver ejemplo

DESCARGAS

Como es habitual a continuación podéis descargar los fuentes y el instalador del Panel:

  • Fichero MXML de Flex por si te interesa ver el código.
  • Fichero SWF del Panel para instalar manualmente el Panel.
  • Instalador MXP del Panel para instalar automáticamente la extensión.

Saludos, cualquier duda o comentario será bienvenido.

Entradas relacionadas

INTRODUCCIÓN

El objetivo de JSFL es ayudar a agilizar el proceso de edición en Adobe Flash Professional. Pero, ¿qué quiere decir esto? bueno, eso nos lo responde la ayuda de Ampliación de Flash CS4 Professional con ejemplos tales como automatizar tareas repetitivas o la creación de herramientas personalizadas.

La API JavaScript permite escribir scripts para aplicaciones Flash que ayudan a agilizar el proceso de edición. Por ejemplo, se pueden escribir scripts para automatizar tareas repetitivas o añadir herramientas personalizadas al panel Herramientas.

TUTORIAL

En este tutorial vamos a ver como automatizar una tarea muy habitual y repetitiva en el día a día de un desarrollador / diseñador Flash. Vamos a ver como crear un comando para embeber caracteres a un campo de texto dinámico y además vamos a ver como utilizar el Panel Historial.

Primero abriremos el Panel Historial, esto lo hacemos desde el menú Ventana -> Otros paneles -> Historial o con los atajos de teclado Ctr + F10 en Windows y Cmd + F10 en Mac OS X.


panel historial adobe flash

Ahora comprobaremos el estado de visualización del Panel, debe estar en “JavaScript del panel”, si no es así lo modificamos.

visualizacion panel historial adobe flash

Ahora si con el Panel abierto haremos esa tarea tan repetitiva que es embeber fuentes en un campo de texto dinámico. Para esto hacemos lo siguiente:

  • Creamos un campo de texto con la herramienta texto.
  • Volvemos dinámico el campo de texto utilizando el Panel de propiedades.
  • Seleccionamos en el desplegable de Suavizado la opción “Suavizado para animación“.

panel propiedades texto adobe flash

  • Hacemos click en el botónIncorporación de caracteres…“.
  • En la ventana que se abre seleccionamos los juegos de caracteres a embeber.
  • En el campo de texto añadimos los caracteres especiales, tales como letras con tildes, diéresis, ñ y ç entre otros.

incorporacion de caracteres adobe flash

Aceptamos y listo ya tenemos nuestro campo de texto dinámico con las fuentes embebidas, ahora nos vamos al Panel Historial y veremos todo lo que hemos estado haciendo, pero con el pequeño añadido que ahora veremos el código JSFL que tenemos que utilizar en nuestro comando.

panel historial comandos embed fonts adobe flash

En la parte inferior derecha del Panel Historial tenemos el botón Guardar, éste se activa cuando seleccionamos alguna línea de código, en este caso lo que queremos hacer es guardar las líneas de código en las que indicamos al campo de texto que utilice Suavizado para animación, los juegos de caracteres y los caracteres especiales. Así que una vez seleccionadas hacemos click en el botón Guardar y ahora simplemente tenemos que escribir el nombre del comando.

ventana guardar como comando adobe flash

Listo, con esto hemos creado un comando sin tener que picar nada de código, es una forma muy simple y eficiente con la que cualquiera puede crear comandos sin necesidad de saber programar.

Ahora para ejecutar el comando simplemente vamos al menú Comandos y seleccionamos de la lista el comando que hemos creado, Embeber caracteres.

menu comandos comando embeber caracteres adobe flash

DESCARGAS

Como es habitual dejo descargas del fichero JSFL y también del fichero MXP para instalar el comando.

  • Comando Embeber caracteres (versión JSFL).
  • Instalador de Comando Embeber caracteres.

NOTAS

Para utilizar el comando debes seleccionar un campo de texto. Para cualquier cosa, dudas, comentarios o sugerencias aquí estaré.

Saludos!!!

Entradas relacionadas

La localización (traducción) de contenidos es un tema muy importante, en ocasiones es el punto clave de los desarrollos, pero en muchas ocasiones no se tiene en cuenta. En mi caso he tenido que pasar por esta situación más de una vez.
Cuando se nos platea la situación siempre pensamos en una configuración inteligente de los contenidos basada en XML, crear un gestor, objetos, eventos, listeners, switch on the fly para cambiar de idioma y muchas ideas súper guays, pero como siempre tenemos al señor tiempo que viene a presionar, por otro lado el cliente ya tiene el curso completo y funcional, lo único que quiere ahora es que su producto esté en X o Y idioma, vamos que eso tiene que estar chupado.
Pero que pasa cuando quien ha desarrollado esos contenidos no pensó en que algún día se localizarían y utilizó mogollón de campos de texto estáticos, por no hablar de imágenes o diseños, pero esa es otra historia.
Bueno, ahora que más o menos he contado un poco el panorama, jejeje vamos a ver para que sirve todo eso, resumiendo, tenemos, por que si, un fla de su padre y de su madre con un montón de campos de texto estáticos distribuidos por símbolos, gráficos, botones, clips de película y en distintos fotogramas de sus líneas de tiempo respectivas, es decir, un verdadero caos del bueno.
Claro, también tenemos un cliente que nos pide para mañana la traducción de ese curso a Chino, Alemán e Italiano.
¿Qué hacemos?
Le decimos al cliente que estamos hasta arriba de trabajo y que no podremos dar prioridad a su trabajo, vamos que no lo vamos a hacer.
Le decimos al cliente que no podemos hacerlo en ese tiempo y que necesitaremos dos semanas por lo menos y que el trabajo será muy costoso.
Le decimos que vale.
Pero que!!!!, ¿cómo que vale? pero este tío está loco, pero si esa tarea es imposible.
Bueno, ahora es donde entra en juego nuestro querido y siempre infravalorado JSFL.
IDEA E HISTORIETA
Tenemos una línea de tiempo y muchos elementos en una biblioteca, pues simplemente tenemos que recorrer todas las líneas de tiempo y encontrar todos los campos de texto estáticos, convertirlos en campos de texto dinámicos, asignarles una variable, leer su contenido y guardarlo en un fichero XML.
Como trabajamos en una súper empresa enorme con múltiples departamentos, contamos con un departamento de traducción y muchos más, nos ponemos en contacto con nuestro amigo Axel del departamento de traducción y le pedimos que nos traduzca el fichero XML a los idiomas que ha pedido el cliente, en unas horas nos lo devuelve. ¡Qué gusto trabajar en esta empresa! todos son tan eficientes que dan ganas de dar el 200% de cada uno.
Bueno, ahora ya tenemos los ficheros XML en Chino, Alemán e Italiano. Pero recordemos, como hemos dicho que trabajamos en una súper empresa en la que todos son la hostia de eficientes, nosotros no vamos a ser menos, así que mientras Axel trabajaba en la traducción del XML, nosotros hemos estado creado el súper lector de XML que simplemente creará variables y asignará valores, para que cuando los textos dinámicos las necesiten ya estén ahí. Así que mira que coincidencia, hemos terminado al mismo tiempo que Axel, con todo el desarrollo que hemos hecho, más esos XML’s ya tenemos el contenido en 3 idiomas y nos ha tomado menos de un día.
QUE NECESITAMOS

INTRODUCCIÓN

La localización (traducción) de contenidos es un tema muy importante, en ocasiones es el punto clave de los desarrollos, pero en muchas ocasiones no se tiene en cuenta. En mi caso he tenido que pasar por esta situación más de una vez.

Cuando se nos platea la situación siempre pensamos en una configuración inteligente de los contenidos basada en XML, crear un gestor, objetos, eventos, listeners, switch on the fly para cambiar de idioma y muchas ideas súper guays, pero como siempre tenemos al señor tiempo que viene a presionar, por otro lado el cliente ya tiene el curso completo y funcional, lo único que quiere ahora es que su producto esté en X o Y idioma, vamos que eso tiene que estar chupado.

Pero que pasa cuando quien ha desarrollado esos contenidos no pensó en que algún día se localizarían y utilizó mogollón de campos de texto estáticos, por no hablar de imágenes o diseños, pero esa es otra historia.

Bueno, ahora que más o menos he contado un poco el panorama, jejeje vamos a ver para que sirve todo eso, resumiendo, tenemos, por que si, un fla de su padre y de su madre con un montón de campos de texto estáticos distribuidos por símbolos, gráficos, botones, clips de película y en distintos fotogramas de sus líneas de tiempo respectivas, es decir, un verdadero caos del bueno.

Claro, también tenemos un cliente que nos pide para mañana la traducción de ese curso a Chino, Alemán e Italiano.

¿Qué hacemos?

  • Le decimos al cliente que estamos hasta arriba de trabajo y que no podremos dar prioridad a su trabajo, vamos que no lo vamos a hacer.
  • Le decimos al cliente que no podemos hacerlo en ese tiempo y que necesitaremos dos semanas por lo menos y que el trabajo será muy costoso.
  • Le decimos que vale.

Pero qué!!!!, ¿cómo que vale? pero este tío está loco, pero si esa tarea es imposible.

Bueno, ahora es donde entra en juego nuestro querido y siempre infravalorado JSFL.

IDEA E HISTORIETA

Tenemos una línea de tiempo y muchos elementos en una biblioteca, pues simplemente tenemos que recorrer todas las líneas de tiempo y encontrar todos los campos de texto estáticos, convertirlos en campos de texto dinámicos, asignarles una variable, leer su contenido y guardarlo en un fichero XML.

Como trabajamos en una súper empresa enorme con múltiples departamentos, contamos con un departamento de traducción y muchos más, nos ponemos en contacto con nuestro amigo Axel del departamento de traducción y le pedimos que nos traduzca el fichero XML a los idiomas que ha pedido el cliente, en unas horas nos lo devuelve. ¡Qué gusto trabajar en esta empresa! todos son tan eficientes que dan ganas de dar el 200% de cada uno.

Bueno, ahora ya tenemos los ficheros XML en Chino, Alemán e Italiano. Pero recordemos, como hemos dicho que trabajamos en una súper empresa en la que todos son la ostia de eficientes, nosotros no vamos a ser menos, así que mientras Axel trabajaba en la traducción del XML, nosotros hemos estado creado el súper lector de XML que simplemente creará variables y asignará valores, para que cuando los textos dinámicos las necesiten ya estén ahí. Así que mira que coincidencia, hemos terminado al mismo tiempo que Axel, con todo el desarrollo que hemos hecho, más esos XML’s ya tenemos el contenido en 3 idiomas y nos ha tomado menos de un día.

QUE NECESITAMOS

Primero un repaso rápido al entorno de Flash, en la imagen que se muestra a continuación podemos ver listados los elementos con los que trabajamos a diario y que para este Comando vamos a necesitar.

esquema objetos jsfl

  1. Documento fl.getDocumentDOM()
  2. Línea de tiempo fl.getTimeline()
  3. Capas fl.getTimeline().layers
  4. Biblioteca fl.getDocumentDOM().library
  5. Panel de Propiedades fl.setProperty(“property”, “value”);

Y ahora si, manos a la obra maestro.

Primero que nada vamos a recorrer la línea de tiempo principal para buscar campos de texto, eso ya nos da pistas sobre lo que tenemos que hacer, veamos, hemos dicho que vamos a recorrer la línea de tiempo principal, entonces esto nos indica que necesitaremos una referencia al documento, esto lo resolvemos fácilmente utilizando el comando:

var oDoc = fl.getDocumentDOM();

Una vez que tenemos una referencia al documento ahora si ya podemos obtener una referencia a la línea de tiempo, esto lo hacemos con el siguiente dódigo:

var oTimeline = oDoc.getTimeline();

Una vez que tenemos una referencia a la línea de tiempo ahora tenemos que obtener una referencia a las capas (layers), esta nos la proporciona el objeto línea de tiempo, lo que nos devuelve es un Array (que guay!!!, de verdad que es súper cómodo trabajar con los Arrays), así que aquí empezaremos a ejecutar bucles for anidados. Utilizando un código similar a este:

var aLayers = oTimeline.layers;
var nTotalLayers = aLayers.length;
for(var i = 0; i < nTotalLayers; i++) { ... }

Ahora que recorremos las capas, …

¿Porqué recorremos las capas?

Muy buena pregunta, un punto para el que hizo esa pregunta. La respuesta es sencilla, recorremos las capas por que para buscar los campos de texto tenemos que buscar en los fotogramas clave y la única forma que tenemos de garantizar una búsqueda completa es recorriendo todos los fotogramas de la línea de tiempo.

Pero qué!!!!

A ver, a ver, lo vas a hacer tú? o tú? o yo, no, lo va a hacer automáticamente Flash por nosotros, así que hay de que preocuparse.

… vamos a utilizar la propiedad frames (fotogramas) del objeto Layer (capa) que también nos devuelve un Array (ahora si que ya no quepo de gozo), para buscar los elementos que tiene ese fotograma, tendríamos un código similar a este:

var oLayer = aLayers[i];
var aFrames = oLayer.frames;
var nTotalFrames = aFrames.length;
for(var j = 0; j < nTotalLayers; j++) { ... }

Con esto llegamos casi al punto que nos interesa, el campo de texto, pero nos falta un pequeño paso, el objeto frame tiene una propiedad muy útil, me refiero a la propiedad elements, esta propiedad curiosamente también nos devuelve un Array (he dicho que me gustan mucho los Arrays, es que son la mar de útiles), el código que utilizaríamos sería algo como lo siguiente:

var oFrame = aFrames[j];
var aElements = oFrame.elements;
var nTotalElements = aElements.length;
for(var k = 0; k < nTotalLayers; k++) { ... }

Ahora si, hemos llegado, después de tres bucles anidados, ya tenemos acceso a los elementos del fotograma, así que simplemente tenemos que preguntar el tipo de elemento y en caso de ser de tipo texto podemos modificar sus propiedades y leer el texto que tiene, el código sería más o menos parecido al siguiente:

var oElement = aElements[k];
if (oElement.elementType == "text") { ... }

Bueno, que en el párrafo de arriba escribí de más, así que ahora tengo que volver a escribir otra vez lo de modificar las propiedades del campo de texto y leer su texto, esto lo haremos con el siguiente código:

oElement.textType = "type";
oElement.variableName = "variable_name";
oElement.getTextString();

Y listo, ya lo tenemos.

Menos mal, ya me estaba cansando.

Hey!!! que puedo leer vuestras mentes, a ver tú y tú, los puntos que os habéis ganado hace rato ahora los habéis perdido.

No, no estoy de acuerdo. Si, me estoy cansando, ¿y qué? es normal, con estos tutoriales tan grandes como quieres conservar la atención tanto tiempo. Si quieres mi atención deberías hacer algo más interactivo, entretenido, divertido, cómico, algo en lo podamos participar y no quedarnos todo el rato leyendo. Pero …

Vale, vale, lo siento. Es que estoy aprendiendo. Pero tomo nota de tus comentario, es más, por ser tan honesto te has ganado 150 puntos. Veis chicos, si todos participaseis cuando menos un poco así …

Ahora veamos el código completo:

//Delcaración de variables
var oDoc;
var oLib;
var SEPARATOR = ";";
var PREFFIX_VAR_NAME = "_root.varCommandTextLocalizable_";
var nCounter;

var sXML;

//Llamada a los métodos de configuración e inicialización del comando
this.config();
this.init();

/**
 * @method		config
 * @description	Método encargado de configurar el comando
 * @return		Void
 */
function config()
{
	//Indicamos que no queremos ver el mensaje sobre un script de ejecución demasiado larga
	fl.showIdleMessage(false);

	//Limpiamos la ventana de salida
	fl.outputPanel.clear();

	if(fl.getDocumentDOM())
	{
		//Obtenemos la referencia al documento y a la biblioteca
		this.oDoc = fl.getDocumentDOM();
		this.oLib = this.oDoc.library;
	}
	else
	{
		//En caso que no haya un documento abierto mostrarmo un mensaje de alerta.
		alert("Debes tener un documento abierto.");
	}
}

/**
 * @method		init
 * @description	Método encargado de inicializar el comando
 * @return		Void
 */
function init()
{
	//Delcaración de variables
	var aItems = this.oLib.items;
	var nTotalItems = aItems.length;
	var oItem;
	this.nCounter = 1;

	//Inicializamos el valor del XML abriendo la etiqueta principal
	this.sXML  = "<DATA>\n";

	//Llamamos al método analizeTimeline para que analice le línea de tiempo principal
	this.analizeTimeline();

	for (var i = 0; i < nTotalItems; i++)
	{
		oItem = aItems[i];
		if ((oItem.itemType == "movie clip") || ( oItem.itemType == "graphic") || (oItem.itemType == "button") )
		{
			this.oLib.editItem(oItem.name);
			this.analizeTimeline();
		}
	}

	//Finalizamos el valor del XML cerrando la etiqueta principal
	this.sXML += "</DATA>";

	//Llamada al método createXmlFile
	this.createXmlFile();

	//Limpiamos la memoria de Flash eliminando las variable que hemos creado
	delete aItems, nTotalItems, oItem;
}

/**
 * @method		analizeTimeline
 * @description	Método encargado analizar una línea de tiempo para buscar campos de texto
 *				si encuentra campos de texto, los convierte en dinámicos y les añade
 *				una variable.
 *				Toda la información que va encontrando la almacena en la variable sXML
 * @return		Void
 */
function analizeTimeline()
{
	//Delcaración de variables
	var oTimeline = this.oDoc.getTimeline();
	var aLayers = oTimeline.layers;
	var nTotalLayers = aLayers.length;
	var oLayer;

	//Recorremos las capas
	for (var j = 0; j < nTotalLayers; j++)
	{
		oLayer = aLayers[j];
		oLayer.locked = false;
		oLayer.visible = true;
		if ((oLayer.layerType != "guide") || (oLayer.layerType != "folder"))
		{
			//Delcaración de variables
			var aFrames = oLayer.frames;
			var nTotalFrames = aFrames.length;
			var oFrame;
			var aElements;

			//Recorremos los fotogramas de la capa
			for (var k = 0; k < nTotalFrames; k++)
			{
				oFrame = aFrames[k];
				if (oFrame.elements.length > 0)
				{
					aElements = oFrame.elements;

					//Delcaración de variables
					var nTotalElements = aElements.length;
					var oElement;

					//Recorremos los elementos del fotograma
					for (var l = 0; l < nTotalElements; l++)
					{
						oElement = aElements[l];
						if (oElement.elementType == "text" && oElement.textType != "input")
						{
							//Delcaración de variables
							var sDataItem = "Nombre de la timeline: " + oTimeline.name;
							var sDataLayer = "Nombre de la capa: " + oLayer.name;
							var sDataFrame = "Número de fotograma: " + (k + 1);
							var sDataElement = "Nombre del elemento: " + oElement.name;
							var sElementText = "Texto del elemento: " + oElement.getTextString();
							var sElementFormat = "Formato del elemento: " + "";
							//fl.trace(sDataItem + this.SEPARATOR + sDataLayer + this.SEPARATOR + sDataFrame + this.SEPARATOR + sDataElement + this.SEPARATOR + sElementText);

							oElement.textType = "dynamic";
							oElement.variableName = this.PREFFIX_VAR_NAME + this.nCounter;

							this.sXML += "	<node varName=\"" + this.PREFFIX_VAR_NAME + this.nCounter + "\">\n";
							this.sXML += "		<![CDATA[" + oElement.getTextString() + "]]>\n";
							this.sXML += "	</node>\n";

							this.nCounter++;
						}
					}

					//Limpiamos la memoria de Flash eliminando las variable que hemos creado
					delete nTotalElements, oElement;

				}

				//Incrementamos el valor de k con la duración del fotograma, esto es para que en el siguiente
				//ciclo del bucle vayamos director al siguiente fotograma clave
				k += oFrame.duration - 1;
			}

			//Limpiamos la memoria de Flash eliminando las variable que hemos creado
			delete aFrames, nTotalFrames, oFrame, aElements;
		}

		this.oDoc.exitEditMode();
	}

	//Limpiamos la memoria de Flash eliminando las variable que hemos creado
	delete oTimeline, aLayers, nTotalLayers, oLayer;
}

/**
 * @method		createXmlFile
 * @description	Método encargado de crear el fichero XML con la relación entre textos y variables
 * @return		Void
 */
function createXmlFile()
{
	//Declaración de variables
	var sPath = this.oDoc.pathURI.split(this.oDoc.name).shift();
	var sFileURI = sPath + "textos_extraidos_automaticamente.xml";

	//Comprobación, si existe el fichero lo eliminamos
	if (FLfile.exists(sFileURI))
		FLfile.remove(sFileURI);

	//Creamos el fichero XML
	FLfile.write(sFileURI, this.sXML);

	//Limpiamos la memoria de Flash eliminando las variable que hemos creado
	delete sPath, sFileURI;
}

Bueno, en este código encontramos además de lo explicado en este tutorial para recorrer las líneas de tiempo, modificar propiedades de campos de texto y extraer textos, código para crear ficheros de texto, en el caso del ejemplo crear un fichero XML con la relación entre la variable asignada al campo de texto y el texto.

El código está comentado, pero si hace falta alguna explicación, si tenéis alguna duda, comentario, mejora, sugerencia, pues aquí estaré gustoso de seguir compartiendo.

DESCARGAS

Como es habitual dejo descargas del fichero JSFL, también el fichero MXP instalable y un zip con el paquete del JSFL y un FLA de ejemplo para extraer los textos.

  • Comando Extractor de Textos (versión JSFL).
  • Instalador de Comando Extractor de Textos.
  • Paquete con JSFL y FLA de ejemplo.

Saludos!!!

NOTAS

Se que algunas personas tendrán mucho que decir, así que por favor háganlo, el tema es complicado, la localización de contenidos es algo muy chungo en ocasiones tal como lo plateo en este ejemplo.

También es cierto que con este ejemplo no salvamos otros obstáculos tales como imágenes que tienen textos y que con la solución de modificar los campos de texto podríamos estropear el funcionamiento de algunos campos de texto que ya fuesen dinámicos y que utilizaran variables.

Ahora si, después de estas notas y una última aclaración, mi objetivo es explicar el funcionamiento de los objetos de JSFL, el ejemplo se presta para sacarle partido al lenguaje, así que por eso lo he desarrollado.

Entradas relacionadas

reflexion flash iphone android

Esta reflexión surge por un sentimiento, una sensación, un pinchazo interior y las cosquillas o la curiosidad de las nuevas tecnologías y sobre todo la interactividad. También tiene mucho que ver con el actual movimiento que existe en la red sobre el futuro de Flash y el panorama que se vive y se ve venir. Algunos post interesantes que tratan más o menos el tema que quiero hablar se pueden leer aquí y aquí.

Pero esta reflexión es mía así que además de tener en cuenta todos los factores que en esos post se habla tendremos en cuenta sobre todo las respuestas que he dado al planteamiento hecho por Charly García en deberías saber por qué (la camiseta que me pongo es la de Flashero).

HISTORIA

Haciendo un poco de historia para remontarnos a los orígenes o por lo menos a mis orígenes Flasheros tengo que hablar sobre el bachillerato y la universidad, ayyy aquellos tiempos donde todo lo que importaba era aprender y sacar buenas notas (jejeje, creo que no ha cambiado tanto, ahora sigue siendo aprender y sacar buenos proyectos XD), bueno, como iba diciendo, en aquellos tiempo lo que conocía era Pascal, C, Java, HTML y con el tiempo descubrí Delphi, Visual C++, FrontPage (si, tengo que decirlo porque es la verdad, jejeje), php y Javascript, hasta aquí no dejaba de ser programación pura y dura, existía una mezcla entre el front-end y el back-end, la lógica y la presentación de nuestra aplicación. Pero un día, gracias a un proyecto y aun gran amigo, se mostró ante mis ojos algo que cambiaría para siempre mi vida, la interactividad, las herramientas de dibujo, las líneas de tiempo, los símbolos (gráfico, clip de película y botón) y de la noche a la mañana me olvidé completamente de todo lo demás para hacerle un gran hueco en mi cabeza a esa preciosa aplicación que acababa de conocer, Flash.

MOTIVOS

Supongo que cada quien tendrá sus motivos, los míos son los siguientes:

  • la facilidad de desarrollo
  • un entorno de diseño
  • el alto nivel de interactividad que se podía conseguir
  • un lenguaje de programación basado en el modelo de eventos
  • animaciones chulas por código (easing y demás)
  • reproducción de sonidos
  • reproducción de videos (si, era posible en aquella época, aunque muy pesado)
  • cargar y actualizar contenidos sin tener que actualizar la página

Todo esto me enamoró y desde ese momento hasta la fecha seguimos felizmente casados.

ACTUALIDAD

Hoy en día han cambiado tanto las tecnologías, se han desarrollado frameworks sobre todo con Javascript, existe AJAX, entornos de desarrollo de alto nivel con los cuales hay que programar muy poco, por ejemplo Dreamweaver facilita enormemente la vida a diseñadores y desarrolladores, HTML 5 quiere (pero yo la verdad lo veo difícil) utilizar una etiqueta VIDEO con lo cual una pieza importante de Flash empieza a moverse (no, estoy de acuerdo, aunque lo leo muy a menudo y mucha gente habla así de esto, pero y que pasa con Red5 y Flash Media Server, que hace HTML contra eso) y algunas cosas más que de alguna forma y otra han hecho a muchas personas plantearse la tecnología a utilizar en sus desarrollos.

MI ACTUALIDAD

Desde que me enamoré hasta ahora hemos pasado por muchas actualizaciones y nuevas versiones, se desarrollo e implementó ActionScript 2, ActionScript 3, Flex, Flash Lite y todo esto me encantó, pero volviendo a mis motivos principales, siento que en esencia la herramienta no ha cambiado mucho.

FRUSTRACIÓN

En mi caso, y este caso se puede extrapolar a muchos casos más que he podido comprobar hablando con mucha gente y leyendo por aquí o por allá, sigo desarrollando con ActionScript 2, por limitaciones muy importante y es que nuestros cliente (empresas grandes como bancos y farmacéuticas entre otros) no tienen en todos sus puestos de trabajo estandarizado un reproductor de Flash avanzado, así es que actualmente desarrollo para Flash Player 7. Otro factor muy importante es la interactividad que se puede conseguir a través de la cámara o el micrófono, pero al final pasa lo mismo que el player, los usuarios finales no lo tienen con lo cual hay que hacer desarrollos que funcionen en el 100% de los puestos de trabajo, o sea que otro :(.

ROMANCE FUERA DEL MATRIMONIO

He conocido a un par de chicas muy atractivas últimamente, me quieren, me invitan a salir, comparten y coquetean conmigo con todas sus funcionalidades apasionantes, han podido mostrar al mundo unas cuantas cositas a tener en cuenta:

  • acelerómetro
  • gps
  • brújula
  • facilidad de uso e interacción con el micrófono
  • facilidad de uso e interacción con la cámara

Esto es lo que me ofrecen iPhone SDK y Android SDK sobre lo que ya tengo con Flash, pero un factor importantísimo que es indudablemente una curva que te deja viendo estrellitas y pensando en ella todo el día es la perfecta combinación entre hardware y software, ya que no hay que luchar contra extrañas características de equipos o altos y bajos rendimientos, existe un muy alto control de calidad que nos garantiza la perfecta funcionalidad de nuestros desarrollos en los dispositivos finales.

VISITAS FUERA DE CASA

He visitado y jugado un poco con estos SDK’s y la verdad es que la experiencia ha sido muy grata, pues están muy completos y sobre todo cuentan con una base muy sólida para empezar a desarrollar, cosa que en principio flash no tiene por defecto. Pero sobre todo lo que me tiene más inquieto y feliz (pienso en ella todo el día), es la nueva interactividad que se consigue con estos dispositivos.

CONCLUSIÓN

Cada quién hace las cosas por los motivos que lo han llevado a ello, en mi caso lo he expuesto arriba y creo que como toda relación hay que mantenerse activos y de vez en cuando hacer regalitos, dar sorpresas, sonreir y aprender juntos ante lo que la vida nos pone o tomar al toro por lo cuernos y vivir aventuras, pero creo que mi relación con Flash lleva un tiempo de monotonía por los motivos que he expuesto aquí. Con todo esto no quiero decir que me voy a ir a desarrollar con otro lenguaje (que ya lo estoy haciendo) sino que simplemente quiero compartir esta reflexión porque creo que algo importante a tener en cuenta en el panorama que se vive.

Entiendo que no todos pensamos igual y que habrá personas que verán las cosas desde otro punto de vista, así que cualquier comentario será bienvenido.

Saludos!!!

Bueno ahora si ya con más calma puedo escribir otro poco sobre el Subflash, cuando le cuento a la gente las cosas que se viven ahí no me lo creen, así que para dar fé de ello a continuación podréis ver algunas fotos que son la evidencia fotográfica de todo cuanto se dice de Subflash.

Poner atención a esta pequeña selección donde se puede ver un poco de todo, la convivencia, la felicidad de los asistentes, los frikis que son pues no dejan el ordenador, las comidas acompañados de grandes personajes del mundo digital, el encuentro de fútbol, la llegada de uno que de verdad ama a Subflash, nuestro querido Jorge Solis que vino desde Argentina (jejeje, cuestiones de trabajo decía :P) y como decía Alex:

Subflash se lleva dentro del corazón

Se les nota lo bien que lo pasan Los frikis que no pueden dejar los ordenadoresSiempre unidos Si hay fútbol, no solo ordenadores Si existen y son personas Se lleva en el corazon

He colgado de picasa las fotos que hice este años del Subflash, así que ahí pueden ver el resto de la historia.

Saludos!!!

subflash 2009 un éxito

Un año más he podido disfrutar de la maravillosa compañía de la gente Subflash durante un fin de semana lleno de gente compartiendo sus vidas, experiencias, proyectos, alegrías, contratiempos, trucos, temores, curiosidades y muchísimo más.

AGRADECIMIENTOS

Gracias a el inagotable equipo de [Q] Interactiva, al apoyo desinteresado de Nitsnets Studios, al apoyo de Criteriondg y los adobe user groups de AdobelaboDreamweaver y de Flash Lite, a los patrocinadores como CDmon, video2brain, lolacamisetas, FX Interactive y seguramente me dejo a muchísimas más personas que han hecho posible esta exitosa nueva edición. A lo que iba, gracias a ellos hemos podido compartir este fin de semana con unas charlas de muy alto nivel donde de una manera muy amena los ponentes nos mostraron pedacitos de cielo, joyas de inestimable valor con las cuales podremos hacer nuestro día a día más fácil y rico en la calidad de contenidos que producir, también aportando ideas y puntos de vista al porque de hacer las cosas y además técnicas para ser más productivos.

CHARLAS

Subflash 2009 Ponentes

Empezamos con Andrés Cayón hablándonos sobre Adobe AIR para utilizarlo con HTML y Javascript desde Dreamweaver para ver que en este mundo no todo es Flash, continuamos con Marcos González y Raúl Jiménez hablando sobre desarrollo móvil y buenas técnicas de desarrollo, por la tarde Sergio Rodríguez nos dejó con la boca abierta mostrándonos el mundo del dibujo animado llevado a Flash y viendo las enormes posibilidades de nuestra querida aplicación, a la mañana siguiente Alex Sánchez nos abrió su corazón para compartir su experiencia en el mundo del desarrollo de proyectos desde la concepción hasta el desarrollo y la implementación pero siempre pensando en el usuario final y el impacto que éste recibirá con nuestros proyectos, nos habló de Papervision3D y realidad aumentada, pero no sólo nos habló de ello sino que se tiró a la piscina para mostrarnos lo fácil que hacer desarrollos. Por último y para cerrar con un broche de oro las charlas el enorme Jorge Mochón nos mostró el poder y la facilidad de utilizar ese poder de After Effects, las novedades y lo sencillo que pueden llegar a ser las cosas cuando conoces la aplicación, nos tuvo toda la charla aplaudiendo por lo increíble que parecían las cosas.

ENTRE TANTO ENTRETENTE

Mientras todo esto pasaba y como muchísima gente opina (opinamos), una gran parte del subflash además de lo que atrae en principio a la gente que son las charlas, se movía un trapicheo de información, un cotilleo constante sobre proyectos, trucos, formas de trabajar, frameworks, entornos de desarrollo, series de televisión, películas, libros, tecnología, vamos todo lo que un buen friki puede pedir, querer, desear, soñar, jejeje. Perdón que me lío a lo que me refería es a la gente, porque al fin y al cabo quien hace posible estos eventos son las personas y esas personas quieren hablar, preguntar, compartir y sentirse identificados con otras personas como ellos (nosotros, jejeje) y eso se nota desde el principio.

EJEMPLOS

Cuando pasabas por cualquier sitio podías escuchar charlas del tipo:

  • ¿Qué entorno de desarrollo utilizas? Aptana, Eclipse, Flex builder, Flashdevelop, TextMate, Smultron, Vim, jejeje eran algunas de las respuestas
  • ¿En que versión de ActionScript programas? AS3, acaso existe otra, AS2, AS2 y AS3 dependiendo del proyecto.
  • ¿Qué hubo antes del Bigbang? La teoría de cuerdas, no hay un origen ni un fin simplemente la eternidad, buenos yo antes de ver BigBbang Theory veía IT Crowd.
  • ¿Vieron lo de Jacob? Ostia tío que fuerte, yo me lo sospechaba desde el principio, pero y que pasa con Locke
  • ¿Qué es twitter? Que!!!!!, no sabes lo que es twitter!!!!, tío pero de que tiempo vienes tu, jejeje
  • ¿Qué motor de 3D prefieres? Papervision3D, Sandy3D, Away3D, pero que no viene ya por defecto en Flash CS4.
  • El otro día instalé un sniffer para ver cuales eran las peticiones que hacía el iTunes para obtener información de los IPA’s del iPhone.

REPETIMOS

Subflash 2009, fútbol y piscina

Tal como el año pasado hemos repetido un encuentro inigualable, porque no tiene precio poder jugar a un partidito de fútbol con grandes personajes del mundo digital como los señores Marc Palau, Jorge Solis, Raúl JiménezMarcos GonzálezArmando SotocaElad Rodríguez, Guillermo de la Iglesia, Andrés KarpJorge CanteliAlberto Ordás y seguro que me dejo a muchísima más gente fuera, a todos, gracias. Por que muchas veces conoces a la gente digital, te haces amigos de ellos, foros, messenger, blog, facebook, twitter y muchísimas cosas más compartimos con esta gente, pero ponerles caras y más aún jugar un partido juntos, ufff, eso es lo mejor de lo mejor.

AGRIDULCE

Después de hablar con la gente sobre como ven, siente, viven el panorama de Flash, he podido sacar como media que gracias al enorme esfuerzo que se ha hecho por parte de los navegadores (HTML y CSS) y los frameworks de javascript, se está perdiendo una cuota de mercado en sites que hace unos años se desarrollaban full-flash, este es un tema que da para mucha charla, pero bueno, el resultado que he obtenido en mis charlas con la gente me ha dado como resultado esto.

Pero no todo es agrio, también hay dulce, y es que con mucha alegría pude comprobar como cada vez hay más desarrollos de eLearning con Flash, lo que me gusta porque veo que con la competencia y la llegada de nuevas personas al mundo del eLearning tendremos que innovar y esforzarnos por hacer mejor los productos con lo cual todos ganamos, el cliente tendrá mejores productos y nosotros dejaremos de hacer lo de siempre para hacer cosas mucho mejores, además de los puntos de vista que llegarán con gente que antes creaba contenidos para agencias de publicidad y que ahora esos conocimientos se podrán aplicar al mundo del eLearning.

Otro sabor dulce es el estado de Flex, porque aunque había poca gente que desarrollase en serio con Flex, el mercado actualmente está muy bien porque se lleva bastante de la mano con grandes desarrollos hechos en JAVA lo cual me da una enorme tranquilidad, vamos, todos sabemos que JAVA está ahí y durante un tiempo importante estará y ahora está utilizando las bondades de Flex para crear RIA’s y dejar con la boca abierta a muchas empresas.

SOMOS UNOS FRIKIS

Subflash 2009 de frikis con el terminal en el iPhone

Si señor, gratamente pude ver muchísimos smartphones en los asistentes a las charlas, desde iPhones, terminales HTC (Hola Sergio), LG y muchos más, con lo cual, bueno la verdad es que no puedo sacar una conclusión justa porque como dice arriba somos unos frikis, pero bueno da gusto ver más frikis como yo, jejejeje. Me gustaría pensar que así como nosotros hay muchísimos smartphones por ahí fuera, pero bueno de momento sólo estamos nosotros aunque espero que en breve seamos más y el desarrollo para estos dispositivos muldialmente sea una realidad.

CONCLUSIÓN

Este concierto ha sido un éxito, ay perdón que no fue un concierto sino una quedada. Ha sido un fin de semana de los que sólo tengo una vez al año, estoy encantado, motivado, con mucha curiosidad, con un cansancio de tres días pero que ha valido la pena cada minuto de no dormír.

ALGO MAS

El que no haya ido, esto es lo único que puedo hacer para compartir mi experiencia de este maravilloso evento con ustedes. Simplemente quiero invitar a la gente a que vengan, estos eventos son gracias a la gente porque nosotros los hacemos y nosotros los disfrutamos. Así que animaros a venir porque vale la pena cada céntimo y segundo invertido.

Y si, hay algo más.

… si te pones la camiseta, deberías saber por qué

Esto es de un grande entre los grandes, Charly García, y quiero compartirlo, cada quien que sienta qué camiseta se pone y que reflexione por qué se la pone.

Otros resúmenes de Subflash:

fla on the fly

Por fin ya de vuelta de las vacaciones y retomando nuevamente el mando de mi vida estoy aquí para compartir otro tutorial sobre JSFL, para ser exactos no es ni un Comando ni un Panel ya que la ejecución de este JSFL se hace automáticamente desde la línea de comandos mediante una llamada desde una aplicación AIR o simplemente haciendo doble clic.

HISTORIA

El otro día hablando con Iván Gajate me preguntaba sobre la forma de crear FLA’s dinámicamente y automáticamente me vino a la cabeza JSFL aunque no es la súper solución porque lo que realmente queríamos conseguir es utilizar una librería en C para generar FLA’s con ciertas características peculiares como el tamaño, el color y los fotogramas por segundo, pero como ninguno de los dos es un experto programador en C pues optamos por el camino de JSFL que me gusta y controlo más.

LA IDEA

Desde la aplicación AIR se generará un fichero de texto que nos servirá para configurar las características del FLA que se va a crear y luego simplemente ejecutamos el JSFL. Ya está, así de simple.

COSAS A DESTACAR (o que vamos a aprender)

Con este tutorial aprenderemos:

  • Otra forma de ejecutar los ficheros JSFL.
  • El uso del objeto FLfile, exactamente del método read.
  • Que podemos hacer más cosas de las que parece a simple vista, por ejemplo a cerrar la propia aplicación.

MANOS A LA OBRA

Parte 1: JSFL desde la línea de comandos

Hasta ahora hemos visto tres formas de utilizar JSFL, a través de Comando, a través de Panel y a través de Herramientas, pero esas no son todas las formas en las que podemos utilizar JSFL ya que existe una más que es de la que vamos a echar mano hoy, me refiero a la ejecución de JSFL mediante línea de comandos.

Me explico, dentro de nuestro equipo tenemos:

lugar_de_instalacion_de_flash\flash.exe

y digamos, por ponerle un nombre, que en C tenemos una carpeta que se llama ejemplo y que dentro de ejemplo tenemos un fichero que se llama generar_fla_dinamicamente.jsfl, entonces podríamos decir desde la línea de comandos lo siguiente:

“lugar_de_instalacion_de_flash\flash.exe” “C:\ejemplo\generar_fla_dinamicamente.jsfl

esto ejecutaría Flash y automáticamente cargaría el JSFL para ejecutarlo, fácil no?, que frikis que sómos, jejeje.

Parte 2: Leer el fichero de configuración

Ahora que ya estamos en nuestro ámbito, recordemos que JSFL sólo funciona con Flash abierto y gracias a la ejecución de JSFL mediante línea de comandos hemos conseguido abrir Flash ya podemos continuar con el proceso del JSFL. Como hemos dicho vamos a leer un fichero de texto que la aplicación AIR ha generado, para seguir con la buena costumbre y quizá también por casualidad o no se muy bien porque, la aplicación AIR genera ese fichero en C dentro de la carpeta ejemplo.

El contenido del fichero es muy simple, se encuentran emparejados variable y valor separados por ampersand (&), como se de variables GET se tratara. Por ejemplo:

frameRate=50&backgroundColor=#00FFFF&width=800&height=200

Esto ahora mismo no viene al caso, pero bueno ya lo escribí así que ahí se quedará y más tarde que lo necesitemos hablaremos de él. Lo que realmente necesitamos es utilizar el objeto FLfile para que con ayuda del método read leamos el fichero de configuración, de tal forma que nuestro código quedaría así:

var sConfiguration = FLfile.read("ruta del fichero de configuración");

Ahora si, dentro de la variable sConfiguration tenemos el contenido del fichero de configuración de tal forma que vamos a tratar el contenido para utilizarlo más adelante, para esto vamos a utilizar funciones básicas de JavaScript, es decir splits y bucles para separar y obtener las variables y su valor, al final lo guardaremos en un array asociativo para tener todas las variables en un mismo sitio y listo, esto lo conseguimos con el siguiente código:

var aConfiguration = new Array();
var aValues = sConfiguration.split("&");
var nTotalValues = aValues.length;
for(var i = 0; i < nTotalValues; i++)
{
	var aTmp = aValues[i].split("=");
	aConfiguration[aTmp[0]] = aTmp[1];
}

Parte 3: Crear el nuevo documento, configurarlo y cerrar Flash

Bueno hasta ahora tenemos acceso al DOM de Flash ya que lo hemos abierto mediante línea de comandos, también tenemos una configuración almacenada en un array asociativo ya sólo nos queda crear el documento y configurarlo, esto lo conseguimos de dos formas, primero lo primero, para crear el documento Fla utilizaremos el método createDocument del objeto fl, este método nos devuelve una referencia al documento creado, lo vamos a almacenar en una variable para más adelante modificar sus propiedades, el ejemplo de la creación del documento es el siguiente:

var oDoc = fl.createDocument();

Ahora simplemente tenemos que configurar los valores que nos indicaron en el fichero de configuración, que ahora ya los tenemos en un array asociativo, así que con una comprobación y una asignación lo tendremos todo resuelto. En este caso deseamos modificar el color de fondo, los fotogramas por segundo, el alto y el ancho del documento, así que pare esto simplemente tendremos que modificar esas propiedades de nuestro objeto Document. El ejemplo es el siguiente:

if(aConfiguration["backgroundColor"])
	oDoc.backgroundColor = aConfiguration["backgroundColor"];

if(aConfiguration["frameRate"])
	oDoc.frameRate = Number(aConfiguration["frameRate"]);

if(aConfiguration["width"])
	oDoc.width = Number(aConfiguration["width"]);

if(aConfiguration["height"])
	oDoc.height = Number(aConfiguration["height"]);

Y listo, ya hemos configurado el nuevo documento, ahora simplemente nos queda guardar el documento y cerrar Flash. Para guardar el documento utilizaremos el método saveDocument del objeto fl, éste método recibe dos parámetros, en el primero indicamos el documento que deseamos guardar y en el segundo la ruta en la que deseamos guardar el documento, por ejemplo:

fl.saveDocument(oDoc, "ruta_donde_queremos_guardar_el_documento\documento_creado_dinamicamente.jsfl")

Vale pues ahora vamos a una de las cosas que más me gusta y sorprende, quizá sea un tontería pero saber que tenemos ese poder me gusta mucho, jejeje. Vamos a cerrar Flash, ya que una vez que hemos creado el documento, lo hemos configurado y lo hemos guardado, ya no necesitamos tener abierto Flash para nada, así que allá vamos. Esta tarea la conseguimos haciendo uso del método quit del objeto fl, éste método recibe un parámetro opcional para preguntar al usuario sobre guardar los cambios, en nuestro caso no lo queremos así que pasaremos false, el ejemplo es el siguiente:

fl.quit(false);

Y listo con esto terminamos este Tutorial que espero os sea de utilidad o que de una vez por todas los haga pensar en utilizar más a menudo JSFL.

DESCARGAS

En este caso pongo un zip donde está todo preparado para funcionar en la carpeta ejemplo en el disco duro C, si lo quieres modificar simplemente cambia la ruta en la primera variable del fichero JSFL, la variable sPath.

Saludos, para cualquier cosa, dudas o comentarios aquí estaré.

Entradas relacionadas

lego briks

Este es un post que tenía pendiente desde hace tiempo, en esta ocasión voy a hablar sobre las herramientas (tools) de Flash y de como personalizarlas o como es nuestro caso crear una nueva herramienta con JSFL.

INTRODUCCIÓN

Recuerdo en los tiempos de Flash 4 que fué cuando empecé con Flash que por comodidad y sobre todo por desconocimiento de la aplicación, quería hacer tablas en Flash y por mucho que busqué no encontré una herramienta que me sirviera para esto, así que al final aprendí a utilizar las herramientas de dibujo y a través de cuadros y líneas con las herramientas rectángulo y trazo conseguí hacer las tablas que quería, luego con el tiempo descubrí el panel alineación y distribución y con eso perfeccioné la tarea y me fué más fácil hacer estas tablas.

Bueno, pues la idea es que vamos a crear una herramienta para crear tablas de una manera fácil como si de rectángulos se tratara.

DESARROLLO

JSFL nos permite extender la funcionalidad de la aplicación, como hemos hablado ya en otras ocasiones, lo podemos hacer con comandos y paneles, pero también existe otro modo de extender y automatizar procesos, me refiero a la creación de herramientas.

Las herramientas al igual que los comandos y paneles se programan con JSFL y se almacenan en las siguiente rutas respectivamente por sistema operativo:

  • Windows Vista

unidad de arranque\Users\nombre de usuario\Local Settings\Application Data\Adobe\Flash

CS4\idioma\Configuration\Tools

  • Windows XP

unidad de arranque\Documents and Settings\usuario\Local Settings\Application Data\Adobe\Flash

CS4\idioma\Configuration\Tools

  • Mac OS X

Macintosh HD/Usuarios/nombre de usuario/Librería/Application Support/Adobe/Flash

CS4/idioma/Configuration/Tools

A diferencia de los comandos y los paneles en las herramientas tenemos acceso a funciones y métodos de nivel superior que nos ayudan a desarrollar y controlar el estado de nuestra herramienta, las funciones disponibles son las siguiente:

  • activate()
  • configureTool()
  • deactivate()
  • keyDown()
  • keyUp()
  • mouseDoubleClick()
  • mouseDown()
  • mouseMove()
  • mouseUp()
  • notifySettingsChanged()
  • setCursor()

Las que utilizaremos para la creación de la herramienta tablas serán, activate que se dispara cuando la herramienta es seleccionada por el usuario, deactivate que se dispara cuando el usuario cambia a otra herramienta, notifySettingsChanged que se dispara cuando el usuario modifica las propiedades de nuestra herramienta, mouseDownmouseMove mouseUp que se disparan cuando el usuario hace lo que el nombre de la función dice :D. Esto con respecto a los eventos para controlar nuestra herramienta.

Pero ¿cómo accedemos a la herramienta?

Pues fácil, como todo en JSFL son objetos necesitamos obtener la referencia a la herramienta activa que será nuestra herramienta, esto lo hacemos con la propiedad activeTool del objeto tools, en el ejemplo siguiente se muestra como obtener una referencia a la herramienta.

theTool = fl.tools.activeTool;

Guay, ¿Y para qué quiero tener una referencia al objeto herramienta?

Pues para asignar a nuestra herramienta nombre, tooltip, icono, opciones, especificar el tipo para el inspector de propiedades por ejemplo y muchas más cosas. Como se muestra a continuación.

// Set the standard tool information
theTool = fl.tools.activeTool;
theTool.setToolName("Tablas");
theTool.setIcon("Tablas.png");
theTool.setMenuString("Herramienta Tablas");
theTool.setToolTip("Herramienta Tablas");
theTool.setOptionsFile("Tablas.xml");

// This tool uses the Shape property inspector
theTool.setPI( "shape" );

Vale, vale, ya me entero, pero ¿Cómo dibujo?

Ah, muy cierto, pues para pintar / dibujar debemos hacer una nota importante y es que tenemos dos momento de dibujo:

  • El momento de la previsualización
  • El momento del dibujo final

Para el momento de la pre-visualización utilizaremos el objeto drawingLayer y sus métodos moveTo y lineTo que son idénticos a los que utilizamos en la API de dibujo de ActionScript y los método beginFrame y endFrame para indicar el incio y el fin del dibujo de la pre-visualización. Por ejemplo, con el siguiente código dibujaríamos un cuadro de 20×20 en 0, 0:

fl.drawingLayer.beginFrame();
fl.drawingLayer.moveTo(0, 0);
fl.drawingLayer.lineTo(20, 0);
fl.drawingLayer.lineTo(20, 20);
fl.drawingLayer.lineTo(0, 20);
fl.drawingLayer.lineTo(0, 0);
fl.drawingLayer.endFrame();

Y para el momento del dibujo final utilizaremos también el objeto drawingLayer para crear un objeto path con el método newPath, luego utilizaremos los métodos addPoint y makeShape para crear nuestro dibujo. Por ejemplo:

var myPath = fl.drawingLayer.newPath();
myPath.addPoint(0, 20);
myPath.addPoint(20, 20);
myPath.addPoint(20, 0);
myPath.addPoint(0, 0);
myPath.makeShape(false, true);

Perfecto, y ahora ¿cómo modifico las propiedades de mi herramienta?

Vale, para esto debemos recordar que en un principio utilizamos el método setOptionsFile del objeto tool donde indicamos un fichero xml, este fichero xml contiene la definición de las propiedades que utilizaremos en la herramienta. Por ejemplo para la herramienta tabla, utilizo dos propiedades nColumns y nRows. Un ejemplo del fichero xml de configuración es el siguiente:

property name="Columnas: " variable="nColumns" min="1" max="100" defaultValue="3" type="Number"
property name="Filas: " variable="nRows" min="1" max="100" defaultValue="3" type="Number"

Cuando el usuario modifique estos valores en el panel de propiedades se nos notificará en el evento (la función) notifySettingsChanged. Un ejemplo de como utilizar los valores modificados es el siguiente:

function notifySettingsChanged()
{
	var theTool = fl.tools.activeTool;

	this.nColumns = theTool.nColumns;
	this.nRows = theTool.nRows;
}

Y listo, con esto ya tenemos controladas todas las fases del diseño de una herramienta.

EJEMPLOS

A continuación un par de ejemplos de lo que podemos conseguir de una manera sencilla con esta herramienta.

Ejemplo 1 Herramienta Tablas

Ejemplo 2 Herramienta Tablas

herramienta tablas

DESCARGAS

Tenemos dos tipos de descargas, para instalar simplemente la herramienta Tablas y para descargar el JSFL:

  • Extensión Herramienta Tablas (instalador mxp).
  • Paquete zip con la Herramienta Tablas (ficheros jsfl, xml y png).

INSTALACIÓN

Una vez que se haya instalado la extensión debemos asignarla a un grupo de herramienta desde el panel Personalizar panel de herramientas y listo ya se puede utilizar.

Personalizar panel herramientas

Dudas, sugerencias o comentarios, aquí estaré.

Saludos.

Entradas relacionadas

outrun lego

Después de escribir este post mi buen amigo Iván aportó una grandísima idea, un diseño y me dió más tareas para el tren, mi lado friki sentía cosquillas por hacerlo con la API de dibujo de Flash, pero para variar un poco en esta ocasión lo he hecho en ActionScript 2.0 y en ActionScript 3.0 que realmente no es tan distinto para los que ya programan en AS2.

INTRODUCCIÓN

La idea es poner un coche en el circuito que ya hicimos en el anterior post, así que simplemente con rectángulos lo vamos a hacer. Para esto haremos uso de la API de dibujo de Flash en AS2 y AS3, las diferencias son pequeñas y en ocasiones grandes, pero con un poco de imaginación haremos que se parezcan más, :P.

DESARROLLO

ActionScript 3.0

En ActionScript 3.0 utilizaremos los métodos beginFill y drawRect de la clase Graphics.

ActionScript 2.0

En ActionScript 2.0 no tenemos una clase Graphics y menos aún el método drawRect, pero la solución es fácil, hacemos una función o método que haga lo mismo y listo :D.

function drawRect(_mc:MovieClip, _nX:Number, _nY:Number, _nW:Number, _nH:Number):Void
{
	_mc.moveTo(_nX, _nY);
	_mc.lineTo(_nX + _nW, _nY);
	_mc.lineTo(_nX + _nW, _nY + _nH);
	_mc.lineTo(_nX, _nY + _nH);
	_mc.lineTo(_nX, _nY);
}

CÓDIGO COMPLETO

A continuación el código en ActionScript 3.0:

package
{
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;

	public class Car extends MovieClip
	{
		private var car:Sprite;

		private var lights:Shape;
		private var bar:Shape;
		private var structure:Shape;
		private var wheels:Shape;

		private var nCounter:uint;

		public function Car():void
		{
			this.drawCar();

			this.nCounter = 0;

			this.addEventListener(Event.ENTER_FRAME, doOnEnterFrame);
		}

		private function drawCar():void
		{
			this.car = new Sprite();

			this.lights = new Shape();
			this.bar = new Shape();
			this.structure = new Shape();
			this.wheels = new Shape();

			//Chasis
			this.wheels.graphics.beginFill(0x1E1E1E);
			this.wheels.graphics.drawRect(38, 146, 316, 28);

			this.wheels.graphics.beginFill(0x1E1E1E);
			this.wheels.graphics.drawRect(157, 172, 78, 6);

			//Llanta izquierda
			this.wheels.graphics.beginFill(0x333333);
			this.wheels.graphics.drawRect(28, 132, 45, 68);

			//Llanta derecha
			this.wheels.graphics.beginFill(0x333333);
			this.wheels.graphics.drawRect(318, 132, 45, 68);

			//Carrosería
			this.structure.graphics.beginFill(0xFF0000);
			this.structure.graphics.drawRect(42, 0, 308, 166);

			//Cristal trasero
			this.structure.graphics.beginFill(0x70A9FE);
			this.structure.graphics.drawRect(49, 7, 293, 68);

			//Retrovisor izquierdo
			this.structure.graphics.beginFill(0xFF0000);
			this.structure.graphics.drawRect(0, 65, 42, 21);

			this.structure.graphics.beginFill(0x70A9FE);
			this.structure.graphics.drawRect(3, 68, 35, 15);

			//Retrovisor derecho
			this.structure.graphics.beginFill(0xFF0000);
			this.structure.graphics.drawRect(350, 65, 42, 21);

			this.structure.graphics.beginFill(0x70A9FE);
			this.structure.graphics.drawRect(353, 68, 35, 15);

			//Luz izquierda
			this.lights.graphics.beginFill(0xFF9900);
			this.lights.graphics.drawRect(46, 100, 34, 18);

			//Luz derecha
			this.lights.graphics.beginFill(0xFF9900);
			this.lights.graphics.drawRect(312, 100, 34, 18);

			//Defensa
			this.bar.graphics.beginFill(0x808080);
			this.bar.graphics.drawRect(38, 124, 316, 28);

			//Matrícula
			this.bar.graphics.beginFill(0xFFFFFF);
			this.bar.graphics.drawRect(157, 128, 78, 20);

			this.car.addChild(this.wheels);
			this.car.addChild(this.structure);
			this.car.addChild(this.bar);
			this.car.addChild(this.lights);

			this.car.scaleX = 0.5;
			this.car.scaleY = 0.5;

			this.addChild(this.car);
		}

		private function doOnEnterFrame(_oEvent:Event):void
		{
			this.nCounter++;
			if(this.nCounter % 4 == 0)
			{
				this.lights.y = (this.lights.y == 0) ? 3: 0;
				this.structure.y = (this.structure.y == 0) ? -3: 0;
				this.bar.y = (this.bar.y == 0) ? 2: 0;
			}
		}
	}
}

Y a continuación el código en ActionScript 2.0:

import gs.TweenLite;

var nColor1:Number = 0xFFFFFF;
var nColor2:Number = 0xCCCCCC;
var nColor3:Number = 0xFF0000;
var nColor4:Number = 0xFFFFFF;

var nColorSky:Number = 0x0066FF;
var nColorGrass:Number = 0x65FF00;

var nWidthSky:Number = Stage.width;
var nHeigthSky:Number = 80;

var nWidthGrass:Number = Stage.width;
var nHeigthGrass:Number = 170;

var nWidthBorderLine:Number = 30;
var nWidthMiddleLine:Number = 8;
var nWidthCenterLine:Number = 140;
var nHeigthLine:Number = 2.5;

var nTotalLines:Number = 68;

var nCounter:Number = 0;
var nFramesToUpdateCircuit:Number = 3;
var nFramesToUpdateCar:Number = 5;

var mcSky:MovieClip;
var mcGrass:MovieClip;
var mcCircuit:MovieClip;

var mcCar:MovieClip;

var mclights:MovieClip;
var mcBar:MovieClip;
var mcStructure:MovieClip;
var mcWheels:MovieClip;

this.create();

function create():Void
{
	Key.addListener(this);

	this.mcSky = this.createEmptyMovieClip("mcSky", 1);
	this.mcGrass = this.createEmptyMovieClip("mcGrass", 2);
	this.mcCircuit = this.createEmptyMovieClip("mcCircuit", 3);

	this.mcSky.beginFill(this.nColorSky, 100);
	this.drawBox(this.mcSky, this.nWidthSky, this.nHeigthSky);
	this.mcSky.endFill();

	this.mcGrass.beginFill(this.nColorGrass, 100);
	this.drawBox(this.mcGrass, this.nWidthGrass, this.nHeigthGrass);
	this.mcGrass.endFill();

	this.mcGrass._y = this.nHeigthSky;
	this.mcCircuit._y = this.nHeigthSky;

	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var nType:Number = ((i % 2) == 0) ? 1: 0;
		var mc:MovieClip = this.createLine(nType);
		mc._xscale = 100 + (i * 2);
		mc._x = Math.round((Stage.width - mc._width) / 2)
		mc._y = i * this.nHeigthLine;
		mc.nPosOriX = mc._x;
	}

	this.drawCar();
	this.mcCar._xscale = 40;
	this.mcCar._yscale = 40;
	this.mcCar._x = (Stage.width - this.mcCar._width ) / 2;
	this.mcCar._y = 100;
	this.mcCar.nPosOriX = this.mcCar._x;
	this.mcCar.nPosOriY = this.mcCar._y;

	this.mcInstructions.swapDepths(this.getNextHighestDepth());
}

function createLine(_nType:Number):MovieClip
{
	var nDepth:Number = this.mcCircuit.getNextHighestDepth();
	var mcLine:MovieClip = this.mcCircuit.createEmptyMovieClip("mcLine_" + String(nDepth), nDepth);
	var mcLine1:MovieClip = mcLine.createEmptyMovieClip("mcLine1", 1);
	var mcLine2:MovieClip = mcLine.createEmptyMovieClip("mcLine2", 2);

	this.contructLine(mcLine1, _nType);
	this.contructLine(mcLine2, _nType + 1);

	mcLine2._visible = false;

	return mcLine;
}

function contructLine(_mc:MovieClip, _nType:Number):Void
{
	var mcBox1:MovieClip = _mc.createEmptyMovieClip("mcBox1", 1);
	var mcBox2:MovieClip = _mc.createEmptyMovieClip("mcBox2", 2);
	var mcBox3:MovieClip = _mc.createEmptyMovieClip("mcBox3", 3);

	var nColor:Number = (_nType == 1) ? this.nColor1: this.nColor3;

	mcBox1.beginFill(nColor, 100);
	this.drawBox(mcBox1, this.nWidthBorderLine, this.nHeigthLine);
	mcBox1.endFill();

	mcBox2.beginFill(this.nColor2, 100);
	this.drawBox(mcBox2, this.nWidthCenterLine, this.nHeigthLine);
	mcBox2.endFill();

	mcBox3.beginFill(nColor, 100);
	this.drawBox(mcBox3, this.nWidthBorderLine, this.nHeigthLine);
	mcBox3.endFill();

	mcBox2._x = this.nWidthBorderLine;
	mcBox3._x = this.nWidthBorderLine + this.nWidthCenterLine;

	if(_nType == 1)
	{
		var mcBox4:MovieClip = _mc.createEmptyMovieClip("mcBox4", 4);
		mcBox4.beginFill(nColor, 100);
		this.drawBox(mcBox4, this.nWidthMiddleLine, this.nHeigthLine);
		mcBox4.endFill();

		mcBox4._x = (_mc._width - mcBox4._width) / 2;
	}
}

function drawBox(_mc:MovieClip, _nWidth:Number, _nHeigth:Number):Void
{
	_mc.lineTo(_nWidth, 0);
	_mc.lineTo(_nWidth, _nHeigth);
	_mc.lineTo(0, _nHeigth);
	_mc.lineTo(0, 0);
}

function onEnterFrame(_mc:MovieClip):Void
{
	this.nCounter++
	if(this.nCounter % this.nFramesToUpdateCircuit == 0)
	{
		for (var i:Number = 0; i < this.nTotalLines; i++)
		{
			var mcLine:MovieClip = this.mcCircuit["mcLine_" + String(i)];
			mcLine.mcLine1._visible = !mcLine.mcLine1._visible;
			mcLine.mcLine2._visible = !mcLine.mcLine2._visible;
		}
	}

	if(this.nCounter % this.nFramesToUpdateCar == 0)
	{
		this.mcLights._y = (this.mcLights._y == 0) ? 3: 0;
		this.mcStructure._y = (this.mcStructure._y == 0) ? -3: 0;
		this.mcBar._y = (this.mcBar._y == 0) ? 2: 0;
	}
}

function moveLeft():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX - (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
	TweenLite.to(this.mcCar, 1, { _x:this.mcCar.nPosOriX - 40, _y:this.mcCar.nPosOriY + 10 } );
}

function moveRight():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX + (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
	TweenLite.to(this.mcCar, 1, { _x:this.mcCar.nPosOriX + 40, _y:this.mcCar.nPosOriY + 10 } );
}

function returnCenter():Void
{
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX } );
	}
	TweenLite.to(this.mcCar, 1, { _x:this.mcCar.nPosOriX, _y:this.mcCar.nPosOriY } );
}

function onKeyDown():Void
{
	if(Key.isDown(Key.LEFT))
	{
		this.moveLeft();
	}
	else if(Key.isDown(Key.RIGHT))
	{
		this.moveRight();
	}
	else if(Key.isDown(Key.UP))
	{
		this.returnCenter();
	}
}

function drawCar():Void
{
	this.mcCar = this.createEmptyMovieClip("mcCar", 4);

	this.mcLights = this.mcCar.createEmptyMovieClip("mcLights", 4);
	this.mcBar = this.mcCar.createEmptyMovieClip("mcBar", 3);
	this.mcStructure = this.mcCar.createEmptyMovieClip("mcStructure", 2);
	this.mcWheels = this.mcCar.createEmptyMovieClip("mcWheels", 1);

	//Chasis
	this.mcWheels.beginFill(0x1E1E1E);
	this.drawRect(this.mcWheels, 38, 146, 316, 28);

	this.mcWheels.beginFill(0x1E1E1E);
	this.drawRect(this.mcWheels, 157, 172, 78, 6);

	//Llanta izquierda
	this.mcWheels.beginFill(0x333333);
	this.drawRect(this.mcWheels, 28, 132, 45, 68);

	//Llanta derecha
	this.mcWheels.beginFill(0x333333);
	this.drawRect(this.mcWheels, 318, 132, 45, 68);

	//Carrosería
	this.mcStructure.beginFill(0xFF0000);
	this.drawRect(this.mcStructure, 42, 0, 308, 166);

	//Cristal trasero
	this.mcStructure.beginFill(0x70A9FE);
	this.drawRect(this.mcStructure, 49, 7, 293, 68);

	//Retrovisor izquierdo
	this.mcStructure.beginFill(0xFF0000);
	this.drawRect(this.mcStructure, 0, 65, 42, 21);

	this.mcStructure.beginFill(0x70A9FE);
	this.drawRect(this.mcStructure, 3, 68, 35, 15);

	//Retrovisor derecho
	this.mcStructure.beginFill(0xFF0000);
	this.drawRect(this.mcStructure, 350, 65, 42, 21);

	this.mcStructure.beginFill(0x70A9FE);
	this.drawRect(this.mcStructure, 353, 68, 35, 15);

	//Luz izquierda
	this.mcLights.beginFill(0xFF9900);
	this.drawRect(this.mcLights, 46, 100, 34, 18);

	//Luz derecha
	this.mcLights.beginFill(0xFF9900);
	this.drawRect(this.mcLights, 312, 100, 34, 18);

	//Defensa
	this.mcBar.beginFill(0x808080);
	this.drawRect(this.mcBar, 38, 124, 316, 28);

	//Matrícula
	this.mcBar.beginFill(0xFFFFFF);
	this.drawRect(this.mcBar, 157, 128, 78, 20);
}

function drawRect(_mc:MovieClip, _nX:Number, _nY:Number, _nW:Number, _nH:Number):Void
{
	_mc.moveTo(_nX, _nY);
	_mc.lineTo(_nX + _nW, _nY);
	_mc.lineTo(_nX + _nW, _nY + _nH);
	_mc.lineTo(_nX, _nY + _nH);
	_mc.lineTo(_nX, _nY);
}

RESULTADO

El resultado final es una bonita carretera con su césped, su cielo y un coche que da saltitos, jejeje :D

Circuito con coche en ActionScript 2.0

El resultado en ActionScript 3.0 para generar el coche es el siguiente:

Coche programado con ActionScript 3.0

DESCARGAS

Tenemos los ficheros para la versión en ActionScript 2.0 y para los de ActionScript 3.0:

Entradas relacionadas:

Saludos

Out Run

En un proyecto que participé hace poco tuvimos que hacer un circuito de carreras  y aunque parece increíble no encontré algo por ahí que me sirviera de base, así que al final me lo tuve que cocinar.

Dentro de los requisitos técnicos tenía que ser para Flash Player 7, con lo cual no podía utilizar la Clase BitmapData de AS2 y muchísimo menos utilizar AS3, así que la cosa se ponía más chunga, pero bueno, sino donde queda la gracia. :P

Teníamos en la mente el mítico juego Out Run y queríamos conseguir algo como eso. Aunque durante la investigación vimos las maravillas de AS3 o las posibilidades al utilizar la Clase BitmapData con el motor del modo 7, pero nada, donde manda capitán no manda marinero, así que a buscarse la vida.

El resultado fué el siguiente, bueno, este realmente no es, esta es una versión lite que programé en mis mañanas de tren, jejeje. Mi lado friki me obligó a hacerlo todo con programación, así que el código se puede copiar, pegar y compilar sin problema.

NOTA:

Utilizo la TweenLite así que no funciona tal cual, hace falta tener la librería TweenLite. :P

CÓDIGO

import gs.TweenLite;

var nColor1:Number = 0xFFFFFF;
var nColor2:Number = 0xCCCCCC;
var nColor3:Number = 0xFF0000;
var nColor4:Number = 0xFFFFFF;

var nColorSky:Number = 0x0066FF;
var nColorGrass:Number = 0x65FF00;

var nWidthSky:Number = Stage.width;
var nHeigthSky:Number = 80;

var nWidthGrass:Number = Stage.width;
var nHeigthGrass:Number = 170;

var nWidthBorderLine:Number = 30;
var nWidthMiddleLine:Number = 8;
var nWidthCenterLine:Number = 140;
var nHeigthLine:Number = 2.5;

var nTotalLines:Number = 68;

var nCounter:Number = 0;
var nFramesToUpdate:Number = 3;

var mcSky:MovieClip;
var mcGrass:MovieClip;
var mcCircuit:MovieClip;

this.create();

function create():Void
{
	Key.addListener(this);

	this.mcSky = this.createEmptyMovieClip("mcSky", 1);
	this.mcGrass = this.createEmptyMovieClip("mcGrass", 2);
	this.mcCircuit = this.createEmptyMovieClip("mcCircuit", 3);

	this.mcSky.beginFill(this.nColorSky, 100);
	this.drawBox(this.mcSky, this.nWidthSky, this.nHeigthSky);
	this.mcSky.endFill();

	this.mcGrass.beginFill(this.nColorGrass, 100);
	this.drawBox(this.mcGrass, this.nWidthGrass, this.nHeigthGrass);
	this.mcGrass.endFill();

	this.mcGrass._y = this.nHeigthSky;
	this.mcCircuit._y = this.nHeigthSky;

	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var nType:Number = ((i % 2) == 0) ? 1: 0;
		var mc:MovieClip = this.createLine(nType);
		mc._xscale = 100 + (i * 2);
		mc._x = Math.round((Stage.width - mc._width) / 2)
		mc._y = i * this.nHeigthLine;
		mc.nPosOriX = mc._x;
	}
}

function createLine(_nType:Number):MovieClip
{
	var nDepth:Number = this.mcCircuit.getNextHighestDepth();
	var mcLine:MovieClip = this.mcCircuit.createEmptyMovieClip("mcLine_" + String(nDepth), nDepth);
	var mcLine1:MovieClip = mcLine.createEmptyMovieClip("mcLine1", 1);
	var mcLine2:MovieClip = mcLine.createEmptyMovieClip("mcLine2", 2);

	this.contructLine(mcLine1, _nType);
	this.contructLine(mcLine2, _nType + 1);

	mcLine2._visible = false;

	return mcLine;
}

function contructLine(_mc:MovieClip, _nType:Number):Void
{
	var mcBox1:MovieClip = _mc.createEmptyMovieClip("mcBox1", 1);
	var mcBox2:MovieClip = _mc.createEmptyMovieClip("mcBox2", 2);
	var mcBox3:MovieClip = _mc.createEmptyMovieClip("mcBox3", 3);

	var nColor:Number = (_nType == 1) ? this.nColor1: this.nColor3;

	mcBox1.beginFill(nColor, 100);
	this.drawBox(mcBox1, this.nWidthBorderLine, this.nHeigthLine);
	mcBox1.endFill();

	mcBox2.beginFill(this.nColor2, 100);
	this.drawBox(mcBox2, this.nWidthCenterLine, this.nHeigthLine);
	mcBox2.endFill();

	mcBox3.beginFill(nColor, 100);
	this.drawBox(mcBox3, this.nWidthBorderLine, this.nHeigthLine);
	mcBox3.endFill();

	mcBox2._x = this.nWidthBorderLine;
	mcBox3._x = this.nWidthBorderLine + this.nWidthCenterLine;

	if(_nType == 1)
	{
		var mcBox4:MovieClip = _mc.createEmptyMovieClip("mcBox4", 4);
		mcBox4.beginFill(nColor, 100);
		this.drawBox(mcBox4, this.nWidthMiddleLine, this.nHeigthLine);
		mcBox4.endFill();

		mcBox4._x = (_mc._width - mcBox4._width) / 2;
	}
}

function drawBox(_mc:MovieClip, _nWidth:Number, _nHeigth:Number):Void
{
	_mc.lineTo(_nWidth, 0);
	_mc.lineTo(_nWidth, _nHeigth);
	_mc.lineTo(0, _nHeigth);
	_mc.lineTo(0, 0);
}

function onEnterFrame(_mc:MovieClip):Void
{
	this.nCounter++
	if(this.nCounter % this.nFramesToUpdate == 0)
	{
		for (var i:Number = 0; i < this.nTotalLines; i++)
		{
			var mcLine:MovieClip = this.mcCircuit["mcLine_" + String(i)];
			mcLine.mcLine1._visible = !mcLine.mcLine1._visible;
			mcLine.mcLine2._visible = !mcLine.mcLine2._visible;
		}
	}
}

function moveLeft():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX - (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
}

function moveRight():Void
{
	var r:Number = 1.5;
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX + (this.nTotalLines - i) * r } );
		r -= 0.01;
	}
}

function returnCenter():Void
{
	for (var i:Number = 0; i < this.nTotalLines; i++)
	{
		var mc:MovieClip = this.mcCircuit["mcLine_" + String(i)];
		TweenLite.to(mc, 1, { _x:mc.nPosOriX } );
	}
}

function onKeyDown():Void
{
	if(Key.isDown(Key.LEFT))
	{
		this.moveLeft();
	}
	else if(Key.isDown(Key.RIGHT))
	{
		this.moveRight();
	}
	else if(Key.isDown(Key.UP))
	{
		this.returnCenter();
	}
}

RESULTADO

Circuito de carreras en Flash con ActionScript

DESCARGAS

Para el que quiera el fla aquí está.

Saludos!!!

Entradas relacionadas:

Next Page »

Get Adobe Flash playerPlugin by wpburn.com wordpress themes