Julio 16, 2011, 05:37:44 AM Ultima modificación: Julio 25, 2011, 08:24:09 AM por MaanuRP
Hola a todos!

Tengo una duda muy simple:

Quiero hacer que cuando mi player choque contra una pared se detenga, pero que intente avanzar, y que si su direction o angle no es totalmente perpendicular a la pared, que se vaya moviendo (Despacio obviamente, como se lo permita su direction).

Resumido: Quiero que mi player choque, literalmente, contra la pared (osea, que no la traspase) pero que si direction lo permite, que se mueva a la velocidad debida.

Creo que me explique, si alguien no entendio, que me pregunte y se lo explico mejor.

PD: Dejo ejemplo (Editable y .exe) de como hago yo para crear la colision con la pared, pero no quiero que suceda eso, sino que choque pero dependiendo del direction del player.

Desde ya muchisimas gracias a todos!

Saludos! :)

Haver Si Entendi.. QuieresQue Cuando Choque Contra La Pared De La Imprecion Que Intenta Avanzar Forzosamente?

Exactamente eso.
Que si esta a 90? de la pared no se va a mover absolutamente nada.
Pero si esta a 89? de la pared se va a empezar a mover pero muy poco, aunque sigue chocandose la pared.

http://www.comunidadgm.org/index.php?page=verdescargas&accion=descargaD&download_id=1985

ModificaloUnPoco Convierte EstoEn Codigo=
CuandoEl Personaje Colisione ConLaPared ElSprite BajeLa Velociad De AnimacionUnPoco , Cuando Este Unos 2 Segundos Se Pueda Mover ElBloque(Esto LoPuedes hacer con alarmas y variables) Mmm..CreoQue Seria Eso :P

#4 Julio 16, 2011, 06:37:26 AM Ultima modificación: Julio 16, 2011, 06:48:34 AM por MaanuRP
No veo de que forma me puede ayudar eso.

Aca dejo una demostracion de lo que yo quiero hacer para que se entienda mejor, dejo el editable.

En este editablo, pongan el juego y fijense que cuando el jugador choca contra una pared su velocidad se hace 0, por ende se deja de mover. Pero lo que yo quiero es que si choque contra la pared y que cuando este mirando a 90? (Osea totalmente perpendicular con la pared) se frene y se quede quieto, pero que cuando tiene algun grado de inclinacion se vaya moviendo (Obviamente, cuando mas lejos de 90? esta el direction del player, va a ir mas rapido)

A ver si asi se entiende mejor

PD: Dejo el .exe tambien por si lo quieren ver mas rapido y solo escribirme lo que hay que hacer, y no editarme el editable (Valga la redundancia).
De cualquiera forma, me gustaria que me lo explicaran asi aprendo a hacerlo!

:D

Ok.. EsperaUnPoco LuegoEdito Y PongoEl Editable ;D

O solo dime lo que tengo que hacer y yo lo hago, o los codigos y yo los pongo :D

Muchas gracias!

Bastantes cosas para notar en el editable que pusiste...

Primero, no uses "transform the sprite" para girar la imagen. Us? image_angle.
[gml]image_angle = direction;[/gml]

Segundo, est?s violando el principio DRY (Don't Repeat Yourself, no te repitas). El principio DRY dice que un c?digo no puede estar repetido. En el evento de colisi?n con el objeto obejct1 y en el evento de colisi?n con el objeto object2 pusiste exactamente el mismo c?digo. En un principio esto solo genera alguna peque?a inconveniencia al tener que cambiar ambos c?digos si cambi?s uno, pero a medida que el juego va creciendo, se vuelve un verdadero problema, y puede generar un mont?n de bugs dif?ciles de encontrar.
La soluci?n es marcar el parent de object2 como object1, y borrar el evento de colisi?n con object2. Al chocar con object2, como es "hijo" de object1, el evento de colisi?n con object1 se ejecuta.

Tercero, est?s usando la variable speed. La variable speed es ?til en ocasiones porque nos permite reducir el c?digo necesario para hacer que el personaje se mueva, pero tiene el problema de que no nos da mucho control sobre el movimiento. En vez de eso, te recomiendo usar move_contact_solid().
Keyboard Check Up:
Moverse en direcci?n "direction" 5 pixeles o hasta tocar algo s?lido.
[gml]move_contact_solid(direction, 5);[/gml]
Keyboard Check Down:
Moverse en direcci?n "direction + 180" (direcci?n contraria a "direction") 5 pixeles o hasta tocar algo s?lido.
[gml]move_contact_solid(direction + 180, 5);[/gml]
Y bueno, al hacer esto, el evento de colisi?n con object1 ya no es necesario, as? que se puede borrar :). Los eventos Key Release Up y Down tambi?n.

Y ahora que el juego est? superoptimizado, respondo tu verdadera pregunta :P.
Supongamos que el jugador se est? moviendo as?:

