Basic platformer maths

Hi all

Im searching the forums here, and will continue to do so, but im wondering if anyone has some links to tutorials that help explain the basics of the maths required in a 2d platformer,

concepts like velocity, acceleration, gravity and friction. Ive seen the odd tutorial that skims over this stuff very lightly and just starts plugging in values etc… Im particularly interested in things like the physics in mario, especially sliding, dealing with ICE and how mario slides and continues to slide even when the direction is changed etc…

Any references people have that they can point me to?

Thanks

1 Like

You can take a look at this it was a guys uni homework project apparently (which i didn’t actually realize at the time or i probably wouldn’t of helped him as much as i did),
You cant use the content as it’s not mine and no rights were given for it but he himself posted a download link and i posted a reply project filled with a redone app.
I actually went back to it and fixed the jump physics a bit better but i don’t have that final version on this computer and they are basically fine here anyways.

That said…

Most of what your asking about is in this project with lots of notes everywere.

More then half of this code i wrote or rewrote or just created, even still i tried to follow what he was trying to do so it’s not like this is something id want to show off.
But you should be able to get some basic ideas. This is actually all posted in some post on here somewere already. Super amount of improvements could be made in terms of design from the start but i was adhock restructuring a broken project in a day.

Still its a simple example for lots of different things maybe it will help the guy said it helped him so.

Vs 2017 project.

https://drive.google.com/file/d/1cFml8OAIVFcI-DMV39CcO_QL2fRERF_i/view?usp=sharing

Should be tons of notes in it that i left for him you can read.

I added a class that makes level maps for him in a code array in the cs file so map making is nothing. I fixed the physics i added the ladders so he could climb them and debuging visuals for the collisions which i subpar reworked just enough so they actually worked and a bunch of other stuff most of which to be honest consisted of deleting horrible things they must have taught him to do. I replaced them with subpar fixes that encapsulated some level of responsibilty to each class and that at least were not ideas from the depths of spegetti hell. Though to me like i said most of this is still very ugly but it works.

2 Likes

There is also a monogame platformer example somewere but i don’t have a link for it.

Maybe not helpful, but that Megaman reminded me of this old article:
http://higherorderfun.com/blog/2012/05/20/the-guide-to-implementing-2d-platformers/

1 Like

Awesome, thanks for the samples guys, appreciate it.

I’m still interested in some of the theory around movement.

eg i have initial simplistic code such as

protected float linearVelocity = 4f; // how fast it moves in a direction.
if (Input.IsKeyDown(Keys.Left)) { objectPostion += new Vector2(-1, 0) * linearVelocity; }
if (Input.IsKeyDown(Keys.Right)) { objectPostion += new Vector2(1, 0) * linearVelocity; }

this moves the character back and forward on, but iguess im trying to understand how acceleration works. My velocity is a simple float where i see people are using a vector2d to maintain this.

Actually what im struggling to understand is really the basics of move movement

i can do something like this

  public Vector2 accelSpeed = new Vector2(4, 0);
    public Vector2 maxVelocity = new Vector2(20, 0);
    public Vector2 minVelocity = new Vector2(-20, 0);

if (Input.IsKeyDown(Keys.Right))
{
state = PlayerState.Walking;

            if (currentVelocity.X > maxVelocity.X)
                currentVelocity = maxVelocity;
            else
                currentVelocity +=  accelSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
        }

Where i have defined a max velocity and a an acceleration speed . This seems to allow the player to build up in speed, but i dont understand why there is the Time Component

ive seen other bits of code posted as

//In my constructor for the Player class
//Position is set equal to a new Vector2(0, 0)
//Velocity is set equal to Vector2.Zero
//Acceleration is set equal to a new Vector2(0, 100.0f);

        //float deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

        //Velocity += Acceleration * deltaTime;
        //Position += Velocity * deltaTime;

Again im not sure why or what the delta time is doing.

Then i started reading about lerp… so i guess im trying to understand some more of the basics… i have to admit i liek to try and understand whats going on and why, i can get sprites on the screen and animate them and all that, but themovement and understand gametime has been a bit confusing.

any pointers are helpful

