Comunidad Game Maker

Ayuda => Preguntas y respuestas => Mensaje iniciado por: Heartgleam en Octubre 02, 2017, 11:04:23 PM

Título: Movimientos orbitales
Publicado por: Heartgleam en Octubre 02, 2017, 11:04:23 PM
Hola, necesito que un objeto orbite a el mouse cuando lo presiono, si no que siga con su inercia. He estado buscando acerca de esto, pero todo es básico, órbitas fijas. Para que quede mas claro, quiero que haga algo similar a esto https://www.yoyogames.com/showcase/4/orbit es decir, que siga una órbita realista, que no sea siempre una esfera perfecta. Gracias de antemano!  :D

Añado: creo que se puede utilizar alguna forma de física modificandola un poco, pero no se como hacerlo, he pensado en la de la gravedad, pero no se si serviría
Título: Re:Movimientos orbitales
Publicado por: 3dgeminis en Octubre 04, 2017, 02:24:18 AM
Hay algunas funciones que te pueden ayudar para empezar
motion_add
gravity
gravity_direction
direction
speed
point_direction
Título: Re:Movimientos orbitales
Publicado por: Heartgleam en Octubre 04, 2017, 04:16:31 PM
Gracias, al final he usado motion add principalmente. Aquí el código, por si alguien lo busca:

temp = 0
repeat(instance_number(obj_ball))
{
inid = instance_find(obj_ball,temp)
if inid.id != id
{
inx = inid.x
iny = inid.y
pow = ((mass*inid.mass)/point_distance(x,y,inid.x,inid.y)^2)/50
dir = point_direction(x,y,inx,iny)
if pow < 0 pow = 0
motion_add(dir,pow*atracction_power)
temp += 1
}
}
Título: Re:Movimientos orbitales
Publicado por: Clamud en Octubre 04, 2017, 07:06:28 PM
La lógica del código está bien, sin embargo, hay muchas cosas que se pueden optimizar.

Esta parte
[gml]
temp = 0
repeat(instance_number(obj_ball))
{
inid = instance_find(obj_ball,temp)
[/gml]
se puede cambiar por with(obj_ball)

La función point_distance internamiente usa raiz cuadrada. No tiene sentido evaluar la raiz y luego elevar al cuadrado. Es mejor utilizar un script que calcule la distancia al cuadrado, lo que ahorra dos operaciones. El script puede ser así:
[gml]
/// distancia_cuadrada(x1,y1, x2,y2);
return sqr(argument0 - argument2) + sqr(argument1 - argument3);
[/gml]
Además el simbolo ^ no indica un exponente, sino que realiza la operación xor a nivel bit.

Esta parte no se necesita if pow < 0 pow = 0, porque las operaciones anteriores siempre dan un resultado positivo.

Con todos los cambios el códgo quedaría así:
[gml]
with( obj_ball ){
// revisar todas las instancias de obj_ball
  if( id <> other ){
  // si la instancia actual es diferente a la
  // instancia que inicio la ejecucion de este codigo
    f = mass * other.mass / 50; //calcular magnitud de la fuerza
    f /= distancia_cuadrada(x,y, other.x,other.y);
    d = point_direction(x,y, other.x,other.y); //calcular direccion
    motion_add(d, f*attraction_power); //aplicar fuerza gravitacional
  }
}
[/gml]
Título: Re:Movimientos orbitales
Publicado por: Heartgleam en Octubre 08, 2017, 10:47:42 PM
perdón por la tardanza, gracias por la optimización, pero con /= distancia_cuadrada a que te refieres?
Título: Re:Movimientos orbitales
Publicado por: Clamud en Octubre 09, 2017, 01:06:16 AM
El valor de la distancia elevado al cuadrado.

f = f/distancia_cuadrada