# [C#] Platform game physics using integration. Is it possible?

This topic is 3027 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

If I wan't to move a sprite left and right I currently do the following:
            Vector2 force = Vector2.Zero;

// Get key presses this frame
if (InputState.Global.IsKeyDown(PlayerIndex.One, Keys.Left))
{
Animation.isYFlipped = false;
force.X = -Speed;
}
if (InputState.Global.IsKeyDown(PlayerIndex.One, Keys.Right))
{
Animation.isYFlipped = true;
force.X = Speed;
}
if (force != Vector2.Zero)
{
}


The force is added to the body and then integrated as follows:
       public void AddForce(Vector2 force)
{
// Accumulation stage must take place before the body is integrated
force_Accumulated += force;
}

public void Integrate(float duration)
{
// ==========================================================================================================
// --[Linear]------------------------------------------------------------------------------------------------
// ==========================================================================================================

// Update acceleration from accumulated forces
// F = M * A
// A = F / M
acceleration = force_Accumulated * mass_Inverse;

// Update linear velocity from the acceleration
// V = V + A * dT
velocity_Linear += acceleration * duration;

// Update linear position
// P = V0 * t + 0.5 * a * t^2
position += velocity_Linear * duration + (0.5f * acceleration * duration * duration);

force_Accumulated = Vector2.Zero;
}


The two other possible forces acting on the sprite are drag and gravity:
    // A force generator tht applies a gravitational force
// (One instance can be used for multiple bodies)
class RigidBody2D_Gravity : IRigidBody2D_ForceGenerator
{
Vector2 gravity;    // Holds the acceleration due to gravity

// Create the generator with the given acceleration
public RigidBody2D_Gravity(Vector2 gravity)
{
this.gravity = gravity;
}

// Applies the gravitational force to the given body
public override void UpdateForce(RigidBody2D body, float duration)
{
if (body.IgnoreGravity || body.Type == RigidBody2D_Type.Static)
{
return;
}

// Apply the mass-scaled force to the body
}
}

/// <summary>
/// A force generator that applies a drag force (One instance can be used for multiple bodies)
/// <para></para>
/// <para>See Physics.cs [Common Drag Coefficients] for possible values</para>
/// </summary>
class RigidBody2D_Drag : IRigidBody2D_ForceGenerator
{
float k1;   // Holds the velocity drag coefficient
float k2;   // Holds the velocity squared drag coefficient

public RigidBody2D_Drag(float k1, float k2)
{
this.k1 = k1;
this.k2 = k2;
}

// Applies the drag force to the given body
public override void UpdateForce(RigidBody2D body, float duration)
{
if (body.HasInfiniteMass)
{
return;
}

Vector2 force = body.Velocity;

// Calculate the total drag coefficient
float drag_Coefficient = force.Length();
drag_Coefficient = k1 * drag_Coefficient + k2 * drag_Coefficient * drag_Coefficient;

// Calculate the final force and apply it
if (force != Vector2.Zero)
{
// Force must be normalised for drag equation to be correct
force.Normalize();
}

force *= -drag_Coefficient;

}
}


How then can I make the sprite move more like a platform character, where the controlled character will start/stop almost instaneously based on user input. This also applies to jumping, as that again is not instant accelleration. Thank you.

##### Share on other sites
You could simply clamp your velocity if you know the character is at a wall, to achieve an instant stop. And for an instant start, just set the velocity to be some initially nonzero velocity when the user presses a key. Since you have your own physics loop, you should be able to do tricks like this pretty easily.

Platformer physics...I'm not sure the force/acceleration thing is entirely appropriate. I know some platformer characters do have periods of acceleration/deceleration. I'm just not sure it makes complete sense to do it formally using forces. You could just have velocity vary as a linear function of time and not worry about forces. Falling or jumping would be a different linear function. Instant starts or stops would be represented easily....anyway, I've never developed a platformer game so I'm kind of speculating about this.

##### Share on other sites
One way to incorporate pre-canned motion into your dynamic simulation is to find the value of a that will move the character to the position where you know it should be. This is not what I recommend, however, since the character motion usually needs to be pretty deterministic.

I've found that it is easier to just snap or blend the position of the character to the pre-canned location, then adjust the velocity to take into account the shift in position that you just introduced. When it is time to turn the pre-canned motion off, the dynamics will smoothly take over.

The main disconnect between pre-canned animation and dynamic physics is that a pre-canned animation usually only updates the position. The dynamic physics needs the position AND the velocity to be updated.

##### Share on other sites
Quote:
 Original post by grhodes_at_workYou could just have velocity vary as a linear function of time and not worry about forces

Something like this for the integration perhaps?

            // Apply gravity            velocity_Linear += new Vector2(0, -10) * duration;            // Apply drag            velocity_Linear *= 0.99f;            position += velocity_Linear * duration;

When I change the body's velocity directly, should I use:

            Vector2 velocity = Vector2.Zero;            if (InputState.Global.IsKeyDown(PlayerIndex.One, Keys.Left))            {                velocity.X = -Speed;            }            if (InputState.Global.IsKeyDown(PlayerIndex.One, Keys.Right))            {                velocity.X = Speed;            }            if (force != Vector2.Zero)            {                body.Velocity = velocity;            }

OR set speed as

velocity.X = -Speed * duration;

OR just set velocity as

body.Velocity = velocity * duration;

Quote:
 I've found that it is easier to just snap or blend the position of the character to the pre-canned location, then adjust the velocity to take into account the shift in position that you just introduced. When it is time to turn the pre-canned motion off, the dynamics will smoothly take over.

This sounds like a great idea as this would allow me to add forces to a characters body from explosions or moving obstacles. I'm not sure how I would do this with my current setup though. Can you explain how the velocity could be changed if I were to adjust just the position.

Are these new methods the same as treating the rigid body as kinematic, or have I got that totally wrong?

Thanks again.

##### Share on other sites
Quote:
 Original post by Spa8nkyHow then can I make the sprite move more like a platform character, where the controlled character will start/stop almost instaneously based on user input.

Player input produces variable force. Make player input force vary inversely to player speed. Then do the opposite when the player lets go of the button add a strong stopping force.

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 14
• 30
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631781
• Total Posts
3002314
×