Sure
A little breakdown in physics game terminology first as i have presented it in that project so that were on the same page.

  1. Velocity is the actual speed a object is moving be it in pixels or commonly in everyday life like meters per second.

  2. Speed is the scalar representation of Velocity its a float determined by the distance of the elements of velocity i.e.
    speed = squareRoot( v.X * v.X + v.Y * v.Y); // aka pythagoras
    In monogame there are built in functions for that in math or mathhelper.

  3. Velocity is speed times a normalize direction.
    directions are found as the difference between two positions such as
    theDirectionToTheTarget = targetPosition - playerPosition
    The normalization is then.
    toTargetNormalForThePlayer = Vector2.Normalize(theDirectionToTheTarget);
    So then velocity is.
    velocity = toTargetNormalForThePlayer * speed;

  4. Acceleration is a addition to velocity it is the result of the application of force.

  5. Thrust is in games typically considered to be acceleration as the result of the addition of force when applied to speed then that is later translated into velocity as shown in (3).

  6. Inertia is alternate description of velocity were displacement of the amount of acceleration a force applys to a massive or low mass object is varyed.
    (typically not used much in games) Objects with lots of mass typically require more kinetic force to accelerate them then a low mass object. They are also slowed down less by wind resistance and such. (this does not apply to gravity which is a special field force in this regard).

  7. Things in motion (objects with velocity like the player) stay in motion unless a force acts on them in this case air resistance and friction and gravity. (gravity is a force that produces constant acceleration)

  8. Per the title platform maths if you can’t make it, fake it knowing this stuff doesn’t mean you have to obey it in your game but it helps to know it.

Elapsed time why?

On the computer a frame takes a real amount of time aka your game world maybe virtual but time is physical even here and it can be misrepresented in your game.
In a game we like to define how fast things move in terms that relate to time like our player moves 5 pixels per second or 5% of the screen or world per second.
So to get smooth consistent motion when we want to be able to change the frame rate maybe increase it.
We want both the acceleration and the velocity to be affected by the portion of time that has actually elapse against the values we set for players and objects as how fast they can move per second.
So we mulitply things like acceleration and gravity by the elapse time between frames.

For example:

Take the difference between a game that runs at 60 fps and 1000 fps
If we define our players acceleration to accelerate 10 pixels in a second.
at 60 frames per second. Then our player would need to accelerate 10 / 60 = .166 pixels.
Now consider the same scenario at 1000 frames per second the player would need to accelerate at .01 pixels per second to move exactly 10 pixels in a second.
That can be a problem if we want to change the frame rate mid development.
We certainly don’t want to design a game were the player had 100 different speed values depending on the frame rate right.

So elapsed time is used or delta time if you think there is any posibility at all you will not use IsFixedTimeStep or keep TargetElapsedTime set to 1/60 or you wish to make your values something other then being based on just a constant amount of updates per second.

In essence using the delta time or elapsed time if you like allows you to decouple physical relations between the values you set in design terms of how fast you want things to move over time, vs how fast your frames per second is moving.

For example to move 10 pixels per second regardless of the frame rate.
we say 10 pixelsPerSecond is our speed.
the amount of distance we will move in a frame then depends on the elapsed fraction of time between two frames that has passed in the form of seconds.
So…
pixelsTraveledThisFrame = 10 * elapsedTimeInSeconds;
The more frames per second there are the smaller the value elapsed time will be.

Now you may ask why even say delta time well thats because to be precise your display resolution x and y are often not the same so while you may have elapsed time if you want to get really precise then you may want to turn your elapsed time into delta X and Y which is elapsed time in relation to smooth screen resolution motions width and height per second.

So even if you just want to use fixed time always and not use elapsed time at all you may still want a sort of delta speed especially if your application will be windowed or on different resolutions which you will probably will but you can get away with a lot Using just isfixedtimestep = true but you might want i bit more so…

Hey Will

Thanks for the detail breakdown. Im starting to feel a bit old and stupid. so im going to brain dump :slight_smile: its been many many years since i was a developer … funny how the brain slows down and isnt so quick on the uptake.

so i understand the concepts.

Eg Velocity being how fast an object is moving.

I have seen this defined as both a float and a vector.

Eg for a character moving along the X plane it could be defined as

Vector2( X, Y ) so Vector (4,0) would be moving 4 along the x plane.

Equally ive seen

Float Speed = 4f. and that i assume could be used for any direction.

ive also seen a vector being used to define the direction eg Vector ( 1,0) , Vector ( 0 , 1 ). vector (-1, 0 ).

