Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: 8 bits en Agosto 08, 2020, 04:15:39 PM

Título: colisión con la pista
Publicado por: 8 bits en Agosto 08, 2020, 04:15:39 PM
Que tal makeros y makeras, aqui el pana 8-bits con la pregunta del siglo.

Lo que pasa es que ahora el modo de carreras del juego de naves va de maravilla pero quiero que cuando la nave no colisione con la pista, que no se mueva.

Mi solución fue que como tenía la pista como background, hacer otro objeto con el sprite de la pista y que la nave en su evento step que detecte si está o no colisionando con ella, entonces recordé que no tengo ni idea de como detectar colisiones mediante código.

Una ayudita?  :-[ (solamente aclaro, necesito un código para detectar colisiones y que ejecute otro código dependiendo del resultado)
Título: Re:colisión con la pista
Publicado por: Tylag en Agosto 08, 2020, 04:26:15 PM
Hola,
Si optas por tu idea de que la pista sea un objeto puedes hacerlo con place_meeting(), esto iria en tu objeto nave:
[gml]
if (!place_meeting(x,y,obj_pista)) {
// Ejecutar codigo de pararse
}
[/gml]

De todos modos tienes muchas maneras de hacerlo, si la pista está estática en un punto y es rectangular puedes usar point_in_rectangle ( https://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/point_in_rectangle.html ) o rectangle_in_rectangle ( https://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/rectangle_in_rectangle.html ) si quieres que use todo el bounding box o el alto/ancho del sprite de la nave.

Edit: tambien podrías usar collision_rectangle
https://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/collision_rectangle.html


[gml]if (!collision_rectangle( x superior izda de tu pista, y superior izda de tu pista, x inferior derecha de tu pista, y inferior derecha de tu pista, obj_nave, 0, 0)) {
// Ejecutar codigo de pararse
}[/gml]


Un saludo.
Título: Re:colisión con la pista
Publicado por: 8 bits en Agosto 08, 2020, 05:18:46 PM
Cita de: Tylag en Agosto 08, 2020, 04:26:15 PM
Hola,
Si optas por tu idea de que la pista sea un objeto puedes hacerlo con place_meeting(), esto iria en tu objeto nave:
[gml]
if (!place_meeting(x,y,obj_pista)) {
// Ejecutar codigo de pararse
}
[/gml]

De todos modos tienes muchas maneras de hacerlo, si la pista está estática en un punto y es rectangular puedes usar point_in_rectangle ( https://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/point_in_rectangle.html ) o rectangle_in_rectangle ( https://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/rectangle_in_rectangle.html ) si quieres que use todo el bounding box o el alto/ancho del sprite de la nave.

Edit: tambien podrías usar collision_rectangle
https://docs.yoyogames.com/source/dadiospice/002_reference/movement%20and%20collisions/collisions/collision_rectangle.html


[gml]if (!collision_rectangle( x superior izda de tu pista, y superior izda de tu pista, x inferior derecha de tu pista, y inferior derecha de tu pista, obj_nave, 0, 0)) {
// Ejecutar codigo de pararse
}[/gml]


Un saludo.

muchas gracias, aunque lo de los rectangulos no me sirven ya que mi pista no se conforma de rectangulos unicamente, como sea en el primer código que mandaste es necesario poner los dos slash?

Edit: que raro, no funciona con o sin slash ¿exactamente como funciona ese código?
Título: Re:colisión con la pista
Publicado por: Tylag en Agosto 08, 2020, 05:30:18 PM
Hola,
No, doble slash te permite poner comentarios a tu codigo (muy recomendable tener el codigo bien documentado) en este caso dentro del if statement tendrias que meter la logica para que la nave se pare ( esto ya dependiendo de como lo vayas a querer implementar, si se para en seco, si pierde velocidad gradualmente, etc...)

Título: Re:colisión con la pista
Publicado por: 8 bits en Agosto 09, 2020, 02:03:55 AM
Cita de: Tylag en Agosto 08, 2020, 05:30:18 PM
Hola,
No, doble slash te permite poner comentarios a tu codigo (muy recomendable tener el codigo bien documentado) en este caso dentro del if statement tendrias que meter la logica para que la nave se pare ( esto ya dependiendo de como lo vayas a querer implementar, si se para en seco, si pierde velocidad gradualmente, etc...)

muy cierto pero igual el codigo no funciona, quiero poner que la hspeed y la vspeed se reduzcan a 0 y... Bueno, no lo hace
Título: Re:colisión con la pista
Publicado por: Tylag en Agosto 09, 2020, 08:40:32 AM
Hmmm, ¿puede que estes volviendo a actualizar el hspeed/vspeed aunque lo hayas puesto a valor 0?
Es decir si tu código es algo así

[gml]
if (!place_meeting(x,y,obj_pista)) {
hspeed = 0;
}
if keyboard_check(vk_left) hspeed = -2;
if keyboard_check(vk_right) hspeed = 2;
[/gml]

Tu hspeed volverá a tomar valores independientemente de si toca la pista o no, tendrás que meterle una condicion extra a tu movimiento de que solo se realice si está tocando la pista.
[gml]
hspeed = place_meeting(x,y,obj_pista) ? (keyboard_check(vk_right) - keyboard_check(vk_left))*tuvelocidadhorizontal : 0
[/gml]
Algo parecido a esto, tendrías que permitir el movimiento unicamente si la nave toca la pista.

Hay muchas otras formas de hacerlo, podrias meter una variable boolean que permita el movimiento pero se actualice a false al no tocar la pista y bloquee el movimiento de la nave, por ejemplo ( no lo veo lo más elegante pero valdría)

[gml]
//Esto en el create
var_movimiento = true;

//Esto ya en el step
if (var_movimiento) {
if keyboard_check(vk_left) hspeed = -2;
if keyboard_check(vk_right) hspeed = 2;
}

if (!place_meeting(x,y,obj_pista)) {
hspeed = 0;
var_movimiento = false
}
[/gml]

Espero que puedas solucionarlo amigo
Título: Re:colisión con la pista
Publicado por: 8 bits en Agosto 09, 2020, 03:30:46 PM
Cita de: Tylag en Agosto 09, 2020, 08:40:32 AM
Hmmm, ¿puede que estes volviendo a actualizar el hspeed/vspeed aunque lo hayas puesto a valor 0?
Es decir si tu código es algo así

[gml]
if (!place_meeting(x,y,obj_pista)) {
hspeed = 0;
}
if keyboard_check(vk_left) hspeed = -2;
if keyboard_check(vk_right) hspeed = 2;
[/gml]

Tu hspeed volverá a tomar valores independientemente de si toca la pista o no, tendrás que meterle una condicion extra a tu movimiento de que solo se realice si está tocando la pista.
[gml]
hspeed = place_meeting(x,y,obj_pista) ? (keyboard_check(vk_right) - keyboard_check(vk_left))*tuvelocidadhorizontal : 0
[/gml]
Algo parecido a esto, tendrías que permitir el movimiento unicamente si la nave toca la pista.

Hay muchas otras formas de hacerlo, podrias meter una variable boolean que permita el movimiento pero se actualice a false al no tocar la pista y bloquee el movimiento de la nave, por ejemplo ( no lo veo lo más elegante pero valdría)

[gml]
//Esto en el create
var_movimiento = true;

//Esto ya en el step
if (var_movimiento) {
if keyboard_check(vk_left) hspeed = -2;
if keyboard_check(vk_right) hspeed = 2;
}

if (!place_meeting(x,y,obj_pista)) {
hspeed = 0;
var_movimiento = false
}
[/gml]

Espero que puedas solucionarlo amigo

a ver si entendí, debo hacer una variable que esté en true por defecto y que se cambie a false si la pista y la nave están en colisión y que si  esté en false la nave no se pueda mover pero que si esté en true si ¿cierto?
Título: Re:colisión con la pista
Publicado por: 8 bits en Agosto 09, 2020, 04:11:12 PM
Cita de: 8 bits en Agosto 09, 2020, 03:30:46 PM
a ver si entendí, debo hacer una variable que esté en true por defecto y que se cambie a false si la pista y la nave están en colisión y que si  esté en false la nave no se pueda mover pero que si esté en true si ¿cierto?

ahora no se que se supone que hago mal, todo iba bien hasta que decidí cambiar el angulo de la imagen por cada tecla, ahora las teclas izquierda y derecha no funcionan y el personaje se mueve libremente por la pista

ya te muestro el codigo

[gml]//evento create

var_movimiento = true;
image_xscale=0.5
image_yscale=0.5
image_angle=90

//evento step

if (var_movimiento) {
if keyboard_check(vk_left) hspeed = -8
image_angle=180;
if keyboard_check(vk_right) hspeed = 8;
if keyboard_check(vk_up) vspeed = -8
image_angle=90;
if keyboard_check(vk_down) vspeed = 8
image_angle=270;
if keyboard_check(vk_nokey) vspeed = 0
hspeed = 0;

}if (!place_meeting(x,y,rainbow_road_colision)) {
hspeed=0;
yspeed=0;
}[/gml]

fallos encontrados en el juego:

Título: Re:colisión con la pista
Publicado por: Tylag en Agosto 09, 2020, 05:10:53 PM
Hola, te cambio un poco el código que has puesto y te comento

[gml]

//evento step
if (var_movimiento) {
   if keyboard_check(vk_left) {
      hspeed = -8
      image_angle=180;
   }
   if keyboard_check(vk_right) {
      hspeed = 8;
      image_angle = 0
   }
   if keyboard_check(vk_up) {
      vspeed = -8
      image_angle=90;
   }
   if keyboard_check(vk_down) {
      vspeed = 8
      image_angle=270;
   }
   if keyboard_check(vk_nokey) {
      vspeed = 0
      hspeed = 0;
   }

}
if (!place_meeting(x,y,rainbow_road_colision)) {
   hspeed=0;
   vspeed=0;
   var_movimiento = false;
}
[/gml]

El problema estaba en que no estabas incluyendo bien las lineas de código dentro de los if statement, si no encapsulas todo  con corchetes {}  el if cogera unicamente la siguiente linea a continuacion.
El resto de lineas se estaban ejecutando siempre.

Edit: Te dejo por aqui otra version del movimiento de tu nave con el código más compacto, un saludo!

[gml]
hspeed = place_meeting(x,y,rainbow_road_colision) ? (keyboard_check(vk_right) - keyboard_check(vk_left))*8 : 0;
vspeed = place_meeting(x,y,rainbow_road_colision) ? (keyboard_check(vk_down) - keyboard_check(vk_up))*8 : 0;
if (keyboard_check(vk_anykey) && place_meeting(x,y,rainbow_road_colision))
image_angle = point_direction(x,y,x+hspeed,y+vspeed);

[/gml]
Título: Re:colisión con la pista
Publicado por: 8 bits en Agosto 09, 2020, 11:49:40 PM
Cita de: Tylag en Agosto 09, 2020, 05:10:53 PM
Hola, te cambio un poco el código que has puesto y te comento

[gml]

//evento step
if (var_movimiento) {
   if keyboard_check(vk_left) {
      hspeed = -8
      image_angle=180;
   }
   if keyboard_check(vk_right) {
      hspeed = 8;
      image_angle = 0
   }
   if keyboard_check(vk_up) {
      vspeed = -8
      image_angle=90;
   }
   if keyboard_check(vk_down) {
      vspeed = 8
      image_angle=270;
   }
   if keyboard_check(vk_nokey) {
      vspeed = 0
      hspeed = 0;
   }

}
if (!place_meeting(x,y,rainbow_road_colision)) {
   hspeed=0;
   vspeed=0;
   var_movimiento = false;
}
[/gml]

El problema estaba en que no estabas incluyendo bien las lineas de código dentro de los if statement, si no encapsulas todo  con corchetes {}  el if cogera unicamente la siguiente linea a continuacion.
El resto de lineas se estaban ejecutando siempre.

Edit: Te dejo por aqui otra version del movimiento de tu nave con el código más compacto, un saludo!

[gml]
hspeed = place_meeting(x,y,rainbow_road_colision) ? (keyboard_check(vk_right) - keyboard_check(vk_left))*8 : 0;
vspeed = place_meeting(x,y,rainbow_road_colision) ? (keyboard_check(vk_down) - keyboard_check(vk_up))*8 : 0;
if (keyboard_check(vk_anykey) && place_meeting(x,y,rainbow_road_colision))
image_angle = point_direction(x,y,x+hspeed,y+vspeed);

[/gml]

muchas gracias colega, eres  tremendo programador, saludos y que Iwata te acompañe sin mas se  despide el pana 8-bits