Actions

Difference between revisions of "SPG:Running"

From Sonic Retro

m (Formatting & extra comments in code examples)
(Simplifying and standardising object & character variables)
Line 7: Line 7:
 
*Variables and constants for Sonic and other characters such as ''xpos'' and ''acc'' will be referenced frequently, they can be found in [[SPG:Basics|Basics]].
 
*Variables and constants for Sonic and other characters such as ''xpos'' and ''acc'' will be referenced frequently, they can be found in [[SPG:Basics|Basics]].
  
 
==Ground Speed Conversion==
 
''gsp'' is used to calculate ''xsp'' and ''ysp'' when on the ground. This is further described in [[SPG:Solid_Tiles#The_Three_Speed_Variables|The Three Speed Variables]].
 
 
xsp = gsp*cos(angle);
 
ysp = gsp*-sin(angle);
 
  
 
==Movement==
 
==Movement==
Line 19: Line 13:
 
===Acceleration===
 
===Acceleration===
  
If you're holding {{left}}, Sonic's ''gsp'' decreases by ''acc'' every step. If you're holding {{right}} (Also applies if you're holding {{left}}, which you may not want in your engine), his ''gsp'' increases by ''acc'' every step.
+
If you're holding {{left}}, Sonic's Ground Speed decreases by ''acc'' every step. If you're holding {{right}} (Also applies if you're holding {{left}}, which you may not want in your engine), his Ground Speed increases by ''acc'' every step.
  
 
===Deceleration===
 
===Deceleration===
  
If Sonic is already moving when you press {{left}} or {{right}}, rather than at a standstill, it's checked whether you are holding the direction he's already moving. If so, ''acc'' is added to his ''gsp'' as normal.  However if you are pressing in the opposite direction than he's already moving, the deceleration constant (''dec'') is added instead.  Thus Sonic can turn around quickly.  If no distinction is made between ''acc'' and ''dec'', Sonic takes too long to overcome his current velocity, frustrating the player. A good engine must not make such a day one mistake.
+
If Sonic is already moving when you press {{left}} or {{right}}, rather than at a standstill, it's checked whether you are holding the direction he's already moving. If so, ''acc'' is added to his Ground Speed as normal.  However if you are pressing in the opposite direction than he's already moving, the deceleration constant (''dec'') is added instead.  Thus Sonic can turn around quickly.  If no distinction is made between ''acc'' and ''dec'', Sonic takes too long to overcome his current velocity, frustrating the player. A good engine must not make such a day one mistake.
  
One might think that if ''gsp'' happened to equal 0.1, and you pressed {{left}}, ''dec'' would be subtracted, resulting in an ''gsp'' value of -0.4. Oddly, this is not the case in any of the original games. Instead, at any time an addition or subtraction of ''dec'' results in ''gsp'' changing sign, ''gsp'' is set to 0.5 in the opposite direction. For example, in the instance above, ''gsp'' would become -0.5. The bizarre result of this is that you can press {{left}} for one step, and then press {{right}} (or vice versa), and start running faster than if you had just pressed {{right}} alone! Now, the resulting speed is still lower than one pixel per step, so it isn't very noticeable, but nonetheless it is true.
+
One might think that if Ground Speed happened to equal 0.1, and you pressed {{left}}, ''dec'' would be subtracted, resulting in an Ground Speed value of -0.4. Oddly, this is not the case in any of the original games. Instead, at any time an addition or subtraction of ''dec'' results in Ground Speed changing sign, Ground Speed is set to 0.5 in the opposite direction. For example, in the instance above, Ground Speed would become -0.5. The bizarre result of this is that you can press {{left}} for one step, and then press {{right}} (or vice versa), and start running faster than if you had just pressed {{right}} alone! Now, the resulting speed is still lower than one pixel per step, so it isn't very noticeable, but nonetheless it is true.
  
 
===Friction===
 
===Friction===
  
If you are not pressing {{left}} or {{right}}, friction (''frc'') kicks in.  In any step in which the game recieves no horizontal input, ''frc'' is subtracted from ''gsp'' (depending on the sign of ''gsp''), where if it then passes over 0, it's set back to 0.
+
If you are not pressing {{left}} or {{right}}, friction (''frc'') kicks in.  In any step in which the game receives no horizontal input, ''frc'' is subtracted from Ground Speed (depending on the sign of Ground Speed), where if it then passes over 0, it's set back to 0.
  
 
===Top Speed===
 
===Top Speed===
  
