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;
}
}
```