From Sonic Retro
|Sonic Physics Guide|
|Collision & Physics|
- 1 Intro
- 2 Sonic
- 3 Tails
- 4 Knuckles
Each character in the Sonic games is constructed differently. While similar, they differ in size and moveset.
The sizes of characters are important, they determine how the characters will collide with Solid Tiles, Solid Objects and more.
These are not hitboxes, hitboxes are separate and aren't related to the solid size of objects. Hitboxes will be covered in Solid Objects
For all characters, their Push Radius is always 10.
When standing, Sonic's Width Radius is 9 and his Height Radius is 19, resulting in 19 pixels wide and 39 pixels tall.
When Jumping or rolling, his Width Radius is 7 and his Height Radius is 14, resulting in 15 pixels wide and 29 pixels tall.
Sonic's jump force (jmp) is 6.5.
Drop Dash (Mania)
//Constants drpspd: 8 //the base speed for a drop dash drpmax: 12 //the top speed for a drop dash drpspdsup: 12 //the base speed for a drop dash while super drpmaxsup: 13 //the top speed for a drop dash while super
The drop dash in Sonic Mania isn't simply an instant landing spindash.
To charge Sonic up you release then hold the jump button while already jumping. The dash will take 20 frames to charge and once charged, when Sonic reaches the ground, your ground speed will be set. If the jump button is released before Sonic hits the ground, the move is cancelled.
As Sonic hits the ground, Sonic's Ground Speed is calculated as normal. So at this point, Sonic will have a Ground Speed value (as if he landed normally) which will be used in calculating the drop dash speed.
The game checks if you were moving backwards in the air. By backwards, I mean opposite to the way you were facing/pushing. For example, if your X Speed was positive but you were holding & facing left at the time this would count as backwards, same for the other direction. In either case, Sonic's actual direction is then set to that which you are facing/holding.
If you were moving forwards
Sonic's Ground Speed is set to his Ground Speed divided by 4, plus (or minus, depending on direction) drpspd. This speed is limited to drpmax.
Ground Speed = (Ground Speed / 4) + (drpspd * direction) //direction is either 1 (right) or -1 (left), this speed would then be limited between the min and max values of -drpmax and drpmax
If you were going backwards
If Sonic's ang is 0 (flat), his Ground Speed is simply set to drpspd (or negative drpspd)
Ground Speed = drpspd * direction
Otherwise, on slopes, his speed is set in the same way as normal, but divided by 2 rather than 4. Of course, because you were moving backwards your Ground Speed will be opposite direction of that which the dash is trying to propel you, so this results in a rather slow dash.
Ground Speed = (Ground Speed / 2) + (drpspd * direction) // this speed would then be limited between the min and max values of -drpmax and drpmax
A similar Camera Lag effect to that used when spin dashing is used here too, to make the move more dramatic.
Dash (Super Peel Out)
Once the button is pressed, Sonic will begin charging the Dash. After 30 steps have passed, he is ready to go. When the Up button is released, Sonic launches at a speed of 12. If the Up button is released early, nothing happens.
The Insta-Shield expands Sonic's hitbox giving it a width radius of 24 and a height radius of 24, resulting in an overall height of 49 x 49 (more about Hit Boxes). This lasts for 13 frames.
The Insta-Shield does nothing to Sonic's X Speed or Y Speed. It does however allow him to control a rolling jump.
Tails is much smaller than the other characters. When standing, his Width Radius is 9 and his Height Radius is 15, resulting in 19 pixels wide and 31 pixels tall.
The only time this changes is when he jumps or rolls, where his Width Radius is 7 and his Height Radius is 14, much like Sonic, resulting in 19 pixels wide and 29 pixels tall.
His size is the same as standing when he flies.
Tails' jump force (jmp) is 6.5.
When Tails begins to fly, his Y speed is unaffected. However, since Tails has to release the button in order to press it again to fly, he can't possibly fly up faster than -4.
While flying, the variables are much like a standard jump. He accelerates at 0.09375, and there is no separate deceleration value. The normal air drag calculation is performed, which means Tails can't fly horizontally as fast while moving upward than when moving downward. The air drag cancels out the acceleration at an X speed of 3. There is no air drag while moving down, though, so he can reach an X speed of 6, the normal maximum.
While flying, gravity is 0.03125. Pressing Up or Down doesn't decrease or increase it.
Pressing the button doesn't cause an immediate loss of Y speed (like a double-jump), but instead a temporary change in gravity. Gravity becomes -0.125, and remains so until Y speed is less than -1. Then gravity returns to normal in the next step and Tails begins to fly back down. If Y speed is already less than -1, pressing the button does nothing.
Tails can only fly for 480 frames, or 8 seconds, before getting tired. The only difference being tired makes (besides the pooped-out expression) is that pressing the button doesn't have any effect anymore. Gravity, and all other variables, remain the same.
As stated above if you have negative gravity, a Ysp smaller than -1 is needed to return to positive gravity. This can cause issues when you hit a ceiling and your Ysp is set to 0. Your gravity will remain negative and you will be stuck. In your engine, to prevent Tails from being stuck in negative gravity, you should reset the gravity to the positive value when a ceiling is detected.
Note: Tails' tails deflect projectiles (just like the Shields do) while he is flying.
Knuckles sizes are the same as Sonic's.
Well that is except for when he is gliding, climbing and sliding.
Here, his Width Radius is 10 and his Height Radius is also 10, resulting in 21 pixels wide and 21 pixels tall. This makes him very wide but very slim compared to normal, which makes sense for his gliding pose. When falling from a glide, he uses his standing sizes.
Knuckles' jump force (jmp) is only 6, which results in a much lower jump than the others.
When Knuckles first begins gliding, his X speed is set to 4 in the direction he is facing. Y speed is set to 0, but only if it was negative at the time, otherwise it is unaffected. X speed then accelerates by 0.015625 every step.
Gliding has a top speed of 24. This top speed is so high that it is unreachable anywhere in the game -- except for Mushroom Hill Zone Act 1, where Super/Hyper Knuckles can glide across the top of the level to achieve this speed.
During the glide, gravity is 0.125, which is weaker than usual. Also, unlike a normal jump, gravity is only added while Y speed is less than 0.5. If Y speed is higher than that (say Knuckles was falling quickly when he began to glide), gravity is subtracted from Y speed instead, slowing his descent.
if (ysp < 0.5) ysp += 0.125; if (ysp > 0.5) ysp -= 0.125;
When you let go of the button, Knuckles drops, and his X speed is multiplied by 0.25. When he hits the ground, it is set to 0. While dropping from a glide, gravity is the normal value, 0.21875.
If you don't release the button, but allow Knuckles to glide into the ground and slide on his stomach, he has a friction value of 0.125 while sliding. He starts to stand up as soon as X speed reaches 0. If you release the button after he has begun to slide, X speed is set to 0 immediately, and he begins to stand up. Pressing Left or Right while sliding or standing up has no effect, but you can break into the standing up animation to jump if you press the jump button again.
If Knuckles hits a wall while gliding, he catches on, and can climb it. He will catch on even if he's turning around, as long as his X speed is still in the direction of the wall.
Note: Knuckles' knuckles deflect projectiles (just like the Shields do) while he is gliding.
When Knuckles is gliding, you can turn him around simply by tapping the Left or Right button. Even if you let go, he will continue to make a full turn. You can, however, reverse your decision and turn him back in the original direction before he makes a full turn.
You might think that turning around while gliding would be much like turning around while running on the ground. X speed would be steadily decreased until it reached zero, and then would start adding in the other direction. This is not the case, though, and a special method is used that preserves Knuckles' gliding speed.
When Knuckles is gliding, there is a value, which we'll call a, that is 0 when he's gliding to the right, and 180 when he's gliding to the left.
When Knuckles begins to turn, his X speed is stored - let's call the stored value t. If he's turning from the left to the right, a is decreased by 2.8125 until it reaches 0 (which takes 64 steps). If he's turning from right to left, a is increased by 2.8125 until it reaches 180. During the turn X speed is made to equal t times the cosine of a.
a += 2.8125 * -sign(t); xsp = t * cosine(a);
So, no matter how fast Knuckles is gliding, he turns around in the same amount of time, and his speed reverses fully. During the turn, there is no acceleration. It kicks back in once he's finished turning all the way around.
An interesting side-effect of the fact that Knuckles' Y speed is not immediately blunted when he begins gliding while falling quickly is the "Gliding Rebound". If you press the button to begin gliding just as Knuckles connects with an enemy or item monitor, his Y speed is reversed from the rebound just as he begins to glide. Since gliding gravity is weaker than standard gravity, he goes soaring up into the air. This is not necessarily a bug - it's actually kind of fun.
Once Knuckles is already gliding, rebound operates normally. Since he can't exceed a Y speed of 0.5 while gliding, though, the effect is rather weak.
Strangely enough, Knuckles' gliding and climbing physics are totally unaffected by water. I suspect this is because the code performed when entering and exiting the water simply changes the acceleration, deceleration, and top speed constants (this is why falling in water nullifies Super Fast Shoes). Because Knuckles' gliding and climbing code operates irrespective of these values, his abilities couldn't be affected by water without rewriting the water entry and exit code. In your engine you may wish to halve some of Knuckles' speeds when submerged to be more realistic, unless you want to remain 100% true to the original games.
When you finish a glide by sliding on the ground, the game doesn't set Knuckles' grounded flag until he stops. Though, he mostly acts grounded, sticking to the floor and changing his angle as normal.
He climbs up and down at a speed of 1. When Knuckles jumps off of a wall, his X Speed is set to 4 in the opposite direction of the wall, and his Y Speed is set to -4.
Interestingly, because of a pixel offset when sprites are flipped, Knuckles' feet poke 1px out from the side of his size when he is on a wall to the left. This means his feet should be inside the wall a bit. Well, when on a left wall there is actually a 1px gap between knuckles X - Push Radius and the wall, purely to make it look correct.
When climbing, Knuckles will fall off the bottom of a wall if no wall is found at his Y Position + Height Radius (checking horizontally into the wall).
Knuckles will clamber atop a ledge if it no wall is found at his Y position - Height Radius (checking horizontally into the wall).
When clambering, Knuckles plays a 3 sub-image animation. Each sub-image of the animation lasts 6 frames, and after the 3rd sub-image knuckles is standing on the ledge, where his X Position is the ledge X. Each frame of the animation moves knuckles to a new position as shown.
His position moves back and forth a bit as he climbs so that his sprite aligns. If your camera is set up correctly, usually the first 2 sub-images of motion will push the camera forward into place and the 3rd sub-image's backward motion won't move the camera at all, which makes it look smooth enough.
Stopping at Floors and Ceilings
If there is a floor that meets the wall, he will stop climbing down when the floor is within around 19 pixels of his Y Position (so, his normal Height Radius).