Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: Klind en Marzo 27, 2013, 08:05:32 PM

Título: Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Marzo 27, 2013, 08:05:32 PM
Epale gente!

Otra vez yo pidiendo ayuda  :-[

Esta vez no sé cómo explicar el problema, por lo que creé una demostración aparte del proyecto original para mostrarles lo que pasa.

Descarguen el ejemplo y muevan el personaje hacia una pared varias veces, es decir, que el personaje choque contra la pared, y luego hacen que vuelva a moverse en esa dirección para que siga chocando. Hasta que vean que el personaje queda viendo a una sola dirección (generalmente hacia arriba y a la izquierda) y queda ahí estancado. No se mueve más. ¿Cómo puedo solucionar eso y crear una mejor colisión?

La forma de moverse es darle click al personaje y soltar el botón donde queramos moverlo. Luego le dan a la tecla Espacio.

OJO: NO pueden soltar el mouse en una zona donde haya pared porque NO se creará la ruta. Simplemente le dan Click a la bolita, y sueltan el mouse en una zona verde pero de manera que la ruta atraviese una pared para que la bolita choque.

Gracias de antemano y disculpen la molestia, pasan y pasan los años y las colisiones en el Game Maker siguen siendo un dolor de cabeza para mí  :(
Título: Re:Ayuda con este tipo de colisión
Publicado por: metalfox6383 en Marzo 27, 2013, 08:54:47 PM
Aun no veo tu ejemplo, pero me imagino que tu problema es que el personaje se te queda atascado en la pared, cierto? O me equivoco. Bueno, yo lo solucionaba con INSTANCE_PLACE. Con ella verificaba si al poner mi objeto en una nueva coordenada, iba en ella colisionar con otra, entonces ponia un FOR con para probar coordenadas menores y encontrar el espacio libre. A ver, revisa esa funcion y me dices si algo asi te sirve.
Título: Re:Ayuda con este tipo de colisión
Publicado por: Klind en Marzo 28, 2013, 12:47:20 AM
Cita de: metalfox6383 en Marzo 27, 2013, 08:54:47 PM
Aun no veo tu ejemplo, pero me imagino que tu problema es que el personaje se te queda atascado en la pared, cierto? O me equivoco. Bueno, yo lo solucionaba con INSTANCE_PLACE. Con ella verificaba si al poner mi objeto en una nueva coordenada, iba en ella colisionar con otra, entonces ponia un FOR con para probar coordenadas menores y encontrar el espacio libre. A ver, revisa esa funcion y me dices si algo asi te sirve.

Conozco ese método, pero en mi caso no sé cómo usarlo ya que para mover a la bolita uso una coordenada (x,y) y un move_towards_point(x,y,speed) para que vaya dando steps hacia esa coordenada, entonces no sé cómo chequear con el instance_place la coordenada a la que voy a caminar, porque siempre es una dirección distinta.

Cuando puedas revisa el ejemplo a ver qué se te ocurre, ¡muchas gracias por responder!

¿Alguien más se anima a ayudar? Les aseguro que les va a gustar el juego cuando lo termine  ;D
Título: Re:Ayuda con este tipo de colisión
Publicado por: Klind en Marzo 29, 2013, 06:08:51 PM
Sigo sin poder resolver este problema, alguien que por favor me eche una manito. Me tiene frustrado no poder continuar el proyecto por este rollo de la colisión.
Título: Re:Ayuda con este tipo de colisión
Publicado por: brunoxzx en Marzo 29, 2013, 07:49:13 PM
No puedo ver el ejemplo, pero algo simple que podrias hacer es usar un "move_outside_solid" en end step para salir de la colision en la que estabas metido.

No recuerdo bi[en pero creo que la funci'on de move_towards_point modificaba variables predefinidas como speed y direction para funcionar. As[i que es probable que poniendo este c[odigo en end step y borrando todo lo de mas que tenga que ver con colisiones funcione.
move_outside_solid(-direction, speed, false);.
Título: Re:Ayuda con este tipo de colisión
Publicado por: Klind en Marzo 29, 2013, 08:13:42 PM
Qué tal brunoxzx,

todo lo que me faltaba era ese "-direction" en el move_outside_solid"  :-[.

Lo que hice fue agregarle ese código que me dijiste al evento de colisión con la pared y me quedó así:

move_outside_solid(-direction, speed)
mover = false
ds_queue_clear(xCola)
ds_queue_clear(yCola)


¡Mil gracias hermano!

Saludos.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: Klind en Marzo 29, 2013, 08:36:23 PM
Probando el nuevo código de distintas maneras, me doy cuenta que ahora cuando el personaje está muy muy pegado de una pared (de manera que se detecta una colisión) y lo hago moverse hacia la dirección contraria a la pared, el personaje se "teletransporta", atraviesa toda la pared apareciendo del otro lado.

Sé por qué pasa eso, pero no sé cómo solucionarlo.

Si alguien puede descargar el ejemplito para que vea el modo de movimiento, se lo agradecería un montón. No pesa nada de verdad.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: brunoxzx en Marzo 29, 2013, 08:53:00 PM
Primero que nada intentalo de este modo.
[gml]move_outside_solid(direction+180, speed).[/gml]

Se como lo har[ia de otro modo pero me da flojera escribirlo ahorita, ademas es mejor no cambiar tus codigos. intentar[e descargar el ejemplo aunque no lo podre ver por que estoy en linux, mientras comenta que tal te va usandolo as[i.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: Klind en Marzo 29, 2013, 09:00:15 PM
Intenté con eso y nada, sigue pasando lo mismo de que cuando está muy pegado a la pared y lo hago caminar en sentido contrario a la pared, en vez de moverse normal salta al otro lado de la pared.

Ok, voy a estar pendiente aquí.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: brunoxzx en Marzo 29, 2013, 09:05:15 PM
OK como ultimo ultimo (ahora si ultimo) intento hazlo de este modo.
[gml]
if !place_free(x, y){
       move_outside_solid(direction+180, speed);
}[/gml]

asegurate de ponerlo en @end step@ y poner el move_towards en step.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: Klind en Marzo 29, 2013, 09:29:34 PM
Me sigue pasando lo mismo.

Y tiene sentido, porque supongamos que voy caminando de abajo hacia arriba, y la bolita pega contra la pared, entonces la hago moverse hacia abajo y la derecha, la dirección contraria es hacia arriba y a la izquierda entonces por eso atraviesa la pared y aparece del otro lado de la pared y en la dirección contraria a la que yo le dije que se moviera.

EDIT:

Es curioso porque SOLO pasa cuando el movimiento del personaje es en diagonal. Cuando lo tengo pegado a la pared y me muevo en linea recta hacia abajo se mueve perfecto.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: brunoxzx en Marzo 29, 2013, 10:01:55 PM
Cita de: Klind en Marzo 29, 2013, 09:29:34 PM
Es curioso porque SOLO pasa cuando el movimiento del personaje es en diagonal. Cuando lo tengo pegado a la pared y me muevo en linea recta hacia abajo se mueve perfecto.
Reviza que no tengas colisiones precisas activadas en tus sprites...

.
Bueno, para hacerlo a la antigua se har[ia as[i.
[gml]
var dx, dy;
dx=legthdir_x(1, point_direction(x,y, xx,yy));
dy=legthdir_y(1, point_direction(x,y, xx,yy));
repeat(vel){
    if !place_free(x+dx, y+dy) break;
    x+=dx:
    y+=dy;
}
[/gml]
Cambia tu movimiento por algo este, elimina el move towards y las cosas que tengan que ver con speed.
Edit: ups me faltaba un y+=dy en el c[odigo.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: Klind en Marzo 29, 2013, 10:27:00 PM
No me funciona, le puse varios valores a "vel" pero o no se mueve, o se mueve todo extraño, o se queda titilando el personaje, se duplica... O.o

Qué karma las colisiones en el Game Maker  :'(

EDIT:

¡ME FUNCIONO! Es que me había puesto a cambiar los "1" de los lengthdir por números más altos pensando que así iba a subir la velocidad (no me preguntes por qué pensé eso xD una laguna mental ahí jajaja).

Pero sí, ya funciona perfecto el movimiento y la colisión, lo único que tuve que modificar fue:

image_angle = point_direction(x,y,xx,yy)

Porque como lo tenía igual a direction y ahora no usa direction, la imagen no rotaba.

Muchas gracias otra vez, no había visto nunca ese código para movimiento, grande bruno  ;D
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: brunoxzx en Marzo 29, 2013, 10:48:10 PM
Que raro reviza que la speed sea 0 siempre 0 en el debug mode. Elimina todo lo que tenga que ver con ella. reviza que en las variables xx e yy sean a las que quieres ir, es decir las que estaban antes en el move_towards, fuera de eso no se me ocurre nada m[as.
Título: Re:Ayuda con este tipo de colisión (nuevo problema)
Publicado por: Klind en Marzo 29, 2013, 11:00:04 PM
No no, ya está listo hermano, lee el EDIT de mi post anterior. Tu código funcionó perfecto.
Título: Re:Ayuda con este tipo de colisión (casi SOLUCIONADO)
Publicado por: Klind en Marzo 29, 2013, 11:46:06 PM
Bruno, el código funciona excelente, pero a veces se sigue quedando atascada la bola cuando, estando pegada a una pared, el ángulo en el que la muevo está muy cerrado pero no lo suficiente como para que su trayectoria sea casi paralela a la pared.

Te pongo una imagen para explicarme bien. (Ve la imagen por favor) Cuando estoy así de pegado a la pared y trato de moverlo en esa dirección o un poco más abajo, no se mueve. En cambio si le trazo una línea recta hacia la derecha sí se mueve (a veces).
Muy rara vez pasa que tengo que hacerle la línea casi completamente hacia abajo para que pueda moverse de ahí.
He probado tildando y destildando la Precise collision checking de la pared y de la bola pero nada que se acomoda.
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: brunoxzx en Marzo 30, 2013, 01:04:02 AM
Mmmm, es cierto se me paso pensar en eso  :P. Perdon  :-[.

[gml]
image_angle=point_direction(x,y, xx,yy);
var dx, dy;
dx=lengthdir_x(1, image_angle);
dy=lengthdir_y(1, image_angle);
repeat(vel){
    x+=place_free(x+dx, y);
    y+=place_free(x, y+dy);
}
[/gml]
Creo que asi funcionara  :-X.
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Marzo 30, 2013, 01:16:13 AM
Hermano revisa el código, el place_free(x,y) devuelve true o false, con ese código le estas sumando siempre 1 a la "x" y a la "y" del personaje, se va a mover siempre hacia abajo y la derecha xD
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: brunoxzx en Marzo 30, 2013, 05:01:12 AM
Ahh era así.
[gml]
image_angle=point_direction(x,y, xx,yy);
var dx, dy;
dx=lengthdir_x(1, image_angle);
dy=lengthdir_y(1, image_angle);
repeat(vel){
    x+=place_free(x+dx, y)*dx;
    y+=place_free(x, y+dy)*dy;
}
[/gml]
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Marzo 30, 2013, 07:13:10 PM
Con ese código se mueve bien el personaje, pero cuando toca la pared se queda todo trancado porque no tengo un condicional donde diga que:

if (el personaje llega a la pared) {mover = false; limpiar colas; destruir el punto al que uno llega;}

Entonces a éste último código le puse el condicional que usábamos en los códigos anteriores, quedando así:

image_angle = point_direction(x,y, xx,yy);
var dx, dy;
dx=lengthdir_x(1, image_angle);
dy=lengthdir_y(1, image_angle);
repeat(velocidad){
    x += place_free(x+dx, y)*dx;
    y += place_free(x, y+dy)*dy;
   
if !place_free(x+dx, y+dy)
{
    mover = false
    ds_queue_clear(xCola)
    ds_queue_clear(yCola)
    with (obj_point) {instance_destroy()}
    break;
}


Pero entonces sigue pasando lo mismo, por lo que creo que el problema está en ese condicional.
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Marzo 30, 2013, 07:35:40 PM
Bruno ¿sabes de qué me he dado cuenta? Que sea cual sea el código que usemos para movimiento, el problema de quedarse atascado el personaje NUNCA pasa cuando quito el image_angle = point_direction(x,y, xx,yy)
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Johann en Marzo 30, 2013, 07:52:43 PM
No he leído todo el post, pero en el ultimo código TODO debería estar dentro del condicional if(!place_free... porque primero te mueves y luego si verificas que el espacio este libre, por eso es que se atasca.
Y por cierto, evita hacer doble post, por ahí hay una opción de modificar asi como lo hiciste antes (http://www.comunidadgm.org/index.php?topic=18429.msg87724#msg87724)
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Marzo 30, 2013, 08:24:07 PM
Lo coloqué de este modo haciendo lo que dices de primero chequear y luego mover:
if mover = true
{
var dx, dy;
dx=lengthdir_x(1, point_direction(x,y, xx,yy));
dy=lengthdir_y(1, point_direction(x,y, xx,yy));

if !place_free(x+dx, y+dy)
{
    mover = false
    ds_queue_clear(xCola)
    ds_queue_clear(yCola)
    with (obj_point) {instance_destroy()}
}
else
{
repeat(velocidad)
    {
    x += place_free(x+dx, y)*dx;
    y += place_free(x, y+dy)*dy;
    }
image_angle = point_direction(x,y, xx,yy);
}


Pero sigue pasando lo mismo.

Estoy buscando la forma de que el personaje detenga el movimiento 1 o 2 píxeles antes de llegar a la pared, pero se hace difícil por la forma en la que se mueve el personaje.

EDIT:

El problema lo da el image_angle = point_direction(x,y, xx,yy). Al girar la imagen queda un píxel dentro de la pared o algo así.

Cierto, disculpa por el doble post. Es que ando ya desesperado.
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Johann en Marzo 30, 2013, 08:52:42 PM
¿Qué tipo de mascara usa el sprite?
Si es cuadrada cambiala por la mascara circular, o mira cual sirve mejor
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Marzo 30, 2013, 09:33:56 PM
Tiene máscara circular. Cada vez que le cambio algo al código, lo pruebo con las distintas máscaras (precisa, circular). Con rectangular ni hablar, el sprite es redondo por lo que no funciona esa máscara.

¿Con ese tipo de movimiento que uso hay alguna forma de saber la coordenada de cada step antes de darlo? En ese caso puedo usar instance_place para que el personaje nunca llegue a tocar la pared.
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: brunoxzx en Marzo 31, 2013, 12:23:33 PM

Cita de: Maitreya en Marzo 30, 2013, 07:52:43 PM
No he leído todo el post, pero en el ultimo código TODO debería estar dentro del condicional if(!place_free... porque primero te mueves y luego si verificas que el espacio este libre, por eso es que se atasca.
Y por cierto, evita hacer doble post, por ahí hay una opción de modificar asi como lo hiciste antes (http://www.comunidadgm.org/index.php?topic=18429.msg87724#msg87724)
Mmm podría tener el "place_free" antes pero no es realmente necesario, ademas el código verifica si el espacio está libre antes de moverse.

Cita de: Klind en Marzo 30, 2013, 09:33:56 PM
Tiene máscara circular. Cada vez que le cambio algo al código, lo pruebo con las distintas máscaras (precisa, circular). Con rectangular ni hablar, el sprite es redondo por lo que no funciona esa máscara.
Mmmm que raro, teóricamente no debería suceder, en todo caso una solución algo fea a eso es dejar de usar image_angle, creas una nueva variable llamada por ejemplo "angulo" y modificas esa en lugar de image_angle, entonces en el evento draw pones esto.
[gml]draw_sprite_ext(sprite_index, image_index, x, y, image_scale, image_yscale, angulo, image_alpha, image_blend);[/gml]


Cita de: Klind en Marzo 30, 2013, 09:33:56 PM
¿Con ese tipo de movimiento que uso hay alguna forma de saber la coordenada de cada step antes de darlo? En ese caso puedo usar instance_place para que el personaje nunca llegue a tocar la pared.
En teoría eso es lo que debería de hacer el código que puse. Que alguien me corrija si me equivoco.

Aunque pensándolo bien esta este código que tenia en un juego viejo con el mismo tipo de movimiento. No recuerdo de donde lo saque, pero en general la idea del código no es mala a pesar de no ser el más eficiente.

Solo ponlo en end step y sigue usando el move_towards sin usar algún otro código para las colisiones.
[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]
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Marzo 31, 2013, 06:52:46 PM
Demasiado enredo jaja  XD...

Solucioné el problema de una forma un tanto "fea" y "pobre" pero a fin de cuentas está solucionado, puse esto en el evento press <Space> del personaje (que es la tecla que lo hace caminar por la ruta luego de que uno la traza:

if xx > x && place_free(x+1.5, y) {x += 1.5}
if xx < x && place_free(x-1.5, y) {x -= 1.5}
if yy > y && place_free(x, y+1.5) {y += 1.5}
if yy < y && place_free(x, y-1.5) {y -= 1.5}
mover = true


Eso lo desatasca de las paredes justo antes de mover la bolita. Igualmente espero en un futuro darle una solución decente a eso.

Una pregunta, ¿cómo haces que tu código se vea así grande y con los colores que identifican a las variables y funciones?
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: brunoxzx en Abril 01, 2013, 05:47:08 AM
Cita de: Klind en Marzo 31, 2013, 06:52:46 PM
Demasiado enredo jaja  XD...

Solucioné el problema de una forma un tanto "fea" y "pobre" pero a fin de cuentas está solucionado, puse esto en el evento press <Space> del personaje (que es la tecla que lo hace caminar por la ruta luego de que uno la traza:

if xx > x && place_free(x+1.5, y) {x += 1.5}
if xx < x && place_free(x-1.5, y) {x -= 1.5}
if yy > y && place_free(x, y+1.5) {y += 1.5}
if yy < y && place_free(x, y-1.5) {y -= 1.5}
mover = true


Eso lo desatasca de las paredes justo antes de mover la bolita. Igualmente espero en un futuro darle una solución decente a eso.

Una pregunta, ¿cómo haces que tu código se vea así grande y con los colores que identifican a las variables y funciones?
Que mal que no te haya podido ayudar, me habira gustado hacerte un ejemplo pero aqui en linux no puedo, me siento como wadk  :-[.

Para hacer lo de los colores tienes que usar el tag de codigo gml, durante un tiempo habia un icono pero con las actualizaciones murio  ;D. Se usa as'i [gml]if wololo then transformar() end;[/gml].
[gml]if wololo then transformar() end;[/gml]
Título: Re:Ayuda con este tipo de colisión (casi solucionado)
Publicado por: Klind en Abril 01, 2013, 06:50:11 PM
¿Cómo que no? Al contrario, ayudaste un montón.

Excelente, mucho mejor ese formato jajaja.

Gracias por todo bro!