this would be moving along the X plane 1, moving along the Y Plane 1, moving along the x plane -1 ( so left right up down type movement. ).

Using the vector as a direction i have seen people then define movements as

Position = DirectionVector * Speed.

Position = (1,0) * 4F

the above might be the default formula to define a character walking. A running character might have a linear velocity of say 8f. this is a very simplistic way to move a character at a fixed rate. basically ths will move the player 4 pixels per frame.

These concepts make sense to me and its just different ways to do the same thing i assume. move the sprite by X along a direction.

Acceleration i also understand in concept, that being a building up of movement to a defined limit.

Eg if i know the walking speed is 4 then i might have an acceleration step of 1 And this will slowly be added to my velocity until i reach that max value of 4 where it will stay until i let go of the trigger , as which point it might decrease slowly or just stop depending on the effect desired. i would assume the rate of deceleration is probably faster than the acceleration, This is my example code which builds the velocity of the player up and then depending on which way im moving will reduce the speed of the player back to zero

In the above im using the GameTime and multiplying by it, which right now make no difference aside from making my velocity very slow as im multiplying by 1/60. So this is where i need to get my head around the appropriate sizes as if im drawing 60 frames per second. Your explanation definitely helps :slight_smile: i just need to think more about how far i want my character to move

What has confused me is looking at other peoples codes where they have comments like

        //In my constructor for the Player class
        //Position is set equal to a new Vector2(0, 0)
        //Velocity is set equal to Vector2.Zero
        //Acceleration is set equal to a new Vector2(0, 100.0f);

        //float deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

        //Velocity += Acceleration * deltaTime;
        //Position += Velocity * deltaTime;

And im unsure why they were using Delta Time twice. one for veloctiy and one for position

I have to admit i wasnt sure where you were going with this comment?

Speed above for me was just 4F… and wasnt calculated based on the formula you had, it was just a random value …

Now i need to understand how gravity works… eg if i want a player to jump.

i see in your example code you have defined

and you have simple controls like

if (IsUserInputMovingRight)
VelocityX = VelocityX + AccelerationX;

heroFuturePosition.X = heroPosition.X + VelocityX;

if (IsUserInputJumping && IsCollisionBottom)
VelocityY = -JumpAcceleration;

but im looking through the code and not seeing how you actually made him jump to a max height or is the above like setting the -JumpAcceleration shifting him 35 pixels and then you are adding gravity?

if (CollidingWithIsClimable == false)
{
VelocityY += Gravity;
}

The jump seems smoother than a 35 pixel jump.

Hard to debug as i have break points everywhere to see what the values are :slight_smile:

Thanks again for putting up with my stupid questions.

Sorry i was late to reply.

I’ll elaborate a little on the questions and clarify a couple things as well.

but im looking through the code and not seeing how you actually made him jump to a max height or is the above like setting the -JumpAcceleration shifting him 35 pixels and then you are adding gravity?

When the player jumps a simple Acceleration upwards is added to the players total velocity that is fairly large but only added one frame then the jump button is ignored for some amount of jump reset time. Every frame after the frame he jumped his total velocity X is slowed partially by friction or his total Y velocity is pulled down by gravity.

im unsure why they were using Delta Time twice. one for veloctiy and one for position

I have to admit i wasnt sure where you were going with this comment?

To clarify what i said earlier.

  1. velocity and speed.

Velocity proper is (a Vector representation) of Speed which is a (float value).
Aka velocity has a X and Y component (or XYZ component in 3d).
Speed is just a scalar a float s.
You can convert between velocity and speed equivalently.

by pythagoras
speed = squareRoot( velocity.X * velocity.X + velocity.Y * velocity.Y);
normalDirection = new Vector2( velocity.X / speed, velocity.Y / speed);
velocity = normalDirection * Speed;

(since they are the same sometimes the words and the ideas become misnomers)

Be aware of the difference between a direction and a normalized direction.
A Normalize direction can be scaled by a Scalar to give a velocity from a speed properly.

Acceleration is also a Vector or a Scalar in the exact same manner and often we say simply a object speeds up by some amount every second i.e. it is accelerating by some speed or thrusting.

You will usually need to apply the vector version (Velocity) as a addition to the position as opposed to a scalar speed so conversion is typically done.