Sonic can only accelerate up to a certain point.  At some point, he reaches top speed and can no longer move any faster under his own power. So, after ''acc'' is added to ''gsp'', if ''gsp'' exceeds ''top'' it's set to ''top''.
+
Sonic can only accelerate up to a certain point.  At some point, he reaches top speed and can no longer move any faster under his own power. So, after ''acc'' is added to Ground Speed, if Ground Speed exceeds ''top'' it's set to ''top''.
  
In Sonic 1, while Sonic is already running at a higher speed than he can possibly achieve on his own (such as having been impelled by a spring), if you press in the direction he's moving, ''acc'' will be added to ''gsp'' as usual. However, notice that ''gsp'' now exceeds ''top'', which means ''gsp'' will be set to ''top''.  Thus it is possible to curtail your forward momentum by pressing in the very direction of your motion.  This can be solved in your engine (and was fixed in Sonic 2 and beyond) by checking to see if ''gsp'' is less than ''top'' before adding ''acc''. Only if ''gsp'' is already less than ''top'' will it check if ''gsp'' exceeds ''top''.
+
In Sonic 1, while Sonic is already running at a higher speed than he can possibly achieve on his own (such as having been impelled by a spring), if you press in the direction he's moving, ''acc'' will be added to Ground Speed as usual. However, notice that Ground Speed now exceeds ''top'', which means Ground Speed will be set to ''top''.  Thus it is possible to curtail your forward momentum by pressing in the very direction of your motion.  This can be solved in your engine (and was fixed in Sonic 2 and beyond) by checking to see if Ground Speed is less than ''top'' before adding ''acc''. Only if Ground Speed is already less than ''top'' will it check if Ground Speed exceeds ''top''.
 
 
[[Sonic CD]] and [[Sonic 2]] actually has a fix like this, where the ''top'' check won't happen if ''gsp'' is already above ''top'', because in Sonic CD can perform the "[[Super Peel Out]]", which launches him above his typical ''top'', and in Sonic 2 because it's supposed to be a much faster game. The issue is, in both games, it doesn't fix this error when Sonic is in mid-air, causing him to usually lose his speed when running off of a ledge.
+
[[Sonic CD]] and [[Sonic 2]] actually has a fix like this, where the ''top'' check won't happen if Ground Speed is already above ''top'', because in Sonic CD can perform the "[[Super Peel Out]]", which launches him above his typical ''top'', and in Sonic 2 because it's supposed to be a much faster game. The issue is, in both games, it doesn't fix this error when Sonic is in mid-air, causing him to usually lose his speed when running off of a ledge.
  
 
Here's some code logic that can accurately emulate movement and friction:
 
Here's some code logic that can accurately emulate movement and friction:
Line 43: Line 37:
 
  <nowiki>if (the player is pressing left)
 
  <nowiki>if (the player is pressing left)
 
{
 
{
     if (gsp > 0) //if moving to the right
+
     if (Ground Speed > 0) //if moving to the right
 
     {
 
     {
         gsp -= dec;  //decelerate
+
         Ground Speed -= dec;  //decelerate
         if (gsp <= 0)
+
         if (Ground Speed <= 0)
             gsp = -0.5;  //emulate deceleration quirk
+
             Ground Speed = -0.5;  //emulate deceleration quirk
 
     }
 
     }
     else if (gsp > -top) //if moving to the left
+
     else if (Ground Speed > -top) //if moving to the left
 
     {
 
     {
         gsp -= acc;  //accelerate
+
         Ground Speed -= acc;  //accelerate
         if (gsp <= -top)
+
         if (Ground Speed <= -top)
             gsp = -top; //impose top speed limit
+
             Ground Speed = -top; //impose top speed limit
 
     }
 
     }
 
}
 
}
Line 59: Line 53:
 
if (the player is pressing right)
 
if (the player is pressing right)
 
{
 
{
     if (gsp < 0) //if moving to the left
+
     if (Ground Speed < 0) //if moving to the left
 
     {
 
     {
         gsp += dec; //decelerate
+
         Ground Speed += dec; //decelerate
         if (gsp >= 0)
+
         if (Ground Speed >= 0)
             gsp = 0.5; //emulate deceleration quirk
+
             Ground Speed = 0.5; //emulate deceleration quirk
 
     }
 
     }
     else if (gsp < top) //if moving to the right
+
     else if (Ground Speed < top) //if moving to the right
 
     {
 
     {
         gsp += acc; //accelerate
+
         Ground Speed += acc; //accelerate
         if (gsp >= top)
+
         if (Ground Speed >= top)
             gsp = top; //impose top speed limit
+
             Ground Speed = top; //impose top speed limit
 
     }
 
     }
 
}
 
}
  
 
if (the player is not pressing left or right)
 
