As a Defrag player, I would like to add advanced movements to my (simple) game, in particular strafe jumping. I currently have basic fps movements (WASD and free look to be clear), but how can I add quake-like movement techniques? This article explains very well the theory behind it, but I really don't know where to start to actually implement it.
The article you linked to first explains how the game works and then discusses at length how to exploit the way it works to strafe-jump. I believe only a few paragraphs are useful to you: the one about how the engine decides whether to add an acceleration vector times a small amount of time (which amounts to a small variation of the speed vector):
and how it truncates that small variation of speed so the component of the resulting speed vector along the acceleration direction doesn't exceed a predefined maximum:
Just to spare you some confusion when actually implementing the thing, note that the author refers to the vector "a" as the "acceleration vector" but throughout the article it is used sometimes as a unit vector having the same direction as the acceleration vector as in
or as an amount of speed as in
or even as a distance (length) as in
where "s" is the global maximum speed (the
To sum up in physics/applied maths notation: the player has a speed vector v(t) at time t and we want to compute his speed vector v(t+dt) at time t + dt where dt is a small amount of time. Here, dt will be the duration of a frame, or 1/(framerate). There exists a speed constant V used to cap other speeds or something along those lines, and we will use that constant.
We know v(t) and we can deduce the direction u towards which the player wants to move using the currently pressed movement keys. u is a unit vector. The amount of speed we initially want to add to v(t) is A.dt.u where A, a real number, is the unique, global movement acceleration constant, so that v(t+dt) = v(t) + A.dt.u.
Note that A is not a speed, but an acceleration! The engine uses the same variable
We want to add that amount of speed A.dt.u, but we need to truncate it if it makes the component of the resulting vector v(t+dt) bigger than V along u. Therefore, we get the following pseudocode:
Sorry for the poor variable names. Please have better variable naming habits than mine. Here, I compute and store
I hope I didn't miss anything. Remember you can customize both A (the global movement-induced acceleration) and V (the maximum speed along acceleration direction).
That being said, just translate that and adapt it to your codebase, I think I got most of it right.
major edit: I forgot to add that this only works in the air! Don't forget to make it so that, if the player lands with the jump key pressed, he only touches the ground for 1 frame at most before he jumps again! Special handling of physics might be required during that particular frame. It's 6AM. Bed.
Actually, I think driven by the question in this post, Adrian "Flafla2" Biagioli has created a very well written and explained post/answer on this same topic.
The product of the post is a C# implementation of the system:
All credits to Adrian.