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.22 Movimiento con el ratón.

Ha llegado la hora de dejar el teclado y echar mano de esa cosa asquerosa sobre su escritorio. ¡No esa no!, el ratón de la computadora !. Aunque mover al heroe con las teclas, es fácil y divertido, y de hecho durante mucho, mucho, mucho tiempo se ha hecho así, debemos entender que el ratón del computador es muy popular por algo, y es que el ratón también tiene su lado divertido, click aquí!, click allá!...en definitiva otra opción mas para nuestros juegos.
Fijesé en la película mas abajo como el heroe se mueve hacia donde ordenamos con un click de ratón:



Antes de comenzar a ver el movimiento con el ratón, vamos a aclarar un detalle acerca de la implementación que hemos realizado. Como recordará, en los ejemplos anteriores, el hereo se movía de un modo pixel-perfecto, lo cual no sucede en el tipo de implementación que hemos realizado. En este caso, al utilizar el ratón, el heroe se mueve desde el centro del Tile origen, hasta el centro del Tile destino. Es decir que no es posible que el heroe quede entre medias de dos Tiles por ejemplo. El movimiento desde un Tile origen a un Tile destino, es mucho mas sencillo que el basado en pixel-perfecto. En este caso no es necesario la detección de colisiones, ya que cuando hemos de avanzar hacia un Tile lo único que debemos es comprabar si ese Tile es pisable (walkable=true), así que todo se reduce a un paseo feliz hacia el Tile destino.


El puntero del ratón.

Hagamos un puntero que nos sirva de resalte del Tile en el que esté el puntero del ratón. Dibuje un simple rectangulo, con las dimensiones de los Tiles que utilizamos, tal y como se puede ver en la imagen mas abajo. conviertalo en un movieClip y exportelo para ActionScript (en el linkage), con identificador "mouse".
Asegurese de alinear el gráfico del rectangulo igual que el resto de los Tiles, con el punto de referencia en la esquina izquierda superior.

Ahora añadiremos el movieClip creado a la escena por encima del resto de Tiles. En la función buildMap escriba:

_root.attachMovie("mouse", "mouse", 2);

Todo lo demás en la función buildMap queda igual, así que no volveremos a comentar esta función.
Para que el puntero del ratón actualizace su posición correctamente crearemos una nueva función llamada "work":

function work() {
  game.xmouse=Math.round((_root._xmouse-game.tileW/2)/game.tileW);
  game.ymouse=Math.round((_root._ymouse-game.tileH/2)/game.tileH);
  _root.mouse._x=game.xmouse*game.tileW;
  _root.mouse._y=game.ymouse*game.tileH;
}

Calculamos las propiedades xmouse e ymouse dentro del objeto "game", que conocerán donde está el ratón. Para ser exactos contienen el número de Tile. El objeto "char" dispone de unas propiedades similares xtile e ytile, las recuerda?. Las últimas dos líneas, situan el ratón en ese Tile.

Esta función debe ser llamada en cada paso del ciclo de juegos (onEnterFrame) de la escena principal:

onClipEvent (enterFrame) {
  _root.work();
}

Como no utilizamos teclas para el movimiento, puede eliminar la función detectKeys en caso de que esté arrastrandola de los ejemplos de algún capítulo anterior.

Ahora que el ratón (el movieClip mouse) se está moviendo como debiera, añadiremos una forma de detectar los "clicks" en la escena. Escriba este código en el control principal del juego:

onClipEvent (mouseUp) {
  _root.getTarget();
}

Cuando se suelta el botón del ratón tras hacer click, se llama a la función getTarget. Al utilizar el evento de clip "mouseUp", se llama a la función solo cuando soltamos el botón del ratón tras hacer un click. Si prefiere otro modo, por ejemplo cuando apretemos el botón izquierdo del ratón (aunque lo mantengamos presionado) puede reemplazarlo por el evento "mouseDown", es libre de elegir el método.
Escribamos la función getTarget:

function getTarget() {
  if(game["t_"+game.ymouse+"_"+game.xmouse].walkable){
    game.targetx=game.xmouse;
    game.targety=game.ymouse;
    char.moving=true;
  }
}

