Aprender sobre cinemática lineal

Representar la animación en términos de vectores es intuitivo, pero entender las matemáticas vectoriales es un dolor. En este tutorial, espero aliviar ese dolor y proporcionar una solución a los problemas de animación utilizando una clase escrita Vector2D personalizada. Veremos algunos conceptos fundamentales de la cinemática lineal en el enfoque euleriano: desplazamiento, velocidad y aceleración. Entonces, vamos a construir una aplicación sencilla con él..


Vista previa del resultado final

Echemos un vistazo al resultado final en el que trabajaremos. Haga clic en el panel de Flash a continuación y controle la punta de flecha presionando las cuatro teclas direccionales.


Paso 1: Cantidad de vectores

Todas las cantidades vectoriales tienen dos componentes: magnitud y dirección.


Paso 2: Cambio en la cantidad de vectores

Un cambio en cantidades vectoriales se refiere a uno de estos casos:

  1. Cambio de direccion
  2. Cambio de magnitud
  3. Cambio tanto en magnitud como en dirección.

Paso 3: El desplazamiento como cantidad vectorial

El desplazamiento, la velocidad y la aceleración son cantidades vectoriales. Sus definiciones son las siguientes:

  • Desplazamiento: vector del camino más corto que apunta desde el origen hasta el destino. Defino origen como punto (0, 0) y destino como ubicación de la partícula en relación con este punto. Básicamente, se refiere al sistema de coordenadas cartesianas implementado por Flash.
  • Velocidad - La velocidad es el cambio de desplazamiento en el tiempo.
  • Aceleración: la aceleración es el cambio de velocidad en el tiempo.

La siguiente animación muestra el desplazamiento, tal como lo implementaremos en Flash más adelante..


Paso 4: Velocidad como cantidad vectorial

La velocidad se ilustra en la siguiente animación. La velocidad de la nota es constante, lo que significa que la aceleración está ausente en este escenario. Si la velocidad es cero, el desplazamiento permanecerá constante a lo largo de.


Paso 5: Aceleración como cantidad vectorial

La aceleración se ilustra en la siguiente animación. Nota: la cinemática implica. constante aceleración. Si la aceleración cambia con el tiempo, cae bajo el tema de dinámica. La dinámica es el estudio de las fuerzas que causan que la aceleración varíe con el tiempo. Una de esas fuerzas es la gravedad, y he escrito un post animando que.


Paso 6: Comienza a construir un proyectil

Ahora que ha adquirido una breve comprensión de las cantidades de cinemática lineal y puede relacionarlos con vectores, podemos comenzar a construir nuestra clase de proyectiles. Nos gustaría que el proyectil sea capaz de capturar todas estas cantidades: desplazamiento, velocidad y aceleración, para que pueda ser manipulado en cada cuadro..

A continuación se muestran los datos que registraremos en nuestra clase de proyectiles:

 privada var desplazar: Vector2D; var velo privado: Vector2D; var privado: Vector2D;

Paso 7: Inicializar proyectil

Al iniciar esta clase de proyectil, inicializaremos las variables mencionadas y dibujaremos su representación gráfica..

 función pública Projectile () // draw graphics this.draw (); // init todas las cantidades vectoriales desplazan = nuevo Vector2D (this.x, this.y); velo = nuevo Vector2D (0, 0); acc = nuevo Vector2D (0, 0);  función protegida draw (): void // dibujando la punta de flecha var height: Number = 30; ancho var: Número = 60; graphics.beginFill (0x0000FF); graphics.moveTo (0, 0); graphics.lineTo (ancho / -3, altura / -2); graphics.lineTo (ancho / 2, 0); graphics.lineTo (ancho / -3, altura / 2); graphics.lineTo (0, 0); graphics.endFill (); 

Paso 8: Accesores de cantidades vectoriales

Los siguientes son los accesores de nuestras variables privadas. - desplazar, velo, acc - en la clase de proyectil.

 función pública setDisp (mag: Número, ángulo: Número): void displace.redefine (mag, angle);  función pública getDisp (): Vector2D return desplazar;  función pública setVelo (mag: Number, angle: Number): void velo.redefine (mag, angle);  función pública getVelo (): Vector2D return velo;  función pública setAcc (mag: Number, angle: Number): void acc.redefine (mag, angle);  función pública getAcc (): Vector2D return acc

Paso 9: Actualizadores de cantidades vectoriales

