¡Es el primer cumpleaños de ActiveTuts +! Celebremos haciendo una tarjeta de cumpleaños musical en 3D con Papervision3D y TweenMax.
Comience por crear una nueva carpeta (esta será la carpeta raíz de su proyecto) y cree un nuevo AS3 FLA dentro de esa carpeta, llamado Main.fla. Esto contendrá toda la IU que necesitamos para crear la tarjeta..
Para este tutorial necesitaremos dos bibliotecas Flash populares: Papervision3D y TweenMax. Descargue Papervision (estoy usando la versión 2.1.932) y extraiga el com y nochump Carpetas desde el zip a la carpeta raíz de tu proyecto. Descargue TweenMax (estoy usando la versión 11) y extraiga también el zip a la carpeta raíz de su proyecto.
Ahora crea un archivo AS vacío; guárdelo como "CardViewport.as" en la carpeta raíz de su proyecto. Esta será nuestra ventana gráfica papervision3d que contiene la tarjeta. Cree otro archivo AS vacío, en la misma carpeta, llamada "Main.as." Esta será tu clase de documentos. (¿No está seguro de cómo usar una clase de documento? Lea esta breve introducción.)
La estructura de su carpeta debe verse así:
Abre Main.fla y edita el escenario para convertirlo en 500x440 con una velocidad de fotogramas de 30 fps. Establezca la clase de documento en Principal:
Solo necesitamos dos capas para este tutorial:
En la capa viewport crea una forma rectangular. Ajústelo al tamaño del escenario y muévalo a la posición 0,0. Pulsa F8 para convertir la forma en un símbolo MovieClip. Marque la casilla para exportar para ActionScript y agregue el nombre de clase CardViewport. Se conectará a la clase que construiremos más adelante..
Ahora haga clic en el clip de película de la ventana gráfica y asigne un nombre de instancia de "ventana gráfica".
Abra el símbolo de clip de película de la ventana gráfica y cree el fondo que desee. Esto es lo que hice: un par de formas de degradado, una para el cielo y otra para el suelo y el logotipo de ActiveTuts + centrado en el cielo..
En la capa de botones crea una forma rectangular. Conviértalo en un símbolo de clip de película y llámelo "open_mc"; Asegúrate de darle el mismo nombre de instancia.
Dentro de open_mc haz un campo de texto. Configúrelo para que sea dinámico, asígnele un nombre de instancia de label_txt e incruste las fuentes haciendo clic en "Incrustar caracteres" y seleccionando el alfabeto que desea usar.
Haz que se vea como quieras. Construí el mío con un degradado y algunas líneas diagonales corriendo:
NOTA: No tengo derecho a distribuir. estándar 07_66, La fuente que estoy usando en este proyecto. Lo siento por eso.
Hora de Photoshop: Construiremos nuestra tarjeta con cuatro planos (rectángulos planos) uno frente al otro. Para eso necesitamos cuatro archivos de imagen diferentes para mapear en esos planos.
Nuestros aviones serán 700x900 y, por lo tanto, nuestras cuatro imágenes también serán de ese tamaño. La razón de este tamaño es porque los aviones flotarán en el espacio 3d a cierta distancia de la cámara; Necesitan ser grandes para que podamos verlos. Nombra las imágenes "page_1_front.jpg", "page_1_back.jpg", "page_2_front.jpg", "page_2_back.jpg" y colócalas en la carpeta raíz de tu proyecto.
Aquí están mis imágenes:
Estas imágenes están incluidas en el código fuente principal, pero también puede descargarlas directamente si lo prefiere ...
Haz lo mismo con un sonido si quieres agregar uno. Scott Wills de audiojungle tuvo la amabilidad de armar esta pista funky para nosotros.
Abra CardViewport.as. Usaré FlashDevelop para codificar, pero puede usar Flash si lo prefiere.
Crea un paquete e importa las clases que necesitamos:
package // basic classes import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; // clases de papervision import org.papervision3d.objects.primitives.Plane; importar org.papervision3d.materials.BitmapFileMaterial; importar org.papervision3d.view.BasicView; importar org.papervision3d.objects.DisplayObject3D; importar org.papervision3d.render.QuadrantRenderEngine; // tweening engine import com.greensock.TweenMax;
Configure las variables privadas que necesitaremos para CardViewport:
clase pública CardViewport extiende BasicView // BasicView es una clase que incluye una configuración básica de ventana gráfica para nuestra escena // Crea 4 planos privados var front_cover: Plane; private var front_inside: Plane; private var back_cover: Plane; private var back_inside: Plane; // Crea 4 materiales privados var front_cover_img: BitmapFileMaterial; private var front_inside_img: BitmapFileMaterial; private var back_cover_img: BitmapFileMaterial; private var back_inside_img: BitmapFileMaterial; // Crea el contenedor de la página frontal, que anidará 2 planos private var front_container: DisplayObject3D; // Crea el contenedor de la página trasera, que anidará los otros 2 planos private var back_container: DisplayObject3D; // Crea un contenedor de tarjetas que anidará el contenedor frontal y el contenedor posterior var card_container: DisplayObject3D;
Aquí está la función que se ejecutará cuando se crea CardViewport:
función pública CardViewport () super (); // para eliminar algunos errores acerca de cómo se calcula la profundidad z en nuestra escena // necesitamos cambiar el tipo de render a uno que pueda corregirlo setRenderType (); // Crea una instancia de los materiales y establece sus propiedades setMaterials (); // Crea una instancia de los planos, agrega los materiales a los planos, agrega los planos a las envolturas (contenedores) setPlanes (); // representa la cámara cada frame stage.addEventListener (Event.ENTER_FRAME, render); // coloca los planos en función de la posición del ratón stage.addEventListener (MouseEvent.MOUSE_MOVE, positionPlanes);
Para eliminar algunos errores acerca de cómo se calcula la profundidad z en nuestra escena, necesitamos cambiar el tipo de render a uno que pueda corregir. El QuadrantRenderEngine acepta un parámetro: el tipo de corrección. Estaremos corrigiendo el filtro z esta vez, utilícelo sabiamente, ya que puede saturar su CPU en situaciones complejas.
función privada setRenderType () this.renderer = new QuadrantRenderEngine (QuadrantRenderEngine.CORRECT_Z_FILTER)
Aunque no veamos el cuarto plano (la parte de atrás de la tarjeta), decidí agregarlo de todas formas, en caso de que quieras jugar con la escena..
Usaremos un BitmapFileMaterial, al establecer "preciso" a verdadero Estoy mejorando la calidad general, sin embargo También estoy usando más potencia de CPU.
función privada setMaterials (): void // Portada de portada front_cover_img = new BitmapFileMaterial ("page_1_front.jpg", true); front_cover_img.doubleSided = false; front_cover_img.fillAlpha = 1.0; // Front Inside Page front_inside_img = new BitmapFileMaterial ("page_1_back.jpg", true); front_inside_img.doubleSided = false; front_inside_img.fillAlpha = 1.0; // Atrás dentro de la página back_inside_img = new BitmapFileMaterial ("page_2_front.jpg", true); back_inside_img.doubleSided = false; back_inside_img.fillAlpha = 1.0; // Página de portada trasera back_cover_img = new BitmapFileMaterial ("page_2_back.jpg"); back_cover_img.doubleSided = false; back_cover_img.fillAlpha = 1.0;
Aquí creamos los cuatro planos que conforman nuestra tarjeta, ordenándolos en un par de contenedores para que aparezcan como dos páginas..
función privada setPlanes (): void // Crea la cubierta delantera del plano front_cover = new Plane (front_cover_img, 700, 900, 3, 3); front_cover.z = 0; front_cover.x = 350 // este desplazamiento se usará más adelante para que podamos abrir la tarjeta // Crea el interior del plano frontal front_inside = new Plane (front_inside_img, 700, 900, 3, 3); front_inside.z = 0; front_inside.rotationY = 180; // girado 180 grados para que podamos verlo desde el interior front_inside.x = 350 // es exactamente la mitad del ancho del plano // Crea un objeto de envoltura para que podamos rotar la página de inicio de una forma diferente Eje // El de las páginas. Es más simple de esta manera, ya que no tiene que meterse con las coordenadas de creación // y podemos compensarlo. front_container = new DisplayObject3D (); front_container.addChild (front_cover); front_container.addChild (front_inside); front_container.x- = 350 // aquí lo estamos compensando // Repita el proceso para la segunda página back_inside = new Plane (back_inside_img, 700, 900, 3, 3); back_inside.z = 0.1; back_inside.x = 350 back_cover = new Plane (back_cover_img, 700, 900, 3, 3); back_cover.z = 0.1; back_cover.rotationY = 180; back_cover.x = 350 back_container = new DisplayObject3D (); back_container.addChild (back_inside); back_container.addChild (back_cover); back_container.x - = 350 // Y después de todo, agregue los contenedores frontal y posterior a la envoltura principal y agregue la envoltura a la escena. card_container = new DisplayObject3D (); card_container.addChild (front_container) card_container.addChild (back_container) scene.addChild (card_container);
Tenga en cuenta que esta es una función pública, por lo que podemos acceder a ella a través de la clase de documento principal cuando hacemos clic en el botón:
public function openCard () // Cuando abrimos la tarjeta, necesitamos quitar los escuchas del mouse del escenario porque // cuando movemos el mouse giramos cosas, a veces los contenedores a veces los planos, // por lo tanto, no podemos rotar ambos simultáneamente como terminaremos con los errores de animación stage.removeEventListener (MouseEvent.MOUSE_MOVE, positionPlanes); // necesitamos restablecer las posiciones de los planos dentro de los contenedores resetPlanesPosition (); // rotamos el contenedor frontal 180 grados y ajustamos la x a 0, // porque compensamos los planos anteriores, ahora gira en consecuencia. TweenMax.to (front_container, 1.4, rotationY: 180, x: 0, onComplete: function () stage.addEventListener (MouseEvent.MOUSE_MOVE, positionContainer);); TweenMax.to (back_container, 1.4, x: 0); // Después de la rotación agregamos un nuevo oyente al mouse. Esta vez para reposicionar el contenedor principal.
Lo mismo para el cierre de la tarjeta:
public function closeCard () // cuando cerramos la tarjeta, los pasos son muy similares a cuando abrimos. stage.removeEventListener (MouseEvent.MOUSE_MOVE, positionContainer); // la diferencia es donde reiniciamos la rotación del contenedor principal card_container.rotationY = card_container.rotationX = 0 // restablecemos las propiedades xy rotationY de los contenedores frontal y posterior TweenMax.to (front_container, 1.4, rotationY: 0, x: - 350, onComplete: function () stage.addEventListener (MouseEvent.MOUSE_MOVE, positionPlanes);); TweenMax.to (back_container, 1.4, x: -350); // y después de la animación, agregamos la acción anterior del evento de movimiento del mouse para posicionar los planos
Esto se llama cada vez que se mueve el mouse mientras la tarjeta está cerrada:
función privada positionPlanes (evento: Evento): void // gira entre -25º y 25º según la posición del mouse front_cover.rotationY = back_inside.rotationY = (stage.mouseX / stage.stageWidth * 50) -25 front_cover.rotationX = front_inside.rotationX = back_cover.rotationX = back_inside.rotationX = (stage.mouseY / stage.stageHeight * 50) - 25 // solo necesitamos agregar 180 a las caras que se supone que están contra nosotros front_inside.rotationY = back_cover.rotationY = ((stage.mouseX / stage.stageWidth * 50) - 25) + 180
Esto se llama cuando el mouse se mueve mientras la tarjeta está abierta:
Función privada positionContainer (evento: Evento): void // al igual que los planos. rota entre -25º y 25º según la posición del ratón card_container.rotationY = (stage.mouseX / stage.stageWidth * 50) -25 card_container.rotationX = (stage.mouseY / stage.stageHeight * 50) - 25
Esto se llama cuando se hace clic en la tarjeta para abrirla:
private function resetPlanesPosition () // el nombre de la función lo dice todo, hace que los planos vuelvan a su posición original creada front_inside.rotationY = back_cover.rotationY = 180 front_cover.rotationY = back_inside.rotationY = front_cover.rotationX = front_inside.rotationX = back_cover.rotationX = back_inside.rotationX = 0
El último paso es, obviamente, representar la ventana gráfica, después de eso pasamos a la clase de documento.
render de función privada (evento: Evento): void // singleRender es una función BasicView que activa el render en ese momento dado. singleRender ();
Ese es el final de la clase. No olvides añadir tus llaves de cierre..
No cambiaremos nada más en la clase CardViewport, así que no dude en obtener la fuente del archivo zip y compararla con la suya..
Este paso es bastante simple, solo necesitamos asociar la tarjeta abierta y cerrar las acciones de la tarjeta al botón. Antes de eso, importemos las siguientes clases en nuestro paquete:
paquete import flash.display.MovieClip; import flash.events.Event; import flash.events.MouseEvent; import flash.media.Sound; // recuerdas el cumpleaños.mp3? se agregará aquí import flash.net.URLRequest;
Una vez más, nada especial, extiende MovieClip y crea un objeto de sonido:
Clase pública Principal extiende MovieClip private var birthday_song: Sound
Aquí hay un pequeño consejo para ustedes: para evitar errores nulos, inicialice sus comandos solo después de que la clase haya sido agregada al escenario. De esta manera, está seguro de que todo lo que intenta acceder está presente..
función pública Main (): void addEventListener (Event.ADDED_TO_STAGE, init)
... y esta es la función que se ejecutará cuando la clase de documento se haya agregado a la etapa:
función privada init (evento: Evento): void removeEventListener (Evento.ADDED_TO_STAGE, init) // ya no lo necesitamos open_mc.label_txt.text = "_! OPEN CARD! _" // Etiqueta el botón open_mc.buttonMode = verdadero; // Establece el botón para que actúe como un botón open_mc.mouseChildren = false; // Deshabilita los eventos del mouse en open_mc children open_mc.addEventListener (MouseEvent.CLICK, openCard) // Agrega un detector de eventos al clic del mouse
Esta función se ejecutará cuando se haga clic en la tarjeta si está cerrada:
función privada openCard (evento: MouseEvent): void open_mc.removeEventListener (MouseEvent.CLICK, openCard); // elimina la escucha abierta viewport.openCard (); // accede a la ventana para abrir la tarjeta (¿recuerdas que la configuramos en público antes?) open_mc.label_txt.text = "_! CLOSE CARD! _" // cambia la etiqueta open_mc.addEventListener (MouseEvent.CLICK, closeCard) // agrega un oyente para cerrar la tarjeta al hacer clic con el mouse birthday_song = new Sound (new URLRequest ("birthday.mp3")); // carga la canción de cumpleaños birthday_song.play (); // toca la canción de cumpleaños
Esto es básicamente lo mismo que openCard (), pero al revés. ;)
función privada closeCard (evento: MouseEvent): void open_mc.removeEventListener (MouseEvent.CLICK, closeCard) viewport.closeCard (); open_mc.label_txt.text = "_! OPEN CARD! _" open_mc.addEventListener (MouseEvent.CLICK, openCard)
Terminado. No hay secretos en esta clase de documentos, es bastante sencillo. No olvides añadir tus llaves de cierre..
Me gustaría verlo evolucionar desde este tutorial tomando algunos de los pequeños consejos que le di, desde ADDED_TO_STAGE hasta el envoltorio displayObject3d, hasta usar una clase de interpolación para rotar y mover un objeto 3D. Toma esta tarjeta y hazla tuya..
¡Feliz cumpleaños Activetuts +! Espero que te haya gustado este tutorial, gracias por leerlo.!