Velocity is a constant motion (aka things in motion stay in motion unless a force is applied to it)
Velocity is altered by variable Accelerations each frame.
Accelerations are generated by conceptual forces (conceptual forces are the ideas of what affects your game objects each frame e.g. thrust gravity friction wind ect…).
These ideas are defined in terms of accelerations per second.
Aka…

GravityPerSecond
GroundFrictionPerSecond
AirFrictionPerSecond
PlayerKeyPressAccelerationPerSecond

The player then has his
CurrentVelocityPerSecond V note elapsed time needs to be be applied before adding to position.
and his
CurrentPositionThisFrame P

You may accumulate the different accelerations in a frame then apply them to change the players velocity which at the very end will update the players position.

For example.

When player moves right he generates a force that Accelerates him Vector2.Right * playerSpeed, aka it’s a acceleration that will be added to his total velocity. The force of gravity also accelerates him down changing the velocity.
The velocity of the player himself is de-Accelerated by friction which can be simulated by having a direction opposite the players Velocity or maybe just the X component of it finding the normal of that result a amount of speed is applied a a counter acceleration. Or the total velocity can just be muliplied by a value like .99f.

A pseudo implementation.

first define the following vectors.

Let P stand for Position Now.
Let V stand for Total Velocity Now.
Let A stand for Total Acceleration this frame.
Let E stand for ElapsedTime or the portion of time that has passed between the last frame and the current (the portion of a second elapsed).
Let K stand for my defined kinetic Acceleration (of velocity or speed x and y) that i want to see a game object increase its velocity or speed by per second, when i press a key. E.g. 10 pixels per second We wont use this atm well redefine it as ak shortly for simplicity as it depends on which key is pressed and maybe our current total velocity as well or however we want it too.

Further so we define a bunch of acceleration forces represented as scalars (aka floats) you set these individually to get things to feel right in your game.

Let ag stand for the force of gravity, acceleration per second.
Let aw stand for the force of wind resistance, acceleration per second.
Let ar stand for the force of ground or running resistance, acceleration per second.
Let ak stand for the force of player key press, acceleration per second.
(in truth we have forward back and up for a platformer we switch on which key is pressed and if the action is possible to do)

We need normalized directions for the forces or vectors of force for each.

ng = Vector2.Normalize(new Vector2(0, -1)); // downwards direction
nw = Vector2.Normalize(V) * -1f; // negated velocity direction.
nr = Vector2.Normalize(V) * -1f; // negated velocity direction.
nk = SomeVectorReturningFunctionDependingOnKeyPresses();

we add together all the forces that accelerate our object tempered by the elapse portion of time
A = (ng * ag * E) + (nw * aw * E) + (nr * ar * E) + (nk * ak * E);

the above gives us Acceleration per this frame which is a portion of a second.

we alter the velocity by the total accelerations from all the forces acting on our player for that frame.
V = V + A;

note the above velocity v is per second.

Every update we normally displace the position of our player by the current velocity he has per second for this portion of time elapsed.
P = P + V * E;

Now by the above steps if we were in a space game removing all friction values then we essentially have newtonian motion the player will stay in motion unless he thrusts.

By the above steps in a platformer with friction, provided we apply enough gravity and enough acceleration for running and jumping, aka we set our per second values up to make it behave how we like. Then we have our similar normal everyday motion.

Now while collisions are technically friction in game we handle them specially to because modeling such a thing accurately would be ridiculously expensive and over complicated.
Often for things like climbing ladders we cheat and just turn off gravity and collisions on the ladder just do some special behavior to replace movement.

Note some people will shortcut the math and determine the Acceleration per second total then before adding to velocity multiply by elapsed time that is short form of what i did long form for clarity.
It is math wise equal so you come out with the same numbers.
Accelerations xy
Velocity xy
Positional displacement xy.
A = (vg * ag) + (nw * aw) + (nr * ar) + (nk * ak);
V = V + A * E;
P = P + V * E;

while you store scalars to apply against (or to scale) normalized direction vectors, since these forces impart accelerations in some direction like gravity applys a downward acceleration to a objects total velocity.

ak … playersSpeedPerSecond = 10; // our dude runs fast or slow ect.
ag … gravitySpeedPerSecond = 3; // it never turns off and it stays the same.
aw … windResistanceSpeedPerSecond = 0.2f; // when the player jumps the air itself slows him down.
ar …groundResistanceSpeedPerSecond = 3; // friction keeps us from staying in motion.

1 Like