[Platformer] [Top-Down] Verlet integration for position calculus #3405
Replies: 4 comments 1 reply
-
Ah very interesting! It's true that we're missing this quadratic term.
That would be very interesting to see. This would really help improving the fluidity of games. Totally up to apply this to all behaviors involving movement :) This being said we have to be careful when the speed is capped to consider that the acceleration is then 0 (and not the acceleration set). |
Beta Was this translation helpful? Give feedback.
-
I started to write helper functions around the platformer jump. It will be useful for:
This is an example to test a behavior that find the right initial jump speed for a given jump height. |
Beta Was this translation helpful? Give feedback.
-
I wrote a mathematical model of the jump with SageMath. I think it might help to write test or add new features to the jump extension.
For instance, this is the resulting code to solve the initial speed from a given jump height. It has some branches because of the piecewise nature of the y function. const maxFallingSpeedReachedTime = maxFallingSpeed / gravity;
let jumpSpeed = -gravity * jumpSustainTime + Math.sqrt(2 * gravity * gravity * jumpSustainTime * jumpSustainTime - 4 * jumpHeight * gravity);
let peakTime = (gravity * jumpSustainTime + jumpSpeed) / (2 * gravity);
// If the peakTime is outside of the piecwise part,
// use the formula for this part.
if (peakTime > maxFallingSpeedReachedTime) {
jumpSpeed = -gravity * jumpSustainTime + maxFallingSpeed
+ Math.sqrt(gravity * gravity * jumpSustainTime * jumpSustainTime - 2 * jumpHeight * gravity - maxFallingSpeed * maxFallingSpeed);
peakTime = (gravity * jumpSustainTime + jumpSpeed - maxFallingSpeed) / gravity;
// Same here, use the formula of the other side.
if (peakTime < jumpSustainTime) {
jumpSpeed = Math.sqrt(-jumpHeight * gravity * 2);
}
}
else if (peakTime < jumpSustainTime) {
jumpSpeed = Math.sqrt(-jumpHeight * gravity * 2);
peakTime = jumpSpeed / gravity;
// Same here, use the formula of the other side.
if (peakTime > maxFallingSpeedReachedTime) {
jumpSpeed = -gravity * jumpSustainTime + maxFallingSpeed
+ Math.sqrt(gravity * gravity * jumpSustainTime * jumpSustainTime - 2 * jumpHeight * gravity - maxFallingSpeed * maxFallingSpeed);
peakTime = (gravity * jumpSustainTime + jumpSpeed - maxFallingSpeed) / gravity;
}
}
if (jumpSpeed >= 0) {
character.setJumpSpeed(jumpSpeed);
} |
Beta Was this translation helpful? Give feedback.
-
The PR: The documentation: The extension PR: |
Beta Was this translation helpful? Give feedback.
-
Position calculus from speed and acceleration
The Platformer and Top-Down Movement are using the Euler method.
We're doing something like this (maybe not in that order).
The Verlet method is more precise, resilient to fps changes and doesn't cost much more (2 additional multiplications)
Considering that the acceleration is constant we could do this instead.
FPS independent
The Verlet method will ensure that a platform character jump the same height no matter the FPS.
Moreover, I think that the feeling of fluidity even with frame drops (who said GC?) should make it up for the 2 additional multiplications.
I wrote a test to make a comparison.
The difference is sensible.
Easier jump properties
For the Platformer behavior, it could allow to setup the jump with easier to understand parameters like height and width distance (and jump sustain time, gravity changes...). It could be done with an event-based extension.
It could be interesting to have some sort of calculator in the Platformer configuration directly. It could update properties according to other with lock buttons but it would need to implement these lock buttons. It's probably not worth the effort.
Backward compatibility
The Platformer will need a property to choose the legacy mode, but the top-down movement could use the new method directly as the impact will only be a slight change in the acceleration which is not very important.
Source
Beta Was this translation helpful? Give feedback.
All reactions