Dynamic Acceleration in Movement?

Hey, I am in the process of refining the movement for the player character in my Paper2d project. Right now, I have it so that the player, while running, gradually accelerates up to the max walk speed, as the movement buttons are held. When released, however, the player comes to a slow halt. The deceleration only kicks in once the player reaches a certain velocity. That way, they do not have to decelerate after only a couple of steps.

I was wondering if you guys knew a way to do something similar with acceleration. I am interested in experimenting with a system wherein the player is allowed to make quick, short movements, at max speed, but must accelerate up to max speed when running a distance. In my head this would be similar to dashing in real life. You can make quick, explosive movements, but you cannot necessarily run at top speed right away.

My idea for this would be to somehow calculate the amount of time the player has activated the “MoveRight” axis input. If held for a certain amount of time, the acceleration would kick in. If only held for a short time, the player could make quick movements at top speed. Is there a way to calculate such a thing? I know there is a node that can keep track of how long a specific button has been pressed, but I am not aware of a similar one for axis inputs.

It is very possible that I am not making much sense, as the idea is not entirely fleshed out in my head. I thought of the idea just an hour ago, and have been trying to get it working, but to no avail.

I appreciate any and all replies.

I think I understand what you’re trying to do.

Just have them accelerate at the normal speed whenever the button is pressed.

Then if it’s released, check how long it was pressed for (store the initial time it was pressed in a variable to compare to). If it was short enough, give them an acceleration boost. Be sure to add a cooldown period so they can’t spam the move key and keep boosting!

Thanks for the reply, Kelso. I actually added a short impulse when the directional buttons are pressed. This gives a jump start to the movement. The player will then accelerate as he continues to move. I found this to do what I wanted.

I actually did have a question about “storing initial time”. I have been trying to implement a sort of “grace period” when jumping, so that the player can jump from a surface, even if they missed the jump by a few pixels. It feels bad, during gameplay, when you miss a jump by a couple of milliseconds. I want the player to be able to jump while falling, essentially, but only for a few milliseconds after being grounded. I have no clue how to calculate the amount of time the player has been falling, though. Do you have any tips on that? I’d really appreciate it.

This is a bit lengthy and has no TL;DR…

Assuming you are in the OnTick event for this, assuming you use blueprints, and assuming you are still using a variation of character movement.

First, you have an “is falling” value that is automatically handled by the engine for every pawn/actor or anything that has a movement component really. Probably (not sure) also paper2D. This is probably irrelevant, however it’s worth mentioning because of how it works.
Constant line-trace from capsule end downwards to “find the floor” and trigger the Boolean if the floor is not at a range of nearly 1.

Second thing to note, Physics. You need or usually want to apply a mathematical movement interpretation.
There are many variation on how to do things. A well thought out system goes a long way to making game-play cooler - for instance slipper surfaces. silent surfaces, so on.
Consider the fact that the characters are always sliding around and just seem to be walking 2d or 3d doesn’t change this. The capsule is locked onto the floor or whatever it hits, it can’t “float” mid air with every step.

Essentially, go back to newton’s second law:’s_laws_of_motion#Newton’s_second_law
An object’s acceleration is the result of all forces acting on the object - this includes wind resistance - which since the item is sliding is basically ground attrition - and gravity.

So, Force = Mass * Acceleration per the law.
Ergo Acceleration = Force / Mass (per basic algebra).

The weight of the object is the Mass x Gravity - not very relevant if you approximate your movement system, but good to know.

The mass can be used to calculate the Friction on a given surface.

But what is Force within the equation above?
Force = Force Apparent - Force Friction

All that said, A character is not really a billiard ball - right?
So in order to come to a stop we can apply a liberal amount of counter-force to the movement to cause the moving object to stop in a slightly more “natural” way.

We can call that our “break force” or “Breaking Deceleration Walking” within the movement controller.

Assuming that clears up the physics, you should now be able to implement a very basic version of an actual mathematical formula that allows you to change the current acceleration more dynamically.

You can put a MAX to the overall force, which will cause the speed to max out as well. you can apply the same amount of force over time to reach said speed, and all you have to do is tweak the numbers to taste.
You can Burst like described by also applying a different amount of force (double the normal?).
You can also scale the amount of force initially to have the same effect you described above - purely based on velocity and accumulated momentum (total applied force).
Essentially you know that if your force is going down you won’t apply double the force, if your force is going up you can x2 it a couple times to reach the max faster.

Now back to the Jumping stuff.
I would actually only allow the second jump if in X proximity to the wall/edge/floor, where X is both the variable of how close you are, and the X axis for distance assuming the unreal Right Handed coordinate system applies to paper2d as well and that Y is in this case depth where Z is Vertical.

As a way of checking the vertical position I would use something like this:
Store the previous value of the variable - OLD Variable = Variable THEN set Variable = value.You can then check the delta between the 2 ( Old - Variable).
This tells you 2 things in 2D space; the direction: an increase or decrease in delta is essentially “which way am I going”? AND the distance from the previous position over the frame.

Worked out example:
Assume that the floor is at X 330 and Z10
Assume the jump is moving the same direction but ends up short at X 329 and Z10. Assume there is no floor so the character falls off the edge Mario style.

Per tick Current X - Previous X = X delta, Current Z - Previous Z = Z delta.
If Z delta is negative AND X delta is Positive (jumping towards target)
Merge the math:
if next frame Z is below floor level (Z = 10 AND Z Delta < 0) AND (X location < 330 AND location >310 AND X Delta > 0) THEN allow a double jump.

Hope that makes sense and that you can work out the exact math that makes it possible from the basic logic :slight_smile:

The “time” you can actually ignore completely by the way. you can simply make the Z check be between 2 values instead of seeing if it’s the same as the floor.
Maybe in a Z > Z - grace AND Z < Z + grace fashion so you can easily manipulate your grace “period”.

Assuming you made use of proper physics as above your Mass/Gravity calculations will take care of the time dilation between the grace period and the floor level…