Bagaimana cara membuat partikel yang bereaksi terhadap pemain dan musuh?

38

Saat ini saya membuat game dengan mesin game saya sendiri yang saya tulis dalam C ++ dan saya menggunakan directx SDK terbaru.

Gim ini adalah penembak ruang angkasa dari atas ke bawah (dengan sentuhan yang cukup menarik) dan saya ingin memiliki semacam efek nebula yang akan dilalui pemain. Saya benar-benar ingin mencoba dan merasakan sentuhan taktil yang bagus dari ratusan partikel yang bergerak keluar dari jalan kapal pemain saat ia terbang ke dalamnya. Agak seperti bagaimana partikel akan bergerak seperti pemain di Geomtry Wars di XBLA.

Saya seorang programmer berpengalaman ketika datang ke C ++. Namun, saya tidak tahu bagaimana cara mulai menerapkan efek ini. Adakah yang punya ide keren atau pilihan desain yang mungkin ingin saya lihat? Jangan ragu untuk menjawab setiap tingkat kedalaman yang Anda inginkan.

Matt McDonald
sumber

Jawaban:

65

Itu ide yang keren. Anda perlu semacam gradien difusi di sekitar kapal Anda. Ada tiga model fisik yang dapat saya pikirkan yang mungkin Anda inginkan:

  1. Anda ingin itu tampak seperti media cair, di mana gradien tekanannya kembali, yaitu begitu Anda telah melewati beberapa partikel, mereka bergerak kembali ke bangun Anda (seperti air di belakang perahu). Dalam hal ini, posisi partikel bersifat absolut, dan hanya hubungannya dengan pemain yang mengubah posisi render mereka untuk sementara . Ini agak seperti ketika Anda melewatkan kaca pembesar tebal di atas benda-benda, dan difraksi tampaknya membuat mereka bergerak - tetapi hanya sampai Anda memindahkan gelas itu. Dalam hal ini, kapal Anda adalah gelasnya.

  2. Jika Anda ingin mereka menjauh dari kapal, dan terus bergerak begitu mereka sudah pindah. Ini seperti fisika standar dalam ruang yang umumnya kosong di mana tidak ada (atau sangat kecil) gradien tekanan.

  3. Anda ingin memindahkan partikel menjauh dari kapal dengan cepat ketika mendekati, seperti dalam (1) dan (2), tetapi begitu kapal hilang, partikel-partikel tersebut perlahan-lahan akan menyeimbangkan kembali diri mereka agar berjarak sama setelah Anda bangun.

Umum untuk ketiga solusi : Anda harus memiliki bidang difusi yang bergerak bersama kapal Anda. Dalam contoh ini kita akan membuatnya melingkar. Anda kemudian mendeteksi vektor, sebut saja v1, antara kapal dan setiap partikel di wilayah itu. Dorong partikel Anda di sepanjang vektor itu. Seberapa kuat Anda akan mendorongnya tergantung pada jaraknya dari kapal: gunakan 1 - v1.magnitude. Formula ini akan memberi Anda kekuatan linier, namun Anda bisa memodifikasinya untuk menggunakan sesuatu yang lain seperti kurva kekuatan melingkar yang berkurang kekuatannya ke arah tepinya. Ini akan memberikan lebih banyak tampilan seolah-olah ada gradien tekanan bola daripada melingkar di sekitar kapal.

Untuk solusi 1 : Yang sekarang Anda lakukan adalah memodifikasi posisi render dari partikel tersebut (yaitu, posisi sprite) pada setiap pembaruan render , dengan vektor ini. Karena Anda melakukannya dengan cara ini, ini murni efek render dan tidak berpengaruh pada posisi dunia partikel yang sebenarnya. Jadi, Anda menambahkan posisi dunia ke offset render (v1) dan kini Anda memiliki partikel yang dipindahkan dengan baik saat Anda bergerak melewati atau di sampingnya, dan dengan mulus mengembalikan partikel saat Anda lewat (di belakang Anda).

Untuk solusi 2 : Alih-alih hanya menerapkan v1 ke posisi tampilan, terapkan pada setiap pembaruan logika , ke posisi partikel. Jadi, p1.position += v1. Jadi Anda menerapkan gaya akseleratif pada partikel, yang diterjemahkan menjadi kecepatan. Mungkin, Anda ingin agar kecepatan masing-masing partikel dibasahi sehingga mereka lambat laun akan melambat dan berhenti setelah Anda melewatinya. Anda dapat melihat bagaimana solusi ini akan menghasilkan partikel yang berkumpul di nebula Anda, karena mereka tidak akan pernah rediffuse. Tidak terlalu realistis, saya yakin, karena nebula memiliki gradien tekanan di dalamnya, tidak peduli seberapa lemah kenyataannya.

Untuk solusi 3: Sama seperti (2), tetapi dalam hal ini Anda harus menggunakan kembali partikel Anda. Untuk melakukan ini dengan mudah adalah sedikit pendekatan brute force, tetapi karena ini hanya partikel dan dengan demikian eye-candy, Anda mungkin tidak perlu membahas bidang yang sangat menarik (mungkin hanya jari-jari pemainPosisi + maxPlayerSpeedPerTick, atau apa pun area persegi panjang membatasi itu, untuk tujuan logika). Setiap partikel akan menerapkan gaya pada setiap partikel lainnya di dalam area yang diinginkan. Mereka akan menerapkan kekuatan berdasarkan, sekali lagi, pada jarak mereka satu sama lain. Hitung semua gaya antar partikel dalam satu sapuan melintasi area yang diinginkan, dan kemudian terapkan semua gaya dalam satu sapuan. Terakhir, pastikan bahwa Anda hanya melakukan pemrosesan gaya antar-partikel ini pada partikel yang memiliki kecepatan nol. Dan sekali partikel yang diberikan mencapai kecepatan minimum,

Ada semua jenis rumus difusi dll di luar sana, tapi saya pikir dalam hal ini solusi sederhana paling baik.

Insinyur
sumber
Mate, sayangnya saya saat ini tidak memiliki reputasi untuk memperbaiki jawaban Anda (dan saya hanya bisa melakukannya sekali, yang kurang dari yang pantas). Anda benar-benar menemukan apa yang saya cari dalam solusi pertama Anda. Jawaban yang fantastis. Secara jujur. Terima kasih!
Matt McDonald
Kenikmatan total, Matt, ini pertanyaan yang bagus & layak untuk melenturkan otak!
Insinyur
Saya juga telah memutuskan bahwa dengan sedikit perubahan dalam kode saya dapat menerapkan ini pada asteroid yang lebih kecil di dalam sabuk. Terima kasih lagi.
Matt McDonald