Al actualizar cada fotograma, necesitamos actualizar la velocidad (utilizando la aceleración) y actualizar el desplazamiento (utilizando dicha velocidad). Esto se puede lograr utilizando las siguientes funciones. Para una explicación detallada sobre la adición de Vector, visite este gran post de Daniel Sidhon.

 public function applyVelo (): void this.displace = this.displace.add (velo);  public function applyAcc (): void this.velo = this.velo.add (acc);  // actualizar la posición del sprite por desplazamiento. función pública animate (): void this.x = this.displace.x; this.y = this.displace.y; 

Paso 10: Actualizador para la Orientación de Sprite

También necesitaremos actualizar la orientación del Sprite. Esto se puede lograr a través de la rotación propiedad de Sprite.

 función pública orientar (): void this.rotation = Math2.degreeOf (velo.getAngle ()); 

También he implementado un Matemáticas2 clase estática, en la que he escrito una función para convertir fácilmente hacia adelante y hacia atrás desde las unidades de grados y radianes del ángulo.

 función estática pública radianOf (deg: Number): Number return deg / 180 * Math.PI;  grado de función estática públicaOf (rad: Número): Número return rad / Math.PI * 180; 

Paso 11: La clase principal

Ahora que hemos establecido nuestra clase de Proyectil y Matemáticas2, podemos comenzar a codificar nuestra clase Principal. También necesitaremos una clase Vector2D aunque no se incluye una explicación completa debido al artículo mencionado anteriormente sobre Vectores por Daniel Sidhon. Asumo que los lectores entienden la clase Vector2D después de leerla. Sin embargo, si se necesitan aclaraciones, indíqueme sus consultas.

En primer lugar, necesitamos conocer las variables privadas de esta clase..

 var var privado: proyectil; // keypress flags private var UP: Boolean = false; var privado ABAJO: Booleano = falso; var privado IZQUIERDA: Booleano = falso; var privado DERECHA: Booleano = falso;

Paso 12: Inicializando Main

Tras la inicialización de Main, función en eso se pondrá en marcha. Esta función creará un nuevo proyectil y establecerá su velocidad inicial. Luego, se asignarán oyentes a los eventos..

 función privada init (e: Event = null): void removeEventListener (Event.ADDED_TO_STAGE, init); // punto de entrada b1 = nuevo proyectil (); stage.addChild (b1); // ajuste de la velocidad inicial b1.setVelo (5, Math2.radianOf (30)); // configurando escuchas de eventos b1.addEventListener (Event.ENTER_FRAME, proj_enterFrame); stage.addEventListener (KeyboardEvent.KEY_DOWN, handle_keyDown); stage.addEventListener (KeyboardEvent.KEY_UP, handle_keyUp); 

Paso 13: Oyentes del evento de teclado