Para hacer lo que quer?s, primero ten?s que descomponer la direcci?n en dos: la componente "x" y la componente "y". Eso se hace as?:


Ah? la componente "x" est? en rojo y la componente "y" en azul. Como ves, la idea es que si el objeto se mueve en direcci?n de la componente "x" y despu?s en direcci?n de la componente "y" (o viceversa), acaba en la posici?n deseada.
GM tiene dos funciones que sirven justamente para obtener las componentes "x" e "y" de un vector: lengthdir_x y lengthdir_y.
Keyboard Check Up:
[gml]var l_x, l_y, d_x, d_y;
// Obtenemos el largo de las componentes "x" e "y".
l_x = lengthdir_x(5, direction);
l_y = lengthdir_y(5, direction);

// Y su direcci?n.
d_x = 180 * (l_x < 0);
d_y = 270 + 180 * (l_y < 0);

move_contact_solid(d_x, abs(round(l_x)));
move_contact_solid(d_y, abs(round(l_y)));[/gml]
Keyboard Check Down:
[gml]var l_x, l_y, d_x, d_y;
// Obtenemos el largo de las componentes "x" e "y".
l_x = lengthdir_x(5, direction + 180);
l_y = lengthdir_y(5, direction + 180);

// Y su direcci?n.
d_x = 180 * (l_x < 0);
d_y = 270 + 180 * (l_y < 0);

move_contact_solid(d_x, abs(round(l_x)));
move_contact_solid(d_y, abs(round(l_y)));[/gml]
Esos dos ?ltimos c?digos son bastante similares... Ser?an otra violaci?n del principio DRY. Pero voy a dejar que vos pienses en c?mo arreglarla, si es que quer?s :P.

Te dejo adjunto el editable modificado con todas las sugerencias que hice en el post. No uses el script move_contact_solid que viene, lo tuve que crear porque uso LGM, y a?n no tiene una funci?n move_contact_solid.
Vim.

Me Parti La Cabeza Como 2 Horascon 1 millon de codigos   XD No Me ManejoMucho En 2d Pero Por Todo Eso Que Puso Wadk Se Aprecia Que Esta pregunta eramuy Dificil Grax Por Resolver Dudas Wadk ...

Gracias a ambos por la dedicacion!

Wadk te pasaste con toda la explicacion :D

Pero igual no funciona igual como yo lo quiero, eso solo avanza si el player esta a 45? u otro angulo en particular, pero la mayoria de los angulos se queda quieto :S

Excelente wadk en mi otra compu tengo linux y intente correr un juego en enigma pero usaba move_contact_solid() y no funciono y la verdad me dio flojera hacer un script que simule move_contact_solid() as? que no he vuelto a usar enigma, pero con tu c?digo espero poderlo probar gracias.

Wadk, ya te haces un Script con tus creditos ;) jajaj

De nada :).

Cita de: MaanuRP en Julio 17, 2011, 01:12:07 AMPero igual no funciona igual como yo lo quiero, eso solo avanza si el player esta a 45? u otro angulo en particular, pero la mayoria de los angulos se queda quieto :S
Hmm... a mi me funciona perfecto, y el personaje siempre se mueve a no ser que camine de forma directa o casi directa hacia la pared. ?C?mo implementaste los c?digos que puse? ?Podr?as describir m?s detalladamente el problema? :/
Vim.

#13 Julio 17, 2011, 04:13:45 AM Ultima modificación: Julio 17, 2011, 04:15:52 AM por MaanuRP
Use tu editable sin modificarle nada.

Quiero que cuando el player choque contra la pared, pase lo que pasaria en la realidad, mira este video (Espero que no se considere spam, si se considera asi, diganme y lo borro).

http://www.youtube.com/watch?v=Xftb-vV0xMY&

Mira desde el minuto 2:25 (Presta atencion a la colision con las paredes que hay, eso quiero yo)

PD: Con el editable que me diste, se mejora el problema de que el player se frena completamente sin importar su angulo, pero solo se mejora muy poco, yo quiero que sea super fluido el movimiento, como en el video, como si fuera mas "real".

#14 Julio 17, 2011, 06:06:02 AM Ultima modificación: Julio 17, 2011, 06:09:01 AM por brunoxzx
Intenta con este c?digo lo (encontr? en la gmc hace mucho y lo use para uno de mis juegos), va en end step  :-[.
[gml]var xmot, ymot;

if place_meeting(x,y,muro)
{

x = xprevious;y = yprevious

for (i=0; i<90; i+=2)
{
xmot=x+lengthdir_x(speed,direction+i)
ymot=y+lengthdir_y(speed,direction+i)
if place_free(xmot,ymot){x = xmot;y = ymot;exit}
xmot=x+lengthdir_x(speed,direction-i)
ymot=y+lengthdir_y(speed,direction-i)
if place_free(xmot, ymot){x = xmot;y = ymot;exit}
}
}[/gml]

Edit: si no lo entiendes te lo explico.