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.10 Saltando...

Saltando...

Vamos a hacer un giro de 90 grados a nuestro juego y a pasar de la vista superior a una vista lateral. De este modo podremos hacer algo mas, ¡saltar!.
En el ejemplo bajo estas líneas, estamos mirando el juego, desde una vista lateral, así que nuestro heroe puede caminar de izquierda a derecha utilizando las flechas de los cursores. También puede saltar, utilizando para ello la tecla "SPACE". Mire:



Lo básico para conseguir saltos.

Cualquier salto comienza con un impulso. Como recordará, ir hacia arriba (o subir), en la escena de flash implica que la coordenada "y" debe decrecer (reducir su valor). Así que calculamos nueva_y = actual_y - jumpspeed. Si solamente hacemos esto, el heroe se mueve hacia arriba en función de jumpspeed y a saber donde parará. Por supuesto, debemos continuar calculando la nueva posición de "y" mientras el heroe esté saltando, pero al mismo tiempo hemos de variar esa misma velocidad (jumpspeed), o nuestro heroe comenzará a volar hacia el infinito y nunca volverá.

Para modificar "jumpspeed", debemos declarar una nueva varaible "gravity", que haga referencia a la gravedad. La gravedad, devolverá al heroe a tierra firme. En cada paso (del ciclo de juego), añadiremos gravedad a la velocidad de salto así: jumpspeed = jumpspeed + gravity. Podemos jugar con diferentes valores de gravedad, cuanto mas bajo sea el valor, mas alto saltará nuestro heroe (como un globo), cuando incrementemos el valor de la gravedad, nuestro heroe saltará poco (como una piedra :). Como tenemos diferentes objetos en nuestro juego, y el heroe también es uno de ellos, podemos utilizar diferentes valores de gravedad para para objetos diferentes...un globo, un heroe !

Hagamos un ejemplo. El valor inicial para la velocidad de salto es -10 (jumpspeed=-10), y la gravedad es 2 (gravity=2). En el primer paso, el heroe se mueve hacia arriba 10 pixels y al actualizar jumpspeed, esta última queda con un valor de -8. En el siguiente paso, el heroe se mueve 8 pixels mas hacia arriba y jumpspeed queda siendo 6. Tras unos pocos pasos mas, jumpspeed adquiere un valor de 0, lo cual implica que nuestro heroe ya no se moverá mas hacia arriba. En el siguiente paso, jumpspeed comienza a tener un valor positivo, y el heroe comienza a moverse ¡hacia abajo!.

Pero, ¿Que hacemos si el heroe está saltando y choca contra un Tile de sólido muro?. En ese caso, estableceremos el valor de jumpspeed a 0 y dejaremos que el heroe vuelva a caer hacia el suelo. Si el heroe, vuelve a chocar contra el suelo, entonces podremos decir que el salto ha finalizado.

En los juegos basados en Tiles, es siempre importante no asignar un valor de velocidad (jumpspeed) mas alto que el tamaño del Tile. Si el heroe tiene una velocidad de salto muy alta, no podremos comprobar cual es el siguiente Tile y podremos permitir que éste se mueva a traves de las paredes. Así como algunos magufos! pueden atravesar las paredes, en los juegos normales esto suele ser un fallo!

Como puede observar, los saltos no afectarán al movimiento horizontal. Este se comprobará exactamente igual a como lo haciamos antes. Tan solo debemos comprobar, tras mover al heroe, a izquierdas o derechas, si este ha dejado de caminar por un Tile sólido y debe comenzar a caer hacia abajo.


Mi heroe!

Vamos a añadir algunas propiedades mas a nuestro personaje, el heroe.

char={xtile:2, ytile:1, speed:4, jumpstart:-18, gravity:2, jump:false};

Las propiedad "speed" marcará la velocidad de desplazamiento cuando el movimiento sea izquierda/derecha, "jumpstart" es el valor de inicio de la velocidad de salto ("jumpspeed"). "gravity" es la gravedad que hará que nuestro heroe vuelva al suelo y "jump" la utilizaremos para poder comprobar en cualquier momento si nuestro heroe está saltando (jump=true), o andando/corriendo/sentado/luchando.... en tierra firme (jump=false).

La siguiente línea que debemos cambiar, se encuentra en la función buildMap, en el momento de inicializar la posición del heroe. En los ejemplos anteriores, situabamos al heroe centrado en el Tile sobre el que lo posicionabamos (lógico para una vista superior). Sin embargo para la vista lateral que vamos a utilizar, esto produce una mala sensación, y no es bonito ver caer al heroe una cuantos pixels hasta que toque tierra cada vez que el heroe entre en una nueva habitación (generemos un nuevo mapa). Así que haremos que el heroe comience siempre pegado a la parte inferior del Tile en el que se inicializa su posición. Esta nueva línea la tenemos que poner después de la línea donde declaramos la altura, char.height.

char.y = ((char.ytile+1)*game.tileH)-char.height;

Dame Alas!

Comencemos con la función detectKeys. Necesitamos añadir algo de código para comprobar cuando se presiona la tecla "SPACE" y podemos eliminar el código que utilizabamos para detectar las flechas "UP" y "DOWN":

