The Unbearable Lightness of 2D Jumping
After implementing a simple shooter game as my most recent Godot endeavor, I wanted to increase the difficulty level a little and go for a 2D platformer. I started the project full of enthusiasm: fighting with TileMaps and laying down the main level tiles, creating a Player object affected by physics, implementing horizontal movement, and adding appropriate animations for each action.
Setting up the game's basic elements was a breeze, at least initially. For instance, I was already prepared to add basic controls to the playing character (a tiny orange alien that vaguely resembles Gudetama) and move it horizontally. However, if I thought that going forward was that easy, I was exquisitely wrong.
The #1 rule of the Platform Club
What's the foundational mechanic of any platform? Of course, it's jumping. Yes, by jumping you can explore the game world, reach that shiny golden coin and even fight enemies. Jumps are there to solve any game's problem: in fact, jumps are the game, and for the game to be fun I needed to implement them masterfully.
Well, it seems that I am no master regarding jumps: my first attempts were so clumsy and weird that I wondered if the little alien on the screen would try to bury himself into the ground tiles for the embarrassment. And yet the work done right out of the gate went relatively well. I introduced a straightforward implementation of gravity: I just kept adding some value to the Y dimension of the character velocity:
velocity.y += gravity;
and then, while jumping, setting (not adding) the value of the ordinate axis to the
velocity.y = -jumpVelocity;
Note that gravity is positive here: as you may know, in 2D graphics the topmost pixels usually have a 0 coordinate value, which increases as you go further down the screen. This is very funny in a sense, since it is the opposite of what my Physics professor always taught us back at the University: having positive gravity means that you are flying! Sorry, sir Professor, I left the textbook at home. I am trying to develop a game here.
When I say "jump"...
In any case, while the idea of introducing a flying game mode was surely enticing, I had a more pressing matter to take care of: my jump mechanic sucked. Regardless of how much I put into meddling with my code, I was only able to alternate between two opposite - and underwhelming - modes of jump:
- the character didn't move at all, or was performing a vertical movement so limited and brief that I probably followed the recipe for the vibration mechanic;
- the character jumps, or rather "teleports", to a fixed altitude in a sudden and uncanny way, then gravity brings it back to the ground very slowly.
After a good night's rest, I was able to detect many issues with my code. Some of them were particularly embarrassing for my current level of experience in software engineering, so that's maybe why I refused to even consider them. For instance, I was redeclaring the
velocity at each frame, with varying and disastrous effects on the alien dynamic. From time to time, I was mixing up the direction of gravity with the one for jumps, in effect jumping downwards towards the ground (aka not moving at all).
However, after a few iterations, I was able to have decent jumps in my game. But they didn't feel right: the timing was off, the parabola of the trajectory was weird, and the overall experience was unsatisfying. It turns out that if I want satisfying jumps I need to go back to Physics textbooks and apply their laws. Luckily for me, there are phenomenal developers out there that studied such laws for me: why be top of the class when you can just copy their notes? 😈
Jokes aside, a refresher on this topic and a simple explanation saved my game: even without designing any level or adding any soundtrack, I can already feel some positive "vibes" from my game and even imagine a unique personality for my little orange friend! We truly rest on the shoulders of giants.