Bueno, les cuento que ya he solucionado mi problema y les cuento un poco de como lo he hecho por si a alguien se le ofrece mas adelante, aunque quizás halla formas mas sencillas de hacerlo, pero pues apenas llevaré una semana usando el game maker y no domino aún el lenguaje.
Primero que nada les cuento que es lo que quería.
Lo que buscaba era hacer que mi personaje solo se moviera con respecto a las celdas, tal cual juego de pokemon, de hecho, el movimiento es igual. Si el botón se presionaba un momento mi personaje solo voltearía a ver en la dirección, si se mantenía presionado mas tiempo, el personaje caminara hacia la dirección según la tecla presionada.
Uno de los problemas con los que me topé, es que los eventos del teclado tienen una especie de prioridad, esto es, que si dos teclas se mantenían presionadas, mi personaje caminaría hacia la dirección que indicara la tecla con mas prioridad, algo indeseable en mi caso, ya que yo quería que mi personaje caminara en dirección a la última tecla presionada. Para solucionar esto, hice una lista donde iba almacenando las teclas presionadas y el último elemento de esta lista era el que me indicaría hacia donde mi personaje se tenía que dirigir, aquí el código donde agrego a la lista cada tecla presionada:
Esto lo he hecho para cada tecla direccional y en el evento key press el cual es esencial ya que una tecla es imposible presionarla dos veces sin antes soltarla una vez, por lo que cada tecla estará en la lista solo una vez.
Cuando suelto una tecla agrego las siguientes lineas de códigos:
Con esto, ya puedo obtener siempre la última tecla que ha presionado el usuario, lo cual es justamente lo que deseaba.
Como he dicho antes, quería que si un botón era presionado solo un instante mi personaje solo volteara, y si se mantenía presionado mi personaje empezara a caminar, por lo que le he agregado líneas al evento keypress, el cual pasó a ser de esto:
A esto:
Esto quiere decir que si mi personaje está volteando para un lado que no sea la dirección de la tecla que estoy pulsando y que si es la primera tecla pulsada solo quiero que mi personaje voltee a ver en la dirección, mas no que empiece a caminar.
La variable orientaciónActual me dice en qué dirección está mi personaje volteando actualmente, si es 0 mi personaje mira hacia la derecha, si es 90 mi personaje mira hacia arriba, si es 180 mi personaje mira hacia la izquierda y por último, si es 270 es por que mi personaje mira hacia abajo.
Como tengo que dar tiempo a que mi personaje espere x tiempo para saber si solo tengo que hacer que mi personaje mire en otra dirección o que mi personaje camine hacia otra dirección he llamado a mi script de movimiento en el evento step y queda de la siguiente manera:
Ahora si viene lo bueno, todo el código anterior fue para agregar teclas a la lista y para saber si mi personaje tiene que voltear o caminar, pero la verdadera magia viene en el siguiente script el cual copio y pego y lo explico un poco con comentarios ya que es un poco grande:
Y con esto logramos un movimiento idéntico al que se lleva a cabo en los juegos de pokemon, quizás como dije antes, se puede hacer mucho mas fácil, pero es algo que ahora mismo desconozco y es a la solución a la que he podido llegar, lo he puesto por que no me gustan los temas inconclusos, y le puede ser suficiente a mas de uno.
Si les parece un poco lento el movimiento, solo hay que cambiar la velocidad a la que se mueve el personaje.
Para cualquier duda o sugerencia me comentan.
Saludos
Primero que nada les cuento que es lo que quería.
Lo que buscaba era hacer que mi personaje solo se moviera con respecto a las celdas, tal cual juego de pokemon, de hecho, el movimiento es igual. Si el botón se presionaba un momento mi personaje solo voltearía a ver en la dirección, si se mantenía presionado mas tiempo, el personaje caminara hacia la dirección según la tecla presionada.
Uno de los problemas con los que me topé, es que los eventos del teclado tienen una especie de prioridad, esto es, que si dos teclas se mantenían presionadas, mi personaje caminaría hacia la dirección que indicara la tecla con mas prioridad, algo indeseable en mi caso, ya que yo quería que mi personaje caminara en dirección a la última tecla presionada. Para solucionar esto, hice una lista donde iba almacenando las teclas presionadas y el último elemento de esta lista era el que me indicaría hacia donde mi personaje se tenía que dirigir, aquí el código donde agrego a la lista cada tecla presionada:
Código [Seleccionar]
ds_list_add(numeroLista,vk_left);
Esto lo he hecho para cada tecla direccional y en el evento key press el cual es esencial ya que una tecla es imposible presionarla dos veces sin antes soltarla una vez, por lo que cada tecla estará en la lista solo una vez.
Cuando suelto una tecla agrego las siguientes lineas de códigos:
Código [Seleccionar]
posicion = ds_list_find_index(numeroLista,vk_left);
ds_list_delete(numeroLista,posicion);
Con esto, ya puedo obtener siempre la última tecla que ha presionado el usuario, lo cual es justamente lo que deseaba.
Como he dicho antes, quería que si un botón era presionado solo un instante mi personaje solo volteara, y si se mantenía presionado mi personaje empezara a caminar, por lo que le he agregado líneas al evento keypress, el cual pasó a ser de esto:
Código [Seleccionar]
ds_list_add(numeroLista,vk_left);
A esto:
Código [Seleccionar]
teclasPulsadas = ds_list_size(numeroLista);
if(teclasPulsadas == 0 && orientacionActual != 180)
soloVoltear = true;
ds_list_add(numeroLista,vk_left);
Esto quiere decir que si mi personaje está volteando para un lado que no sea la dirección de la tecla que estoy pulsando y que si es la primera tecla pulsada solo quiero que mi personaje voltee a ver en la dirección, mas no que empiece a caminar.
La variable orientaciónActual me dice en qué dirección está mi personaje volteando actualmente, si es 0 mi personaje mira hacia la derecha, si es 90 mi personaje mira hacia arriba, si es 180 mi personaje mira hacia la izquierda y por último, si es 270 es por que mi personaje mira hacia abajo.
Como tengo que dar tiempo a que mi personaje espere x tiempo para saber si solo tengo que hacer que mi personaje mire en otra dirección o que mi personaje camine hacia otra dirección he llamado a mi script de movimiento en el evento step y queda de la siguiente manera:
Código [Seleccionar]
scr_moverPersonaje();
Ahora si viene lo bueno, todo el código anterior fue para agregar teclas a la lista y para saber si mi personaje tiene que voltear o caminar, pero la verdadera magia viene en el siguiente script el cual copio y pego y lo explico un poco con comentarios ya que es un poco grande:
Código [Seleccionar]
//Aquí obtengo el número de teclas presionadas actualmente
numeroTeclas = ds_list_size(numeroLista);
//Si es mayor que 0 hago que mi personaje camine o voltee hacia la dirección indicada por la última tecla presionada, si es igual a 0, hago que mi personaje se detenga.
if(numeroTeclas > 0)
{
//Si mi personaje está colocado en una celda de forma correcta hago el movimiento correspondiente
if(place_snapped(64,64))
{
//Obtenemos la última tecla presionada
ultimaTecla = ds_list_find_value(numeroLista,numeroTeclas - 1);
//Hacemos la acción correspondiente según la última tecla presionada
switch(ultimaTecla)
{
//Aquí solo explicaré lo que se hace cuando la última tecla presionada es la que hace que nuestro personaje vaya a la derecha, pero se hace lo mismo para cada tecla, solo se cambian sprites y direcciones
//Si la ultima tecla presionada fue la de dirección derecha
case vk_right:
//Si solo quiero voltear o la siguiente celda es un obstáculo, cambio el sprite actual y hago que mi personaje se detenga,
if(soloVoltear || !place_free(x+64,y))
{
sprite_index = Spr_Ash_MirarDerecha;
motion_set(0,0);
}
//Si no se cumple la condición anterior es por que debemos de caminar, así que ponemos el sprite correspondiente y hacemos que camine hacia la dirección y con la velocidad deseada
else
{
sprite_index = Spr_Ash_CaminarDerecha;
motion_set(0,4);
}
//Sin importar si volteamos o caminamos cambiamos la dirección actual
orientacionActual = 0;
break;
case vk_up:
if(soloVoltear || !place_free(x,y-64))
{
sprite_index = Spr_Ash_MirarArriba;
motion_set(0,0);
}
else
{
sprite_index = Spr_Ash_CaminarArriba;
motion_set(90,4);
}
orientacionActual = 90;
break;
case vk_left:
if(soloVoltear || !place_free(x-64,y))
{
sprite_index = Spr_Ash_MirarIzquierda;
motion_set(0,0);
}
else
{
sprite_index = Spr_Ash_CaminarIzquierda;
motion_set(180,4);
}
orientacionActual = 180;
break;
case vk_down:
if(soloVoltear || !place_free(x,y+64))
{
sprite_index = Spr_Ash_MirarAbajo;
motion_set(0,0);
}
else
{
sprite_index = Spr_Ash_CaminarAbajo;
motion_set(270,4);
}
orientacionActual = 270;
break;
}
}
}
//Si no hay teclas presionadas hacemos lo siguiente
else
{
//Si mi personaje está colocado en la celda correctamente podemos detener nuestro personaje
if(place_snapped(64,64))
{
//Dependiendo de la orientación actual es el sprite que usaremos, ya que queremos pasar de una animacion caminando a una que solo este parado el personaje mirando hacia la dirección correspondiente
switch(orientacionActual)
{
//Si volteamos hacia la derecha
case 0:
sprite_index = Spr_Ash_MirarDerecha;
break;
//Si volteamos hacia arriba
case 90:
sprite_index = Spr_Ash_MirarArriba;
break;
//Si volteamos hacia la izquierda
case 180:
sprite_index = Spr_Ash_MirarIzquierda;
break;
//Si volteamos hacia abajo
case 270:
sprite_index = Spr_Ash_MirarAbajo;
break;
}
//Detenemos nuestro personaje
motion_set(0,0);
}
}
//Esto es para controlar el delay de voltear, ya que si no lo hacemos nuestro personaje volteará, pero empezará a caminar casi al instante, cosa indeseable
//Si queremos solo voltear nuestro personaje
if(soloVoltear)
{
//Si se cumple el tiempo que le damos a nuestro personaje para que voltee y no empiece a caminar en el momento
if(delayVoltear == 0)
{
soloVoltear = false;
delayVoltear = 3;
}
delayVoltear--;
}
Y con esto logramos un movimiento idéntico al que se lleva a cabo en los juegos de pokemon, quizás como dije antes, se puede hacer mucho mas fácil, pero es algo que ahora mismo desconozco y es a la solución a la que he podido llegar, lo he puesto por que no me gustan los temas inconclusos, y le puede ser suficiente a mas de uno.
Si les parece un poco lento el movimiento, solo hay que cambiar la velocidad a la que se mueve el personaje.
Para cualquier duda o sugerencia me comentan.
Saludos