Bueno despues de retrasar bastante esta entrada, parece el momentos apropiado de colocarla en mi blog. Voy a intentar a hacer esto lo más rápido, claro y conciso, aunque no os prometo nada.
Como punto de partida y como ya va siendo normal vamos a explicar por encima que es el mouse mapping; así es como llaman los libros o más bien los autores al proceso de transformar las cordenadas del ratón a las cordenadas de tiles (como su propio nombre indica mapeo de cordenadas (al igual que es autodescriptivo tonelada == mil kilos)), ya sea cenital o isométrico como es nuestro caso. Bueno este término se suele extender a la transformada entre cordenadas en píxeles a cordenadas en tiles. Este proceso suele ser directo, como en el caso de cenital o de la isométrica diamond; pero el caso que aqui nos atañe, la staggered, es un caso bastante particular como veremos a lo largo de los párrafos.
Otros conceptos que tenemos que comprender antes de empezar con el mouse mapping son: viewer, scrolling, world coordinates y viewer coordinates. Voy a utilizar estas nomenglaturas porque son las que me aprendí hace bastante tiempo con el libro de j2me game programming de wells y que por deformación profesional sigo utilizando.
- Viewer: vamos a denominar viewer a la zona de mapa que vemos, en nuestro caso va a ser la ventana de la aplicación, en otros casos puede ser pantalla completa, una pantalla de un dispositivo movil... Es decir el area que vemos. Si os fijais bien, el ratón nos va a devolver una posición dentro del viewer, asi que a eso es lo que llamaremos viewer coordinates, las cordenadas dentro del visor.
- Scroll/scrolling: Espero que para todos este término sea bastante conocido, sino vamos bien jodidos. Pero bueno vamos a darle sentido dentro de nuestro ámbito. Como el mapa o el mundo, es decir el espacio de juego, suele ser más grande que el viewer necesitamos algún mecanismo para desplazar el viewer por el mundo esto va a ser el scroll, lo que vamos a hacer es bastante simple, es mover las cordenadas x e y del viewer. Asi que las world coordinates son la coordenada real del objeto en el mundo. De aqui deducimos rapidamente que cuando el viewer esté en la posición 0,0 las cordenadas del viewer y las del mundo coincidirán.

Como podeis observar en el dibujo existe una relación directa entre las coordenadas del mapa y las de dentro del viewer. Como podeis ver el mouse mapping nos proporcionará lo que he llamado xScreen e yScreen, si a esto le sumamos la xView y la yView, es decir la posición del viewer con respecto al mundo, ya tenemos la localización de cursor dentro de mundo en pixeles, ahora tan solo tenemos que encontrar la manera de transformar esa coordenada en coordenadas de tiles. Y aqui viene lo diber chicos; porque como no me canso de repetir esto no es una fórmula mágica sino un procedimiento que cada autor lo hace como le sale de... los cojones.
Bueno siguiendo la recomendación de mi gran amigo y compañero de carrera Roberto Espinoso me dijo una vez "no hagas nada, primero mira en internet si alguien ya ha hecho lo que quieres, si es asi copialo y no te sientas mal, ya que si no está tu deber es hacerlo y ponerlo en internet para que otros como yo lo copiemos". Asi que puse en práctica su consejo y miré como lo hacian en el libro de isométrica, y no me gustaba mucho lo que hacian, asi que me puse a mirar por internet y me topé con el engine del argentum de morgolock y miré como lo hacian, y aunque se parecía bastante en algunos puntos a lo que hacía el libro de isométrica era distintos en otros, y tampoco me convencía mucho su método, pero ambos dos usaban un concepto que más tarde si me sería de gran utilidad, utilizaban una imagen base (concepto que explicaré más tarde) y me puse a desarrollar mi propia manera de transformar las coordenadas x e y basándome en ese concepto de imagen base. Vamos a ello.
Bueno lo primero q tenemos que hacer es tener una imagen igual de tamaño que tile del suelo, y rellenarla de la siguiente manera. Fijaros que tiene unos colores muy bonitos en las esquinas luego explicaremos para que son.

