简体   繁体   English

基于不断不一致的运动

[英]Movement based on constant inconsistant

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

This line is confusing.这条线很混乱。 Because AND && has higher precedence than OR || 因为 AND &&优先级高于 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 , or A is pressed or Right is NOT pressed" then set X as a larger value.这条线看起来像“如果 x 的速度接近零并且LeftDA被按下或Right未被按下”然后将 X 设置为更大的值。

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.您希望 Left 和 Right 做同样的事情,但不是在代码中。

My suggestion is "use parenthesis for readability" and "use bool if there is more than 3 conditions to check in a line".我的建议是“使用括号提高可读性”和“如果有超过 3 个条件要检查一行,则使用 bool”。

the solution was the one sprovided by Louis Go,解决方案是由 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.事实证明,就像将 if 语句更改为 2 个嵌套语句一样简单,并且使计算机感到困惑。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM