I've seen a lot of tutorials for things like "fixed circular orbit" and "elliptical orbits" which end up never been what I actually want.
I have two objects: oPlayer
, and oPlanet
.
I am trying to allow the player to move around freely, but be able to be caught by the gravity of oPlanet
, causing the player to go around in circles/elliptical orbit. I also need the player to be able to escape thate orbit, and end up on a trajectory. In fact, I want it to work for any oPlanet
.
What I am looking for is something similar to the orbital gravity in Kerbal Space Program.
Is there any way I should go about this? If anyone can be of help, I would rather answers be in GML rather than the Drag and Drop, but any help is great!
Answer
I use Game Maker 8.1 all the time, and I've done orbital sims in them too. More good news: Game Maker has a built-in function that does vector addition for you:
motion_add(direction, acceleration)
this will automatically change an object's hspeed and vspeed with the correct vector addition.
Remember that Game Maker treats 0 degree angle pointing right, 90 degree pointing up (which is the negative y direction), 180 deg pointing left, 270 deg pointing down. However, with motion add, you don't even need to know that.
Here's what I would do. In oPlayer, use the built-in variables x, y, hspeed, vspeed so that GM automatically does motion based on speed. Now you just need to do the acceleration from gravity, using motion_add. In the step event of oPlayer, write this:
var g, gdir; // it's necessary to make these temp vars because GM code remembers them in the scope even if you go into "with" for other objects. THIS ALSO ASSUMES YOU HAVE NO OTHER VARIABLES NAMED g OR gdir IN EITHER oPlayer OR oPlanet
with (oPlanet)
{
// this assumes each planet has a mass variable, I used 1000
g = mass/sqr(point_distance(x, y, oPlayer.x, oPlayer.y)); // handy built-in distance function
gdir = point_direction(oPlayer.x, oPlayer.y, x, y); // VERY HANDY built-in get direction function from point 1 to point 2
with (oPlayer)
motion_add(gdir, g);
}
Now in the key down events for oPlayer, for all 4 arrow buttons, put this
hspeed += 0.2; // for right arrow
hspeed -= 0.2; // for left arrow
vspeed -= 0.2; // for up arrow
vspeed += 0.2; // for down arrow
So if you hold down the right arrow, each step will add 0.2 to your hspeed. Softcode this with whatever variable name you want.
I tested this exact code myself in a GM example. The room speed was 60, oPlanet mass was 1000, and things seemed to flow at a normal pace. One orbit took 1 or 2 seconds and I could easily break or re-enter orbit by pressing the arrows.
There is 1 caveat: If the player goes too close to the planet, such as sinking beneath its surface, it will get SO close to the center that gravity becomes extremely strong, which tends to make the ship go flying off in a random direction and never coming back. To avoid this, you should make a destruction event so that the ship just crashes when it hits or goes below a planet's surface, then restart the game. Use point_distance() to test if the distance is less than or equal to the planet's radius.
Finally, like I said, I use GM 8.1. I have never used GM 9, also known as GM Studio because it looks very bloated and way, way different than the nice interface of GMs 5, 6, and 8 that I am used to.
No comments:
Post a Comment