Cansado de esas tarjetas navideñas animadas pasadas de moda con Papá Noel riéndose, un trineo volando en el cielo con un grupo de árboles y luces brillantes.?
Este año no tienes excusa. Voy a mostrarte cómo construir un teclado virtual que toca Jingle Bells. Incluso podrás extender el concepto y agregar más canciones y notas al piano..
Para esto, usaré una combinación de Tweenlite, Flex SDK, Flash IDE y Flash Develop..
Inicie Adobe Flash y cree un archivo ActionScript 3 Flash..
Abra las propiedades y configure el FPS a 30 y el tamaño del escenario a 600 x 380 px.
Renombra la capa 1 como "fondo" y crea un rectángulo blanco de 580x360. Conviértalo en un símbolo de clip de película llamado "frame_mc" y establezca su posición en x: 10 y: 10.
Agrega un filtro de sombra con los siguientes parámetros:
Agregue una nueva capa llamada "teclado", cree un rectángulo primitivo 60x190 con un radio de esquina de 5 píxeles y sin trazo. Conviértalo en un símbolo de clip de película y llámelo "keybase_mc".
Pulsa F8 y crea un nuevo clip de vídeo llamado "key_mc". Cree dos capas más dentro de key_mc (además de la que ya está presente con keybase_mc). Nómbrelos: "reflexión" y "resplandor". Copia el marco a las capas recién creadas..
NOTA: He cambiado los colores de frame_mc por un tiempo para que pueda ver las modificaciones en las teclas. Seleccione el movieclip en la capa luminosa, llámelo "glow_mc", abra los filtros y edítelos de acuerdo con la siguiente imagen:
Seleccione el movieclip en la capa de reflexión, asígnele el nombre "reflection_mc", abra los filtros y edítelos para que coincidan con la imagen siguiente:
ahora seleccione el movieclip en la capa base, llámelo "base_mc", abra los filtros y edítelos para que coincidan con la imagen de abajo:
Copia y pega la clave hasta que obtengas 7 instancias. Colóquelos uniformemente en el escenario..
Abra la herramienta de alineación y haga clic en el icono "espaciado horizontal".
Crea una nueva capa, llámala "notas". Entonces escribe C D E F G A B en las teclas agregue el texto a un nuevo movieclip. Abra los filtros de movieclip y edítelos como la imagen a continuación:
Crea una nueva capa, llámala "números". Escriba los números del 1 al 7, esto representará los números que presionará en su teclado para resaltar la tecla de tarjeta electrónica.
Vaya a editar> preferencias> ActionScript> configuración de ActionScript 3.0 y localice su ruta de Flex SDK (necesitará esto para incrustar archivos directamente a través del código).
Abra Flash Develop (solo uso esta causa, me gusta mucho más que el editor ActionScript habitual del IDE de flash al escribir paquetes) y cree 2 archivos AS3 en blanco. Llámalos "Main.as" y "Background.as", guárdalos en la misma carpeta que tu .fla.
Inside Flash IDE establece Main.as como su clase de documento.
Cree un clip de película de reproducción automática y asígnele el nombre "autoplay_mc". Este será un botón de reproducción automática..
Para crear algunos copos de nieve cayendo, cree un nuevo clip de vídeo, dibuja un círculo blanco pequeño dentro y agrega un identificador de vinculación de "SnowFlake".
En Flash Develop, abra Main.as, defina su clase Main extendiendo un movieclip y cree una función llamada Main.
Comience importando estas clases dentro de su paquete:
importar flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; importar flash.display.StageScaleMode; import flash.events.KeyboardEvent; import flash.utils.Timer; import com.greensock.TweenLite; import com.greensock.easing. *; Importar fondo; // crearemos una clase de fondo basada en el ruido perlin y una matriz de transformación junto con algunas formas rellenas para que podamos tener una transición de nieve agradable y suave; // Acabo de agarrar kirupas snow y lo empaqueté -> http://troyworks.com/blog/2008/11/26/flash-kirupa-snow-in-as30/ import flash.media.Sound;
Dentro de tu clase define estas variables:
// este será nuestro fondo privado var _background: Background; // esta será nuestra tormenta de nieve privada var snow: Snow; // -> notas // Incrustar de esta manera requiere FLEX SDK -> el método alternativo es agregar estos sonidos a su biblioteca y agregarles una identificación de enlace. [Incrustar (fuente = "activos / A.mp3")] privado var A: Clase; var a privado: Sonido = nuevo A () como sonido; [Incrustar (fuente = "activos / B.mp3")] privado var B: Class; var privado: sonido = nuevo B () como sonido; [Incrustar (fuente = "activos / C.mp3")] privado var C: Class; var privado: sonido = nuevo C () como sonido; [Incrustar (fuente = "activos / D.mp3")] privado var D: Class; var privado: sonido = nuevo D () como sonido; [Incrustar (fuente = "activos / E.mp3")] privado var E: Class; Variedad privada: Sonido = nuevo E () como sonido; [Incrustar (fuente = "activos / F.mp3")] privado var F: Class; privado var f: Sound = new F () as Sound; [Incrustar (fuente = "activos / G.mp3")] privado var G: Class; var var privado: Sonido = nuevo G () como sonido; // Almacenar las notas en una matriz facilitará el enlace al teclado privado var notes: Array = [c, d, e, f, g, a, b] // Secuencia de notas para la música privada var noteSequence: Array = [f, f, f, f, f, f, a, d, e, f, g, g, g, g, e, e, d, b, a, f, d, c] // Nota actual que se está reproduciendo en privado var curnote: Número = 0 // Secuencia de demora que la música debe tener entre las notas private var noteDelay: Array = [100, 100, 300, 100, 100, 300, 100, 100 , 100,100,200, 100, 100, 200, 90, 100, 90,100, 100, 120, 120, 120, 120, 300] // Temporizador para reproducir la música privada tun tunímetro: Temporizador = nuevo Temporizador (noteDelay [0]);
La funcion principal
// La función principal espera a que la línea de tiempo principal se agregue a la función pública de la etapa Main (): void addEventListener (Event.ADDED_TO_STAGE, addedToStage);
Después de agregarse a la etapa, inicializaremos el fondo y el teclado virtual:
// cuando se agrega al escenario, podemos establecer un modo de escala de escenario, el fondo y el inicio de la función privada de piano virtual addedToStage (e: Event): void stage.scaleMode = StageScaleMode.NO_SCALE; addBackground (); startMachine ();
Vamos a resolver el fondo en movimiento y la nieve:
// agrega la función privada de fondo addBackground (): void _background = new Background (150,150); // la razón por la cual el tamaño es más pequeño es porque requiere mucha CPU _background.x = 5; // para dar un margen blanco para el marco _background.y = 5; _background.width = 570 // amplíelo al tamaño correcto _background.height = 350 frame_mc.addChild (_background); // agrega fondo al marco snow = new Snow (570, 350) // crea una instancia de tormenta de nieve
La inicialización del teclado virtual.
private function startMachine (e: MouseEvent = null): void // asocia los eventos del teclado stage.addEventListener (KeyboardEvent.KEY_DOWN, onkeyDown) stage.addEventListener (KeyboardEvent.KEY_UP, onkeyUp) // asocia un método de reproducción automática al botón de reproducción automática. .addEventListener (MouseEvent.CLICK, startAutoPlay); autoplay_mc.buttonMode = true; // asocia las notas a las teclas var i: int = 0 while (i < 7) this["key"+i].note = notes[i] i++ //makes the highlight of the keys disappear lowlightKeys();
Necesitamos crear una función para eliminar el resaltado de las teclas:
función privada lowlightKeys () var i: int = 0 while (i < 7) TweenLite.to(this["key" + i].glow_mc, 0.5,alpha:0 ); i++
Ahora manejemos los eventos Key up y Key down:
función privada onkeyDown (e: KeyboardEvent): void var i: int = 0 switch (e.keyCode) caso 49: // código de tecla para 1 i = 0 break; caso 50: // código clave para 2 i = 1 interrupción; caso 51: // código clave para 3 i = 2 break; caso 52: // código clave para 4 i = 3 break; caso 53: // código clave para 5 i = 4 break; caso 54: // código clave para 6 i = 5 break; caso 55: // código clave para 7 i = 6 break; notas [i] .play (); TweenLite.to (esta ["clave" + i] .glow_mc, 0.5, alpha: 1); // resalta la tecla función privada onkeyUp (e: KeyboardEvent): void var i: int = 0 switch (e.keyCode) case 49: i = 0 break; caso 50: i = 1 descanso; caso 51: i = 2 ruptura; caso 52: i = 3 ruptura; caso 53: i = 4 ruptura; caso 54: i = 5 ruptura; caso 55: i = 6 descanso; TweenLite.to (esta ["clave" + i] .glow_mc, 0.5, alpha: 0); // resalta la tecla
Cómo iniciar y detener la reproducción automática.
función privada startAutoPlay (e: MouseEvent = null) curnote = 0; // cada vez que comienzo la reproducción automática, reinicio la nota de reproducción actual tunetimer.delay = noteDelay [curnote] * 3 // esto aumenta el retardo establecido previamente tunetimer.addEventListener (TimerEvent.TIMER, autoPlayTune) // agrega un oyente al evento del temporizador para cada vez que se activa el temporizador tunetimer.start () // inicia el temporizador función privada stopAutoPlay (e: MouseEvent = null) tunetimer.stop () // detiene el temporizador tunetimer.removeEventListener (TimerEvent.TIMER, autoPlayTune) // elimina la evento
Actualización del teclado virtual junto con la música.
función privada updateMachine (): void lowlightKeys (); // restablece las teclas resaltadas var i: int = 0 while (i < 7) if (this["key" + i].note == noteSequence[curnote]) TweenLite.to(this["key" + i].glow_mc, 0.5,alpha:1 ); //if current note is the one associeated with the key then highlights it i++ curnote++ //goes to next note if (curnote > noteSequence.length) curnote = 0; // restablece la nota actual stopAutoPlay (); // detiene la reproducción automática
Aquí está el código completo de Main.as
paquete import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; importar flash.display.StageScaleMode; import flash.events.KeyboardEvent; import flash.utils.Timer; import com.greensock.TweenLite; import com.greensock.easing. *; Importar fondo; importar nieve import flash.media.Sound; clase pública Main extiende MovieClip private var _background: Background; nieve privada var: nieve; [Incrustar (fuente = "activos / A.mp3")] privado var A: Clase; var a privado: Sonido = nuevo A () como sonido; [Incrustar (fuente = "activos / B.mp3")] privado var B: Class; var privado: sonido = nuevo B () como sonido; [Incrustar (fuente = "activos / C.mp3")] privado var C: Class; var privado: sonido = nuevo C () como sonido; [Incrustar (fuente = "activos / D.mp3")] privado var D: Class; var privado: sonido = nuevo D () como sonido; [Incrustar (fuente = "activos / E.mp3")] privado var E: Class; Variedad privada: Sonido = nuevo E () como sonido; [Incrustar (fuente = "activos / F.mp3")] privado var F: Class; privado var f: Sound = new F () as Sound; [Incrustar (fuente = "activos / G.mp3")] privado var G: Class; var var privado: Sonido = nuevo G () como sonido; Notas de var privado: Array = [c, d, e, f, g, a, b] Nota de var privada: Array = [f, f, f, f, f, f, a, d, e, f, g, g, g, g, g, e, e, d, b, a, f, d, c] private var curnote: Número = 0 private var noteDelay: Array = [100, 100, 300, 100, 100, 300, 100, 100, 100,100,200, 100, 100, 200, 90, 100, 90,100, 100, 120, 120, 120, 120, 300] tunetímero de var privado: Temporizador = nuevo Temporizador (noteDelay [0]); función pública Main (): void addEventListener (Event.ADDED_TO_STAGE, addedToStage); función privada addedToStage (e: Event): void stage.scaleMode = StageScaleMode.NO_SCALE; addBackground (); startMachine (); // agrega la función privada de fondo addBackground (): void _background = new Background (150,150); _background.x = 5; _background.y = 5; _background.width = 570 _background.height = 350 frame_mc.addChild (_background); nieve = nieve nueva (570, 350); frame_mc.addChild (snow); función privada startMachine (e: MouseEvent = null): void stage.addEventListener (KeyboardEvent.KEY_DOWN, onkeyDown) stage.addEventListener (KeyboardEvent.KEY_UP, onkeyUp) autoplay_mc.buttonMode = true; var i: int = 0 while (i < 7) this["key"+i].note = notes[i] i++ lowlightKeys(); private function lowlightKeys() var i:int = 0 while (i < 7) TweenLite.to(this["key" + i].glow_mc, 0.5,alpha:0 ); i++ private function onkeyDown(e:KeyboardEvent):void var i:int=0 switch(e.keyCode) case 49: i=0 break; case 50: i=1 break; case 51: i=2 break; case 52: i=3 break; case 53: i=4 break; case 54: i=5 break; case 55: i=6 break; notes[i].play(); TweenLite.to(this["key" + i].glow_mc, 0.5,alpha:1 ); private function onkeyUp(e:KeyboardEvent):void var i:int=0 switch(e.keyCode) case 49: i=0 break; case 50: i=1 break; case 51: i=2 break; case 52: i=3 break; case 53: i=4 break; case 54: i=5 break; case 55: i=6 break; TweenLite.to(this["key" + i].glow_mc, 0.5,alpha:0 ); //AUTO PLAY FUNCTIONS private function startAutoPlay(e:MouseEvent = null) curnote = 0; tunetimer.delay = noteDelay[curnote] * 3 tunetimer.addEventListener(TimerEvent.TIMER, autoPlayTune) tunetimer.start() private function stopAutoPlay(e:MouseEvent = null) tunetimer.stop() tunetimer.removeEventListener(TimerEvent.TIMER, autoPlayTune) private function autoPlayTune(e:TimerEvent) if(curnotenoteSequence.length) curnote = 0; stopAutoPlay ();
Ahora en la clase de fondo. Comenzaremos importando estas clases ...
importar flash.display.Shape; import flash.events.Event; importar flash.display.Sprite; importar flash.display.MovieClip; importar flash.display.Bitmap; importar flash.display.BitmapData; importar flash.display.BlendMode; importar flash.geom.ColorTransform; import flash.geom.Rectangle; importar flash.geom.Point; importar flash.geom.Matrix; importar flash.filters.ColorMatrixFilter; importar flash.display.GradientType; importar flash.display.Graphics; importar flash.display.InterpolationMethod; importar flash.display.SpreadMethod;
… Luego definiendo las variables:
// Noise private var dir: Array private var punto: Point private var bd: BitmapData; privado var bmp: mapa de bits; private var bdmultiply: BitmapData; var bms privados: Sprite; private var rect: Rectangle private var cmf: ColorMatrixFilter; private var w: Number private var h: Number // Linear Gradient Fill private var gshape: Shape private var gmetrics: Rectangle private var gmatrix: Matrix private var gtype: String private var gspread: String private var ginterpolation: String private var gcolours: Array private var galphas: Array private var gratios: Array // Solid Fill private var sshape: Shape
Aquí está la función inicial:
Fondo de la función pública ($ ancho: Número = 100, $ altura: Número = 100) w = $ ancho h = $ altura rect = nuevo Rectángulo (0, 0, w, h); punto = nuevo punto (0, 0); dir = [punto nuevo (1, 262), punto nuevo (400, 262)]; // este es solo para dar un fondo sólido a toda la etapa initBackgroundSolid (); // esto controlará el contraste y la saturación del ruido initColorMatrix (); // habrá dos fondos de ruido, esto los iniciará initBackgroundNoise (); // se agrega un gradiente para que no nos pongamos ruidosos ... (¿lo entiendes? ¿demasiado ruido te hace ruidoso? jaja ... hmmm) initBackgroundGradient ();
Esta función controlará el contraste y la saturación del ruido, es un filtro muy potente..
función privada initColorMatrix (): void cmf = new ColorMatrixFilter ([2, 0, 0, 0, -20, // red 0, 2, 0, 0, -20, // green 0, 0, 2, 0, -20, // azul 0, 0, 0, 1, -20]); // alfa
Este es solo para dar un sólido fondo a toda la etapa..
función privada initBackgroundSolid (): void sshape = new Shape (); sshape.graphics.beginFill (0x170a02,1) sshape.graphics.drawRect (0, 0, w, h); sshape.graphics.endFill (); addChild (sshape)
Los ruidos:
función privada initBackgroundNoise (): void // first noise bd = new BitmapData (w, h, false, 0); bmp = nuevo mapa de bits (bd); bmp.smoothing = true; addChild (bmp); // segundo ruido que se superpone al primer ruido a través de un modo de mezcla de superposición bdmultiply = new BitmapData (w, h, false, 0); bms = nuevo Sprite (); bms.addChild (nuevo mapa de bits (bdmultiply)) addChild (bms) bms.blendMode = "overlay"; // representa el fondo de manera que el ruido parece estar moviendo addEventListener (Event.ENTER_FRAME, renderBG);
Aquí está la máscara de degradado:
función privada initBackgroundGradient () // esta es una caja de gradiente básica con alfa y girada 90º para que comience desde arriba hacia abajo en lugar de izquierda-derecha gshape = new Shape (); gmetrics = new Rectangle (); gmatrix = nueva matriz (); gtype = GradientType.LINEAR; gspread = SpreadMethod.PAD; ginterpolation = InterpolationMethod.LINEAR_RGB; gcolours = [0x170a02, 0x170a02]; galphas = [0, 1]; gratios = [0, 255]; gmatrix.createGradientBox (w, h, (Math.PI / 180) * 90); gshape.graphics.clear (); gshape.graphics.beginGradientFill (gtype, gcolours, galphas, gratios, gmatrix, gspread, ginterpolation); gshape.graphics.drawRect (0, 0, w, h); gshape.graphics.endFill (); addChild (gshape)
Es tiempo de render!
función privada renderBG (evento: Evento): void // actualiza noise direction dir [0] .x- = 1.5 dir [0] .y- = 0 // estos están aquí para que juegue con dir [1] .x - = 0 // estos están aquí para que juegues con dir [1] .y - = 0 // estos están aquí para que juegues con // define el primer mapa de bits de fondo para tener un ruido perlin bd.perlinNoise (w, h, 2, 10, falso, verdadero, 7, verdadero, dir); // tiempo de coloración (jugar con estos valores) bd.colorTransform (rect, new ColorTransform (1, 0.7, 0.5)); // aplica el contraste de brillo y las modificaciones de saturación realizadas anteriormente bd.applyFilter (bd, rect, point, cmf) // el otro ruido perlin bdmultiply.perlinNoise (w, h, 3, 21, false, true, 7, true, dir ) // los otros colors perlin noise bdmultiply.colorTransform (rect, new ColorTransform (1, 0.6, 0.4));
Aquí está toda la clase de fondo:
paquete import flash.display.Shape; import flash.events.Event; importar flash.display.Sprite; importar flash.display.MovieClip; importar flash.display.Bitmap; importar flash.display.BitmapData; importar flash.display.BlendMode; importar flash.geom.ColorTransform; import flash.geom.Rectangle; importar flash.geom.Point; importar flash.geom.Matrix; importar flash.filters.ColorMatrixFilter; importar flash.display.GradientType; importar flash.display.Graphics; importar flash.display.InterpolationMethod; importar flash.display.SpreadMethod; la clase pública Fondo amplía MovieClip private var dir: Array private var point: Point private var bd: BitmapData; privado var bmp: mapa de bits; private var bdmultiply: BitmapData; var bms privados: Sprite; private var rect: Rectangle private var cmf: ColorMatrixFilter; private var w: Number private var h: Number private var gshape: Shape private var gmetrics: Rectangle private var gmatrix: Matrix private var gtype: String private var gspread: String private var ginterpolation: String private var gcolours: Array private var gifs: Array private var gratios: Array private var sshape: Shape public function Background ($ width: Number = 100, $ height: Number = 100) w = $ width h = $ height rect = new Rectangle (0, 0, w, h) ; punto = nuevo punto (0, 0); dir = [punto nuevo (1, 262), punto nuevo (400, 262)]; initBackgroundSolid (); initColorMatrix (); initBackgroundNoise (); initBackgroundGradient (); función privada initColorMatrix (): void cmf = nuevo ColorMatrixFilter ([2, 0, 0, 0, -20, // rojo 0, 2, 0, 0, -20, // verde 0, 0, 2, 0 , -20, // azul 0, 0, 0, 1, -20]); // alpha función privada initBackgroundSolid (): void sshape = new Shape (); sshape.graphics.beginFill (0x170a02,1) sshape.graphics.drawRect (0, 0, w, h); sshape.graphics.endFill (); addChild (sshape) función privada initBackgroundNoise (): void bd = new BitmapData (w, h, false, 0); bmp = nuevo mapa de bits (bd); bmp.smoothing = true; addChild (bmp); bdmultiply = new BitmapData (w, h, false, 0); bms = nuevo Sprite (); bms.addChild (nuevo mapa de bits (bdmultiply)) addChild (bms) bms.blendMode = "overlay"; addEventListener (Event.ENTER_FRAME, renderBG); función privada initBackgroundGradient () gshape = new Shape (); gmetrics = new Rectangle (); gmatrix = nueva matriz (); gtype = GradientType.LINEAR; gspread = SpreadMethod.PAD; ginterpolation = InterpolationMethod.LINEAR_RGB; gcolours = [0x170a02, 0x170a02]; galphas = [0, 1]; gratios = [0, 255]; gmatrix.createGradientBox (w, h, (Math.PI / 180) * 90); gshape.graphics.clear (); gshape.graphics.beginGradientFill (gtype, gcolours, galphas, gratios, gmatrix, gspread, ginterpolation); gshape.graphics.drawRect (0, 0, w, h); gshape.graphics.endFill (); addChild (gshape) función privada renderBG (evento: Evento): void dir [0] .x- = 1.5 dir [0] .y- = 0 dir [1] .x- = 0 dir [1] .y - = 0 bd.perlinNoise (w, h, 2, 10, false, true, 7, true, dir); bd.colorTransform (rect, nuevo ColorTransform (1, 0.7, 0.5)); bd.applyFilter (bd, rect, point, cmf) bdmultiply.perlinNoise (w, h, 3, 21, false, true, 7, true, dir) bdmultiply.colorTransform (rect, new ColorTransform (1, 0.6, 0.4)) ;
La clase de nieve no es mía, fue escrita por Troy Gardner, simplemente la adapté de la línea de tiempo a un paquete, por eso no estoy comentando el código. Crea un "Snow.as" y copia este código dentro.
paquete import flash.display.MovieClip; import flash.events.Event; import flash.utils.Dictionary; La clase pública Snow extiende MovieClip var snowflakes: Array = new Array (); var snowflakeProps: Dictionary = new Dictionary (true); var max_snowsize: Number = .04; // pixels var snowflakesCnt: Number = 150; var oheight: Número; var owidth: Número; Función pública Snow ($ width, $ height): void owidth = $ width; oheight = $ altura; // cantidad para (var i: int = 0; ioight + 10) dO.y = -20; if (dO.x> owidth + 20) dO.x = - (owidth / 2) + Math.random () * (1.5 * owidth); dO.y = -20; else if (dO.x<-20) dO.x= -(owidth/2)+Math.random()*(1.5*owidth); dO.y = -20;
Mis habilidades musicales no son las mejores, la música puede sonar un poco extraña. Oh, bueno, con este tutorial ahora deberías poder crear tus propias canciones con más notas y diferentes tonos :). Espero que te haya gustado este tutorial, encontrarás el código comentado y las versiones de cs4 y cs3 en el archivo zip. Gracias por leer!