Septiembre 14, 2018, 08:32:23 PM Ultima modificación: Septiembre 20, 2018, 07:12:27 PM por pixel rojo gamer
Estoy intentando hacer un simulador de mecánica orbital en 2D. Tomen como referencia a los siguientes juegos:


Así como Angry Birds tiene una forma de predecir sus trayectorias parabólicas, los juegos dichos también predicen las trayectorias elípticas:



¿Cómo podría hacer esto último en Game maker? (A partir de mi código)

Mi juego, por el momento consiste en un objeto Sol (oSol) al centro y un objeto player (oPlayer) que está orbitando a su alrededor.

Evento Create de oPlayer

x=oSol.x;
y=oSol.y-350;

hspeed=0.3;


Evento Step de oPlayer

//Codigo de gravedad hacia el Sol
var g, DirG;
with (oSol){
   g = masa/sqr(point_distance(x, y, oPlayer.x, oPlayer.y)); //Ley de gravitacion F=GM/r^2
   DirG = point_direction(oPlayer.x, oPlayer.y, x, y); //Direccion de la gravedad
   with (oPlayer) {motion_add(DirG, g);} //Aceleracion de la gravedad
}


Evento Create de oSol
masa=25;

Evento Keyboards de oPlayer
hspeed -= 0.001; //<Left>
vspeed -= 0.001; //<Up>
hspeed += 0.001; //<Right>
vspeed += 0.001; //<Down>



Lo que necesito saber es qué poner en el evento Draw para lograr hacer algo como lo que dije... Desde ya, muchas gracias!!

Se puede hacer de esta forma, pero no es la más eficiente.
Puedes ver como funciona aquí: Ejemplo en GMLive
[gml]
// Arguments
var px = argument0; //planet x
var py = argument1; //planet y
var pg = argument2; //planet gravity

var bx = argument3; //bullet x
var by = argument4; //bullet y
var bv = argument5; //initial speed
var bd = argument6; //initial direction

var bvx = lengthdir_x(bv, bd);
var bvy = lengthdir_y(bv, bd);
var bg, bgd; //gravity and gravity direction for bullet

draw_primitive_begin(pr_linestrip);
repeat(500) {
    draw_vertex(bx,by); //bullet position
    bx += bvx; //move bullet
    by += bvy;
    bg = pg / point_dist_sqr(px,py, bx,by); //update gravity
    bgd = point_direction(bx,by, px,py); //update gravity direction
    bvx += lengthdir_x(bg, bgd); //update speed
    bvy += lengthdir_y(bg, bgd);
}
draw_primitive_end();
[/gml]
Dentro de ese script se usa otro script: point_dist_sqr
[gml]
// point distance squared
return sqr(argument0 - argument2) + sqr(argument1 - argument3);
[/gml]
Es mejor que usar point_distance y después elevar al cuadrado, nos ahorramos 2 operaciones.

Sería más eficiente si la trayectoria no se re-dibujara en cada evento Draw. Se podría dibujar en una surface.
También podría calcularse más rápido si se obtiene una ecuación paramétrica a partir de las condiciones inicales, no lo he investigado, pero debe se posible.
Algo que me parece complicado es hacer líneas punteadas con segmentos de longitud igual.