Este tutorial es una traducción y adaptación al español por Julio Laguna, Autorizada por el autor , del tutorial de TONYPA Tile Based Games sujeta a una licencia Creative Commons.
Creative Commons License

Juegos basados en tiles para Flash.
por Julio Laguna (Traducción) - Originalmente escrito en Inglés por TONYPA

1 Juegos basados en "tiles" para Flash.

1.25 Heroe con movimiento giratorio.

Tras varios capítulos con lo mismo, imagino que habrá observado como el protagonista de nuestro juego hace tiempo que aprendió a caminar, a caminar recto. Este personaje puede andar recto hacia la izquierda, o recto hacia la derecha. incluso hacia arriba y hacia abajo en los juegos de vista superior, pero NO en ángulo. Así que vamos a trabajar!, a trabajar para permitir a los jugadores de las entregas de videojuegos que creemos, la capacidad de girar o rotar al heroe en cualquier dirección. Juegue con este ejemplo. Utilice las teclas a izquierda y derecha para girar al heroe y las flechas arriba y abajo para desplazarse:



Para este tipo de juego, tan solo nos hace falta una vista del heroe en el movieClip "char". Puede deshacerse de todos los fotogramas que componían el moviClip del heroe excepto de uno, el de la vista en que el heroe esta encarado hacia la derecha. El movimiento hacia la derecha es la posición por defecto para el movimiento, cuando el angulo de rotación es 0.

Para el movimiento en cualquier dirección, necesitaremos 2 variables, el angulo del movimiento y el valor del movimiento. Utilizaremos la rotación del movieClip del heroe para el angulo, y la variable "speed" en el objeto "char" para el valor de movimiento. Cuando conocemos el angulo y el valor, podemos encontrar las componentes x e y. Fijese en la imagen como:

Las proyecciones del vector speed (speedx y speedy), se pueden calcular , conocida su longitud y el angulo formado en el eje x y el eje y utilizando estas formulas:

speedx = speed*Math.cos(angle);
speedy = speed*Math.sin(angle);

Tenga en cuenta (extraño caso) que la propiedad _rotation de un movieClip está expresada en grados y los métodos/funciones de la clase Math que operan con ángulos como sin(x),cos(x),etc... asumen que los datos de ángulos que se pasan como parametros estén expresados en radianes.
Si utilizamos la propiedad _rotation como suministro de la variable de ángulo y si queremos operar con funciones de la clase Math, primero debemos hacer la transformación de grados a radianes utilizando:

anglerad = _rotation*Math.PI/180;

Así que visto esto, pasemos a resscribir la función para la detección de teclas. Lo que queremos es girar al heroe cuando presionemos las teclas de flecha izquierda o derecha y mover al heroe cuando pulsemos las flechas arriba o abajo:

if (Key.isDown(Key.RIGHT)) {
  ob.clip._rotation +=5;
} else if (Key.isDown(Key.LEFT)) {
  ob.clip._rotation -=5;
}
if (Key.isDown(Key.UP)) {
  ob.speedx=ob.speed*Math.cos((ob.clip._rotation)*Math.PI/180);
  ob.speedy=ob.speed*Math.sin((ob.clip._rotation)*Math.PI/180);
  keyPressed = _root.moveChar(ob, ob.speedx, ob.speedy);
}else if (Key.isDown(Key.DOWN)) {
  ob.speedx=-ob.speed*Math.cos((ob.clip._rotation)*Math.PI/180);
  ob.speedy=-ob.speed*Math.sin((ob.clip._rotation)*Math.PI/180);
  keyPressed = _root.moveChar(ob, ob.speedx, ob.speedy);
}

Cuando se presionan las teclas de flecha arriba o abajo (UP,DOWN), calculamos los valores de movimiento de x e y (como vimos y ya convertidos a radianes), y seguidamente se llama a la función moveChar utilizando los valores calculados. Puesto que estamos pasando como parametro a la función moveChar ambos valores x e y , debemos hacer unos cuantos cambios a esta función. Recuerde que hasta ahora a esta función solo le pasabamos en los parametros 0, 1 o -1 en las direcciones x e y (refresque la memoria, lo vimos en el capítulo 7).

