Marzo 14, 2019, 01:18:18 PM Ultima modificación: Marzo 15, 2019, 01:42:18 PM por yottaomi
Buenos días.

Tengo un problema con las colisiones y es que no consigo que:
a) El objeto jugador no reduzca su caída por estar junto al objeto que forma el suelo (por supuesto no estando encima suyo, solo a un lado).
b) El objeto jugador no quede solapado con el objeto suelo(obj_wall).

Puedo evitar una, pero no las dos a la vez:

Si utilizo este script, al chocar con el objeto (obj_wall) en el aire, el (obj_jugador) se desliza poco a poco hacia abajo, como si estuviera algo pegado, pero no solapado:
///Procesar movimiento
pm = place_meeting(x+hsp,y+vsp,obj_wall);
cl = collision_line(x,y,x+hsp,y+vsp,obj_wall,0,0);

if (pm or cl) {
    //Comprobando colision horizontal
    for(var i=0;i<abs(hsp);i++){
        if (place_meeting(x+sign(hsp),y,obj_wall)) then break;
        x += sign(hsp);
    }
    //Comprobando colisión vertical
    for(var i=0;i<abs(vsp);i++){
        if (place_meeting(x,y+sign(vsp),obj_wall)) then break;
        y += sign(vsp);
    }
    hsp = 0;
    vsp = 0;
}


Y si utilizo este, al colisionar con las esquinas del (obj_wall) se queda atrapado en estas:
// Horizontal collision
if (place_meeting(x+hsp,y,obj_wall))
{
    //sign 1/-1 positive or negative
    while(!place_meeting(x+sign(hsp),y,obj_wall))
    {
        x += sign(hsp);
    }
    hsp = 0;
}


// Vertical collision
if (place_meeting(x,y+vsp,obj_wall))
{
    //sign 1/-1 positive or negative
    while(!place_meeting(x,y+sign(vsp),obj_wall))
    {
        y += sign(vsp);
    }
    vsp = 0;
}

Si hace falta poner más código avisadme. Sólo he puesto el de las colisiones.

Lo mejor es separar las colisiones, cada eje por su lado:
[gml]
hsp=(keyboard_check(vk_right)-keyboard_check(vk_left))*4

if place_meeting(x+hsp,y,obj_wall)
   {
    while !place_meeting(x+sign(hsp),y,obj_wall) {x+=sign(hsp)}
    hsp=0
   }
x+=hsp

/////////////////////////////////////////////////////////////////////

if vsp<20 {vsp+=1}
if keyboard_check_pressed(vk_up) {vsp=-15}

if place_meeting(x,y+vsp,obj_wall)
   {
    while !place_meeting(x,y+sign(vsp),obj_wall) {y+=sign(vsp)}
    vsp=0
   }
y+=vsp
[/gml]

Que mascara de colision usas ?

Muchas gracias. Ya está resuelto.

Al final utilicé el primer código que puse, pero separando  las coordenadas x de las y:
///Procesar movimiento
pmx = place_meeting(x+hsp,y,obj_wall);
clx = collision_line(x,y,x+hsp,y,obj_wall,0,0);

if (pmx or clx) {
    //Comprobando colision horizontal
    for(var i=0;i<abs(hsp);i++){
        if (place_meeting(x+sign(hsp),y,obj_wall)) then break;
        x += sign(hsp);
    }
    hsp = 0;
}

pmy = place_meeting(x,y+vsp,obj_wall);
cly = collision_line(x,y,x,y+vsp,obj_wall,0,0);

if (pmy or cly) {
    //Comprobando colision vertical
    for(var i=0;i<abs(vsp);i++){
        if (place_meeting(x,y+sign(vsp),obj_wall)) then break;
        y += sign(vsp);
    }
    vsp = 0;
}

Lo extraño es que creo que ya lo había probado, pero no me había funcionado.

Por si alguien utiliza este código, lo primero, es de Hektor Profe
https://www.youtube.com/watch?v=jZXRVhdo7Ks

Y lo segundo, utilicé la máscara de colisión para el objeto jugador:
mask_index = spr_jugador (la máscara de colisión del sprite en parado, para todos los sprites del obj_jugador)

Y para tanto obj_jugador como obj_wall, máscara de colisión rectangular.