Jak wdrożyć opóźnienie?

11

Mówię „zwalnianie”, ponieważ obecnie nie używam przyspieszenia; mam na myśli przesunięcie prędkości z powrotem w kierunku zera, ostatecznie zatrzymując się.

Jestem nowy w wektorze i nie tak dobrze z fizyką i tym podobne. Jak zwykle obsługiwane jest „zmniejszanie prędkości”?


To, co mam teraz, działa, ale wydaje się trochę hacking .

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

Użyłem 3, ponieważ cokolwiek niższego wykazuje dziwne zachowanie, domyślam się, że jeśli zwiększyłem prędkość, to trzeba by to zmienić.

Xavura
źródło
2
Także trochę semantyczny szczegół .. w rachunku jest w rzeczywistości swoją przyspieszenie, czyli szybkością, że prędkość zmienia się przez. :)velocity.i += speed;speed
Ipsquiggle,
Flixel nazywa to „przeciąganiem”, na wypadek, gdybyś szukał terminu niezależnego od przyspieszenia.
Gregory Avery-Weir
„Zwolnienie” oznacza przyspieszenie ujemne. Czy wziąłeś rachunek różniczkowy?
3Dave
1
W rzeczywistości „opóźnienie” nie jest rzeczywiste, podobnie jak „przyspieszenie ujemne”. To wszystko regularne przyspieszenie, tylko w różnych kierunkach.
MichaelHouse

Odpowiedzi:

16

Coś tak prostego jak

this.velocity.i *= 0.9;

działa ładnie.

David Young
źródło
Heh, zaufaj mi do nadmiernego skomplikować że źle. Właśnie przeczytałem niedawno, że można zasymulować podstawowy opór powietrza, mnożąc go przez 0,9, a jednak to nie przyszło mi do głowy. Dziękuję Ci.
Xavura,
Haha, och wow, tak. Obliczałem normalny wektor odwrotny i mnożąc go przez współczynnik spowolnienia. Dlaczego tego nie zrobiłem? Czasami najłatwiej przeoczyć naprawdę oczywiste odpowiedzi.
CodexArcanum,
7

W Pseudocode robię odmiany tego:

Prędkość + = ((MoveDirection * MaximumSpeed) - Speed) * AccelerationFactor

Gdzie:

  • Prędkość to bieżąca prędkość, z jaką jednostka porusza się na bieżącej osi.
  • MoveDirection to kierunek, w którym jednostka próbuje się poruszać na bieżącej osi, 1 jest do przodu, 0 jest nadal, a -1 jest do tyłu. Wszystkie wartości pomiędzy są dozwolone.
  • MaximumSpeed ​​to stała określająca najszybsze, jakie jednostka może poruszać się na bieżącej osi.
  • AccelerationFactor to stała między 0 a 1, która reprezentuje szybkość przyspieszania i zwalniania. 1 jest natychmiastowe, a 0 nigdy się nie poruszy.

Który ładnie radzi sobie zarówno z przyspieszaniem, jak i zwalnianiem na zakrzywionej, a nie liniowej linii. Jeśli chcesz mieć różne prędkości przyspieszania i zwalniania, możesz wykonać instrukcje JEŻELI, które określają, czy gracz próbuje się nie ruszyć ani nie ruszyć w przeciwnym kierunku.

earok
źródło
1
To bardzo interesująca formuła. Będę musiał pamiętać o tym na przyszłość!
Ipsquiggle,
+1 Wygląda interesująco, myślę, że mógłbym wrzucić go do jakiegoś kodu, aby zobaczyć, jak działa.
David Young,
Bardzo dobra formuła. Użyję tego. Skąd to masz? A może sam to wyprowadziłeś?
Riki
Przepraszam za opóźnienie w odpowiedzi, niejasno pamiętam, że zostałem zainspirowany kodem jednej z wersji demonstracyjnych Blitz3D, ale nie pamiętam, która z nich.
earok
3

Odpowiedzi tutaj ( vel = vel * 0.9) są w rzeczywistości tłumieniem , a nie tym, co uważam za „opóźnienie” .

Często robię takie spowolnienie:

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

Niektóre zalety i wady a tłumienie:

Plusy :

  • Przyspieszenie i spowolnienie przyspieszenia są liniowe, co daje przyjemne subtelne „wyczucie gry”, którego, moim zdaniem, nie zapewnia tłumienie. To jest ważna część.
  • Postać zatrzymuje się w przewidywalnym całkowitym zatrzymaniu po przewidywalnej liczbie iteracji.

Wady :

  • Jest to trudniejsze do wdrożenia, jeśli używasz ruchu nieortogonalnego (który brzmi jak jesteś?) Zasadniczo musisz uzyskać wektor siły, który jest wyrównany z prędkością, porównać długości i odjąć lub wyzerować jako odpowiedni. (Jeśli chcesz to wyjaśnić kodem, po prostu zapytaj.)
Ipsquiggle
źródło
1

Bardzo prosto, w pseudokodzie:

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]

Należy jednak sprawdzić, czy (aktualna prędkość <0,001 f) lub coś, i ustawić na 0.

Kaczka komunistyczna
źródło
Pomyślałem, że będę musiał również wprowadzić czek, ale wydaje się, że działa bez niego.
Xavura,