Comment mettre en œuvre la décélération?

11

Je dis "décélération" parce que je n'utilise pas d'accélération pour le moment; ce que je veux dire, c'est ramener la vitesse vers zéro, finalement arrêter.

Je suis nouveau dans les vecteurs et pas très bon en physique et autres. Comment la "décélération" est-elle normalement gérée?


Ce que j'ai maintenant fonctionne, mais cela semble un peu hackish .

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

J'ai utilisé 3 car tout ce qui est inférieur présente un comportement étrange, je suppose que si j'augmentais la vitesse, il faudrait la changer.

Xavura
la source
2
De plus en détail peu sémantique .. dans la déclaration velocity.i += speed;du speedest en fait votre accélération, soit le taux qui change la vitesse par. :)
Ipsquiggle
Flixel appelle cela «glisser», au cas où vous recherchez un terme indépendant de l'accélération.
Gregory Avery-Weir
La "décélération" est une accélération négative. Avez-vous fait du calcul?
3Dave
1
En fait, la "décélération" n'est pas une chose réelle, ni "l'accélération négative". C'est une accélération régulière, juste dans des directions différentes.
MichaelHouse

Réponses:

16

Quelque chose d'aussi simple que

this.velocity.i *= 0.9;

fonctionne bien.

David Young
la source
Hé, faites-moi confiance pour compliquer les choses à ce point. Je viens de lire récemment que vous pouvez simuler la résistance de l'air de base en multipliant par 0,9 et cela ne me vient pas à l'esprit. Je vous remercie.
Xavura
Haha, oh wow, ouais. Je calculais un vecteur inverse normal et le multipliais par un facteur de ralentissement. Pourquoi n'ai-je pas simplement fait ça? Parfois, les réponses vraiment évidentes sont les plus faciles à manquer.
CodexArcanum
7

Dans Pseudocode, je fais des variations de ceci:

Vitesse + = ((MoveDirection * Vitesse maximale) - Vitesse) * AccelerationFactor

Où:

  • La vitesse est la vitesse actuelle à laquelle l'entité se déplace sur l'axe actuel.
  • MoveDirection est la direction dans laquelle l'entité essaie de se déplacer sur l'axe actuel, 1 est en avant, 0 est toujours et -1 est en arrière. Toutes les valeurs intermédiaires sont autorisées.
  • MaximumSpeed ​​est une constante déterminant la vitesse la plus rapide que l'entité peut parcourir sur l'axe actuel.
  • AccelerationFactor est une constante entre 0 et 1 qui représente le taux d'accélération et de décélération. 1 est instantané et 0 ne bougera jamais.

Qui gère à la fois l' accélération et la décélération dans une courbe plutôt qu'une ligne. Si vous voulez des taux d'accélération et de décélération différents, vous pouvez faire des instructions IF qui déterminent si le joueur essaie de ne pas bouger ou de se déplacer dans la direction opposée.

earok
la source
1
C'est une formule très intéressante. Je dois garder cela à l'esprit pour l'avenir!
Ipsquiggle
+1 Semble intéressant, je pense que je pourrais le jeter dans du code pour le voir fonctionner.
David Young
Très bonne formule. Je vais l'utiliser. Où est-ce que tu l'as trouvé? Ou l'avez-vous dérivé vous-même?
Riki
Désolé pour le retard dans la réponse, je me souviens vaguement avoir été inspiré par le code d'une des démos de Blitz3D, je ne me souviens pas lequel cependant.
earok
3

Les réponses ici ( vel = vel * 0.9) sont en fait un amortissement , pas ce que je considérerais comme une «décélération» .

Je fais souvent une décélération comme ceci:

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

Quelques avantages et inconvénients par rapport à l'amortissement:

Avantages :

  • L'accélération et l'accélération du ralentissement sont toutes deux linéaires, ce qui donne une agréable sensation de jeu subtile que je pense que l'amortissement ne fournit pas. C'est la partie importante .
  • Le personnage arrive à un arrêt complet prévisible après un nombre prévisible d'itérations.

Inconvénients :

  • C'est plus difficile à mettre en œuvre si vous utilisez un mouvement non orthogonal (ce qui ressemble à vous?) Fondamentalement, vous devez obtenir un vecteur de force aligné avec la vitesse, comparer les longueurs et soustraire ou mettre à zéro comme approprié. (Si vous voulez que cela soit expliqué avec du code, demandez simplement.)
Ipsquiggle
la source
1

Très simplement, en pseudo code:

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]

Cependant, vous devrez vérifier si (vitesse actuelle <0,001f) ou quelque chose et régler à 0.

Le canard communiste
la source
J'ai pensé que je devrais également mettre un chèque en place, mais cela semble fonctionner sans un chèque.
Xavura