Indonesian (Bahasa Indonesia) translation by Taufan Prasetyo Basri (you can also view the original English article)
Efek partikel sangat umum dalam permainan - sulit untuk menemukan permainan modern yang tidak menggunakannya. Dalam tutorial ini kita akan melihat bagaimana membangun mesin partikel yang cukup kompleks dan menggunakannya untuk membuat adegan menyenangkan bersalju. Mengenakan topi Anda wol dan mari kita mulai.
Catatan: Meskipun tutorial ini ditulis menggunakan AS3 dan Flash, Anda harus dapat menggunakan teknik dan konsep yang sama di hampir setiap lingkungan pengembangan game.
Hasil akhir Tinjauan
Klik dan tarik mouse untuk berinteraksi dengan efek salju.
Tidak ada Flash? Check out video ini dari demo di YouTube:
Setup
Implementasi demo di atas menggunakan AS3 dan Flash, dengan kerangka Starling untuk GPU dipercepat render. Gambar pra-diberikan 3D adegan (tersedia di download sumber) akan digunakan sebagai latar belakang. Di lapisan tengah kami akan menempatkan efek partikel, dan seluruh adegan akan dikalikan dengan tekstur yang mewakili atribusi cahaya.
Efek partikel
Dalam permainan kami sering untuk mensimulasikan berbagai visual dan gerak fenomena, dan sering perlu untuk menampilkan efek visual yang dinamis seperti kebakaran, asap dan hujan. Ada beberapa cara kita dapat melakukan ini; metode umum adalah dengan menggunakan efek partikel.
Ini melibatkan menggunakan banyak elemen kecil - biasanya gambar berorientasi untuk menghadapi kamera - tetapi mereka bisa dilakukan menggunakan 3D model juga. Tujuan utama adalah untuk memperbarui posisi, skala, warna dan sifat-sifat lainnya dari sekelompok banyak partikel (mungkin beberapa ribu). Ini akan menciptakan ilusi bagaimana efek terlihat dalam kehidupan nyata.
Dalam tutorial ini kita akan mensimulasikan efek dua: salju efek yang akan terdiri dari banyak serpihan sprite, dipengaruhi oleh angin dan gravitasi, dan efek kabut halus yang akan menggunakan segenggam besar asap sprite.
Pelaksanaan emisi, Colliders dan kekuatan sumber
Efek partikel khas terdiri dari satu atau lebih emisi partikel. Emitor adalah tempat di mana partikel berasal dari; dapat mengambil berbagai bentuk dan memiliki perilaku yang berbeda. Itu menambah posisi awal dan sudut partikel, dan juga dapat menentukan parameter lain awal, seperti awal kecepatan.
Kami akan membuat satu jenis emitor, emitor kotak, yang akan menelurkan partikel dalam - Anda sudah bisa menebaknya - kotak yang kita mendefinisikan.

Untuk membuatnya mudah bagi kita untuk menambahkan semakin emitter, kita akan menggunakan membangun pemrograman disebut antarmuka yang mendefinisikan yang menerapkan kelas harus memiliki yang ditetapkan seperangkat metode. Dalam kasus kami, kami akan membutuhkan hanya satu metode:
function generatePosition():Point
Menerapkan ini dalam kotak emitor super sederhana; kami mengambil titik acak antara titik minimum dan maksimum yang menentukan kotak:
public function generatePosition():Point { var randomX:Number = Math.random() * (maxPoint.x - minPoint.x) + minPoint.x; var randomY:Number = Math.random() * (maxPoint.y - minPoint.y) + minPoint.y; return new Point(randomX, randomY); }
Untuk membuat contoh ini lebih menarik dan sedikit lebih lanjut kami akan menambahkan konsep: sumber collider dan kekuatan.
Collider akan menjadi sebuah obyek yang terdiri dari satu atau lebih geometri definisi, yang dapat dilampirkan ke emitor partikel. Ketika partikel memiliki interaksi dengan collider (yaitu, ketika memasuki geometri) kita akan mendapatkan sebuah event untuk memutuskan apa yang ingin kita lakukan. Ini akan digunakan untuk menghentikan serpih salju dari bergerak ketika mereka bertabrakan dengan tanah.

Dengan cara yang sama seperti dengan emitter kami akan menggunakan antarmuka yang mengharuskan kita untuk melaksanakan fungsi berikut:
function collides(x:Number, y:Number):Boolean;
Catatan: ini adalah implementasi sederhana, sehingga kita mengambil posisi hanya diperhitungkan saat memeriksa tabrakan.
Pelaksanaan collider kotak sederhana; kami memeriksa apakah titik dalam batas-batas kotak:
public function collides(x:Number, y:Number):Boolean { var xInBounds:Boolean = this.minPoint.x < x && this.maxPoint.x > x; var yInBounds:Boolean = this.minPoint.y < y && this.maxPoint.y > y; return xInBounds && yInBounds; }
Jenis lain dari obyek yang kita akan memperkenalkan adalah sumber kekuatan. Ini akan memiliki efek pada kecepatan partikel berdasarkan parameter dan partikel posisi dan massa.
Sumber yang paling sederhana akan dipanggil sumber directional kekuatan, dan kami akan mendefinisikannya dengan vektor tunggal D (digunakan untuk arah kekuatan dan kekuatan). Tidak mengambil posisi partikel ke rekening; itu hanya berlaku angkatan di semua partikel dari efek. Dengan ini kami akan dapat mensimulasikan gravitasi dan angin - untuk angin arah akan bervariasi dalam waktu untuk merasa lebih realistis.
Jenis lain dari sumber Angkatan akan tergantung pada jarak antara titik didefinisikan dan partikel, mendapatkan lebih lemah lebih lanjut pergi dari pusat. Sumber ini akan ditentukan oleh posisi P dan kekuatan faktor S. Kita akan menggunakan ini untuk mengaktifkan mouse interaksi dengan salju.

