Xna добавляет гравитацию к 2-му спрайту - PullRequest
6 голосов
/ 07 февраля 2011

Я пытаюсь симулировать гравитацию в моей первой игре xna 2d.У меня есть следующее

        //Used for Jumping
    double elapsedAirTime = 0.0;
    double maxAirTime = 8.35;
    //End Jumping

Так что я пытаюсь переместить спрайт вверх на определенную величину, в то время как elapsedAirTime

if (newState.IsKeyDown(Keys.Space))
        {
            if(oldState.IsKeyUp(Keys.Space))
            {
                //if we are standing or jumping then change the velocity
                if (playerState == PlayerStates.Standing)
                {
                    playerState = PlayerStates.Jumping;
                    this.position.Y -= (float)(30.0 + ((1.2)*elapsedAirTime)*elapsedAirTime);
                }
            }
        }
        //if we are jumping give it some time
        if (playerState == PlayerStates.Jumping)
        {
            if ((elapsedAirTime < maxAirTime) && position.Y < 3)
            {
                this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime);
                elapsedAirTime += gameTime.ElapsedGameTime.TotalSeconds;
            }
            //otherwise time to fall
            else
            {
                playerState = PlayerStates.Falling;
            }

        }

        //add gravity to falling objects
        if (playerState == PlayerStates.Falling || playerState == PlayerStates.Standing)
        {
            //if we are above the ground
            if (this.position.Y < windowBot - 110)
            {
                //chnage state to falling
                playerState = PlayerStates.Falling;
                this.position.Y += 3.0f + ((float)(gameTime.ElapsedGameTime.TotalSeconds));
            }
            else
            {
                playerState = PlayerStates.Standing;
                elapsedAirTime = 0.0f;
            }
        }

Любая помощь очень ценится, пожалуйста, и спасибо!

Ответы [ 2 ]

11 голосов
/ 07 февраля 2011

Чтобы дать вашему спрайту ощущение гравитации, вы должны добавить скорость и ускорение в ваш класс Sprite. Затем создайте метод Обновления для Sprite, и к вашей скорости добавляется ускорение при каждом обновлении, а скорость добавляется в положение при каждом обновлении. Положение не должно основываться на количестве прошедшего эфирного времени. Вы можете установить ускорение на постоянное гравитационное значение, а затем увеличивать скорость спрайта при каждом прыжке. Это создаст плавный параболический прыжок, который выглядит красиво. Если вы хотите включить синхронизацию, вы можете передать GameTime в метод обновления Sprite и использовать его в качестве модификатора скорости. Вот пример метода обновления:

void Update(GameTime gt) { int updateTime = gt.ElapsedGameTime.TotalMilliseconds - oldgt.ElapsedGameTime.TotalMilliseconds; float timeScalar = updateTime / AVG_FRAME_TIME; this.velocity += this.acceleration * timeScalar; this.position += this.velocity; oldgt = gt; }

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

void Update() { this.velocity += this.acceleration; this.position += this.velocity; }

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

2 голосов
/ 07 февраля 2011

Похоже, эта строка ошибочна:

this.position.Y -= (float)(30.0 + ((1.2) * elapsedAirTime)*elapsedAirTime);

Я думаю, вы обнаружите, что это обновляет позицию спрайтов быстрее, чем вы думаете, спрайт переместится на 330 пикселей вверх по экрану за 10 обновлений (при условии Game.IsFixedTimeStep == true), что составляет одну десятую секунды в реальном времени

Вполне вероятно, что это просто обновляется настолько быстро, что вы не получите изменения, чтобы увидеть его повышение до того, как условие && position.Y < 3 вступит в силу иизменяет playerState.

Похоже, вы пытаетесь сказать - прыгайте со скоростью x пикселей в секунду в течение до 8,5 секунд, пока остается место.

Для этого вам нужно изменить расчет на this.position.y -= (float) (30 * gameTime.ElapsedGameTime.TotalSeconds), это придаст движению прыжка очень линейный характер, но это будет означать, что спрайт прыгает ровно 30 пикселей в секунду.

Если Game.IsFixedTimeStep == true - по умолчанию - обновление вызывается 60 раз в секунду, так что gameTime.ElapsedGameTime.TotalSeconds будет составлять около 0,1 при каждом обновлении.Если что-то приводит к пропуску обновления (например, проблемы с рендерингом), обновление будет отложено, а gameTime.ElapsedGameTime.TotalSeconds может быть равно 0,3 (пропущено 2 обновления), но формула по-прежнему работает с правильной скоростью перехода.

...