Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: jodidox en Abril 23, 2016, 07:53:36 PM

Título: VERIFICAR ESPACIO LIBRE
Publicado por: jodidox en Abril 23, 2016, 07:53:36 PM
No me quiero volver canson XD

Pero viendo que no he podido o no tengo idea de la solucion os pregunto,

Quisiera calcular la distancia entre los objetos obBlock y el obPlayer

Para saber si hay mas espacio a la izquiera o a la derecha o arriba

asi....

Título: Re:VERIFICAR ESPACIO LIBRE
Publicado por: bygdle en Abril 23, 2016, 08:05:17 PM
Hmmm... podrías hacer un ciclo que verificara cada pixel desde la posición del objPlayer y el objBlock, y mientras esté libre ese pixel, sumarle 1 a la variable que te dirá la distancia libre.
Eso, claro, sólo funcionaría si tienes almacenadas las id's de los dos objetos a comprobar su distancia libre.
Por ejemplo:
[gml]
//obj es la instancia del muro
var distancia = 0;
for(var i = x; i < obj.x; i++) {
    if place_free(x + i, y)
        distancia++;
}
[/gml]
Al final del ciclo, la variable distancia tendrá la cantidad de pixeles libres entre el player y el muro. O eso debería pasar, no sé si funciona porque no lo he probado.
Título: Re:VERIFICAR ESPACIO LIBRE
Publicado por: jodidox en Abril 23, 2016, 08:10:51 PM
Ese seria el ciclo horizontal derecho cierto?

O al menos eso entendi.

Título: Re:VERIFICAR ESPACIO LIBRE
Publicado por: bygdle en Abril 23, 2016, 08:12:27 PM
Sí, para las otras sería lo mismo pero diferente(?) xD
Pero como te digo, no sé si funcione  :-[
Título: Re:VERIFICAR ESPACIO LIBRE
Publicado por: Clamud en Abril 24, 2016, 06:47:36 PM
Se puede revisar pixel por pixel, como dice Niu, pero el proceso sería muy pesado y no sería recomendable que se ejecute en cada Step.

Una forma de optimizar sería realizar la comprobación en pasos más grande y al encontrar colisión ir refinando poco a poco el cálculo de la distancia. Por ejemplo, para detectar la distancia horizontal a la derecha, se comprobaría con place_free en pasos iguales a la anchura del player, después al detectar colisión, se comprobaría la posición libre en sentido contrario haciendo pasos de un pixel. Sería más óptimo si los pasos se reducen a la mitad en cada evento de detección de colisión o detección de espacio libre.

Si todos los objetos son rectángulos, creo que sería mejor usar un método que compruebe la distancia de "intervalos".
Usemos este script:
[gml]
///interA( a,b, c,d );
//Dados dos intervalos ABIERTOS (a,b) y (c,d)
//devuelve true si hay interseccion
return argument0 < argument3 and argument1 > argument2;
[/gml]
Sea (x1,y1) la posición de la esquina superior izquierda de un rectángulo y (x2,y2) la esquina contraria.

La distancia a la derecha se podría calcular así (en el objeto player):
[gml]
d = "Inf"; //distancia infinita
var t;

with( obBlock )
{
    if interA( other.y1,other.y2, y1,y2 ) //si los rectangulos se "ven" en direccion horizontal
    {
        t = x1 - other.x2; //distancia a la derecha
       
        if( t > 0 )      //si el bloque esfectivamente esta a la derecha
        if( t < d        //y la distancia es menor a otra encontrada
        or d == "Inf" ){ //o no se ha encontrado otra distancia valida
            d = t;       //la menor distancia es igual a t
        }
        else if( t == 0 ){ //si t es cero
            d = 0;         //la distancia es cero
            break;         //no es necesario seguir buscando
        }
    }
}
//d contiene el resultado
[/gml]