if (the player is not pressing left or right)
     gsp -= minimum(absolute(gsp), frc) * sign(gsp); //decelerate
+
     Ground Speed -= minimum(absolute(Ground Speed), frc) * sign(Ground Speed); //decelerate
 
</nowiki>
 
</nowiki>
  
 
[[Category:Sonic Physics Guide|Running]]
 
[[Category:Sonic Physics Guide|Running]]

Revision as of 11:34, 13 March 2021

Notes:

  • The following describes ground speed, the forces that impact it and the effects of player input. It only applies when Sonic is on dry land with no special power-ups. Curves, water physics, Super Sonic, and Speed Shoes will be covered in separate guides.
  • Variables and constants for Sonic and other characters such as xpos and acc will be referenced frequently, they can be found in Basics.


Movement

Note: In the original games, holding Left and Right at the same time will run both direction's code in one step, if you want in your engine, you can disable Left + Right input (Emulators like Fusion will just cancel the right input if left is also held).

Acceleration

If you're holding Left, Sonic's Ground Speed decreases by acc every step. If you're holding Right (Also applies if you're holding Left, which you may not want in your engine), his Ground Speed increases by acc every step.

Deceleration

If Sonic is already moving when you press Left or Right, rather than at a standstill, it's checked whether you are holding the direction he's already moving. If so, acc is added to his Ground Speed as normal. However if you are pressing in the opposite direction than he's already moving, the deceleration constant (dec) is added instead. Thus Sonic can turn around quickly. If no distinction is made between acc and dec, Sonic takes too long to overcome his current velocity, frustrating the player. A good engine must not make such a day one mistake.

One might think that if Ground Speed happened to equal 0.1, and you pressed Left, dec would be subtracted, resulting in an Ground Speed value of -0.4. Oddly, this is not the case in any of the original games. Instead, at any time an addition or subtraction of dec results in Ground Speed changing sign, Ground Speed is set to 0.5 in the opposite direction. For example, in the instance above, Ground Speed would become -0.5. The bizarre result of this is that you can press Left for one step, and then press Right (or vice versa), and start running faster than if you had just pressed Right alone! Now, the resulting speed is still lower than one pixel per step, so it isn't very noticeable, but nonetheless it is true.

Friction

If you are not pressing Left or Right, friction (frc) kicks in. In any step in which the game receives no horizontal input, frc is subtracted from Ground Speed (depending on the sign of Ground Speed), where if it then passes over 0, it's set back to 0.

Top Speed

Sonic can only accelerate up to a certain point. At some point, he reaches top speed and can no longer move any faster under his own power. So, after acc is added to Ground Speed, if Ground Speed exceeds top it's set to top.

In Sonic 1, while Sonic is already running at a higher speed than he can possibly achieve on his own (such as having been impelled by a spring), if you press in the direction he's moving, acc will be added to Ground Speed as usual. However, notice that Ground Speed now exceeds top, which means Ground Speed will be set to top. Thus it is possible to curtail your forward momentum by pressing in the very direction of your motion. This can be solved in your engine (and was fixed in Sonic 2 and beyond) by checking to see if Ground Speed is less than top before adding acc. Only if Ground Speed is already less than top will it check if Ground Speed exceeds top.

Sonic CD and Sonic 2 actually has a fix like this, where the top check won't happen if Ground Speed is already above top, because in Sonic CD can perform the "Super Peel Out", which launches him above his typical top, and in Sonic 2 because it's supposed to be a much faster game. The issue is, in both games, it doesn't fix this error when Sonic is in mid-air, causing him to usually lose his speed when running off of a ledge.

Here's some code logic that can accurately emulate movement and friction:

if (the player is pressing left)
{
    if (Ground Speed > 0) //if moving to the right
    {
        Ground Speed -= dec;  //decelerate
        if (Ground Speed <= 0)
            Ground Speed = -0.5;  //emulate deceleration quirk
    }
    else if (Ground Speed > -top) //if moving to the left
    {
        Ground Speed -= acc;  //accelerate
        if (Ground Speed <= -top)
            Ground Speed = -top; //impose top speed limit
    }
}

if (the player is pressing right)
{
    if (Ground Speed < 0) //if moving to the left
    {
        Ground Speed += dec; //decelerate
        if (Ground Speed >= 0)
            Ground Speed = 0.5; //emulate deceleration quirk
    }
    else if (Ground Speed < top) //if moving to the right
    {
        Ground Speed += acc; //accelerate
        if (Ground Speed >= top)
            Ground Speed = top; //impose top speed limit
    }
}

if (the player is not pressing left or right)
    Ground Speed -= minimum(absolute(Ground Speed), frc) * sign(Ground Speed); //decelerate