Движение основано на постоянном несовместимом - PullRequest
0 голосов
/ 12 марта 2020

Я создал класс, который является персонажем, и в методе обновления я использовал как можно больше физики, чтобы заставить его работать реалистично, и отредактировал значения, чтобы сделать движение приятным.
Я недавно заметил, когда я двигаюсь влево и вправо он движется с разными скоростями, и понятия не имеет, как долго это было правдой. Я объявляю все константы с прописными именами в начале и использую одну и ту же константу для движения, поэтому я понятия не имею, что является причиной этого.

Я изо всех сил старался найти, где проблема, и исправить ее. но у меня ничего нет.

начало, где я установил свои константы:

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;

Функция обновления:

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

Ответы [ 2 ]

1 голос
/ 12 марта 2020

решение было предоставлено Луи Go,

Оказывается, это было так же просто, как заменить операторы if на 2 вложенных, как порядок оператора, и сбить компьютер с толку.

Старый код:

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 (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;
        }
    }
}
1 голос
/ 12 марта 2020

Эта строка сбивает с толку. Поскольку 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)))

Заявление станет.

 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 ( ( 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)))
)

Однако вы не оставили ни одного комментария, я не знаю, как это интерпретировать. Эта строка выглядит как «если скорость x почти равна нулю и нажата Left, D, или A или Right НЕ нажата», тогда установите X как большее значение.

Но эта строка противоречит тому, что вы описали.

Я недавно заметил, что когда я двигаюсь влево и вправо, он движется с разными скоростями, и не знаю, как долго это было правдой.

Вы хотите, чтобы Left и Right делали одно и то же, но не в коде.

Я предлагаю "использовать круглые скобки для удобства чтения" и "использовать bool, если в строке более 3 условий для проверки" .

...