Bagaimana cara menerapkan deselerasi?

11

Saya katakan "deselerasi" karena saya tidak menggunakan akselerasi saat ini; yang saya maksud adalah menggerakkan kecepatan kembali ke nol, akhirnya berhenti.

Saya baru mengenal vektor dan tidak terlalu hebat dalam fisika dan sebagainya. Bagaimana biasanya "deselerasi" ditangani?


Apa yang saya miliki sekarang berfungsi, tetapi sepertinya agak retas .

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

Saya menggunakan 3 karena apapun yang lebih rendah menunjukkan perilaku aneh, saya menduga jika saya meningkatkan kecepatan maka itu perlu diubah.

Xavura
sumber
2
Juga sedikit semantik rinci .. dalam pernyataan velocity.i += speed;yang speedsebenarnya percepatan Anda, yaitu tingkat yang kecepatan perubahan oleh. :)
Ipsquiggle
Flixel menyebut ini "seret," jika Anda mencari istilah yang tidak tergantung pada akselerasi.
Gregory Avery-Weir
"Deselerasi" adalah akselerasi negatif. Sudahkah Anda mengambil kalkulus?
3Dave
1
Sebenarnya "Deselerasi" bukanlah hal yang nyata, juga bukan "akselerasi negatif". Ini semua akselerasi biasa, hanya ke arah yang berbeda.
MichaelHouse

Jawaban:

16

Sesuatu yang sederhana

this.velocity.i *= 0.9;

berfungsi dengan baik.

David Young
sumber
Heh, kepercayaan saya untuk lebih-menyulitkan itu yang buruk. Saya baru saja membaca bahwa Anda dapat mensimulasikan hambatan udara dasar dengan mengalikannya dengan 0,9 dan tetap saja itu tidak terlintas dalam pikiran. Terima kasih.
Xavura
Haha, oh wow, yeah. Saya menghitung vektor invers normal dan mengalikannya dengan faktor perlambatan. Kenapa aku tidak melakukan ini saja? Terkadang jawaban yang sangat jelas adalah yang paling mudah untuk dilewatkan.
CodexArcanum
7

Di Pseudocode, saya melakukan variasi ini:

Kecepatan + = ((MoveDirection * MaximumSpeed) - Kecepatan) * AccelerationFactor

Dimana:

  • Kecepatan adalah kecepatan saat entitas bepergian pada sumbu saat ini.
  • MoveDirection adalah arah yang coba dilakukan entitas pada sumbu saat ini, 1 maju, 0 masih dan -1 mundur. Semua nilai di antaranya diizinkan.
  • MaximumSpeed ​​adalah konstanta yang menentukan tercepat yang dapat dilalui entitas pada sumbu saat ini.
  • AccelerationFactor adalah konstanta antara 0 dan 1 yang mewakili tingkat akselerasi dan deselerasi. 1 instan, dan 0 tidak akan pernah bergerak.

Yang menangani kedua Percepatan dan Perlambatan baik dalam melengkung, bukan garis. Jika Anda menginginkan kecepatan akselerasi dan perlambatan yang berbeda, Anda bisa melakukan pernyataan IF yang menentukan apakah pemain berusaha untuk tidak bergerak atau bergerak ke arah yang berlawanan.

earok
sumber
1
Itu formula yang sangat menarik. Aku harus mengingatnya untuk masa depan!
Ipsquiggle
+1 Terlihat menarik, saya pikir saya mungkin membuangnya ke beberapa kode untuk melihatnya berfungsi.
David Young
Formula yang sangat bagus. Saya akan menggunakan ini. Dari mana Anda mendapatkannya? Atau apakah Anda mendapatkannya sendiri?
Riki
Maaf atas keterlambatan merespons, saya samar-samar ingat terinspirasi oleh kode salah satu demo Blitz3D, saya tidak ingat yang mana.
earok
3

Jawabannya di sini ( vel = vel * 0.9) sebenarnya redaman , bukan apa yang saya anggap 'deselerasi' .

Saya sering melakukan deselerasi seperti ini:

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

Beberapa pro dan kontra vs redaman:

Pro :

  • Akselerasi percepatan dan akselerasi melambat keduanya linier, yang memberikan 'rasa permainan' halus yang menyenangkan yang menurut saya redaman tidak memberikan. Ini bagian yang penting .
  • Karakter berhenti total yang dapat diprediksi setelah jumlah iterasi yang dapat diprediksi.

Cons :

  • Ini lebih sulit untuk diterapkan jika Anda menggunakan gerakan non-ortogonal (yang kedengarannya seperti Anda?) Pada dasarnya, Anda harus mendapatkan vektor gaya yang disejajarkan dengan kecepatan, membandingkan panjang, dan mengurangi atau nol-keluar sebagai apporpriate. (Jika Anda ingin itu dijelaskan dengan kode, tanyakan saja.)
Ipsquiggle
sumber
1

Sederhananya, dalam kode pseudo:

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]

Namun, Anda perlu memeriksa apakah (kecepatan saat ini <0,001f) atau sesuatu dan set ke 0.

Bebek Komunis
sumber
Saya pikir saya harus meletakkan cek juga, tetapi tampaknya bekerja tanpa itu.
Xavura