Estoy (desde hace unos años) tratando de hacer un juego basado en Lakitu, y aunque he avanzado, he tenido que pausarme mucho por las fisicas.
En este caso mi problema es que en varios intentos he tratado de hacer unas colisiones suaves con solidos, y constantemente me salen bugs o fisicas desagradables (ya sea en drag and drop o en script) tales como rebotes o pre-colision, sin contar que colisiones con solidos en movimiento, es un asco~*
Solo se trata de una colision suave y en caso de ser un solido movil, que el jugador se mueva si es empujado sin quedar atrapado vilmente dentro del bloque.
Si alguien pudiera apoyarme con esto, le agradeceria muchisimo.
http://host-a.net/u/haku-shinigami/LakituPhysicsA.gmk
No se si me ha faltado mencionar algo, creo que no, pero puedo equivocarme~*
Me parece interesante la idea de un juego con ese protagonista.
El principal error con las colisiones es que no se asegura que el personaje va a quedar afuera del bloque, ¿el signo menos es para darle un efecto de rebote?. En lugar de usar el evento Collision puedes usar el evento Step y usar variables personalizadas para la velocidad vertical y la velocidad horizontal para dividir el movimiento en dos partes. Puedes basarte en esto para programar las colisiones: http://www.comunidadgm.org/articulos/tips-para-juegos-de-plataformas-(programacion)/ (http://www.comunidadgm.org/articulos/tips-para-juegos-de-plataformas-(programacion)/).
También deberías usar máscaras de colisión completamente rectangulares.
Me gustaría ayudarte con este problema, ya que también he tenido problemas con las físicas y coliciones, es una marca distintiva de GameMaker. Mira, la forma de lograr las "colosiones perfectas" (como se le suela llamar) mas viable que he intentado, consiste en checar si en el siguiente step el objeto estará colicionando, para esto albergas los valores de velosidad en variables, y haces el chequeo antes de aplicarlo directamente en X y Y. Si SI hay una colisión en el siguiente step, puedes, por ejemplo, usar un while para colocar el objet6o justo un pixel al lado del objeto en la dirección a la que se dirigía, por ejemplo:
speed= 6
jump=7
grav=2
hspd+=(keyboard_chek(vk_left)-keyboard_check(vk_right))*speed
vspd-=(keyboard_check(vk_space)&&!place_free(x,y+1))*jump
vspd+=grav
if(!place_free(x+hspd,y+vspd)){
while!(place_free(x+sign(hspd),y)||place_free(x,y+sign(vspd))){
var dir=point_direction(x,y,x+hspd,y+vspd)
x+=dcos(dir)
y+=dsin(dir)
}
hspd=0
vspd=0
}
x+=hspd
y+=vspd
Este código hace justo lo que te dige anteriormente, el problema es que aún así, es muy específico y no comprender coliciones en movimiento. Te lo digo así, si en tu juego hay mucha interacción entre sólidos y contantemente colisionarás con mas de un sólido a la vez, te recomendaría usar el motor de físicas; este es un consejo un poco delicado, y por eso te digo, que no uses las físicas si no las necesitas, pero si es el caso, creo que sería lo mejor.
@Jeshuark
De hecho me gustaria meterle mejores fisicas, solo que no se como~*
Si es importante que los solidos tambien se muevan
@Clamud
El link no me lleva al post, solo a la categoria~*
EDITO I: Creo que encontre el post, sin embargo las fisicas son para objetos con gravedad
http://www.comunidadgm.org/articulos/tips-para-juegos-de-plataformas-%28programacion%29/msg86322/#msg86322
EDITO II: Volvi a probar de otro modo, pero no mejore nada, resubi el archivo
http://host-a.net/u/haku-shinigami/LakituPhysicsA.gmk
Tengo una pregunta, a la hora de colisionar con una pared, Lakitu rebota o se queda quieto ?
Cita de: 3dgeminis en Mayo 31, 2017, 07:49:37 PM
Tengo una pregunta, a la hora de colisionar con una pared, Lakitu rebota o se queda quieto ?
Queria que se quedara quieto, que reposara suave en las paredes, en esta version trate y no me salio, rebotar es lo que mejor me va por ahora
Te dejo un ejemplo. Las colisiones aun no son perfectas, ya que a veces cuando colisiona con las paredes lo hace unos pixels antes (estoy tratando de corregir eso), pero creo yo que te puede servir.
Yo tengo otro método, en este caso no utilizo las máscaras de colisión, en cambio, comparo la posición relativa de las instancias para detectar las colisiones.
[gml]
if (abs(other.x - x) < 16) and (abs(other.y - y) < 16)
[/gml]
Si hay colisión, el bloque empuja a Lakitu hacia la posición más cercana fuera del bloque, así no queda atascado.
[gml]
lado = sign( other.x - x ); //1:Lakitu a la derecha, -1:Lakitu a la izquierda
other.x = lado*16 + x; //Lakitu se mueve a un lado del bloque
[/gml]
También agregué un mecanismo para detectar si Lakitu es aplastado por los bloques: lo que hace es comprobar si es empujado en direcciones contrarias en el mismo Step, si es así, entonces ha sido aplastado. Hay situaciones en las que no funciona bien, creo que ya encontré la solución, pero la agregaré después.
Cita de: 3dgeminis en Junio 03, 2017, 12:05:41 AM
Te dejo un ejemplo. Las colisiones aun no son perfectas, ya que a veces cuando colisiona con las paredes lo hace unos pixels antes (estoy tratando de corregir eso), pero creo yo que te puede servir.
Eso me suele pasar mucho al no ponerle rebote xD se pone solito el freno de mano, igual grazie!
Cita de: Clamud en Junio 03, 2017, 09:55:59 PM
Yo tengo otro método, en este caso no utilizo las máscaras de colisión, en cambio, comparo la posición relativa de las instancias para detectar las colisiones.
[gml]
if (abs(other.x - x) < 16) and (abs(other.y - y) < 16)
[/gml]
Si hay colisión, el bloque empuja a Lakitu hacia la posición más cercana fuera del bloque, así no queda atascado.
[gml]
lado = sign( other.x - x ); //1:Lakitu a la derecha, -1:Lakitu a la izquierda
other.x = lado*16 + x; //Lakitu se mueve a un lado del bloque
[/gml]
También agregué un mecanismo para detectar si Lakitu es aplastado por los bloques: lo que hace es comprobar si es empujado en direcciones contrarias en el mismo Step, si es así, entonces ha sido aplastado. Hay situaciones en las que no funciona bien, creo que ya encontré la solución, pero la agregaré después.
Me doy cuenta de las micro excepciones de aplastamiento, pero de todo lo demas, puedo decir que funciona de maravilla! Justamente no sabia si agregar aplastamientos por que no sabia cual era el metodo, me gusta mucho todo ese funcionamiento, esperare la version final! QuQ
La solución era más sencilla de los que esperaba solo sgregué esto repeat(2) para revisar 2 veces las colisiones en horizontal.
Cita de: Clamud en Junio 06, 2017, 02:02:07 AM
La solución era más sencilla de los que esperaba solo sgregué esto repeat(2) para revisar 2 veces las colisiones en horizontal.
Funciona de maravilla! Solo una molestia mas, trate de meterle mano para ver si podia hacerlo para colisiones en vertical, y la verdad que solo no quedaba :v espero no molestar mucho al pedirtelo tambien asi en vertical, igual muchas gracias!
No es muy complicado, solo hay que copiar el mismo código del movimiento horizontal. ¿Qué parte necesita más explicación?
Nota: Cambie un poco la forma de agregar la aceleración para no usar la variable aM.