Как создать плавное движение в xna для wp7? - PullRequest
2 голосов
/ 27 июля 2011

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

protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            pos.Y = pos.Y + 1;
            base.Update(gameTime);
        }

движение работает, но оно не выглядит гладким, похоже, что оно покачивается. pos - это вектор2 для позиции на изображении.

как сделать его более плавным?

Ответы [ 4 ]

3 голосов
/ 27 июля 2011

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

protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            pos.Y = pos.Y * 100 * (float)gameTime.ElapsedGameTime.TotalSeconds;
            base.Update(gameTime);
        }

У меня сейчас нет доступа к XNA + visual studio, но внесенные мной изменения должны дать вам представление о том, что попробовать. Имейте в виду, что вызов Update происходит несколько раз в секунду, поэтому истекшее время будет небольшим числом, поэтому вам придется умножить его на большее значение «движения», в этом случае я ставлю 100. Изменяйте 100, пока не увидите желание.

2 голосов
/ 14 сентября 2011

Beanish - это правильно, вы должны умножить на GameTime, если хотите плавности. Физика - это перебор, если вы хотите, чтобы ваша анимация выглядела гладко.

Лучший способ, который я нашел для анимации, - это использовать интерполяцию положения, , чтобы это работало, вы должны знать начальную (вы уже знаете) и конечную позицию изображения.

Если вы хотите перейти от A к B, скажем, за 2 секунды, вы можете использовать следующий код.

Vector2 a = new Vector2(0, 0);
Vector2 b = new Vector2(0, 100);

float elapsedTime = 0;
float duration = 2.0;

public override void Update(GameTime gameTime)
{
    float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
    elapsedTime += dt;
    if (elapsedTime > 1)
        elapsedTime = 1;

    float param = elapsedTime / duration;
    pos = Vector2.Lerp(a, b, param);
}

Самое лучшее в использовании этого подхода - это то, что теперь вы можете использовать "замедление", чтобы анимация выглядела действительно очень красиво.

Для этого просто добавьте операцию Power в параметр интерполятора:

pos = Vector2.Lerp(a, b, (float)Math.Pow(param /2.0, 0.5));

Это замедлит изображение по мере приближения к B. Вы можете поиграть со значением экспоненты (0.5), чтобы получить другие результаты, например, 2.0.

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

Чтобы узнать больше об ослаблении, отметьте Уравнения ослабления Роберта Пеннера .

1 голос
/ 01 августа 2011

Сначала я скажу вам, в чем проблема . Вам не нужен физический движок для плавного движения.И изменение Update для включения ElapsedGameTime не будет иметь большого значения для гладкости (при условии, что вы не изменили значение по умолчанию IsFixedTimestep на false).При фиксированном временном шаге ElapsedGameTime всегда будет иметь одинаковое значение, оно не будет меняться.

Я не знаю, сколько вы делаете в своем коде, но если его слишком много, XNA запуститсяпропуская часть кода Draw, и это, безусловно, может привести к рывку.Один из способов проверить: в вашем методе Update проверьте значение IsRunningSlowly.Всякий раз, когда это правда, XNA пропустит некоторые Draw вызовы.

Если вы не делаете что-то сложное, виновником может быть частота обновления вашего монитора.Если для него установлено значение, отличное от 60 Гц, у вас будет дрожь.Вы можете исправить это, изменив частоту обновления вашего монитора.Или вы можете изменить значение TargetElapsedTime, чтобы оно соответствовало скорости вашего монитора.

0 голосов
/ 27 июля 2011

Вам следует подумать о добавлении в вашу игру библиотеки для работы с физикой, например, FarseerPhysics . При расчете положения за единицу времени с применением правил физики ваши движения будут плавными и естественными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...