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)
Azter

#1 Agosto 08, 2020, 04:26:15 PM Ultima modificación: Agosto 08, 2020, 04:32:45 PM por Tylag
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.

#2 Agosto 08, 2020, 05:18:46 PM Ultima modificación: Agosto 08, 2020, 05:28:39 PM por 8 bits
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?
Azter

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


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
Azter

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

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?
Azter

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:


  • las teclas left y right no funcionan
  • la nave se mueve fuera de la pista
  • la nave ignora los angulos cuando se presionan las teclas
  • la nave comienza apuntando hacia abajo cosa que no tiene sentido ya que si el sprite apunta a la derecha el angulo 90 apuntaría hacia arriba
Azter

#8 Agosto 09, 2020, 05:10:53 PM Ultima modificación: Agosto 09, 2020, 05:18:42 PM por Tylag
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]

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
Azter