El valor de 5 que utilizamos para aplicar la rotación del movieClip, como paso de ángulo, es tan solo un ejemplo. Puede utilizar los números que crea conveniente y que mas se ajusten al movimiento que desee. Intente utilizar números divisores de 360. 2, 4, 6, 12 o 90 son pasos de ángulo adecuados, 13.5 o 7 posiblemente sean una mala elección.

Elimine todas las referencias a ob.speed de esa función para que quede así:

function moveChar (ob, dirx, diry) {
  getMyCorners(ob.x, ob.y+diry, ob);
  if (diry < -0.5) {
    if (ob.upleft and ob.upright) {
      ob.y += diry;
    } else {
      ob.y = ob.ytile*game.tileH+ob.height;
    }
  }
  if (diry > 0.5) {
    if (ob.downleft and ob.downright) {
      ob.y += diry;
    } else {
      ob.y = (ob.ytile+1)*game.tileH-ob.height;
    }
  }
  getMyCorners(ob.x+dirx, ob.y, ob);
  if (dirx < -0.5) {
    if (ob.downleft and ob.upleft) {
      ob.x += dirx;
    } else {
      ob.x = ob.xtile*game.tileW+ob.width;
    }
  }
  if (dirx > 0.5) {
    if (ob.upright and ob.downright) {
      ob.x += dirx;
    } else {
      ob.x = (ob.xtile+1)*game.tileW-ob.width;
    }
  }
  ob.clip._x = ob.x;
  ob.clip._y = ob.y;
  ob.xtile = Math.floor(ob.x/game.tileW);
  ob.ytile = Math.floor(ob.y/game.tileH);
  return (true);
}

He añadido comprobaciones para los valores del movimiento, para tener en cuenta aquellos superiores en valor absoluto a 0.5 pixels. Cuando calculamos speedx y speedy utilizando funciones de seno y coseno (Math.sin, Math.cos), Flash puede devolver valores muy muy pequeños en lugar de 0, valores como 0.00000000000000001255. Así podemos detectar valores muy pequeños de movimiento e ignorarlos.

Como podrá observar, cuando se rota/gira al heroe, se permite que las esquinas que definen el border del heroe se solapen una pequeña cantidad de pixels en las paredes. Esto ocurre porque no estamos teniendo en cuenta su rotación cuando obtenemos las esquinas que conforman su borde. Puesto que este heroe tiene forma de cuadrado, sus esquinas no se introducirán demasiado en las paredes, pero en el caso de que utilice un heroe con una forma rectangular mas pronunciada, el error se puede hacer mas agudo y obvio.

Puede arreglar este fallo actualizando los valores de ancho y alto del objeto "char" cada vez que le aplicamos una rotación. Ponga estas 2 líneas en el código para la detección de las teclas de flecha izquierda y derecha, tras cambiar el valor de rotación:

char.width = char.clip._width/2;
char.height = char.clip._height/2;

Bien, esto soluciona nuestro problema ¡yeah!, peroooo nos genera otro. Como verá solo comprobamos las esquinas cuando el heroe se mueve, pero no cuando solo gira. Por tanto esta solución permitiría al heroe, si esta cerca de una pared, girar y solaparse contra ella. Sin embargo cuando intentaramos andar con el heroe, se realizaría la comprobación de las esquinas y se ajustaría, lo cual produciría un salto en el movimiento del heroe que no quedaría muy natural. No estoy seguro de que técnica puede resultar mejor, yo he dejado que el heroe se pueda solapar un poco contra la pared, tampoco queda excesivamente mal.

Como apunte final y antes de finalizar este capítulo, le quiero recomendar otro tutorial que hace algún tiempo publicamos en redribera.es y que trata algo mas en profundidad este mismo tema y que quizás sea de su interés. Se trata del tutorial de movimiento dirigido y velocidad con flash. Qizás en este tutorial encuentre temas que le puedan aportar algo de luz en el desarrollo de sus juegos.
Y con esto finalizamos este capítulo, como siempre puede descargar el fichero fla para ver como quedó todo.

En el próximo capítulo, continuamos con la diversión de la rotación, esta vez en vez de girar el heroe, giraremos el fondo!!

« Anterior
Indice
Siguiente »