Jenis sumber kekuatan kita akan membuat
Sumber-sumber kekuatan akan memiliki antarmuka sendiri, memerlukan metode berikut untuk diimplementasikan:
function forceInPoint(x:Number, y:Number):Point;
Saat ini, namun, kami memiliki beberapa implementasi: satu untuk arah yang memaksa sumber dan satu untuk sumber kekuatan titik.
Arah kekuatan sumber implementasi yang lebih sederhana dari dua:
public function forceInPoint(x:Number, y:Number):Point { /// Each particle gets the same force return new Point(forceVectorX, forceVectorY); }
Ini adalah titik kekuatan sumber implementasi:
/// x. y are the position of the particle public function forceInPoint(x:Number, y:Number):Point { /// Direction and distance var differenceX:Number = x - positionX; var differenceY:Number = y - positionY; var distance:Number = Math.sqrt(differenceX * differenceX + differenceY * differenceY); /// Falloff value which will reduce force strength var falloff:Number = 1.0 / (1.0 + distance); /// We normalize the direction, and use falloff and strength to calculate final force var forceX:Number = differenceX / distance * falloff * strength; var forceY:Number = differenceY / distance * falloff * strength; return new Point(forceX, forceY); }
Perhatikan bahwa metode ini akan dipanggil terus-menerus. Hal ini memungkinkan kita untuk mengubah parameter kekuatan ketika efek aktif. Kita akan menggunakan fitur ini untuk mensimulasikan angin dan menambahkan mouse interaktivitas.
Efek dan partikel implementasi
Bagian utama dari implementasi adalah efek kelas, yang bertanggung jawab untuk pemijahan dan memperbarui partikel.
Jumlah partikel untuk bertelur akan ditentukan oleh nilai spawnPerSecond dalam metode update:
_spawnCounter -= time; /// Using a loop to spawn multiple particles in a frame while (_spawnCounter <= 0) { /// Spawn the number of particles according to the passed time _spawnCounter += (1 / _spawPerSecond) * time; spawnParticle(); }
Memperbarui sedikit lebih rumit. Pertama pelaksanaan update pasukan, kemudian panggilan partikel simulasi update dan cek untuk tabrakan. Hal ini juga bertanggung jawab untuk menghapus partikel ketika mereka tidak dibutuhkan lagi.
var i:int = 0; /// using while loop so we can remove the particles from the container while (i < _particles.length) { var particle:Particle = _particles[i]; /// Calculate particle accleration from all forces particle.acceleration = calculateParticleAcceleration(particle); /// Simulate particle particle.update(time); /// Go through the colliders and report collisions if (_colliders && _collisionResponse != null) { for each (var collider:ICollider in _colliders) { if (collider.collides(particle.x, particle.y)) { _collisionResponse(particle, collider); } } } /// remove particle if it's dead if (particle.isDead) { _particles.splice(i, 1); addParticleToThePool(particle); particle.removeFromParent(); } else { /// We are in the while loop and need to increment the counter i++; } }
Saya belum sebutkan bagian paling penting dari pelaksanaan: bagaimana kita mewakili partikel. Kelas partikel yang akan mewarisi dari objek kami dapat menampilkan (gambar) dan memiliki beberapa sifat yang akan efek perubahan yang selama update:
- startingLife - berapa lama partikel dapat tetap hidup.
- bergerak - Apakah posisi partikel diganti (digunakan untuk membekukan partikel di tempat).
- kecepatan - berapa banyak partikel akan bergerak dalam satu set jumlah waktu.
- percepatan - berapa banyak partikel kecepatan akan berubah dalam satu set jumlah waktu.
- angularVelocity - seberapa cepat perubahan rotasi dalam satu set jumlah waktu.
- fadeInOut - Apakah kita menggunakan nilai alpha memudar untuk lancar menciptakan dan menghancurkan partikel.
- alphaModifier - menentukan nilai alpha dasar.
- massa - massa fisik partikel (digunakan ketika menghitung percepatan dari kekuatan).
Setiap partikel memiliki fungsi update yang disebut dengan waktu delta (dt). Saya ingin menunjukkan bagian yang berfungsi berurusan dengan memperbarui partikel posisi, yang umum dalam permainan:
/// update position with velocity x += _velocity.x * dt; y += _velocity.y * dt; /// update velocity whith acceleration _velocity.x += _acceleration.x * dt; _velocity.y += _acceleration.y * dt;
Hal ini dilakukan menggunakan Euler integrasi dan memiliki akurasi kesalahan, tapi karena kami menggunakannya hanya untuk efek visual ini tidak akan mengganggu kita. Jika Anda melakukan simulasi fisika yang penting dalam permainan Anda harus melihat ke dalam metode lain.
Contoh efek
Akhirnya kami datang ke titik di mana saya akan menjelaskan bagaimana menerapkan efek yang sebenarnya. Untuk membuat efek baru kami akan memperluas kelas efek.

Partikel tekstur
Biarkan salju
Kita akan mulai dengan efek salju. Pertama, menempatkan emitor kotak di atas layar, dan menggunakannya untuk menelurkan beberapa partikel. Collider akan digunakan untuk mendeteksi apakah sebuah partikel telah mencapai lantai, dalam hal mana kami akan menetapkan properti bergerak ke false.
Yang penting kita harus memastikan adalah bahwa partikel cukup acak sehingga mereka tidak menciptakan pola-pola yang terlihat pada layar, yang merusak ilusi. Kami melakukan ini dalam beberapa cara:
- Acak awal kecepatan - setiap partikel akan bergerak dengan cara yang sedikit berbeda.
- Skala acak - Selain ukuran yang berbeda, ini juga menambah lebih mendalam dengan efek yang membuatnya tampak lebih 3D.
- Rotasi acak - secara efektif membuat setiap partikel yang terlihat unik meskipun mereka menggunakan gambar yang sama.
Kami menginisialisasi setiap partikel salju dengan cara ini:
particle.fadeInOut = true; /// Life [3, 4> seconds particle.startingLife = 3 + Math.random(); /// Small amount of starting velocity particle.velocity = Point.polar(30, Math.random() * Math.PI * 2.0); /// Random rotation [0, 360> degrees particle.rotation = Math.PI * 2.0 * Math.random(); /// Random scale [0.5, 1> particle.scaleX = particle.scaleY = Math.random() * 0.5 + 0.5;
Untuk memberi mereka gerakan realistis jatuh dari langit kita akan menggunakan sumber directional kekuatan sebagai gravitasi. Itu akan terlalu mudah untuk berhenti di sini, jadi kami akan menambahkan kekuatan arah lain untuk mensimulasikan angin, yang akan bervariasi dalam waktu.
/// -20 is arbitrary number which worked well when testing /// (9.81m/s/s is the actual acceleration due to gravity on Earth) var gravity:DirectionalField = new DirectionalField(0, -9.81 * -20); /// Initialization is not important; values will change in time _wind = new DirectionalField(1, 0); /// set forces to the effect this.forces = new <IForceField>[gravity, _wind];
Kami akan bervariasi nilai angin yang menggunakan fungsi sinus; ini sebagian besar ditentukan melalui eksperimen. Untuk sumbu x kita meningkatkan sinus dengan kekuatan 4, membuat puncaknya lebih tajam. Setiap enam detik akan ada puncak, menghasilkan efek kuat embusan angin. Pada sumbu y angin akan cepat berosilasi antara-20 dan 20.
/// Calculate wind force _counter += time; _wind.forceVectorX = Math.pow(Math.sin(_counter) * 0.5 + 0.5, 4) * 150; _wind.forceVectorY = Math.sin(_counter * 100) * 20;
Lihatlah plot fungsi untuk mendapatkan pemahaman yang lebih baik tentang apa yang terjadi.

Sumbu x mewakili waktu; sumbu mewakili kecepatan angin. (Bukan untuk skala.)
Tambahkan beberapa kabut
Untuk menyelesaikan efek kita akan menambahkan efek kabut halus, menggunakan emitor kotak yang mencakup seluruh adegan.
Karena tekstur yang kita akan gunakan untuk partikel relatif besar, emitor akan ditetapkan untuk bertelur kecil jumlah partikel. Tingkat alpha partikel dari awal akan rendah untuk mencegah hal itu benar-benar mengaburkan adegan. Kami juga akan mengatur mereka untuk memutar perlahan-lahan, untuk mensimulasikan efek angin.
/// Cover large portion of the screen this.emitter = new Box(0, 40, 640, 400); /// We want just a few of the particles on screen at a time this.spawnPerSecond = 0.05; this.setupParticle = function(particle:Particle):void { /// Move slowly in one direction particle.velocity = Point.polar(50, Math.random() * Math.PI * 2.0); particle.fadeInOut = true; /// [3, 4> seconds of life particle.startingLife = 3 + Math.random(); particle.alphaModifier = 0.3; /// Random rotation [0, 360> degrees particle.rotation = Math.PI * 2.0 * Math.random(); /// Rotate <-0.5, 0.5] radians per second particle.angularVelocity = (1 - Math.random() * 2) * 0.5; /// Set the scale to [1, 2> particle.scaleX = particle.scaleY = Math.random() + 1; };
Untuk menambah suasana yang sedikit lebih contoh, saya telah menambahkan tekstur yang ringan yang akan di lapisan atas adegan; pencampuran yang akan ditetapkan untuk berkembang biak. Efek partikel sekarang akan jauh lebih menarik, karena warna putih mereka dasar akan berubah untuk menyesuaikan cahaya, dan adegan secara keseluruhan akan merasa lebih terintegrasi.

Meningkatkan kinerja
Cara yang umum untuk mengoptimalkan simulasi banyak partikel adalah dengan menggunakan konsep penggabungan. Penggabungan memungkinkan Anda untuk menggunakan kembali benda-benda yang telah dibuat, tetapi tidak lagi diperlukan.
Konsep ini sederhana: ketika kita selesai dengan objek tertentu, kita memasukkannya ke dalam "renang"; kemudian, ketika kita membutuhkan objek lain dari jenis yang sama, kita pertama Periksa untuk melihat apakah "cadangan" pada di kolam renang. Jika ya, kami hanya mengambil dan menerapkan nilai-nilai baru untuk itu. Kita dapat menyisipkan sejumlah benda-benda di kolam di awal simulasi untuk mempersiapkan mereka untuk nanti.
Cara lain yang kita dapat mengoptimalkan efek partikel adalah dengan precomputing mereka untuk tekstur. Dengan melakukan ini, Anda akan kehilangan banyak fleksibilitas, tapi keuntungan adalah bahwa menggambar efek akan sama seperti menggambar berkas tunggal. Anda akan menghidupkan efek dengan cara yang sama seperti yang biasa sprite lembar animasi.

Efek partikel api dalam bentuk lembaran sprite
Namun, Anda perlu hati-hati: hal ini tidak cocok untuk layar penuh efek seperti salju, karena mereka akan mengambil banyak memori.
Cara yang lebih murah untuk mensimulasikan salju akan menggunakan tekstur dengan beberapa serpihan di dalam, dan kemudian melakukan simulasi serupa yang kami lakukan, tetapi menggunakan partikel jauh lebih sedikit. Ini dapat dibuat untuk terlihat bagus, tetapi membutuhkan upaya tambahan.
Berikut adalah contoh yang (dari adegan intro Fahrenheit, alias Indigo nubuat):
Akhir pikiran
Sebelum Anda mulai menulis mesin partikel Anda sendiri, Anda harus memeriksa apakah teknologi yang Anda gunakan untuk membuat permainan Anda sudah memiliki efek partikel, atau apakah pihak ketiga Perpustakaan ada. Namun, hal ini benar-benar berguna untuk mengetahui bagaimana mereka diimplementasikan, dan ketika Anda memiliki pemahaman yang baik itu, Anda seharusnya tidak memiliki kesulitan menggunakan varian tertentu, karena mereka diimplementasikan dengan cara sama. Mesin partikel dapat bahkan datang dengan editor yang menyediakan cara WYSIWYG untuk mengedit properti mereka.
Jika efek yang Anda butuhkan dapat ditarik dari lembar sprite berdasarkan efek partikel, saya akan merekomendasikan TimelineFX. Ini dapat digunakan untuk menciptakan efek yang menakjubkan dengan cepat, dan memiliki perpustakaan besar efek Anda dapat menggunakan dan memodifikasi. Sayangnya, itu tidak alat yang paling intuitif, dan belum diperbarui dalam beberapa saat.
Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post