0
\$\begingroup\$

I recently started rewriting my engine from scratch, because the old one was my first attempt and the structure was very messy. Everything has been going great, but now I'm being held back by some stuff related to character movement and collision detection.

So, I wanted to remake the character movement with acceleration and deceleration physics. I got it working fine, but I didn't use gameTime.ElapsedGameTime.TotalSeconds. Now it would seem to be complicated and messy to add it to all the places where I use velocity, Acceleration, and Deceleration

What I'm wondering is that, is it worth it to even use gameTime at all? I think I've read in many posts and tutorials that using gameTime is best practice because then movement isn't coupled to frame rate. And if it is worth using it, how would you implement it in such a system along with acceleration and normalizing for diagonal movement?

I wouldn't mind restructuring the code at all, but I just don't know where to start from. I've been thinking about and trying to solve this issue for so long and I don't know what to do. It's draining all my motivation :( If you notice any other improvements here, feel free to mention. Thanks.

Here is the movement code:

    private void UpdateMovement(List<GameObject> objects) {

        if (velocity != Vector2.Zero){

            if (SimpleCollisionCheck(objects, out GameObject obj) == true) {
                    DirectionalCollisionCheck(obj);
            }

        }

        position += velocity;

        if (velocity.X > 0) { // Decrease X velocity over time
            if (velocity.X - Deceleration > 0) { velocity.X -= Deceleration; } else { velocity.X = 0; }
        } else if (velocity.X < 0) {
            if (velocity.X + Deceleration < 0) { velocity.X += Deceleration; } else { velocity.X = 0; }
        }

        if (velocity.Y > 0) { // Decrease Y velocity over time
            if (velocity.Y - Deceleration > 0) { velocity.Y -= Deceleration; } else { velocity.Y = 0; }
        } else if (velocity.Y < 0) {
            if (velocity.Y + Deceleration < 0) { velocity.Y += Deceleration; } else { velocity.Y = 0; }
        }

    }

    protected void MoveLeft() {
        if (velocity.X - Acceleration > -VelocityMaximum) { velocity.X -= Acceleration + Deceleration; }
        direction.X = -1;
    }

    protected void MoveRight() {
        if (velocity.X + Acceleration < VelocityMaximum) { velocity.X += Acceleration + Deceleration; }
        direction.X = 1;
    }

    protected void MoveUp() {
        if (velocity.Y - Acceleration > -VelocityMaximum) { velocity.Y -= Acceleration + Deceleration; }
        direction.Y = -1;
    }

    protected void MoveDown() {
        if (velocity.Y + Acceleration < VelocityMaximum) { velocity.Y += Acceleration + Deceleration; }
        direction.Y = 1;
    }

Here is the collision code:

    protected bool SimpleCollisionCheck(List<GameObject> objects, out GameObject obj) {

        Rectangle futureCollision = Collision;

        if (Velocity.X != 0) {
            if (Velocity.X > 0) { futureCollision.X += (int)VelocityMaximum; } else { futureCollision.X -= (int)VelocityMaximum; }
        }

        if (Velocity.Y != 0) {
            if (Velocity.Y > 0) { futureCollision.Y += (int)VelocityMaximum; } else { futureCollision.Y -= (int)VelocityMaximum; }
        }

        foreach (GameObject o in objects) {
            if (o != this && o.Active == true && o.CollisionEnabled == true && o.CollisionCheck(futureCollision) == true) {
                obj = o;
                return true;
            }
        }

        obj = null;
        return false;

    }

    private bool CollisionLeft(GameObject o) {
        return ((Collision.Left - VelocityMaximum) < o.Collision.Right) &&
            (Collision.Right >= o.Collision.Right) &&
            (Collision.Top < o.Collision.Bottom) &&
            (Collision.Bottom > o.Collision.Top);
    }

    private bool CollisionRight(GameObject o) {
        return ((Collision.Right + VelocityMaximum) > o.Collision.Left) &&
            (Collision.Left <= o.Collision.Left) &&
            (Collision.Top < o.Collision.Bottom) &&
            (Collision.Bottom > o.Collision.Top);
    }

    private bool CollisionUp(GameObject o) {
        return ((Collision.Top - VelocityMaximum) < o.Collision.Bottom) &&
            (Collision.Bottom >= o.Collision.Bottom) &&
            (Collision.Left < o.Collision.Right) &&
            (Collision.Right > o.Collision.Left);
    }

    private bool CollisionDown(GameObject o) {
        return ((Collision.Bottom + VelocityMaximum) > o.Collision.Top) &&
            (Collision.Top <= o.Collision.Top) &&
            (Collision.Left < o.Collision.Right) &&
            (Collision.Right > o.Collision.Left);
    }

    private void DirectionalCollisionCheck(GameObject o) {

        if (velocity.X < 0.0f && CollisionLeft(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if ((PositionCentered.Y /*- CollisionThickness*/) < (o.Collision.Top - collisionNudgeOffset)) {
                    velocity.Y = velocity.X;
                } else if ((PositionCentered.Y /*+ CollisionThickness*/) > (o.Collision.Bottom + collisionNudgeOffset)) {
                    velocity.Y = -velocity.X;
                }
            }

            velocity.X = 0.0f;

        } else if (velocity.X > 0.0f && CollisionRight(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if ((PositionCentered.Y /*- CollisionThickness*/) < (o.Collision.Top - collisionNudgeOffset)) {
                    velocity.Y = -velocity.X;
                } else if ((PositionCentered.Y /*+ CollisionThickness*/) > (o.Collision.Bottom + collisionNudgeOffset)) {
                        velocity.Y = velocity.X;
                }
            }

            velocity.X = 0.0f;
        }

        if (velocity.Y < 0.0f && CollisionUp(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if (PositionCentered.X < (o.Collision.Left - collisionNudgeOffset)) {
                    velocity.X = velocity.Y;
                } else if (PositionCentered.X > (o.Collision.Right + collisionNudgeOffset)) {
                    velocity.X = -velocity.Y;
                }
            }

            velocity.Y = 0.0f;

        } else if (velocity.Y > 0.0f && CollisionDown(o)) {

            if (CollisionNudgeEnabled && o.CollisionNudgeEnabled) {

                if (PositionCentered.X < (o.Collision.Left - collisionNudgeOffset)) {
                    velocity.X = -velocity.Y;
                } else if (PositionCentered.X > (o.Collision.Right + collisionNudgeOffset)) {
                    velocity.X = velocity.Y;
                }
            }

            velocity.Y = 0.0f;
            }
        }
```
\$\endgroup\$
1
  • \$\begingroup\$ If it's not broken, don't fix it. It may be a best practice. But I don't think it's something that should keep you awake. If you got your code already working fine. Then I'd say keep it at it. It shouldn't cause huge problems as long as the convention remains consistent. \$\endgroup\$
    – Steven
    Jan 24 at 7:39

1 Answer 1

0
\$\begingroup\$

So, I broke out some old physics formula books and had some sort of a revelation. I added updateTime = (float)gameTime.ElapsedGameTime.TotalSeconds; into the main update function of the character and changed the following code and now it seems to work (?):

    private float accelDistance = 20f;
    private float decelDistance = 60f;
    public float velocityMaximum = 180f;
    private float updateTime;

    public float Acceleration { protected get { return accelDistance * updateTime; } set { accelDistance = value; } }
    public float Deceleration { protected get { return decelDistance * updateTime; } set { decelDistance = value; } }
    public float VelocityMaximum { protected get { return velocityMaximum * updateTime; } set { velocityMaximum = value; } }
```
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .