Dos veces al mes, volvemos a visitar algunas de las publicaciones favoritas de nuestros lectores de toda la historia de Activetuts +. Este tutorial se publicó por primera vez hace un año en enero de 2010..
En este tutorial, aprenderá cómo usar la clase DisplacementMapFilter de AS3 para crear un efecto de distorsión estática reutilizable para los desplazamientos de botones.
Echemos un vistazo al resultado final en el que trabajaremos:
Un mapa de desplazamiento funciona utilizando los valores de color de una imagen para alterar la posición de los píxeles en otra imagen. Este efecto se usa a menudo para hacer un gráfico envolvente alrededor de una imagen dimensional. Vamos a usarlo aquí para distorsionar un botón para que parezca que está recibiendo interferencia estática.
Puedes leer más sobre mapeo de desplazamiento aquí.
Crear un nuevo archivo Flash (ActionScript 3).
La configuración de tu película variará dependiendo de tu juego. Para esta demostración, estoy configurando mi película como 500x300, fondo negro y 30 fps.
Cree un nuevo símbolo de botón en el escenario (Insertar> Nuevo símbolo). Diseña los 4 estados para tu botón. El diseño exacto debe ser algo que coincida con su juego. Algo brillante y semitransparente funciona bien con este efecto..
Utilicé una fuente llamada Genetrix Square para la mía, pero deberías usar algo que coincida con el aspecto de tu juego.
Dale a tu botón un nombre de instancia de 'button1'.
Si guarda y prueba su película (Control> Probar película) ahora debería ver su botón en el escenario respondiendo al mouse con los estados de rollover que diseñó. Me gusta esto:
Necesitamos agregar funcionalidad personalizada a nuestro botón. Lo lograremos creando una nueva clase personalizada y poniendo nuestro simple botón dentro de ella..
Cree un nuevo archivo ActionScript llamado 'JitteryButton.as'. Guarde este archivo en el mismo directorio que su archivo principal de Flash. Agregue este código para crear la envoltura para nuestro botón:
paquete import flash.display.Sprite; importar flash.display.SimpleButton; la clase pública JitteryButton extiende Sprite private var myButton: SimpleButton; // contiene la referencia a nuestro simple botón // CLASS CONSTRUCTOR public function JitteryButton (button: SimpleButton) myButton = button; // el botón en el escenario se pasa en
Todo lo que este código hace hasta ahora es aceptar el botón simple y almacenar una referencia a él. Añadiremos más funcionalidad más tarde..
Cree un nuevo archivo ActionScript llamado 'Game.as'. Esta será la clase de documentos para nuestra película. Guárdelo en el mismo directorio que el archivo principal de Flash..
Este código agregará nuestro envoltorio de botón personalizado alrededor del botón en el escenario:
paquete import flash.display.MovieClip; El juego de clase pública extiende MovieClip private var startButton: JitteryButton; // CLASS CONSTRUCTOR public function Game () // crear el botón nervioso del botón simple en el escenario startButton = new JitteryButton (button1); // agregar el nuevo botón al escenario addChild (startButton);
Este código crea una nueva instancia de nuestra clase personalizada JitteryButton y le pasa el botón en el escenario ('button1').
Por supuesto, su clase de documentos terminará luciendo muy diferente ya que tendrá el código para su juego. Aquí solo nos interesa el código de nuestro botón..
De vuelta dentro de su archivo Flash configure la clase de documento en 'Juego'. Recuerde, no incluye la extensión de archivo aquí.
Si guarda y vuelve a probar su película en este punto, debería ver exactamente lo mismo que cuando probamos en el Paso 4. La única diferencia es que ahora nuestro código está configurado para poder agregar nuestro comportamiento personalizado.
Ahora crearemos la imagen del patrón estático que usaremos para distorsionar el gráfico de nuestro botón..
Abra Photoshop y cree una nueva imagen con gris neutro (# 808080). La imagen debe ser ligeramente más ancha que su botón y aproximadamente 3 o 4 veces más alta. Mi botón es 277x56, y mi imagen es 310x220.
Estamos empezando con un gris neutro porque eso no afectará nuestra imagen..
Ahora añadiremos un poco de ruido a nuestra imagen. Esto no será muy notable en nuestro efecto estático, pero le da un poco de brillo adicional. Puedes saltarte este paso si quieres..
Duplique la capa de fondo y nombre la nueva capa 'Ruido'. Ahora deberías tener 2 capas rellenas de gris neutro. Seleccione la nueva capa de ruido y elija Filtro> Ruido> Agregar ruido. Conjunto Cantidad al 120% y Distribución al uniforme. Comprobar Monocromo.
Pulsa OK.
Establece la capa 'Ruido' a 10% de opacidad.
Crea una nueva capa llamada 'Líneas'. Ahora use un pincel para lápiz de 1px para agregar algunas líneas horizontales negras y grises a la imagen.
Recuerda cómo estas líneas afectarán nuestra imagen: cualquier cosa más oscura que neutral cambiará nuestra imagen en una dirección y cualquier cosa más clara la moverá en la otra.
Elija Archivo> Guardar para Web y dispositivos y guarde su imagen como un gif de 8 colores llamado 'staticMap.gif'.
De vuelta en Flash, importe el archivo 'staticMap.gif' a su biblioteca (Archivo> Importar> ¿Importar a biblioteca?). Abra las propiedades de enlace, compruebe Exportar para ActionScript, y establece el nombre de la clase en 'StaticMap'.
Ahora podemos hacer referencia a esta imagen en nuestro código usando el nombre de clase StaticMap.
Agrega esta función a tu clase de JitteryButton:
// crear la función privada de filtro de mapa de desplazamiento createDMFilter (): DisplacementMapFilter var mapBitmap: BitmapData = new StaticMap (0,0); // use los datos de mapa de bits de nuestra imagen StaticMap var mapPoint: Point = new Point (0, 0); // posición de la imagen StaticMap en relación con nuestros botones var del botón: uint = BitmapDataChannel.RED; // qué color usar para el desplazamiento var componentX: uint = channels; var componentY: uint = canales; var scaleX: Number = 5; // la cantidad de desplazamiento horizontal var scaleY: Number = 1; // la cantidad de modo de variación vertical: String = DisplacementMapFilterMode.COLOR; color var: uint = 0; var alfa: Número = 0; devuelve el nuevo DisplacementMapFilter (mapBitmap, mapPoint, componentX, componentY, scaleX, scaleY, mode, color, alpha);
Esta función simplemente crea el Filtro de Mapa de Desplazamiento utilizando el BitmapData de nuestra imagen StaticMap. Esto no necesita estar en su propia función, solo lo hago para mayor claridad..
Para que funcione, debemos importar estas clases en la parte superior de nuestra clase JitteryButton:
importar flash.display.BitmapData; importar flash.display.BitmapDataChannel; importar flash.filters.DisplacementMapFilter; importar flash.filters.DisplacementMapFilterMode; importar flash.geom.Point;
(Puede obtener más información sobre la clase DisplacementMapFilter en la documentación de AS3)
Ahora crearemos una variable para mantener el filtro. Lo aplicamos al botón configurando la propiedad 'filtros' del botón a una matriz que contiene nuestro filtro.
Aquí está la clase de JitteryButton hasta ahora (las líneas 18 y 25 son nuevas):
paquete import flash.display.Sprite; importar flash.display.SimpleButton; importar flash.display.BitmapData; importar flash.display.BitmapDataChannel; importar flash.filters.DisplacementMapFilter; importar flash.filters.DisplacementMapFilterMode; importar flash.geom.Point; importar caurina.transitions.Tweener; la clase pública JitteryButton extiende Sprite private var myButton: SimpleButton; // crear una variable para mantener el filtro de mapa de desplazamiento privado var dmFilter: DisplacementMapFilter = createDMFilter (); // CLASS CONSTRUCTOR public function JitteryButton (button: SimpleButton) myButton = button; // aplica el filtro al botón myButton.filters = new Array (dmFilter); // crear la función privada filtro de mapa de desplazamiento createDMFilter (): DisplacementMapFilter var mapBitmap: BitmapData = new StaticMap (0,0); // use los datos de mapa de bits de nuestra imagen StaticMap var mapPoint: Point = new Point (0, 0); // esta es la posición de la imagen StaticMap en relación con nuestros canales var canales: uint = BitmapDataChannel.RED; // qué color usar para el desplazamiento var componentX: uint = channels; var componentY: uint = canales; var scaleX: Number = 5; // la cantidad de desplazamiento horizontal var scaleY: Number = 1; // la cantidad de modo de variación vertical: String = DisplacementMapFilterMode.COLOR; color var: uint = 0; var alfa: Número = 0; devuelve el nuevo DisplacementMapFilter (mapBitmap, mapPoint, componentX, componentY, scaleX, scaleY, mode, color, alpha);
Si guardamos y probamos el archivo ahora, podemos ver el filtro de mapa de desplazamiento que se aplica a nuestro botón:
Puedes ver cómo las líneas horizontales que dibujamos en StaticMap están desplazando los píxeles en nuestro botón a la izquierda y la derecha. La cantidad del cambio depende de la oscuridad de las líneas en la imagen y la configuración de scaleX en nuestro filtro de mapa de desplazamiento.
Desafortunadamente, la estática no está animando, por lo que parece bastante aburrida. Vamos a arreglar eso ahora?
Esta es una función simple que devuelve un entero aleatorio dentro de un rango especificado:
// devuelve un número aleatorio entre el rango especificado (incluido) función privada randRange (min: int, max: int): int var randomNum: int = Math.floor (Math.random () * (max - min + 1) ) + min; return randomNum;
Me parece que hace que sea un poco más fácil generar valores aleatorios. Estaremos asignando al azar unos valores diferentes para nuestro efecto estático, por lo que será útil.
Agrégalo a tu clase de JitteryButton.
Hay un par de maneras en que podemos animar el efecto estático. El primero será alterar la cantidad de desplazamiento horizontal aplicado a nuestro botón. Esto se hace a través de la propiedad scaleX del DisplacementMapFilter.
También podemos animar la posición de la imagen StaticMap en relación con nuestro botón. Esto asegurará que las mismas áreas del botón no siempre se desplacen.
Para animar el efecto, agregaremos una función llamada 'displayStatic' que se llama a cada fotograma para actualizar estas dos propiedades del filtro. Agrega esta función a tu clase de JitteryButton:
// llamado en la función privada ENTER_FRAME displayStatic (e: Event): void dmFilter.scaleX = randRange (fuzzMin, fuzzMax); dmFilter.mapPoint = new Point (0, randRange (0, -160)); myButton.filters = nueva matriz (dmFilter);
La primera línea de esta función asigna al azar la cantidad de desplazamiento horizontal a un valor entre las variables fuzzMin y fuzzMax. Agrega estas dos variables a tu clase de JitteryButton:
var privado fuzzMin: int = 0; var privado fuzzMax: int = 2;
La segunda línea de la función displayStatic aleatoriza la posición Y del StaticMap en relación con nuestro botón. Ya le dijimos al filtro que usara nuestra imagen StaticMap, así que solo necesitamos actualizar la posición.
La tercera línea simplemente vuelve a aplicar el filtro a nuestro botón..
Lo último que debemos hacer para obtener esta animación es agregar el detector de eventos ENTER_FRAME. Agregue esta línea a la función del constructor JitteryButton:
// comienza a mostrar el efecto estático addEventListener (Event.ENTER_FRAME, displayStatic);
Y no olvide importar la clase de evento en la parte superior del archivo JitteryButton:
import flash.events.Event;
Si guarda y prueba la película ahora verá que el efecto hace que nuestro botón brille y salte:
Eso es genial, pero queremos que el efecto también reaccione al mouse. Adelante?
Ahora agregaremos dos funciones para ajustar la intensidad del efecto jitter. Llamaremos al efecto que actualmente tenemos Baja intensidad, por lo que agregaremos una configuración para Intensidad media y Alta. Agrega estas funciones a tu clase de JitteryButton:
// incrementa la intensidad de la función privada estática a mediaStStaticMedium (e: MouseEvent = null): void fuzzMin = 2; fuzzMax = 6; staticLength = randRange (8, 12); // aumentar la intensidad de la función estática a ALTA función privada setStaticHigh (e: MouseEvent = null): void fuzzMin = 12; fuzzMax = 25; staticLength = 12;
Puede ver que estamos ajustando la intensidad al establecer los valores de las variables fuzzMin y fuzzMax. De esta manera, nuestra función displayStatic utilizará estos nuevos valores cuando establezca el desplazamiento horizontal del filtro.
También agregamos una variable llamada staticLength. Usaremos esto para establecer cuánto tiempo debe durar el efecto más intenso (el número de cuadros) antes de volver a la intensidad baja. Agregue esta variable a su clase JitteryButton y modifique su función displayStatic de la siguiente manera:
private var staticLength: int; // llamado en la función privada ENTER_FRAME displayStatic (e: Event): void dmFilter.scaleX = randRange (fuzzMin, fuzzMax); dmFilter.mapPoint = new Point (0, randRange (0, -160)); myButton.filters = nueva matriz (dmFilter); staticLength--; if (staticLength <= 0) fuzzMin = 0; fuzzMax = 2;
Este nuevo código disminuye la variable staticLength y restablece fuzzMin y fuzzMax a los valores de baja intensidad una vez que el valor de staticLength llega a cero.
Para hacer que nuestro botón reaccione al mouse, necesitamos agregar dos escuchas de eventos de ratón y una función de controlador de eventos para cada uno..
Agregue los escuchas del mouse en la función de constructor de su clase JitteryButton:
// agrega los escuchas de eventos de rollover al botón myButton.addEventListener (MouseEvent.ROLL_OVER, onButtonRollOver); myButton.addEventListener (MouseEvent.ROLL_OUT, onButtonRollOut);
Ahora cree los dos controladores de eventos a los que se hace referencia en esas dos nuevas líneas. Estos también van en la clase JitteryButton:
// llamado en el botón ROLL_OVER función privada onButtonRollOver (e: MouseEvent): void setStaticHigh (); // llamado en el botón ROLL_OUT función privada onButtonRollOut (e: MouseEvent): void setStaticMedium ();
Para que todo esto funcione, tendremos que importar la clase MouseEvent en la parte superior de nuestro archivo JitteryButton:
import flash.events.MouseEvent;
Ahora, cuando nuestro botón detecta un evento ROLL_OVER, llamará al controlador de eventos que, a su vez, llama a nuestra función setStaticHigh. Esta función aumenta los valores de fuzzMin y fuzzMax (utilizados para configurar el desplazamiento horizontal) durante el tiempo especificado por la variable staticLength.
Podríamos detenernos aquí. Nuestro efecto es animar muy bien y reacciona a los vuelcos del mouse. Todavía siento que aquí falta algo. Vamos a añadir un poco de efecto de escala..
Necesitará descargar la Biblioteca Tweener para este paso si aún no lo tiene. Coloque la carpeta 'caurina' en el directorio de su proyecto e importe las clases de Tweener en la parte superior de su archivo JitteryButton:
importar caurina.transitions.Tweener;
Tweener nos permite agregar algunos efectos de escalado agradables con solo un par de líneas de código. Podemos agregar una línea a cada uno de nuestros controladores de eventos de reinversión:
// llamado en el botón ROLL_OVER función privada onButtonRollOver (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1.1, time: .5, transition: "easeOutElastic"); setStaticHigh (); // llamado en el botón ROLL_OOUT función privada onButtonRollOut (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1, time: .5, transition: "easeOutElastic"); setStaticMedium ();
Aquí estamos agregando una animación al controlador de rollover que escala la propiedad scaleX del botón al 110% en .5 segundos. Estamos usando un tipo de transición elástica para darle esa sensación de rebote. En el controlador de despliegue, estamos haciendo lo mismo a la inversa, reduciéndolo al 100%.
Puede obtener más información sobre cómo usar Tweener en la documentación de Tweener..
Lo último que debemos hacer para completar este efecto es agregar un poco de sonido. Hice mi efecto de sonido en Garage Band. Puedes hacer el tuyo o intentar encontrar uno en línea..
Una vez que tenga uno que le guste, impórtelo en su biblioteca y configure el enlace para exportar como 'StaticSound'.
Para agregarlo a nuestro JitteryButton primero necesitamos importar la clase de sonido:
import flash.media.Sound;
Luego lo inicializaremos (agregue esta línea justo antes de la función del constructor):
private var staticSound: Sound = new StaticSound ();
Dentro del controlador de rollover le diremos el sonido a reproducir:
// llama al botón ROLL_OVER función privada onButtonRollOver (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1.1, time: .5, transition: "easeOutElastic"); setStaticHigh (); staticSound.play ();
Ahora estamos bien para irnos. Pon a prueba tu película y todo debería estar funcionando. Si su botón o sonido no funciona bien, revise los archivos de origen para ver mi clase de JitteryButton completada.
Lo bueno de crear este efecto como una clase separada que envuelve nuestro botón es que podemos reutilizarlo fácilmente en otros botones.
Si desea agregar más botones al menú del juego, simplemente cree un nuevo botón y agréguelo al escenario. Dale el nombre de instancia 'button2'. Luego, dentro de su clase de documento (el archivo 'Game.as') cree un nuevo JitteryButton y pásele el nuevo botón. Así es como podría verse:
paquete import flash.display.MovieClip; El juego de clase pública extiende MovieClip private var startButton: JitteryButton; privado var menuButton: JitteryButton; // CLASS CONSTRUCTOR public function Game () // crear los botones vibrantes a partir de los botones simples en el escenario startButton = new JitteryButton (button1); addChild (startButton); // ¡Añadir un nuevo botón es fácil! menuButton = new JitteryButton (button2); addChild (menuButton);
Es casi seguro que necesitará cambiar un poco este código para que encaje en la estructura de su juego. Esperemos que este tutorial te dé un buen punto de partida..
Si desea cambiar el aspecto de este efecto, puede probar diferentes tipos de imágenes para su gráfico StaticMap y ajustar los valores de fuzzMin y fuzzMax..
Este es mi primer tutorial, así que avísame si hay algo que pueda mejorar la próxima vez. Gracias por leer!