Buenas gente! Tengo un problema con la colision vertical entre una plataforma que se vaya moviendo por el nivel y el personaje. Mi idea es que el personaje se mueva "solo" (o sea, que la plataforma le lleve) al estar encima de la misma. Horizontalmente no tengo ningún problema, pero con las colisiones verticales se me complica.
Personaje: script de colisíon:
[gml]//Colisión vertical
if (place_meeting(x,y+vsp,argument0)){
while(!place_meeting(x,y+sign(vsp),argument0)) {y += sign(vsp);}
vsp = 0;
on_ground = true;
}
//Colisión horizontal
if (place_meeting(x+hsp,y,argument0)){
while(!place_meeting(x+sign(hsp),y,argument0)) {x += sign(hsp);}
hsp = 0;
}
//Si atravesó la hitbox en el step anterior
if (place_meeting(x,y,argument0) && last_move != -1){
switch (last_move){
case 0:
while(place_meeting(x-1,y,argument0)) {x++;} //Derecha
x -= 1;
break;
case 1:
while(place_meeting(x,y+1,argument0)) {y--;} //Arriba
y -= 1;
break;
case 2:
while(place_meeting(x+1,y,argument0)) {x--;} //Izquierda
x += 1;
break;
case 3:
while(place_meeting(x,y-1,argument0)) {y++;} //Abajo
y += 1;
break;
}
}
//Actualizar variable
last_move = -1;
//Si atraviesa la hitbox48x48
if (place_meeting(x,y,argument0)){
//Actualizar variables
x_ = x;
y_ = y;
y_p = 0;
y_n = 0;
x_p = 0;
x_n = 0;
//Ver qué dirección es la más corta para salir de la colisión
while(place_meeting(x,y-1,argument0)) {y++; y_p++;} //Desde arriba
x = x_;
y = y_;
while(place_meeting(x,y+1,argument0)) {y--; y_n++;} //Desde abajo
x = x_;
y = y_;
while(place_meeting(x-1,y,argument0)) {x++; x_p++;} //Desde izquierda
x = x_;
y = y_;
while(place_meeting(x+1,y,argument0)) {x--; x_n++;} //Desde derecha
x = x_;
y = y_;
//Mover al objeto a la posición
var result = min(y_p,y_n,x_p,x_n);
if (y_p == result) {y += y_p-1; last_move = 3;} //Abajo
else if (y_n == result) {y -= y_n-1; last_move = 1;} //Arriba
else if (x_p == result) {x += x_p-1; last_move = 0;} //Derecha
else if (x_n == result) {x -= x_n-1; last_move = 2;} //Izquierda
}
[/gml]
Plataforma: Evento CREATE:
[gml]
///VALORES GENERALES
change_state = false;
state = true; //Si se está moviendo o no
go_to = 1; //Si es 1, va desde x1, y1 a x2, y2, y si es -1 va desde x2, y2 a x1, y1.
dist = 0; //Distancia entre el punto x, y hasta el destindo
_dist = 0; //Distancia entre el punto x, y desde la salida
dir = 0; //Ángulo entre el punto A y el punto B
hitbox = instance_create(x,y,obj_hitbox48x48); //ID del objeto hitbox que se usará como hitbox de la plataforma
spd = 0;
[/gml]
Plataforma: Evento STEP:
[gml]///CONTROL DE ESTADO
dir = point_direction(x1,y1,x2,y2);
//Cambiar de estado
if (change_state){
change_state = false;
//Cambiar estado
if (state) {state = false;}
else {state = true;}
}
//Comprobar el estado
if (state){
//Desde qué punto hasta qué punto
if (go_to == 1) {dist = point_distance(x,y,x2,y2); _dist = point_distance(x,y,x1,y1);}
else if (go_to == -1) {dist = point_distance(x,y,x1,y1); _dist = point_distance(x,y,x2,y2);}
//Moverse
if (_dist < 48) {spd = log10(1.1+_dist/3)*go_to}
else if (dist < 48) {spd = log10(1.1+dist/3)*go_to}
//Detenerse
if (dist < spd || (spd < 0.1 && spd > -0.1) && _dist >= 48){
if (go_to == 1) {x = x2; y = y2; go_to = -1;}
else if (go_to == -1) {x = x1; y = y1; go_to = 1;}
}
}
//Colision con el personaje
//if (place_meeting(x,y-1,obj_character)){ ANTERIOR
if (y > obj_character.y - 0.1 && place_meeting(x,y-1,obj_character)){
obj_character.x += spd * cos(degtorad(dir));
obj_character.y += spd * -sin(degtorad(dir));
}
//Mover la plataforma
x += spd * cos(degtorad(dir));
y += spd * -sin(degtorad(dir));
//Mover la hitbox
if (hitbox != 0){
hitbox.x = x;
hitbox.y = y;
}
[/gml]
Adjunto un video para que se entienda mejor mi problema.
Cuando la imagen del personaje es azul es porque está cayendo. Cuando es roja es porque está quieto o "idle".
Yo preferiría no utilizar place_meeting, porque utiliza una hitbox con valores redondeados. Puedes crear tu propio sistema de hitbox o puedes utilizar un sistema como este que va almacenando los residuos no enteros de velocidad y solo verifica colisiones con números enteros
https://marketplace.yoyogames.com/assets/1724/moving-platforms
Lo que falta en tu código es hacer que la plataforma mueva al personaje antes de que el personaje se mueva. Si subes el proyecto sería más fácil probar el código.