Limitación de velocidad baja en el clásico pathfinding

Publicado por kostra, Enero 14, 2021, 11:37:47 AM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

kostra

Tengo el clásico sistema de pathfinding que enseñan en el 99% de los tutoriales

[gml]///AI_init(width,height,precise)

precise = argument[2];
width = argument[0];
height = argument[1];

_grid = mp_grid_create(0,0,ceil(room_width/argument[0])
,ceil(room_height/argument[1]),argument[0],argument[1]);
_path = path_add();
_obstacles = ds_list_create();

mp_grid_add_instances(_grid,obj_wall,precise);

_priorityGrid = ds_grid_create(width,height);
[/gml]

y

[gml]///AI_patrol(x,y,allowDiagonal,speed)

if !mp_grid_path(_grid,_path,x,y,argument[0],argument[1],argument[2]) {
    //show_debug_message("Path could not be computed")
    return false;
    }
else{
    path_start(_path,0.6,path_action_reverse,true)
    return true;
    }[/gml]

me funciona bien pero... solo si pongo una speed >= 1... si pongo una speed < 1 por ejemplo 0.6 pues ya no funciona cuando ha de dirigirse hacia abajo y/o derecha, sin embargo arriba y/o izquierda sí funca... me topé con el mismo problema con más velocidad cuando implementé estos scripts en el evento step, entonces lo cambié a un bucle de 2 steps en una alarm y se arregló, hasta ahora que lo estoy intentando con menos velocidad.

Antes que comentéis lo que me imagino, la razón por la que la quiero poner en bucle es porque mi juego, a parte de que el pathfinding lo hago para los enemigos sigan al player (y el player obviamente se mueve xd),  también he de resetear a tiempo real los obstáculos, ya que es un juego estilo minecraft y las paredes, agua, etc (obstáculos) pueden cambiar en cualquier momento.

Cómo soluciono esto? me encantaría poner enemigos lentos :(

Black_Cat

una solucion que te puede ayudar es descomponer el path en sus puntos
primero tendrias que obtener todos los puntos con path_get_number() y luego ir enlistando uno a uno con path_get_point_x y path_get_point_y
de ahi en vez de usar path_start podrias usar cualquier otra funcion para dirigirte a las coordenadas a la velocidad que se te antoje

salu3


kostra

algo así?

[gml]var _pointsx =  ds_list_create();
var _pointsy =  ds_list_create();
for ( var i=0;i<path_get_number(argument[0]);i++ ) {
    ds_list_add(_pointsx,path_get_point_x(argument[0],i) );
    ds_list_add(_pointsy,path_get_point_y(argument[0],i) );
    }[/gml]

a partir de aquí no se me ocurre cómo seguir, desconozco mucho tanto las funciones path como las de ds_ xDD

Black_Cat

si asi va bien, ahí ya tenes los puntos del path, no te olvides de borrar la ds_list cuando ya no haga falta

ahora deberías ir obteniendo punto por punto e ir moviendo la instancia en plan:
1 obtengo el primer punto
2 si la distancia es mayor a 0, me muevo hacia ese punto
3 si la distancia es igual a 0, obtengo otro punto
4 repetir hasta que ya no queden puntos

y asi te vas moviendo sin usar path_start, imagino que con move_towards_point, total el camino ya está calculado, no deberian haber obstaculos sino bueno, los calculas de nuevo :v

kostra

ya tengo mis vars de spd, hsp, vsp y dir PROPIAS, con el ípico bucle que aplica el movimiento

[gml]for ( var i=0;i<abs(hsp);++i )
        if place_free( x+sign(hsp),y )
        && !place_meeting( x+sign(hsp),y,owater )
        && !place_meeting( x+sign(hsp),y,oswamp )
            x += sign(hsp)*min( 1,abs(hsp) );
        else {
            if hsp != 0 {
                dir = irandom(359);
                get_hsp();
                }
            }
    for ( var i=0;i<abs(vsp);++i ) {
        if place_free( x,y+sign(vsp) )
        && !place_meeting( x,y+sign(vsp),owater )
        && !place_meeting( x,y+sign(vsp),oswamp )
            y += sign(vsp)*min( 1,abs(vsp) );
        else {
            if vsp != 0 {
                dir = irandom(359);
                get_vsp();
                }[/gml]

[gml]///get_hsp()

hsp = dcos(dir)*spd;[/gml]

[gml]///get_hsp()

hsp = -dsin(dir)*spd;[/gml]


no podría aprovechar esas vars simplemente asignando la dir con point_direction?

Y no acabo de comprender lo de sacar punto por punto, insisto que cada 2 steps (o 1 si es posible), se reinicia todo, entonces, no podría ahorrarme el for y pillar simplemente el primer x,y (que no sé si ser´el 0 o el 1) y aplicar la dir y la spd y ya está?

Black_Cat

si el caso es que solo necesitas el siguiente punto entonces si, no necesitas almacenar todos jajaja solo sacás 1, y si, podes aprovechar la variable de direccion combinandola con  point_direction, en teoria deberia funcionar

kostra

parecía que si funcaba pero no, pasa lo mismo o algo parecido, con 0.6 parece que oc, con 0.8 va mal para según qué dirección

[gml]///path_start_alt(ind,speed)

var _xx = path_get_point_x(argument[0],1);
var _yy = path_get_point_y(argument[0],1);

dir = point_direction(x,y,_xx,_yy);
spd = argument[1];[/gml]

197 Visitantes, 0 Usuarios