How do I create space like gravity & jetpack

0 favourites
  • 7 posts
From the Asset Store
Fully commented source code/event sheet & sprites to create a space shooter game
  • Hey guys,

    So I'm building a simple 2D platformer.

    I've got the basic movements down and need help with the more advanced movement mechanics.

    First is to create the feel of space when player jumps, falls etc. I've spoken to a programmer friend and he said that I might be able to make it happen through a decay effect on the movements speed during a jump. Makes sense, though not sure how to achieve it on C2.

    The other is to create a jetpack mechanic with a set power, were the player can hover up and down the 2d space by pressing a key. I want them to have the option to press and hold (capped power) and do continues hits too.

    Hope that makes sense?

    Faraz

  • Hey TheZinc,

    If I understand, you're interested in simulating low gravity, and a jetpack with a capped maximum speed.

    I'm not sure what stuff you already know, so I'll just go over the things that might help out.

    Summary:

    Frame rate independent acceleration can be tricky, but is doable with "delta time", some math, and also even more math.

    C2's Physics behavior can do it all automatically.

    Try ignoring Jetpack thrust when player is over desired speed cap.

    Low Gravity

    In a low gravity environment, like the moon, physics will behave exactly the same way as on Earth, except that the global downward acceleration on all objects will be a lower value.

    On earth the downward acceleration (gravity) is

    32 ft/s^2 "feet per second ... per second"

    Meaning every "second", a falling object picks up an extra 32 "feet per second" of speed.

    On the moon the downward acceleration is about

    5 ft/s^2 "feet per second ... per second"

    Meaning every "second", a falling object only picks up an extra 5 "feet per second" of speed.

    In Construct 2 terms this is like saying every second add 5 (feet per second) to an object's Y velocity.

    Acceleration per tick

    So, we could make a C2 event that said:

    "Every second add 5 to an object's Y velocity."

    Unfortunately that accelerates by an amount of 5 in a big burst every 1 second.

    What we really want, is to accelerate by an amount of 5, but smoothly spread out over 60 ticks per second:

    Every tick (60th of a second) add "5 * (1/60)" to an object's Y velocity.

    Now after 1 second of ticks we will have added 60 of those "5 * (1/60)" slices, which is a total increase of "5" for Y velocity, over 1 second. Success!

    This almost works, but remember that not everyone's monitor is capped at 60 frames per second. Some will be 120 fps, or 144 fps, or on a slower machine, you might get 30 fps.

    So if you cant count on 60th of a second ticks, and multiplying by 1/60; but you also can't count on 120th of a second ticks, and multiplying by 1/120; then what do you do?

    It would be handy if C2 could tell you exactly how short a tick was right at the moment the calculation was being done. Fortunately it can, and that value is called "dt" for "delta time", meaning the fraction of a second since the last tick.

    When the frame rate is 60 fps, dt will be 1/60th.

    When the frame rate is 120 fps, dt will be 1/120th.

    It's exactly what we need.

    So instead of saying:

    Every tick (60th of a second) add "5 * (1/60)" to an object's Y velocity.

    We now say:

    Every tick (delta sized sliver of a second) add "5 * (dt)" to an object's Y velocity.

    In practical terms, using a lower gravity value will mean the player jumps higher than in normal gravity, and the arc of motion will appear to be in slow motion.

    Curse of Calculus

    So all the above fiddling with "dt" gets us the right velocity regardless of tick rate, but there's still a problem.

    It doesn't get us the right position, because position is based on velocity over time.

    If your game runs at 1 fps, a dropped stone will have the correct velocity after 1 second, but it won't have gone anywhere yet, because before that first second it's velocity was zero, so it covered no distance at all, for that whole second.

    Drop the same stone, using a faster frame rate (like 60 fps), and after 1 second the velocity will be exactly the same as in the prior example, but the stone will have traveled downward on every tick after the first one.

    In the real world, if you graphed the increase of velocity over time, you'd get a nice increasing diagonal line.

    In the game world you are stuck with ticks, so the velocity is changing in stair steps, and the notches (stairs) are the error. Making the time slices (stairs) smaller makes this error smaller, but this just means the size of the error will vary with the speed of the frame rate.

    Now this error might not be a huge issue, but if you want to eliminate it, you can use Euler integration or Verlet integration, which both attempt to account for the missing stair step area, regardless of step size. Verlet is kind of like an interpolated version of Euler.

    Another way to eliminate it is just to use a pre-built physics engine that handles all this stuff, like C2's built in Physics Behavior, or a comparable 3rd party Physics solution like Chipmunk Physics (which another C2 dev built a plugin for). Note, I think you have to set C2's physics to be frame rate independent with an event, if you want it to do all that "dt" stuff I described above, but it basically just has an "on switch" for that mode.

    Jetpack velocity cap

    One way to cap the power of the jetpack is to make it apply thrust only when the player's upward speed is below a threshold.

    e.g.

    If player is pressing Thrust key,

    AND

    If the player's upward velocity is below 100 pixels a second,

    THEN

    Add +1 to upward velocity.

    Just remember that in Construct 2 upward velocity is actually negative "Y".

    So the above code written in Construct would look like this:

    If player is pressing Thrust key,

    AND

    If the player's Y velocity > -100.

    THEN

    Add -1 to upward velocity.

    Hope that helps out.

  • Firstly, I love you!

    Thanks for taking the time and explaining it so well that I could understand the theory with my elementary understanding of physics and mathematics.

    Secondly, I'm going to have to put these into practice to get a complete understanding of the application and limitations..

    In terms of monitor frame rates, isn't it something that can be capped? Can I not set it to 60 fps and any PC or device playing the game will limit fps?

    I imagine these are some of the problems you had to solve on Down Ward

    Looking forward to it

  • thats a impressive analysis !!!

    Will bookmark this thread for future games !!!

  • Happy to help, TheZinc and :)

    > Firstly, I love you! Secondly, I'm going to have to put these into practice to get a complete understanding of the application and limitations..

    I've found that sometimes it can be handy to open a second copy of Construct 2, just to try something out in a simple blank-slate environment, before adding it to a complex project. Not sure if it's applicable in this case, but I figured I'd mention it.

    > In terms of monitor framerates, isn't it something that can be capped? Can I not set it to 60 fps and any PC or device playing the game will limit fps?

    I believe Construct 2 leaves the scheduling of the frames (basically the framerate) up to whatever HTML5 engine is running the game, whether that's Firefox, or Chrome, or NW.js (NodeWebkit).

    This means that you can't really rely on a given framerate, because each platform may behave differently. Even if you could cap it, it would only limit the maximum framerate, but wouldn't necessarily change the variability of the framerate.

    That said, there's another important side to this, which is that you might not want to limit the maximum framerate in the first place.

    If you can make your game truly framerate independent, it will run correctly at any monitor refresh rate, rather than being 60 Hz only, and it will look very smooth and fluid on high refresh rate monitors.

    My recommendation would be to always aim for framerate independence if possible, unless the project absolutely requires a fixed framerate.

    Construct 2 already allows you to export for multiple platforms, so also setting up a game to run on multiple monitor types just gets you that much closer to having a game that can run on anything. :)

    I should have assumed this in advance, but Ashley put together a nice tutorial article on using "dt" for framerate independence:

    Delta-time and framerate independence

    This is another nice article I found that covers framerate independent acceleration, and shows a few different integration formulas. (Euler, Verlet, and RK4)

    Integration Basics

    (Remember, "integration" is just a method of eliminating that stair-step error I mentioned in the first post. It does it by calculating what you would see if you could increment in finer steps, infinitely finer steps actually.)

    > I imagine these are some of the problems you had to solve on Down Ward

    Yes indeed. :)

    Down Ward is framerate independent, using "dt" in relevant time dependent expressions, and the Physics behavior in "Framerate independent" mode.

    The first game I built framerate independence into from the ground up was my prior game-jam game ArcherOpteryx. After seeing how smooth it looked at a 144 hz refresh rate, and after seeing that my prior game-jam games didn't run correctly on any refresh rate other than 60 Hz, I decided that I would incorporate framerate independence into every future project. After that I retroactively updated Neon Phoenix to be framerate independent. I eventually hope to similarly update my first two game-jam games Owl Camp and Lucid which are currently not framerate independent.

    My recommendation would be to always aim for framerate independence if possible, unless the project absolutely requires a fixed framerate.

    It's actually not as hard as it might seem at first, because almost everything can be made framerate independent just by multiplying "dt" to rate values in expressions.

    The "calculus" type stuff only ever shows up for very few special cases, when you're dealing with stuff that's non-linear over time, like acceleration for physics. Likewise, even if you go the completely from-scratch rout, the only "calculus" based math you'll encounter is actually just some basic multiplication and addition done in the right places. The reason it works is related to calculus, the term used to describe the process ("integration") comes from calculus, but the actual math that makes it work is just basic multiplication and addition.

    As for the jetpack problem, my first game-jam game Owl Camp actually does involve a jetpack, and (if I recall) it is thrust limited in the fashion I described in my prior post. :)

    > Looking forward to it

    Thanks TheZinc. You can actually try out the open alpha of Down Ward right now if you're interested.

    Down Ward (alpha)

    Happy to hear you're looking forward to it. I'm working on the next update now actually. :)

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • So I've attempted to apply the low gravity by doing the following:

    Set platform vector Y to { self.Y + (5*(dt)) }

    Which slows down the drop movement. However, it also alters the jump function (basically can't jump). It could most likely be the way I wrote out the expression, but seemed close to what the scirra.com/tutorials/67/delta-time-and-framerate-independence indicated.

    Also the feel of the drop didn't seem very low-gravity. So I tried decreasing the value to 2-3 without a noticeable difference.

    I also tried applying it to | set Y to { self.Y + (5*(dt)) }

    And that just makes the player object jump up and down at a fast rate so I don't think it's the correct action.

    Framerate Independent

    Sounds like the way to go. Will save me much hassle in the long-run. Although I am having difficulty figuring out how to actually make the switch to dt in the default physics.

    [quote:1xaovkma]You can enable use of dt by using the Set Stepping Mode physics action on start of layout, and choose Framerate independent

    Down Ward

    Dude I'm way ahead of you. On my fourth attempt, can't get passed that curved angle flight on the right of the level after the tutorial. I've seen you do it on the gameplay video though, so I know it's possible .

    The music, sound and the gameplay are great. I think it's what keeps me coming back, even though I keep getting stuck at the same point.

  • UPDATE

    I've managed to get the desired effect by changing the platformer values of my player object.

    Gravity has been decreased to 900

    Fall Speed has been set to 100

    And a decrease in Jump Strength to 250

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)