Aquí lo que hacemos primero, es asegurarnos que el jugador está haciendo click (el objetivo del movimiento) sobre un Tile que es pisable (walkable=true). Ya sabe Usted como son los jugadores, ellos hacen click sobre cualquier sitio, y cuando les pregunta educadamente, ¿Pero porque coj**** ha hecho click ahí?, ellos tan solo responden, "No lo se, me parecio un buen sitio!".....En fin, no podemos hacer que los jugadores no hagan click sobre los Tiles que no queremos, pero si podemos hacer que nuestra función ignore aquellos clicks sobre Tiles que no son pisables!. Si por algún extraño milagro, el jugador hace click en un Tile pisable, estableceremos las propiedades "targetx" y "targety" a las correspondientes al Tile bajo el puntero del ratón. Del mismo modo, establecemos el valor de "char.moving" a true.


Moviendo al heroe al Tile correcto.

En la función getTarget establecimos la variable "moving" a true para el heroe. Mientras esta variable tenga el valor "true" nuestro heroe intentará moverse. Puesto que no queremos que el heroe se mueva nada mas comience el juego, lo que haremos es establecer incialmente dicha variable a "false" en el objeto "char":

char={xtile:2, ytile:1, speed:2, moving:false};

Añada este trozo de código al final de la función "work":

var ob=char;
if (!ob.moving) {
  ob.clip.char.gotoAndStop(1);
} else {
  moveChar(ob);
  ob.clip.char.play();
}

Mientras la variable "moving" sea falso, el heroe permanece quieto y no se reproduce ninguna animación. Pero cuando "moving" pasa a ser "true", empezamos a reproducir la animación y llamamos a la función moveChar. No se preocupe por el movimiento de Tile a Tile, la nueva función moveChar es mucho más sencilla:

function moveChar(ob) {
  if((ob.x-game.tileW/2)%game.tileW==0 and (ob.y-game.tileH/2)%game.tileH==0){
    ob.xtile = Math.floor(ob.x/game.tileW);
    ob.ytile = Math.floor(ob.y/game.tileH);
    if(game["t_"+ob.ytile+"_"+(ob.xtile+1)].walkable and game.targetx>ob.xtile){
      ob.dirx=1;
      ob.diry=0;
    }else if(game["t_"+ob.ytile+"_"+(ob.xtile-1)].walkable and game.targetx<ob.xtile){
      ob.dirx=-1;
      ob.diry=0;
    }else if(game["t_"+(ob.ytile+1)+"_"+ob.xtile].walkable and game.targety>ob.ytile){
      ob.dirx=0;
      ob.diry=1;
    }else if(game["t_"+(ob.ytile-1)+"_"+ob.xtile].walkable and game.targety<ob.ytile){
      ob.dirx=0;
      ob.diry=-1;
    }else{
      ob.moving=false;
      return;
    }
  }
  ob.y += ob.speed*ob.diry;
  ob.x += ob.speed*ob.dirx;
  ob.clip._x = ob.x;
  ob.clip._y = ob.y;
  ob.clip.gotoAndStop(ob.dirx+ob.diry*2+3);
}

La primera línea de la función, comprueba si el heroe, está actualmente en el centro del Tile, lo cual quiere decir que se encuentra preparado para moverse, eso si, si supiera a donde. La posicion x e y se comprueban utilizando el operador de modulo "%". Básicamente, comprueba el resto de la división entre la posición del heroe y el tamaño de Tile. Cuando x e y están en el centro del Tile, la división otorga un resto igual a 0 así que escojemos una nueva dirección.

Existen una enorme variedad de algoritmos para busqueda de rutas o pathfinding, principalmente el algoritmo A* (aquí le dejo un enlace con información acerca del algoritmo A*, si le interesa. Muchos de estos algoritmos, requieren una capacidad de computo bastante elevada y puede llevar bastante tiempo calcular el camino desde el punto A al punto B. El método que utilizamos nosotros es un método bastante sencillo y no encuentra ningún camino. El heroe se mueve en una dirección hasta que encuentra el punto destino o una pared. Y del mismo modo se mueve en vertical.

Para conocer hacia que sitio girar, echemos un vistazo a la siguiente decisión:

if(game["t_"+ob.ytile+"_"+(ob.xtile+1)].walkable and game.targetx>ob.xtile){

Aquí miramos al siguiente Tile que está justo a la derecha de donde se encuentra actualmente el heroe y comprobamos si se trata de un Tile pisable y además comprobamos si el punto destino (que se clicó con el ratón), está a la derecha del heroe.

Y de momento, esto es todo para mover al heroe con el ratón. Puede como siempre descargar el fichero fla de ejemplo bajo la película inicial.

Lo siguiente que veremos, en el siguiente capítulo, es esto mismo aplicado a vistas isométricas.

« Anterior
Indice
Siguiente »