He definido el control del usuario como pulsaciones de las teclas de flecha Arriba, Izquierda, Abajo e Izquierda. Al presionar y soltar esas teclas, las variables de marca de Main (Paso 11) se volverán verdaderas y falsas. Sobre la base de estas banderas, las cantidades de vectores se manipularán en cada fotograma. Tenga en cuenta que también he dividido los controles en manipuladores de eje horizontal y vertical.

 función privada handle_keyDown (e: KeyboardEvent): void if (e.keyCode == Keyboard.UP) UP = true; else if (e.keyCode == Keyboard.DOWN) DOWN = true; if (e.keyCode == Keyboard.LEFT) LEFT = true; else if ((e.keyCode == Keyboard.RIGHT) RIGHT = true;  private function handle_keyUp (e: KeyboardEvent): void if (e.keyCode == Keyboard.UP) UP = false; else if (e.keyCode == Keyboard.DOWN) DOWN = falso; if (e.keyCode == Keyboard.LEFT) LEFT = false; else if ((e.keyCode == Keyboard.RIGHT) RIGHT = false; 

Paso 14: Oyentes del evento EnterFrame

Al actualizar cada cuadro se ejecutará el siguiente código. Es largo, pero no te preocupes; solo sigue leyendo.

 función privada proj_enterFrame (e: Evento): void // define acceleration var accMag: Number = 0.1; if (UP) b1.setAcc (accMag, Math2.radianOf (-90)); b1.applyAcc ();  else if (DOWN) b1.setAcc (accMag, Math2.radianOf (90)); b1.applyAcc ();  if (IZQUIERDA) b1.setAcc (accMag, Math2.radianOf (180)); b1.applyAcc ();  else if (RIGHT) b1.setAcc (accMag, Math2.radianOf (0)); b1.applyAcc ();  // desacelerar cuando se presiona nothng para simular la fricción. if (ARRIBA + ABAJO + IZQUIERDA + DERECHA == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); if (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc ();  b1.applyVelo (); // restringiendo el sprite a los bordes de la etapa b1.getDisp (). x = Math2.implementBound (0, stage.stageWidth, b1.getDisp (). x); b1.getDisp (). y = Math2.implementBound (0, stage.stageHeight, b1.getDisp (). y); b1.animate (); b1.orient (); 

Paso 15: Actualizar Motion

La actualización de la moción se debe hacer en el siguiente orden:

  1. Definir nueva aceleración según la pulsación del usuario..
  2. Usando la aceleración, actualizar la velocidad actual.
  3. Usando la velocidad actual, actualice el desplazamiento actual.
  4. Refine el desplazamiento para mantener el objeto dentro de los límites..

He resaltado los códigos para facilitar la identificación de estos pasos..

 función privada proj_enterFrame (e: Evento): void // define acceleration var accMag: Number = 0.1; if (UP) b1.setAcc (accMag, Math2.radianOf (-90)); b1.applyAcc ();  else if (DOWN) b1.setAcc (accMag, Math2.radianOf (90)); b1.applyAcc ();  if (IZQUIERDA) b1.setAcc (accMag, Math2.radianOf (180)); b1.applyAcc ();  else if (RIGHT) b1.setAcc (accMag, Math2.radianOf (0)); b1.applyAcc ();  // desacelerar ya que no se presiona nada para simular la fricción. if (ARRIBA + ABAJO + IZQUIERDA + DERECHA == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); if (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc ();  b1.applyVelo (); // restringiendo el sprite a los bordes del escenario b1.getDisp (). x = Math2.implementBound (0, stage.stageWidth, b1.getDisp (). x); b1.getDisp (). y = Math2.implementBound (0, stage.stageHeight, b1.getDisp (). y); b1.animate (); b1.orient (); 

Paso 16: Ralentizando el movimiento

Puede encontrar que hay otras funciones entre estos códigos resaltados. ¿Qué son? Una es aplicar otro vector para ralentizar nuestro proyectil, ya que el usuario no presiona ninguna tecla. Esto se aplica antes de añadir velocidad a nuestro desplazamiento..

 // desacelerar a medida que se pulsa nothng para simular la fricción. if (ARRIBA + ABAJO + IZQUIERDA + DERECHA == 0) var currentVeloMag: Number = b1.getVelo (). getMagnitude (); var currentVeloAng: Number = b1.getVelo (). getAngle (); if (currentVeloMag> 1) b1.setAcc (accMag * -1, currentVeloAng); b1.applyAcc (); 

Paso 17: Mantente dentro

El siguiente es restringir nuestro proyectil para que permanezca siempre en el escenario, de lo contrario saldrá de la pantalla. Otra vez, implementarBound es una función que he incluido en la clase estática Math2. Dado un límite superior, un límite inferior y un valor aleatorio, implementarBound devolverá un valor que está dentro de los límites.

Después de aplicar estas restricciones a nuestro desplazamiento (y solo después de eso), actualizamos la posición del Sprite con este valor de desplazamiento.

 // restringiendo el sprite a los bordes del escenario b1.getDisp (). x = Math2.implementBound (0, stage.stageWidth, b1.getDisp (). x); b1.getDisp (). y = Math2.implementBound (0, stage.stageHeight, b1.getDisp (). y);

Paso 18: Orientar Sprite

Antes de dejar este sprite tal como está, deberíamos orientarlo de modo que siempre apunte a la posición que está encabezando usando la función orientar.


Paso 19: ponte en marcha!

Ahora todo está listo para ir. A medida que inicie esta pieza presionando Ctrl + Intro, verá una flecha que disminuye gradualmente a medida que avanza en diagonal hacia abajo en la pantalla. Presione las cuatro teclas de dirección para mover la flecha. No te preocupes por perder tu flecha; se mantendrá dentro de su vista.


Conclusión

Este artículo debería familiarizarte con el uso de vectores para animar el movimiento. Una vez que haya entendido la cinemática, continúe leyendo mi publicación sobre dinámica. Déjame saber como va. Terima Kasih.