Прыжки противСила тяжести - PullRequest
5 голосов
/ 01 декабря 2011

Я работаю над своей первой игрой XNA 2D, и у меня есть небольшая проблема. Если я прыгаю, мой спрайт прыгает, но не падает. И у меня также есть другая проблема: пользователь может удерживать пробел , чтобы прыгать так высоко, как ему хочется, и я не знаю, как удержать его от этого. Вот мой код: Прыжок:

    if (FaKeyboard.IsKeyDown(Keys.Space))
        {
            Jumping = true;
            xPosition -= new Vector2(0, 5);
        }

        if (xPosition.Y >= 10)
        {
            Jumping = false;
            Grounded = false;
        }

Действительно простая базовая гравитация:

    if (!Grounded && !Jumping)
        {
            xPosition += new Vector2(1, 3) * speed;
        }

Вот где заземление имеет значение True или False при столкновении

    Rectangle MegamanRectangle = new Rectangle((int)xPosition.X, (int)xPosition.Y, FrameSizeDraw.X, FrameSizeDraw.Y);
        Rectangle Block1Rectangle = new Rectangle((int)0, (int)73, Block1.Width, Block1.Height);
        Rectangle Block2Rectangle = new Rectangle((int)500, (int)73, Block2.Width, Block2.Height);

        if ((MegamanRectangle.Intersects(Block1Rectangle) || (MegamanRectangle.Intersects(Block2Rectangle))))
        {
            Grounded = true;
        }
        else
        {
            Grounded = false;
        }

Заземленный бул и гравитация были проверены и работают. Есть идеи почему? Заранее благодарим и не стесняйтесь спрашивать, нужна ли вам другая часть Кодекса.

Ответы [ 4 ]

5 голосов
/ 01 декабря 2011

Относительно простой способ справиться с прыжками - реализовать гравитацию как вектор, а прыжки / движения - как импульс.

Например:

foreach (Object obj in GameWorld)
{
    obj.Velocity *= 0.5; // Slow it down slightly
    obj.Velocity += GravityPerSecond * FrameTime; // Gravity adjusted for time
    obj.Move(obj.Velocity); // Handle collision and movement here
}

Скорость должна быть вектором с такими же размерами, что и у мира, и переместить метод, который перемещает объект как можно дальше в заданном векторе.

Код перехода:

OnKeyDown(Key k)
{
    if (k == Key.Space)
    {
        obj.Velocity += Vector2(0, 10); // Add an upward impulse
    }
}

Это заставит объект немного подняться, а затем начать падать. Вы можете использовать подобные импульсы для других эффектов (движение, взрывы, столкновения). Вам нужно будет столкновения изменить скорость, когда два объекта сталкиваются, для подпрыгивания.

Это чрезвычайно простая физическая система, которая значительно упростит будущие изменения и позволит создать интересный дизайн уровней (изменить гравитацию и т. Д.). Он упрощает обработку прыжков, абстрагируя его от сложного кода IsJumping до единой механики.

Чтобы не допустить прыжка, не стоя на объекте, вам необходимо выполнить тест на столкновение или отследить, когда объекты сталкиваются / перестают сталкиваться в направлении вниз. Также возможно проверить, равна ли вертикальная скорость объекта нулю, и разрешить прыжки только тогда (это предотвратит прыжки при падении или движении вверх).

2 голосов
/ 01 декабря 2011

Я полагаю, что это может быть ответом:

измените

    if (FaKeyboard.IsKeyDown(Keys.Space))
    {
        Jumping = true;
        xPosition -= new Vector2(0, 5);
    }

    if (xPosition.Y >= 10)
    {
        Jumping = false;
        Grounded = false;
    }

на

    if (!Jumping && FaKeyboard.IsKeyDown(Keys.Space))
    {
        Jumping = true;
        Grounded = false;
    }

    if (Jumping)
    {
        xPosition -= new Vector2(0, 5);
    } 

    if (xPosition.Y >= 10)
    {
        Jumping = false;
    }

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

1 голос
/ 01 декабря 2011

Вот очень простое решение для прыжка вверх и вниз:

const float SCALE = 20.0f; //SPEED!!!
if (jump <= 15 && jump != 0)
            {
                humanPosition.Y -= SCALE * speed;
                jump++;
            }
            else if (jump > 15)
            {
                humanPosition.Y += SCALE * speed;
                jump++;
                if (jump == 32)
                {
                    jump = 0;
                    humanPosition.Y = 307;
                }
            }

И активируется

            else if (keyboard.IsKeyDown(Keys.Up))
        {
            jump = 1;
            humanPosition.Y -= SCALE * speed;
        }

Что это делает, приводит в движение прыжок поустановив его на 1 Также, если вы хотите ограничить прыжки только когда персонаж находится на земле, вы можете добавить условие, подобное этому

if (humanPosition.Y != GROUNDLEVEL){}
0 голосов
/ 01 декабря 2011

Прыжки не должны быть булевыми, если вам не нужно что-то вроде анимации или способности, которую можно использовать только при прыжке.

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

Тогда гравитация должна быть вектором падения, действующим против игрока, и она будет справляться сама с собой.

...