Movimiento fácil y fluido del teclado en AS3 con la clase de entrada

Hay un montón de juegos por ahí con movimientos bruscos e irreales que solo pueden hacer una cosa con su producto: hacer que sea poco atractivo para la audiencia. Pero el movimiento suave no es difícil de lograr, vamos a trabajar!


Vista previa del resultado final

Echemos un vistazo al resultado final en el que trabajaremos:


Paso 1: Configurar el medio ambiente

Este es un tutorial sencillo, por lo que la configuración también será sencilla..

Crear un nuevo proyecto flash de ActionScript 3.0. El tamaño del escenario y el color no importan, solo usa aquello con lo que te sientas cómodo.

Utilizo FlashDevelop para la codificación, pero esto también se puede hacer en cualquier editor de AS, como Flash Pro (o cualquier editor de texto, tal vez Bloc de notas;)). Entonces, crea un archivo de clase, asegúrate de que tu código se parezca al mío; vea abajo. Llamé al mío "Movimiento". (Si está utilizando Flash Pro, consulte esta guía para crear una clase).

 paquete import flash.display.Sprite; Movimiento público de clase extiende Sprite función pública Movimiento (): void 

Una vez que haya terminado, asegúrese de que su Clase esté vinculada al proyecto de Flash como la Clase principal.


Paso 2: Crea el cuadrado y las variables

Entonces, después de vincular la Clase de movimiento a su documento, defina las variables como lo hice a continuación

 paquete import flash.display.Sprite; import flash.events.Event; clase pública Movimiento extiende Sprite // El objeto que moverá la variable privada var: Sprite; // La velocidad máxima privada var _max: Número = 10; // Las variables que se aplicarán para mover el cuadrado privado var dx: Number = 0; privado var dy: número = 0; función pública Movement (): void // Listen for added to stage event addEventListener (Event.ADDED_TO_STAGE, init);  función privada init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Crear un nuevo Sprite y dibujar dentro de un cuadrado cuadrado = nuevo Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (cuadrado); 

Esto es prácticamente todo lo que haremos para crear el objeto. Puedes usar tu propio objeto, pero para este simple tutorial de movimiento usé este cuadrado simple.


Paso 3: Introduciendo la clase Input.as

Hola chicos, esta es la clase Input.as; Entrada.Como clase, estos son los tipos de los que te hablé. ¡Sé amable con ellos! :)

Entonces, ¿de qué se trata esta clase? Básicamente, hace su trabajo de manejo de claves para usted. Agrega una escucha a los eventos ENTER_FRAME, con baja prioridad, y una escucha clave que llena algunos diccionarios privados. También utiliza otra clase para códigos clave. Puedes echar un vistazo al interior y ver por ti mismo cómo está funcionando..

Nota: La clase Input.as no me pertenece. Fue creado por Matthew Bush, quien portó Box2D a Flash.

 // Ejemplo de uso de la clase Input.as // Siempre tiene que inicializarlo así con el parámetro stage. Input.initialize (stage); // Después de la inicialización, puede usar los métodos kd (), kp () o ku (), que // devuelve un valor booleano si se cumplen las condiciones. // Estos métodos aceptan múltiples argumentos, // así que para un evento puedes usar múltiples claves. // Esto hace que sea mucho más fácil dar un impulso de accesibilidad a tu aplicación. //e.g Vea a continuación cuando uso una llamada para detectar la flecha ARRIBA o W para subir. Input.kd ("UP", "W");

Paso 4: Importando las Clases

Así que ahora que está familiarizado con la Clase Input.as, lo vamos a importar a nuestra Clase de Movimiento e inicializarlo..

 paquete import flash.display.Sprite; import flash.events.Event; entrada de importación; clase pública Movimiento extiende Sprite // El objeto que moverá la variable privada var: Sprite; // La velocidad máxima privada var _max: Número = 10; // Las variables que se aplicarán para mover el cuadrado privado var dx: Number = 0; privado var dy: número = 0; función pública Movement (): void // Listen for added to stage event addEventListener (Event.ADDED_TO_STAGE, init);  función privada init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Crear un nuevo Sprite y dibujar dentro de un cuadrado cuadrado = nuevo Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (cuadrado); // Inicializar la clase Input.as con el manejador en el escenario Input.initialize (stage); // Agregar el bucle de actualización addEventListener (Event.ENTER_FRAME, actualizar);  actualización de la función privada (e: Evento): void 

Paso 5: Manejo de las entradas clave

Utilizo un bucle basado en ENTER_FRAME para detectar las entradas clave; abajo esta el refrescar() Método que es la función de controlador para este evento..

 actualización de función privada (e: Evento): void // Key Handler if (Input.kd ("A", "LEFT")) // Mover a la izquierda if (Input.kd ("D", "RIGHT ")) // Mover a la derecha si (! Input.kd (" A "," IZQUIERDA "," D "," DERECHA ")) // Si no se presiona izquierda / derecha si .kd ("W", "UP")) // Move up if (Input.kd ("S", "DOWN")) // Move down if (! Input.kd ("W", "ARRIBA", "S", "ABAJO")) // Si no hay acción arriba / abajo

Paso 6: Explicación de los cálculos - Manejo de la velocidad

