En Implementar un tanque en una zona de guerra isométrica, aprendiste cómo hacer que un objeto gire para enfrentar al puntero y avanzar hacia una ubicación al hacer clic. En este Consejo rápido, analizaremos las matemáticas que se encuentran detrás: trigonometría.
Este es el resultado final de mi tutorial anterior. Hace uso de los principios de trigonometría que cubriremos en este Consejo rápido:
Mueva el mouse para que la torreta apunte hacia ella y haga clic en cualquier lugar para que el tanque conduzca hasta ese punto..
Cualquier programador, especialmente cualquier programador de juegos, enfrenta la necesidad de mover objetos en la pantalla tarde o temprano. Es una tarea simple si necesita mover un objeto en una dirección, por ejemplo a lo largo del eje x o y. Pero suponga que desea hacer que un objeto siga al puntero del mouse donde sea que lo mueva, o cree un juego de carreras en el que controle la aceleración de un automóvil presionando la tecla de flecha hacia arriba y use las flechas izquierda y derecha para dirigir.
Supongamos que presiona la tecla de flecha derecha una vez y agrega 10 grados a las propiedades de rotación de su automóvil, pero aún desea que el automóvil avance (es decir, acelere) cuando presiona una tecla de flecha hacia arriba, incluso si un automóvil se gira hacia la parte inferior la pantalla o un lado izquierdo o derecho, etc., y no desea que se vea como si se estuviera deslizando hacia los lados. Entonces, ¿cómo harías eso? Ahí es donde un poco de trigonometría ayuda.!
Para aquellos que son buenos en matemáticas no será un problema, pero hay muchas personas que no lo entienden en absoluto, o incluso que le tienen miedo. Intentaré descomponerlo lo más claramente posible en este Consejo rápido.
Al principio, recordemos el sistema de coordenadas cartesiano. ¿Suena complicado? Si es así, mira la imagen de abajo y estoy seguro de que te resultará familiar:
Tiene ejes X e Y; Puedes ver claramente donde X e Y son positivos y negativos. Cuando se trata de coordenadas en Flash, la situación es ligeramente diferente. Flash también tiene su sistema de coordenadas, pero se parece al sistema cartesiano al revés:
También tiene los ejes X e Y y el punto de origen, la única diferencia es que el eje Y es positivo abajo el eje X.
Cualquier símbolo creado en Flash tiene su propio sistema de coordenadas incorporado. Si crea un nuevo símbolo, ya sea un clip de película o un botón, es posible que vea una propiedad de "punto de registro" en el cuadro de diálogo de creación de símbolo. ¿Qué es? El punto de registro es un punto de origen de un símbolo. El punto alrededor del cual girará el objeto si cambia su propiedad de rotación.
Nota: el punto de origen de la instancia del escenario está en su esquina superior izquierda. Esto significa que todos los puntos en el escenario tienen coordenadas X e Y positivas.
En este Consejo rápido veremos las tres funciones trigonométricas más utilizadas en Flash; Seno, coseno y atan2. Algunas personas pueden preguntar, ¿cómo podemos usar estas funciones en Flash? Bueno, veamos algunos ejemplos prácticos y entendamos por qué los necesitamos y cómo pueden hacer nuestra vida un poco más fácil..
Calculemos el ángulo entre dos puntos. Cree un nuevo archivo de Flash (ActionScript 3.0). Seleccione el primer fotograma de la línea de tiempo y presione F9 para abrir un Panel de acciones.
En este punto vamos a hacer algo simple. Solo escribe esto en el Panel de Acciones:
stage.addEventListener (MouseEvent.CLICK, CalculateAngle) función de cálculo de ángulos (e: MouseEvent): void trace ("stage X" + e.stageX); traza ("etapa Y" + e.stageY)
Esto nos dará la posición del puntero del mouse cada vez que hagamos clic en el escenario. No es exactamente fascinante, ¿verdad??
Ok, ahora suponga que quiere "decirle" a algún objeto las coordenadas del puntero de su mouse en relación con este objeto, luego muéstrele la dirección en la que debe viajar para alcanzar la posición del puntero.
Cierre el Panel de acciones y vaya a Insertar> Nuevo símbolo o simplemente presione Ctrl + F8.
Asígnele cualquier nombre (o deje un nombre predeterminado) y presione OK. El pequeño punto de mira en el centro de la pantalla es el punto de registro del símbolo o su punto de origen. Estas serán las posiciones X e Y del objeto. Ahora agarra la herramienta Oval (tecla O) y dibuja un círculo (con la tecla Shift presionada) en cualquier lugar de la pantalla.
Haga clic en el círculo para seleccionarlo y vaya a su panel Propiedades> Posición y tamaño. Para el tipo W (ancho) en 20, lo mismo para H (altura) y para las posiciones X e Y en (-10). Esto hará que el círculo sea de 20x20 px y lo centre exactamente en el punto de registro. Ahora salga del modo de edición de símbolos (haga clic en Escena 1 arriba), tome este símbolo en su biblioteca y simplemente arrástrelo al escenario (en cualquier lugar, obtendremos su posición dinámicamente más adelante). Una vez que tu objeto esté en el escenario, dale un nombre de instancia de mCircle
.
Ahora queremos calcular la dirección desde la posición Y y X de nuestro círculo hasta la posición Y y X del puntero del mouse. La línea roja en la imagen de abajo es la dirección que necesitamos saber. Se puede encontrar utilizando un estándar. Math.atan2 ()
función.
Hagámoslo ahora. Elimine las declaraciones de "seguimiento" del código y cree una nueva variable en su lugar. Luego traza esta variable para ver lo que obtienes:
stage.addEventListener (MouseEvent.CLICK, CalculateAngle); var myAtan2: Number; function calculaAngle (e: MouseEvent): void myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x); traza (myAtan2);
Tenga en cuenta que e.stageY - mCircle.y
es el vertical distancia del ratón al círculo, y e.stageX - mCircle.x
es el Distancia horizontal.
Obtendrás estos tipos de números en el panel de salida:
-2.419017353128333 3.0118660246925346 2.5704959452340326 1.6726588917423932 1.0238847495551058 0.21368467849101092
Estos son los ángulos relativos (entre la línea del eje X y la línea roja) en radianes. ¿Por qué no grados? Bueno, Flash usa radianes para calcular el seno y el coseno, pero si quieres saber qué son estos ángulos en grados, siempre puedes multiplicar "myAtan2" por 180 y dividirlo por Matemáticas.PI
. Me gusta esto:
trace (myAtan2 * 180 / Math.PI) // te da el ángulo en grados;
Editor: Como recurso adicional, aquí hay un gran conjunto de funciones para la conversión de grados / radianes. Se almacena como un fragmento en snipplr.com, el último miembro de la red de Envato!
Como sabemos el ángulo entre dos puntos, ahora podemos calcular cuántos píxeles debemos agregar a las propiedades X e Y del círculo en cada cuadro hasta que llegue al punto de clic. Examinemos lo que necesitamos saber aquí:
La línea azul es el coseno del ángulo, y la naranja es el seno del ángulo. En otras palabras,
En lugar de explicar cómo En el trabajo de seno y coseno, demostraré cómo usarlos con algunos ejemplos prácticos. Sinceramente hablando, el seno y el coseno son las relaciones entre Y y X en nuestro ángulo..
Imagina que el ángulo entre dos objetos es de 45 grados. En este caso, la relación entre seno y coseno es 1: 1 (ver la imagen a continuación), lo que significa que tenemos que aumentar las propiedades X e Y de nuestro círculo en la misma cantidad cada fotograma para llegar al destino. Por ejemplo, tiene que agregar 5 píxeles a X y 5 píxeles a Y cada fotograma.
En este diagrama, el ángulo ha cambiado y la relación entre seno y coseno también ha cambiado. Se trata de 1: 2 ahora.
En este caso, debemos agregar el doble de píxeles a la propiedad X de nuestro círculo que a Y. E.g. X + = 10, Y + = 5;
Probablemente preguntará por qué necesitamos seno y coseno si ya conocemos las coordenadas del punto de clic. Solo podemos mover nuestro mCircle
a ellos de inmediato? Bien, podría haberlo hecho de esta manera si quisiera que su círculo (o cualquier otro objeto) se "teletransporte" en las coordenadas de un punto de clic tan pronto como se produzca el clic. Pero, ¿qué sucede si desea que se mueva gradualmente en la dirección del clic? Para hacer esto necesita agregar una cantidad particular de píxeles a sus propiedades X e Y, por ejemplo, cada fotograma o cada segundo.
Calculemos ahora cuántos píxeles debemos agregar a sus propiedades X e Y según el seno y el coseno del ángulo entre nuestro objeto y un punto de clic. Recuerda, Flash conoce el ángulo entre ellos a partir de esta operación:
myAtan2 = Math.atan2 (e.stageY - mCircle.y, e.stageX - mCircle.x);
Para ello deberíamos actualizar un poco nuestro código..
stage.addEventListener (MouseEvent.CLICK, CalculateAngle); // 2 es la cantidad máxima de píxeles que se pueden agregar a las propiedades X e Y de los objetos en cada cuadro // puede usar cualquier número que desee var moveAmount: Number = 2; var myAtan2: Number; var mouseClickX: Number; var mouseClickY: Número; function calculaAngle (e: MouseEvent): void mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x); addEventListener (Event.ENTER_FRAME, moveTheCircle); función moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount;
Note lo que he hecho aquí: promoví todas mis variables fuera de cualquier función, porque ahora tengo más de una función y quiero que estas variables sean accesibles desde todas las funciones..
var moveAmount: Number = 2; var myAtan2: Number; var mouseClickX: Number; var mouseClickY: Número;
El escenario tiene un detector de eventos para clics del mouse, por lo que cuando se produce el clic, el método calcularAngle ()
se llama y las siguientes variables son instanciadas:
mouseClickX = e.stageX; mouseClickY = e.stageY; myAtan2 = Math.atan2 (mouseClickY - mCircle.y, mouseClickX - mCircle.x);
Esta función también agrega un detector de eventos para ingresar un fotograma al escenario, que llama al moveTheCircle ()
metodo cada cuadro.
addEventListener (Event.ENTER_FRAME, moveTheCircle);
Ahora, vamos a romper nuestra moveTheCircle ()
método en sí mismo. Por ahora solo hace dos cosas:
mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount;
Como puede ver, la primera línea calcula cuántos píxeles debería agregar a la propiedad X y la segunda trata con Y. Déjeme explicarle. Math.cos encuentra el coseno (propiedad x) del ángulo "myAtan2", Math.sin hace lo mismo con su seno (propiedad y). Si nuestro ángulo myAtan2 es igual a aproximadamente 0.785 radianes (45 grados), el coseno y el seno serán iguales a aproximadamente 0.707 ... Puedes usar una calculadora para verificarlo.
Un cálculo simple mostrará cuántos píxeles agregará el código anterior a las propiedades X e Y de nuestro objeto si el ángulo es de 45 grados.
Coseno (45 grados) = 0.707 * 2 = 1.414; Seno (45 grados) = 0.707 * 2 = 1.414; por lo que el código resolverá estos resultados: mCircle.x + = 1.414 píxeles; mCircle.y + = 1.414 píxeles;
Si el ángulo, por ejemplo, es. 60 grados entonces los resultados serían así:
Coseno (60 grados) = 0.5 * 2 = 1; Seno (60 grados) = 0.866 * 2 = 1.732; Y el código funcionaría de esta manera: mCircle.x + = 1 píxel; mCircle.y + = 1.732 píxeles;
Bueno, ya casi terminamos. Pero todavía hay un pequeño problema con nuestro código. Es posible que haya notado que nuestro objeto nunca se detiene, incluso si alcanza el punto de clic que sigue moviéndose. Podemos solucionar este problema muy fácilmente. A medida que nuestro objeto se mueve hacia el punto de clic, la distancia entre ellos se acorta, por lo que la absoluto El valor de la distancia también disminuye. Podemos seguirlo así:
trace (Math.abs (mCircle.x - mouseClickX)); trace (Math.abs (mCircle.y - mouseClickY));
(Math.abs ()
convierte los números negativos en positivos simplemente multiplicándolos por -1. No le hace nada a los números que ya son positivos.)
No es necesario que agregue esta declaración de rastreo a su código, lo puse aquí para mostrarle la forma en que puede ver el valor absoluto. En este caso, ambos valores absolutos son menores que 3 cuando el objeto alcanza el punto de clic. Entonces lo que necesitamos ahora es agregar uno Si
declaración dentro de nuestro moveTheCircle ()
función.
function moveTheCircle (e: Event): void mCircle.x + = Math.cos (myAtan2) * moveAmount; mCircle.y + = Math.sin (myAtan2) * moveAmount; // Compruebe si las distancias horizontales y verticales desde el círculo hasta el punto del mouse están muy cerca si (Math.abs (mCircle.x - mouseClickX) < 3 && Math.abs(mCircle.y - mouseClickY) < 3) removeEventListener(Event.ENTER_FRAME, moveTheCircle);
Cuando el valor absoluto se sitúa por debajo de 3, se elimina el detector de trama. Debemos verificar los valores absolutos de X e Y porque uno de ellos puede llegar a 3, incluso cuando el segundo no lo ha hecho. Esto significa que los objetos podrían detenerse así:
La imagen de arriba muestra la versión en la que solo se comprueba el valor absoluto de X. El valor absoluto de la distancia X ya es menor que 3, por lo que dejó de prestar atención al valor Y.
Bueno, eso es todo. Espero que este Consejo rápido le ayude a comprender la trigonometría utilizada en el desarrollo de Flash :)