Як здійснити сповільнення?


11

Я кажу "уповільнення", тому що зараз не використовую прискорення; що я маю на увазі - переміщення швидкості назад до нуля, врешті-решт зупиняючись.

Я новачок у векторах і не дуже великий з фізикою та ін. Як нормально справляється "уповільнення"?


Те, що я зараз маю, працює, але це здається хакешним .

update:function(Game, t, dt) {
    var speed = Game.Input.isKeyDown('shift') ? 8 : 4;

    if (Game.Input.isKeyDown('a')) {
        this.velocity.i -= speed;
    }
    else if (Game.Input.isKeyDown('d')) {
        this.velocity.i += speed;
    }
    else {
        if (Math.abs(this.velocity.i) > 3) {
            this.velocity.i += (this.velocity.i > 0) ? -speed : speed;
        }
        else {
            this.velocity.i = 0;
        }
    }

    if (Game.Input.isKeyDown('w')) {
        this.velocity.j -= speed;
    }
    else if (Game.Input.isKeyDown('s')) {
        this.velocity.j += speed;
    }
    else {
        if (Math.abs(this.velocity.j) > 3) {
            this.velocity.j += (this.velocity.j > 0) ? -speed : speed;
        }
        else {
            this.velocity.j = 0;
        }
    }

    this.updateVectors(dt);
}

Я використовував 3, тому що що-небудь нижче демонструє дивну поведінку, я здогадуюсь, якби я підвищив швидкість, то це потрібно було б змінити.


2
Також трохи семантична деталь .. в заяві насправді ваше прискорення, тобто швидкість , що швидкість змінюється на. :)velocity.i += speed;speed
Ipsquiggle

Flixel називає це "перетягуванням", якщо ви шукаєте термін, незалежний від прискорення.
Григорій Ейвері-Вейр

"Уповільнення" - це негативне прискорення. Чи взяли ви обчислення?
3Dave

1
Насправді "уповільнення" - це не реальна річ, а також "негативне прискорення". Це все регулярне прискорення, тільки в різних напрямках.
MichaelHouse

Відповіді:


16

Щось таке просто

this.velocity.i *= 0.9;

працює чудово.


Хех, довіру мене до надмірного ускладнювати , що погано. Нещодавно я нещодавно прочитав, що ви можете імітувати основний опір повітря, помноживши на 0,9, і все одно це не прийшло в голову. Дякую.
Xavura

Ха-ха-о, так. Я обчислював нормальний обернений вектор і множив його на коефіцієнт уповільнення. Чому я просто не зробив цього? Іноді справді очевидні відповіді найлегше пропустити.
CodexArcanum

7

У псевдокоді я роблю варіанти цього:

Швидкість + = ((MoveDirection * MaximumSpeed) - Швидкість) * AccelerationFactor

Де:

  • Швидкість - поточна швидкість, якою рухається суб'єкт господарювання на поточній осі.
  • MoveDirection - це напрямок, яким намагається рухатись сутність на поточній осі, 1 - вперед, 0 - нерухоме, -1 - назад. Усі значення між ними дозволені.
  • MaximumSpeed ​​- це константа, що визначає найшвидший, який об'єкт може рухатись по осі струму.
  • AccelerationFactor - константа між 0 і 1, що представляє швидкість прискорення і уповільнення. 1 миттєвий, а 0 ніколи не рухатиметься.

Який обробляє як прискорення, так і гальмування красиво в криву, а не по лінії. Якщо ви хочете різної швидкості прискорення та уповільнення, ви можете зробити ІФ-висловлювання, які визначають, чи намагається гравець не рухатись чи рухатися у зворотному напрямку.


1
Це дуже цікава формула. Я маю це мати на увазі на майбутнє!
Ipsquiggle

+1 Виглядає цікаво, я думаю, я можу вписати його в якийсь код, щоб побачити, як він працює.
Девід Янг

Дуже хороша формула. Я буду використовувати це. Звідки ти це взяв? Або ви вивели це самостійно?
Рікі

Вибачте за затримку з реагуванням, я смутно пам'ятаю, що надихнувся кодом однієї з демонстрацій Blitz3D, я не можу пригадати, який з них.
earok

3

Відповіді тут ( vel = vel * 0.9) насправді демпфірують , а не те, що я вважав би уповільненням .

Я часто роблю уповільнення так:

if ( Game.Input.isKeyDown( "w" ) )
{
    this.velocity.i = Math.max( -WALKSPEED, this.velocity.i - WALKFORCE);
}
else if ( Game.Input.isKeyDown( "d" ) )
{
    this.velocity.i = Math.min( WALKSPEED, this.velocity.i + WALKFORCE);
}
else
{
    if (this.velocity.i < 0)
    {
        this.velocity.i = Math.min( 0, this.velocity.i + WALKFORCE);
    }
    else if (this.velocity.i > 0)
    {
        this.velocity.i = Math.max( 0, this.velocity.i - WALKFORCE);
    }
}

Деякі плюси і мінуси проти демпфування:

Плюси :

  • Прискорення прискорення та уповільнення прискорення є лінійними, що дає приємне тонке «ігрове відчуття», яке я думаю, що демпфірування не забезпечує. Це важлива частина.
  • Персонаж приходить до передбачуваної повної зупинки після передбачуваної кількості ітерацій.

Мінуси :

  • Це складніше для реалізації, якщо ви використовуєте неортогональний рух (який він здається, що ви є?) В основному, ви повинні отримати вектор сили, який вирівняний зі швидкістю, порівняти довжини та відняти або нульове значення, як підходяще. (Якщо ви хочете, щоб це було пояснено з кодом, просто запитайте.)

1

Дуже просто кажучи, у псевдокоді:

if(no movement keys pressed) [Meaning we want to start to decelerate]
current speed *= 0.85 [Or some number between 0 and 1, the smaller the faster the deceleration]

Однак вам потрібно буде перевірити, чи (поточна швидкість <0,001f) чи щось, і встановити 0.


Я подумав, що мені також доведеться поставити чек, але це, здається, працює і без нього.
Xavura
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.