Esto es bastante sencillo. Detecta si alguna de las teclas está presionada, luego actúa en consecuencia.

Utilizo mucho el operador ternario: valor = condición? verdadero Falso;
Esto es básicamente una sentencia if que se ha condensado en una sola línea.

Para cada detección de clave, utilizo este método: si el valor es mayor que _max luego ponlo igual a _max; de lo contrario, incremente o disminuya ese valor particular según corresponda. De esta manera, se mantiene dentro de ciertos límites. Simple a la derecha?

A continuación puedes estudiar las condiciones:

 actualización de funciones privadas (e: Evento): void // Key Handler if (Input.kd ("A", "LEFT")) // Mover a la izquierda dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5;  if (Input.kd("D", "RIGHT"))  //Move to the right dx = dx > _max - 0.5? _max: dx + 0.5;  if (! Input.kd ("A", "IZQUIERDA", "D", "DERECHA")) // Si no se presiona izquierda / derecha si (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5;  else  dx = dx > -0.5? 0: dx + 0.5;  if (Input.kd ("W", "UP")) // Move up dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5;  if (Input.kd("S", "DOWN"))  //Move down dy = dy > _max - 0.5? _max: dy + 0.5;  if (! Input.kd ("W", "UP", "S", "DOWN")) // Si no hay acción arriba / abajo si (dy> 0.5) dy = dy < 0.5 ? 0 : dy - 0.5;  else  dy = dy > -0.5? 0: dy + 0,5;  // Después de todo eso, aplícalos al objeto square.x + = dx; square.y + = dy; 

Si no está familiarizado con el operador ternario, tome un pedazo de papel y un bolígrafo y escriba algunos de ellos en el formato "si no"; Es un gran ejercicio para enfrentarse a lo que está sucediendo..

Ten en cuenta que manipulo el dx y dy variables, y solo establece los valores reales de x e y al final. Esto nos ayuda a hacer que el movimiento sea fluido; no se mueve bruscamente cuando modificamos sus valores directamente a lo largo de la función ...

¡Vamos, pruébalo! Mira lo bien que se está moviendo?


Paso 7: Manejo de colisiones de límites

Bueno. Todo está bien, se mueve con fluidez, ¡pero fuera del escenario! A continuación agregué las condiciones de detección de colisión..

 actualización de funciones privadas (e: Evento): void // Key Handler if (Input.kd ("A", "LEFT")) // Mover a la izquierda dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5;  if (Input.kd("D", "RIGHT"))  //Move to the right dx = dx > _max - 0.5? _max: dx + 0.5;  if (! Input.kd ("A", "IZQUIERDA", "D", "DERECHA")) // Si no se presiona izquierda / derecha si (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5;  else  dx = dx > -0.5? 0: dx + 0.5;  if (Input.kd ("W", "UP")) // Move up dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5;  if (Input.kd("S", "DOWN"))  //Move down dy = dy > _max - 0.5? _max: dy + 0.5;  if (! Input.kd ("W", "UP", "S", "DOWN")) // Si no hay acción arriba / abajo si (dy> 0.5) dy = dy < 0.5 ? 0 : dy - 0.5;  else  dy = dy > -0.5? 0: dy + 0,5;  // Detección de límites si (square.x - dx < 0 || square.x + dx + square.width > stage.stageWidth) // x detección de eje if (square.y - dy < 0 || square.y + dy + square.height > stage.stageHeight) // y detección de eje // Después de todo eso, aplíquelos al objeto square.x + = dx; square.y + = dy; 

Busca los límites de una manera más precisa, verificando si los bordes de la plaza tocan los límites (antes de esto, solo estaba verificando el centro de la plaza contra los límites).

Genial. Ahora necesitamos agregar el código para hacer que el cuadrado rebote en los límites. Lo que hago para eso es multiplicar por -1 el valor del eje dx o dy. ¡Pero eso no es suficiente! Si la velocidad es bastante rápida, entonces el cuadrado pasará a través de los márgenes o simplemente se volverá loco. Por lo tanto, antes de multiplicar, necesitamos establecer la x o la y del objeto para que sea el mismo que el límite que cumple..

Así que si x object.x = 0; y luego multiplica la dx por 1.

 // Detección de margen si (square.x - dx < -dx || square.x + dx + square.width > stage.stageWidth) // x detección de eje square.x = square.x - dx < -dx ? 0 : stage.stageWidth - square.width; dx *= -1;  if (square.y - dy < -dy || square.y + dy + square.height > stage.stageHeight) // y detección de eje square.y = square.y - dy < -dy ? 0 : stage.stageHeight - square.height; dy *= -1; 

Pruébalo ahora! ¿Bouncy verdad? :)

Para hacerlo aún mejor, siga experimentando con diferentes valores, como en lugar de multiplicar por -1, intente -0.7 y vea los resultados.


Conclusión

Así que conoció la clase Input.as, aprendió a trabajar con ella y realizó un movimiento fluido en solo unos minutos. Creo que esto cuenta como un gran momento.!

Por favor, deje sus comentarios a continuación y cualquier otra pregunta, con mucho gusto responderé.

Pero si encuentra algún problema, verifique dos veces su código, compárelo con el archivo fuente y luego, si no puede hacerlo funcionar, no dude en enviar una pregunta..