Reputation: 13
I made a class which is a character, and in the update method I used as much physics as possible to make it work realistically and edited values to make movement feel nice.
I recently noticed when i move left and right it moves at different speeds, and have no idea how long that has been true. I declare all capital named variables constants at the beginning and use the same constant for the movement, so i have no idea what is causing this.
I have tried my best to find where the problem is and to fix it but i have nothing.
the beginning where i set my constants:
const float GRAVITY = 1f;
const float AIR_SPEED_COEFFICIENT = 0.4f;
const float TERMINAL_AIR_HORIZONTAL_VELOCITY = 10f;
const float AIR_RESISTANCE = 0.97f;
const float FRICTION = 0.64f;
Update function:
public void Update(Rectangle floor, GameWindow Window)
{
jumpFrameCounter++;
if (Keyboard.GetState().IsKeyDown(Keys.Up) || Keyboard.GetState().IsKeyDown(Keys.W))
{
if (jumpFrameCounter > 11 && jumpsUsed < amountOfJumps)
{
velocity.Y = -GRAVITY * 16 * jumpHeight;
jumpsUsed++;
jumpFrameCounter = 0;
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X -= RUN_SPEED / 4;
}
else
{
velocity.X -= airSpeed * AIR_SPEED_COEFFICIENT;
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X += RUN_SPEED / 4;
}
else
{
velocity.X += airSpeed * AIR_SPEED_COEFFICIENT;
}
}
if (velocity.X > 0.00001f || velocity.X < -0.00001f && !(Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D) || Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A)))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X *= FRICTION;
}
else
{
velocity.X *= AIR_RESISTANCE;
}
}
if (Keyboard.GetState().IsKeyDown(Keys.Down) || Keyboard.GetState().IsKeyDown(Keys.S))
{
fastFall = true;
}
velocity.Y += GRAVITY * unfloatyness;
if (fastFall)
{
velocity.Y += 6 * GRAVITY;
}
if (hitbox.Bottom >= floor.Top)
{
if (velocity.X > RUN_SPEED * groundSpeed)
{
velocity.X = RUN_SPEED * groundSpeed;
}
else if (velocity.X < -RUN_SPEED * groundSpeed)
{
velocity.X = -RUN_SPEED * groundSpeed;
}
}
else
{
if (velocity.X > TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed)
{
velocity.X = TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed;
}
else if (velocity.X < -TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed)
{
velocity.X = -TERMINAL_AIR_HORIZONTAL_VELOCITY * airSpeed;
}
}
position += velocity;
hitbox = new Rectangle((int)position.X, (int)position.Y, fighterTexture.Width, fighterTexture.Height);
if (hitbox.Bottom > floor.Top && velocity.Y > 0)
{
position.Y = floor.Top - fighterTexture.Height;
jumpsUsed = 0;
fastFall = false;
velocity.Y = -1f;
}
if (hitbox.Left < 0)
{
position.X = 0;
}
else if (hitbox.Right > Window.ClientBounds.Width)
{
position.X = Window.ClientBounds.Width - fighterTexture.Width;
}
if (hitbox.Top < 0)
{
position.Y = 0;
}
else if (hitbox.Bottom > Window.ClientBounds.Height)
{
position.Y = Window.ClientBounds.Bottom - fighterTexture.Height;
}
}
Upvotes: 0
Views: 52
Reputation: 13
the solution was the one sprovided by Louis Go,
It turns out is was as simple as changing the if statements to 2 nested ones as the order of the and was confusing the computer.
Old Code:
if (velocity.X > 0.00001f || velocity.X < -0.00001f && !(Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D) || Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A)))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X *= FRICTION;
}
else
{
velocity.X *= AIR_RESISTANCE;
}
}
revised code:
if (velocity.X > 0.00001f || velocity.X < -0.00001f)
{
if (!(keyboardState.IsKeyDown(Keys.Right) || keyboardState.IsKeyDown(Keys.D) || keyboardState.IsKeyDown(Keys.Left) || keyboardState.IsKeyDown(Keys.A)))
{
if (hitbox.Bottom >= floor.Top)
{
velocity.X *= FRICTION;
}
else
{
velocity.X *= AIR_RESISTANCE;
}
}
}
Upvotes: 1
Reputation: 2588
This line is confusing.
Because AND&&
has higher precedence than OR||
if (velocity.X > 0.00001f || velocity.X < -0.00001f && !(Keyboard.GetState().IsKeyDown(Keys.Right) || Keyboard.GetState().IsKeyDown(Keys.D) || Keyboard.GetState().IsKeyDown(Keys.Left) || Keyboard.GetState().IsKeyDown(Keys.A)))
The statement would become.
if (velocity.X > 0.00001f
||
(velocity.X < -0.00001f && !(Keyboard.GetState().IsKeyDown(Keys.Right) )
|| Keyboard.GetState().IsKeyDown(Keys.D)
|| Keyboard.GetState().IsKeyDown(Keys.Left)
|| Keyboard.GetState().IsKeyDown(Keys.A)))
I assume you actually want:
if ( ( velocity.X > 0.00001f || (velocity.X < -0.00001f )
&&
(
! (Keyboard.GetState().IsKeyDown(Keys.Right)
|| Keyboard.GetState().IsKeyDown(Keys.D)
|| Keyboard.GetState().IsKeyDown(Keys.Left)
|| Keyboard.GetState().IsKeyDown(Keys.A)))
)
However you did not left any comment on it, I don't know how to interpret it.
This line look like "if velocity of x is nearly zero and Left
,D
, orA
is pressed or Right
is NOT pressed" then set X as a larger value.
But this line is conflicted with what you described.
I recently noticed when i move left and right it moves at different speeds, and have no idea how long that has been true.
You want Left and Right doing the same thing, but not in code.
My suggestion is "use parenthesis for readability" and "use bool if there is more than 3 conditions to check in a line".
Upvotes: 1