Come posso implementare la decelerazione?


11

Dico "decelerazione" perché al momento non sto usando l'accelerazione; ciò che intendo è spostare la velocità indietro verso lo zero, alla fine fermarsi.

Sono nuovo ai vettori e non eccezionale con la fisica e simili. Come viene normalmente gestita la "decelerazione"?


Quello che ho ora funziona, ma sembra un po ' hacker .

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

Ho usato 3 perché qualcosa di più basso mostra un comportamento strano, immagino che se avessi aumentato la velocità, allora avrebbe bisogno di essere cambiato.


2
Anche i dettagli poco semantica .. nella dichiarazione velocity.i += speed;l' speedè infatti l'accelerazione, cioè il tasso che la velocità cambia da. :)
Ipsquiggle,

Flixel chiama questo "trascinamento", nel caso in cui tu stia cercando un termine indipendente dall'accelerazione.
Gregory Avery-Weir,

La "decelerazione" è un'accelerazione negativa. Hai preso il calcolo?
3Daveva il

1
In realtà "la decelerazione" non è una cosa reale, né "l'accelerazione negativa". È tutta un'accelerazione regolare, solo in diverse direzioni.
MichaelHouse

Risposte:


16

Qualcosa di semplice come

this.velocity.i *= 0.9;

funziona bene.


Eh, mi fiducia a un eccesso di complicare quel male. Ho appena letto di recente che è possibile simulare la resistenza dell'aria di base moltiplicando per 0,9 e ancora non mi è venuto in mente. Grazie.
Xavura,

Haha, oh wow, sì. Stavo calcolando un vettore inverso normale e moltiplicandolo per un fattore di rallentamento. Perché non l'ho fatto? A volte le risposte davvero ovvie sono le più facili da perdere.
CodexArcanum,

7

In Pseudocode, faccio variazioni di questo:

Speed ​​+ = ((MoveDirection * MaximumSpeed) - Speed) * AccelerationFactor

Dove:

  • La velocità è la velocità corrente a cui l'entità sta viaggiando sull'asse corrente.
  • MoveDirection è la direzione in cui l'entità sta tentando di spostarsi sull'asse corrente, 1 è in avanti, 0 è fermo e -1 è indietro. Sono ammessi tutti i valori intermedi.
  • MaximumSpeed ​​è una costante che determina il più veloce che l'entità può percorrere sull'asse corrente.
  • AccelerationFactor è una costante tra 0 e 1 che rappresenta la velocità di accelerazione e decelerazione. 1 è istantaneo e 0 non si muoverà mai.

Che gestisce bene sia l' accelerazione che la decelerazione in una curva, piuttosto che in una linea. Se desideri tassi di accelerazione e decelerazione diversi, potresti fare delle dichiarazioni IF che determinano se il giocatore sta tentando di non muoversi o muoversi nella direzione opposta.


1
Questa è una formula molto interessante. Dovrò tenerlo a mente per il futuro!
Ipsquiggle,

+1 Sembra interessante, penso che potrei buttarlo in qualche codice per vederlo funzionare.
David Young,

Formula molto buona Lo userò. Da dove lo hai preso? O l'hai ricavato da solo?
Riki,

Scusate il ritardo nel rispondere, ricordo vagamente di essere stato ispirato dal codice di una delle demo di Blitz3D, ma non ricordo quale però.
earok,

3

Le risposte qui ( vel = vel * 0.9) sono in realtà smorzanti , non quello che considererei 'rallentamento' .

Faccio spesso la decelerazione in questo modo:

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

Alcuni pro e contro vs. smorzamento:

Pro :

  • L'accelerazione di accelerazione e l'accelerazione di rallentamento sono entrambe lineari, il che dà una piacevole "sensazione di gioco" sottile che penso che lo smorzamento non fornisca. Questa è la parte importante
  • Il personaggio si ferma in modo prevedibile dopo un numero prevedibile di iterazioni.

Contro :

  • Questo è più complicato da implementare se stai usando un movimento non ortogonale (come sembra che tu sia?) Fondamentalmente, devi ottenere un vettore di forza che è allineato con la velocità, confrontare le lunghezze e sottrarre o azzerare come apprendistato. (Se vuoi che sia spiegato con il codice, basta chiedere.)

1

In parole povere, nello pseudo codice:

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]

Tuttavia, è necessario verificare se (velocità corrente <0,001f) o qualcosa del genere e impostare su 0.


Ho pensato che avrei dovuto mettere anche un assegno, ma sembra funzionare senza uno.
Xavura,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.