Una vez que tenemos esto, lo primero que tenemos que hacer es encontrar en que región tenemos el cursor, esto lo hacemos con la coordenada real ya del mundo ok??. Si os fijais bien lo que estamos haciendo en realidad es desproyectar el pintado del tile, si os fijais bien en la entrada del tile ploting esto sería lo inverso
if (pos.X < 0) pos.X = 0;
if (pos.Y < 0) pos.Y = 0;
//calculamos en q región de tiles cae.
int regiony = (int)(pos.Y / (HTile>>1));
//recordar q por culpa del zigzag las x estan desplazas medio tile
int regionx = (int)((pos.X - ((regiony & 1) * (WTile >> 1))) / WTile);
Con esto no nos vale, ya q si nos fijamos bien vemos que si estamos en una esquina de una región, por ejemplo en la parte roja, estaríamos ya en otro tile isométrico, por lo cual tenemos que arreglar eso. Para ello nos va a venir muy bien la imagen base esta de los colorines. Primero lo que hacemos es encontrar en que parte de la región estamos o lo que es lo mismo en que parte del tile estamos, Con esto accedemos a la imagen. Recordar que la imagen no es más que un array de colores codificados en ARGB(alpha red green blue, el alpha es el nivel de semitransparencia siendo 0xff opaco), una vez que tenemos el pixel de la imagen base vemos que hacemos.
//miramos el offset dentro de esa región
int offsetTileX = (int)((pos.X - ((regiony & 1) * (WTile >> 1)))% WTile);
int offsetTileY = (int)((pos.Y+ ((regiony & 1) * (HTile >> 1))) % HTile);
//para que el array no se desborde si los valores son negativos los ponemos a cero
offsetTileX = (offsetTileX < 0) ? 0 : offsetTileX;
offsetTileY = (offsetTileY < 0) ? 0 : offsetTileY;
//sacamos el color para ver como de fuera esta del tile
uint pxCol=mouseMap[(offsetTileY*WTile)+offsetTileX];
Bueno ahora que tenemos el pixel lo que tenemos que ver es que hacer con él, para eso vamos a mirar la imagen base y un mapa isométrico con las coordenas, como esto es de cajón de madera de tabla, ni os lo voy a explicar en profundidad, tan solo por encima. Fijaros que si el pixel que sacamos es verde no tenemos que hacer nada, significa que estamos bien colocados, pero si no es asi si es de otro color quiere decir q nos hemos equivocado de tile y que tenemos q corregir y según sea el color del tile asi corregiremos de una manera u otra. También si nos fijamos en un mapa el desplazamiento que tenemos que hacer si la fila es par o impar también es distinto. Esto se ve a primera vista viendo el mapa isométrico Asi que aqui os voy a poner el código de los desplazamientos. Fijaos que regiony&1, lo que nos dice es si la fila es par o impar.
int regionDX=0;
int regionDY=0;
switch (pxCol)
{
//RED
case 0xffff0000:
regionDX = -1+(regiony&1);
regionDY = -1;
break;
//BLUE
case 0xff001cff:
regionDX = 0+(regiony&1);
regionDY = -1;
break;
//purple
case 0xfff600ff:
regionDX = 0 + (regiony & 1);
regionDY = 1;
break;
//yellow
case 0xfffffc00:
regionDX = -1+(regiony&1);
regionDY = 1;
break;
default:
regionDX = 0;
regionDY = 0;
break;
}
Ya tenemos el punto asi que le sumamos el desplazamiento y lo devolvemos.
Point aux = new Point();
aux.X = regionx +regionDX;
aux.Y = regiony +regionDY;
return aux;
Alguien que haya estado atento a la explicación, se habrá dado cuenta que nunca se accede a la zona morada y amarilla, ya que la regiones "y" van de medio tile a medio tile, pero lo he dejado para mayor compresión de la explicación.
Bueno ahora os voy a poner la llamada para calcular el mouse mapping. Fijaros que a la x y la y del ratón se le suma la x y la y del viewer para tener la posión real en el mundo.
Point tile = isoEngine.getTileIsoToPixel(new Vector2(mouse.mouseState.X+isoEngine.xView, mouse.mouseState.Y+isoEngine.yView));
Bueno pues creo q eso es todo por hoy. Tan solo decir que en realidad no hace falta acceder a la imagen base para realizar el calculo de offset, sino que se puede realizar mediante operaciones matemáticas, pero que el procedimiento es menos eficiente, tan solo lo recomendaría en caso de que tuvieramos poca memoria y quisieramos ahorrarnos el array de pixels (un movil por ejemplo).
Esta mañana he tenido una dura crítica de uno de los últimos juegos en el q he participado Liaf, asi que para resarcirme os voy a poner el link de "la aventura de numa" y de una crítica que me he encontrado por ahí del juego. Lo primero dar gracias a diego por ponerme en los créditos, ya que tampoco he realizado mucho, ya que entre ordenadores rotos y mierdas no tengo time para nada, pero weno por lo menos hice el menu (lo siento diego la parte online no pudo ser) y soy una de las voces del juego. Cabe destacar lo complicado que es sacar adelante un proyecto entre varias personas ya que no todo el mundo va al ritmo que se desearia y siempre hay más compromisos y Diego esto lo ha sabido llevar muy estoicamente. Cabe destacar el gran trabajo. como dicen en la crítica. de alfredo en el apartado musical, un hombre polifacético allá donde los halla que desprende un aura de sabiduría y tocada de güevos al personal que lo hacen único e inconfundible.
Os pido encarecidamente que os bajeis el juego y que envieis puntos, que aunq no es el gears of wars hay el trabajo, en mayor o menor media, de gente detrás.
No quiero q esto sea una exaltación de mi ego personal, como ya dije al principio poco tengo q ver con este proyecto, sino esta entrada en tan solo el reconocimiento del trabajo incombustible de diego, q mes tras mes ha ido dando forma. Diego si algo me has enseñado en este año y pico q llevo enfrente tuya es q las cosas se hacen pasito a pasito, con una marca clara y alcanzable a corto y largo tiempo, y que más vale ser realista y tener algo terminado, q ser un soñador y encontrarte con un proyecto inalcanzable.
Te echaré de menos compañero, pero algo me dice q no es un adios sino un hasta luego.
PD : yo por lo menos hice algo ehhh morpheo?? donde esta el skybox?? juaz grandes risas.