Este tutorial será guía Usted a través de la adición de misiles homing mortales al arsenal de su próximo juego..
Echemos un vistazo al resultado final en el que trabajaremos:
Cree un nuevo conjunto de documentos Flash para ActionScript 3.0. Usaré las dimensiones de 600x400 y una velocidad de fotogramas de 30 FPS. Guarde el archivo con un nombre de su elección.
Además de la FLA, también necesitamos crear una clase de documento. Cree un nuevo archivo de Actionscript y agregue este código:
paquete import flash.display.Sprite; clase pública principal extiende Sprite función pública principal ()
Guarde este archivo en el mismo directorio que nuestro FLA. NómbreloMain.as.
Para compilar el código de la Principal Clase, tenemos que vincularlo con la FLA. En la jaPropiedades Panel de la FLA, al lado de.Clase, ingrese el nombre de la clase de documento, en este caso, Principal.
Luego, guarda los cambios en la FLA..
Necesitamos un gráfico de misiles para mostrar al disparar. Puede importar un mapa de bits o dibujar una forma allí mismo en Flash. Estaré usando una pequeña forma en este ejemplo.
Lo importante aquí es que tienes que hacer que el misil apunte hacia la derecha, ya que ese es el punto de origen de la rotación. Entonces, 0 ° significa apuntar directamente hacia la derecha, -90 ° significa hacia arriba, 90 ° significa hacia abajo y 180 ° apunta hacia la izquierda. Más adelante tendremos que girar el misil de acuerdo con su dirección..
Una vez que tenga el gráfico del misil, selecciónelo y presione F8 para crear un clip de película. Llámalo "Misil", asegúrate de que el Punto de registro está en el centro y marca la casilla de verificación "Exportar para ActionScript".
Terminarás con un clip de película de misiles en la biblioteca.
Si tiene una instancia de Misil en el escenario, elimínela. Estaremos agregando el MovieClip de Missile por código.
Lo primero que debe saber un misil homing es dónde se encuentra el objetivo. Vamos a establecer la rotación del misil de acuerdo con la posición del cursor del mouse primero. Vamos a trabajar con el enterFrame Evento para una actualización de rotación constante..
Agrega un Misil En el escenario, lo coloco en el centro (300, 200). Luego calcule la distancia desde el misil hasta el cursor del mouse (lo estoy almacenando en variables targetX y objetivo). Finalmente, el ángulo del misil será el arco tangente de ambos puntos (targetX, objetivo). El resultado que obtendrás será en radianes, pero la rotación funciona en grados, por lo que tendrás que hacer la conversión multiplicando por 180 / Pi. (Para ver por qué, revisa este artículo.)
import flash.events.Event; clase pública Main extiende Sprite private var missile: Missile = new Missile (); función pública Main () addChild (misil); misil.x = 300; misil.y = 200; addEventListener (Event.ENTER_FRAME, playGame); función privada playGame (evento: Evento): void var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 / Math.PI;
(No estoy seguro de que Math.atan2 ()
¿es para? Echa un vistazo a este artículo sobre trigonometría..
Si tu Publicar (Ctrl + Enter) el documento en este punto, debería obtener algo como esto:
Mueve el ratón cerca del misil para verlo girar.
Tenemos la rotación, ahora necesitamos el movimiento. El misil tiene que buscar el objetivo, no importa si es un objetivo fijo o en movimiento. Lo que haremos es calcular el movimiento de acuerdo con la rotación actual del misil. Fijemos un valor para la velocidad, y hagamos la persecución del misil después del cursor del mouse.
Incluiremos un par de nuevas variables para calcular la velocidad (vx, vy). Cuando el misil apunta hacia la derecha, su ángulo es inferior a 90 ° y superior a -90 °, por lo que siempre es inferior al valor absoluto de 90 °. Cuando apunta a la izquierda, su ángulo tiene un valor absoluto superior a 90 °. Esto determinará vx de acuerdo a velocidad, entonces vy será la diferencia de velocidad y vx.
velocidad de var privado: int = 10; función pública Main () addChild (misil); misil.x = 300; misil.y = 200; addEventListener (Event.ENTER_FRAME, playGame); función privada playGame (evento: Evento): void var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 / Math.PI; // La velocidad en x es relativa al ángulo, cuando es de 90 ° o -90 °, vx debe ser 0. var vx: Número = velocidad * (90 - Math.abs (missile.rotation)) / 90; var vy: Number; // Velocity en y es la diferencia entre speed y vx. if (missile.rotation) < 0) vy = -speed + Math.abs(vx);//Going upwards. else vy = speed - Math.abs(vx);//Going downwards. missile.x += vx; missile.y += vy;
Obtendrás un misil persiguiendo tu cursor..
Puedes usar una velocidad diferente si quieres..
Los misiles no salen del aire, son lanzados desde los lanzadores de misiles. Hagamos un clip de película que represente un cañón (usaré un rectángulo simple) y lo nombraremos Cañón. Voy a añadir un Cañón instancia por código, así que voy a mantener el escenario vacío.
Ahora, en lugar de agregar un misil, solo voy a agregar un cañón, y se agregará un misil en la posición del cañón cuando haga clic en el escenario. Agregaremos un Booleano para verificar si el misil ha sido disparado, y también una nueva función para disparar después del clic..
import flash.events.MouseEvent; clase pública Main extiende Sprite private var missile: Missile = new Missile (); velocidad de var privado: int = 10; cañón var privado: Cañón = cañón nuevo (); private var missileOut: Boolean = false; // ¿Se ha disparado el misil? Función pública Main () addChild (cañón); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, disparar); función privada playGame (evento: Evento): void if (missileOut) var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; missile.rotation = Math.atan2 (targetY, targetX) * 180 / Math.PI; var vx: Number = speed * (90 - Math.abs (missile.rotation)) / 90; var vy: Número; if (missile.rotation) < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy; private function shoot(event:MouseEvent):void if (!missileOut) addChild(missile); swapChildren(missile, cannon);//missile will come out from behind cannon missileOut = true; missile.x = cannon.x; missile.y = cannon.y;
Esto es lo que obtendrás:
Esto no se ve bien. Tenemos que hacer que el cañón gire también, o forzar el misil para que vaya hacia arriba justo después de ser disparado. Ya que la opción # 1 es el enfoque más fácil, tomaremos la opción # 2.
Si el cañón es vertical, esperaríamos que el misil se lanzara hacia arriba y luego se encaminara hacia su objetivo. El enfoque que usaré para lograr esto es darle al misil un ángulo de inicio de -90 ° (apuntando hacia arriba), y rotar suavemente para ir al camino del cursor del mouse. Añadiremos un facilitar Variable para determinar la suavidad o nitidez de la rotación. Luego, crearemos otra variable para realizar un seguimiento de la rotación real que apunta directamente al objetivo, mientras que la rotación del misil cambiará de acuerdo con la facilitar nosotros fijamos (facilitar = 1 se comportará como antes, cualquier cosa superior hará un giro más suave).
Dado que la mitad de los valores de rotación son negativos, en algunos casos tendremos que calcularlos contra 360 para obtener la diferencia real entre el ángulo objetivo y la rotación del misil.
facilidad de var privado: int = 10; Función pública Main () addChild (cañón); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, disparar); función privada playGame (evento: Evento): void if (missileOut) var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; rotación de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotación - missile.rotation)> 180) si (rotación> 0 y& missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 y rotación < 0) missile.rotation += (360 - rotation + missile.rotation) / ease; else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy; private function shoot(event:MouseEvent):void if (!missileOut) addChild(missile); swapChildren(missile, cannon);//missile will come out from behind cannon missileOut = true; missile.x = cannon.x; missile.y = cannon.y; missile.rotation = -90;//missile will start pointing upwards
Echale un vistazo:
Observe lo que sucede cuando saca el mouse del SWF y cómo esto es diferente del ejemplo anterior..
junto al Misil Clip de película, necesitamos una animación de explosión. En mi caso, haré un MovieClip separado con una simple interpolación de un círculo que se expande. Lo estoy exportando como Explosión. prensa O para seleccionar el Herramienta ovalada, y espera Cambio Mientras dibuja el óvalo para obtener un círculo..
Para un efecto visual más agradable, pondré el círculo dentro de otro clip de película propio y le daré un Bisel Filtro para obtener un color más oscuro en la parte inferior y un color más claro en la parte superior. A continuación, pasaré al cuadro 10 y presionaré. F6 para crear un Fotograma clave, luego haga clic derecho entre el cuadro 1 y el 10 y cree un Tween clásico. De vuelta en el cuadro 10, presione Q para seleccionar el Herramienta de transformación gratuita y ampliar el circulo.
Entonces, crea otro Tween clásico al cuadro 20, añadiré un Difuminar efecto de filtro.
Finalmente, haz que desaparezca en un último Classic Tween para encuadrar 30 con un Alfa efecto de color va a 0.
La animación de la explosión debe eliminarse una vez que finalice, o se repetirá indefinidamente. Agrega una nueva capa y presiona F6 en el último cuadro, luego presione F9 para abrir el Comportamiento panel, y añadir este código:
detener();
parent.removeChild (this);
Esto hará que el Explosión instancia de quitarse a sí mismo después de la animación se realiza.
Ahora cuando el misil Encuentra el cursor, lo reemplazaremos con un Explosión ejemplo. Solo necesitamos agregar un nuevo condicional en el jugar un juego()
función.
función privada playGame (evento: Evento): void if (missileOut) if (missile.hitTestPoint (mouseX, mouseY)) var explosion: Explosion = new Explosion (); addChild (explosión); explosion.x = missile.x; explosion.y = missile.y; removeChild (misil); missileOut = falso; else var targetX: int = mouseX - missile.x; var targetY: int = mouseY - missile.y; rotación de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotación - missile.rotation)> 180) si (rotación> 0 y& missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 y rotación < 0) missile.rotation += (360 - rotation + missile.rotation) / ease; else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy;
Echar un vistazo:
Perseguir el cursor del mouse fue entretenido, pero no tiene sentido en un juego; Necesitamos hacer un objetivo. Voy a dibujar un montón de círculos para formar un Objetivo Clip de pelicula.
Ahora agregaremos un Objetivo Instancia para que el misil tenga un objetivo más tangible. Así que reemplazaremos cualquier referencia del cursor del mouse para la posición del objetivo. Además, no probaremos un punto de acceso, sino un objeto..
privada var target: Target = new Target (); Función pública Main () addChild (cañón); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, disparar); addChild (target); target.x = 550; target.y = 50; función privada playGame (evento: Evento): void if (missileOut) if (missile.hitTestObject (target)) var explosion: Explosion = new Explosion (); addChild (explosión); explosion.x = missile.x; explosion.y = missile.y; removeChild (misil); missileOut = falso; else var targetX: int = target.x - missile.x; var targetY: int = target.y - missile.y; rotación de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotación - missile.rotation)> 180) si (rotación> 0 y& missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 y rotación < 0) missile.rotation += (360 - rotation + missile.rotation) / ease; else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy; private function shoot(event:MouseEvent):void if (!missileOut) addChild(missile); swapChildren(missile, cannon); //missile will come out from behind cannon missileOut = true; missile.x = cannon.x; missile.y = cannon.y; missile.rotation = -90;//missile will start pointing upwards
los hitTestObject ()
el método en realidad solo comprueba si hay una superposición entre los cuadros delimitadores de los dos objetos (es decir, los cuadros azules que aparecen al hacer clic en una instancia del objeto en el escenario), así que tenga cuidado con eso; No es la detección de colisiones de píxeles perfectos. Sin embargo, hace el trabajo bien aquí..
Puedes intentar colocar el objetivo en diferentes ubicaciones, así como el cañón..
Ya vimos que el misil perseguirá un objetivo en movimiento, como el cursor del mouse, así que ahora hagamos el Objetivo caso mover un poco.
Esto no es física realista, solo voy a hacer que el objetivo rebote verticalmente. Elegiré un punto de referencia como el nivel del suelo y agregaré un valor de gravedad para afectar al objetivo. Y para hacerlo más dinámico, aumentaré la velocidad del misil a 15..
piso var privado: int = 385; gravedad privada var: Número = 0.5; private var targetVY: Number = 0; // Velocidad vertical actual de la función pública de destino Main () addChild (cannon); cannon.x = 50; cannon.y = 380; addEventListener (Event.ENTER_FRAME, playGame); stage.addEventListener (MouseEvent.CLICK, disparar); addChild (target); target.x = 550; target.y = 50; función privada playGame (evento: Evento): void if (missileOut) if (missile.hitTestObject (target)) var explosion: Explosion = new Explosion (); addChild (explosión); explosion.x = missile.x; explosion.y = missile.y; removeChild (misil); missileOut = falso; else var targetX: int = target.x - missile.x; var targetY: int = target.y - missile.y; rotación de var: int = Math.atan2 (targetY, targetX) * 180 / Math.PI; if (Math.abs (rotación - missile.rotation)> 180) si (rotación> 0 y& missile.rotation < 0) missile.rotation -= (360 - rotation + missile.rotation) / ease; else if (missile.rotation > 0 y rotación < 0) missile.rotation += (360 - rotation + missile.rotation) / ease; else if (rotation < missile.rotation) missile.rotation -= Math.abs(missile.rotation - rotation) / ease; else missile.rotation += Math.abs(rotation - missile.rotation) / ease; var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90; var vy:Number; if (missile.rotation < 0) vy = -speed + Math.abs(vx); else vy = speed - Math.abs(vx); missile.x += vx; missile.y += vy; targetVY += gravity; target.y += targetVY; if (target.y > piso) target.y = piso; targetVY = -18;
Si tu Publicar esto ahora, deberías estar consiguiendo un blanco móvil.
Si desea un misil homing preciso o si prefiere una animación suave, puede obtener ambos resultados basados en este ejemplo. Ahora tienes una nueva arma para agregar a tu arsenal, tal vez podrías intentar hacer un juego parecido a un gusano, o incluso usar el algoritmo en otra cosa que no sea un misil, como un extraño mosquito que sigue a tu personaje..
Espero que hayas encontrado este tutorial útil. Gracias por leer!