function detectKeys() {
  var ob = _root.char;
  var keyPressed = false;
  if (Key.isDown(Key.SPACE) and !ob.jump) {
    ob.jump = true;
    ob.jumpspeed = ob.jumpstart;
  }
  if (Key.isDown(Key.RIGHT)) {
    keyPressed=_root.moveChar(ob, 1, 0);
  } else if (Key.isDown(Key.LEFT)) {
    keyPressed=_root.moveChar(ob, -1, 0);
  } 
  if (ob.jump) {
    keyPressed=_root.jump(ob);
  }
  if (!keyPressed) {
    ob.clip.char.gotoAndStop(1);
  } else {
    ob.clip.char.play();
  }
}

Observe como no permitimos que el personaje pueda volver a saltar si ya está realizando un salto (!ob.jump). Solo tendremos en cuenta una pulsación de la tecla "SPACE" si el heroe no está saltando. Mientras que si pulsamos la tecla "SPACE" y nuestro personaje no está saltando, estableceremos la variable "jump" a true y añadiremos al heroe velocidad de salto (ob.jumpspeed = ob.jumpstart).

Después de las comprobaciones para las teclas Izquierda y derecha (left/right), comprobamos si la variable "jump" es true, y si esto se cumple, llamaremos a una nueva función "jump" (la función "jump" no es lo mismo que la variable "jump", mala elección de nombres por mi parte, disculpe). Esta función, será llamada cada paso (del ciclo de juego), mientras que la variable "jump" sea true, de ese modo, nuestro heroe continuará saltando aunque dejemos de presionar la tecla "SPACE".

La función "jump" añadirá gravedad a la velocidad de salto actual. Además comprobará si la velocidad de salto ("jumpspeed"), es demasiado alta, y si es así, la reduciremos al tamaño del Tile restado con char.height (para que el heroe no atraviese las paredes,tal como comentamos anteriormente). Las últimas líneas hacen una llamada a la función moveChar, para mover a nuestro heroe.

function jump (ob) {
  ob.jumpspeed = ob.jumpspeed+ob.gravity;
  if (ob.jumpspeed>game.tileH-char.height) {
    ob.jumpspeed = game.tileH-char.height;
  }
  if (ob.jumpspeed<0) {
    moveChar(ob, 0, -1, -1);  
  } else if (ob.jumpspeed>0) {
    moveChar(ob, 0, 1, 1);  
  }
  return (true);
}

También debemos modificar la función moveChar. En los capítulos anteriores, utilizamos ob.speed para cambiar la posición de los objetos, pero ahora tambien tenemos velocidad de salto, que está cambiando a cada paso. Cambie el principio de la función moveChar así:

function moveChar(ob, dirx, diry, jump) {
  if (Math.abs(jump)==1) {
    speed=ob.jumpspeed*jump;
  } else {
    speed=ob.speed;
  }

El argumento "jump" de la función, será 1 o -1 solamente si la función moveChar está siendo llamada desde la función "jump", en cuyo caso la variable "speed" obtendrá su valor desde "jumpspeed". Cuando la función moveChar, se llama desde la detección de las teclas izquierda o derecha, la variable "speed", será igual a ob.speed. Cambie las líneas correspondientes de la función moveChar para reflejar este cambio.

En el código que pongo a continuación, modificacmos "jumpspeed" a 0 si colisionamos con una pared por arriba:

ob.y = ob.ytile*game.tileH+ob.height;
ob.jumpspeed = 0;

y en el siguiente código, establecemos "jump" a falso si se detectamos una pared por la parte de abajo (fin del salto):

ob.y = (ob.ytile+1)*game.tileH-ob.height;
ob.jump = false;

En el movimiento a izquierda o derecha, añadimos una línea para comprobar la situación, cuando el heroe camina al final del borde de una plataforma (solida) y debe caer hacia abajo.

ob.x += speed*dirx;
fall (ob);

Así que aun necesitamos una nueva función, la función fall:

function fall (ob) {
  if (!ob.jump) {
    getMyCorners (ob.x, ob.y+1, ob);
    if (ob.downleft and ob.downright) {
      ob.jumpspeed = 0;
      ob.jump = true;
    }
  }
}

No podemos caernos si ya estamos saltando, así que es la primera comprobación que debemos hacer. Si el heroe no está saltando, llamaremos a la función getMyCorners, para obtener las esquinas del borde del heroe. Utilizaremos la coordenada ob.y+1 , para comprobar si un pixel mas allá de la actual posición de nuestro heroe es pisable. Si ambas esquinas inferiores (la izquierda y la dercha), son pisables (walkable=true), esto quiere decir que nuestro heroe se encuentra literlamente en el aire.

Cuando se produce esta situación, forzaremos a nuestro heroe a saltar estableciendo la variable "jump" a true, pero a diferencia de como lo hacemos cuando se presiona la tecla "SPACE", estableceremos la velocidad inicial de salto a 0, así que el heroe comenzará a caer hacia abajo.

Con esto que hemos visto, será suficiente, de momento, para nuestros propositos.

Lo siguiente ¡Nubes!

« Anterior
Indice
Siguiente »