Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: Marth en Junio 01, 2018, 11:54:12 PM

Título: Lateralidad de las colisiones [Solucionado]
Publicado por: Marth en Junio 01, 2018, 11:54:12 PM
Veran, es muy conocido el evento colisión, el cual detecta si 2 objetos han colisionado.
Yo lo que quiero es que ademas de detectar la colisión, detecte desde que lateral se ha producido el  choque (izquierda, arriba, derecha o abajo).
Un ejemplo, el jugador se mueve hacia arriba y a la derecha y a la derecha hay un muro. En ese caso, el jugador no avanzara a la derecha, pero aun podria moverse hacia arriba.
Título: Re:Lateralidad de las colisiones
Publicado por: Rosergio1 en Junio 02, 2018, 02:43:54 AM
podrías condicionar... como cuando haces un juego básico de mario al colisionar contra un enemigo para aplastarlo.

en el evento de colision contra el enemigo obviamente mientras lo toca, comprobamos que lo toque desde arriba, o no.

Si mario (caida vertical) es positivo

-var_desde_arriba = verdadero
si no
-Var_desde_arriba = falso


etc etc.
búscalo apropiadamente en tutoriales de youtube

(no se GML, pero se lo básico de programar, para eso soy grafista
asi que perdona el ejemplo de codigo horrible, es para ejemplo solamente)
Título: Re:Lateralidad de las colisiones
Publicado por: Marth en Junio 02, 2018, 10:36:10 AM
Voy a dar más detalles.
En la foto  que adjunto vemos un tanque chocando con una roca. Cuando el tanque choca, se detiene por completo. Como esta chocando en diagonal, se queda totalmente parado, pero si por ejemplo chocara en el borde derecho, no avanzaria el tanque lateralmente, pero si hacia abajo.
Título: Re:Lateralidad de las colisiones
Publicado por: zorge en Junio 02, 2018, 09:39:13 PM
por lo que entiendo de tu pregunta es como si se usaran fisicas que cuando un lateral toca y hay una gravedad el objeto circula a traves de la roca por asi decirlo
Título: Re:Lateralidad de las colisiones
Publicado por: Clamud en Junio 03, 2018, 07:33:27 PM
¿Qué código que utilizas?

El método más fácil que he utilizado es realizar el movimiento horizontal y vertical de forma separada y revisar las colisiones despues de cada uno de esos movimientos. Todo en el evento Step.

[gml]
// Horizontal
x += vx; //deplazar

with( obBlock ){ //ejecutar en las instancias bloque
  if place_meeting(x,y, other.id){ //si hay colision
    if (other.x < x) //colision a la izquierda
      other.x = x - 16;
    else //colision a la derecha
      other.x = x + sprite_width + 16;
  }
}

//Vertical
y += vy; //desplazar

with( obBlock ){ //ejecutar en las instancias bloque
  if place_meeting( x,y, other.id ){ //si hay colision
    if (other.y < y) //colision arriba
      other.y = y - 16;
    else //colision abajo
      other.y = y + sprite_height + 16;
  }
}
[/gml]
En el código se supone que el origen del sprite del objeto jugador está centrado y el sprite de los bloques tiene su origen en (0,0).
En tu caso, vx, vy se deben calcular con las funciones lenghtdir y el ángulo del objeto.
No se debe evitar utilizar image_angle para no rotar la máscara de colisión. Para dibujar el objeto rotado se puede utilizar draw_sprite_ext y una variable de ángulo personalizada.

Otro método es utilizar el sistema de física (Box2D).

Ejemplo adjunto.
Título: Re:Lateralidad de las colisiones
Publicado por: Marth en Junio 03, 2018, 09:15:22 PM
Cita de: Clamud en Junio 03, 2018, 07:33:27 PM
¿Qué código que utilizas?

El método más fácil que he utilizado es realizar el movimiento horizontal y vertical de forma separada y revisar las colisiones despues de cada uno de esos movimientos. Todo en el evento Step.

[gml]
// Horizontal
x += vx; //deplazar

with( obBlock ){ //ejecutar en las instancias bloque
  if place_meeting(x,y, other.id){ //si hay colision
    if (other.x < x) //colision a la izquierda
      other.x = x - 16;
    else //colision a la derecha
      other.x = x + sprite_width + 16;
  }
}

//Vertical
y += vy; //desplazar

with( obBlock ){ //ejecutar en las instancias bloque
  if place_meeting( x,y, other.id ){ //si hay colision
    if (other.y < y) //colision arriba
      other.y = y - 16;
    else //colision abajo
      other.y = y + sprite_height + 16;
  }
}
[/gml]
En el código se supone que el origen del sprite del objeto jugador está centrado y el sprite de los bloques tiene su origen en (0,0).
En tu caso, vx, vy se deben calcular con las funciones lenghtdir y el ángulo del objeto.
No se debe evitar utilizar image_angle para no rotar la máscara de colisión. Para dibujar el objeto rotado se puede utilizar draw_sprite_ext y una variable de ángulo personalizada.

Otro método es utilizar el sistema de física (Box2D).

Ejemplo adjunto.

Esto es interesante.
Mi personaje se mueve en modo tanque, es decir, con izquierda y derecha altero direction y con arriba y abajo altero speed. ¿Como adapto una variable "velocidad" y direction para convertirlas en vx y vy?

Edito: Ya he encontrado la forma gracias a este código:

vx=lengthdir_x(veloz, direction) // Movemos al jugador.
vy=lengthdir_y(veloz, direction)

if(!place_meeting(x+vx,y,Muro)) // Movemos y revisamos colisiones.
   x+=vx

if(!place_meeting(x,y+vy,Muro))
   y+=vy


Con esto queda mi pregunta solucionada.