Junio 01, 2018, 11:54:12 PM Ultima modificación: Junio 04, 2018, 12:15:30 AM por Marth
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.

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)

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.

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

¿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.

#5 Junio 03, 2018, 09:15:22 PM Ultima modificación: Junio 04, 2018, 12:15:17 AM por Marth
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.