Advertisement
  1. Code
  2. Games
Code

Deteksi Tabrakan Tingkat-Pixel Berdasarkan Warna Piksel

by
Difficulty:BeginnerLength:MediumLanguages:
This post is part of a series called Collision Detection and Reaction.
Predicting Collision Points With Math in AS3
This post is part of a series called Shoot-'Em-Up.
Build a Stage3D Shoot-'Em-Up: Score, Health, Lives, HUD and Transitions
Build a Stage3D Shoot-'Em-Up: Full-Screen Boss Battles and Polish

Indonesian (Bahasa Indonesia) translation by ⚡ Rova Rindrata (you can also view the original English article)

Dalam tutorial ini, saya akan mengikuti pendekatan yang disarankan oleh Richard Davey (Terima kasih, Richard!), dan digunakan olehnya dan orang lain, dalam mendeteksi tabrakan antara bitmap dengan modifikasi yang halus. Saya juga akan membandingkan kinerja antara berbagai pendekatan deteksi tabrakan bitmap menggunakan PerformanceTest dari Grant Skinner.

Catatan: Selain menjadi bagian dari Sesi Shoot-'Em-Up, artikel ini juga merupakan bagian dari Deteksi dan Reaksi Tabrakan.


Langkah 1: Ikhtisar

Saya menjelaskan pendekatan alternatif ini secara singkat di sini.

  1. Periksa apakah ada tumpang tindih antara dua bitmap.
  2. Jika ada, lanjutkan ke #3. Jika tidak, keluar.
  3. Periksa apakah area tumpang tindih memiliki piksel buram yang tumpang tindih.
  4. Jika demikian, bitmap akan tumpang tindih. Jika tidak, keluar.

Langkah 2: Kotak Pembatas

Pertama, kita periksa apakah kotak pembatas bitmap tumpang tindih menggunakan Rectangle. Skripnya seperti di bawah ini. Pertama, variabelnya.

Di sini kita memeriksa area yang tumpang tindih di antara kotak-kotak itu. Lihat DetectVisible.as dalam unduhan sumber untuk skrip lengkapnya

Ini demonya. Seret pesawat luar angkasa yang lebih kecil di sekitar.

(Jangan khawatir tentang kotak merah yang "tertinggal" ketika pesawat diseret keluar dari kotak pembatas yang lain.)


Langkah 3: Menggambar ke Area Persimpangan

Jadi jika ada area berpotongan, kita melanjutkan untuk memeriksa apakah ada piksel yang tumpang tindih di area tersebut. Namun, pertama mari kita coba menggambar bitmap ke area persimpangan ini. Skrip lengkap ada di DetectVisible2.as

Perhatikan bahwa karena kita menggambar area dengan menggunakan matriks, setiap skala, skewing dan transformasi lainnya pada kedua bitmap akan diperhitungkan. Ini demonya; lihat kotak di sudut kiri bawah.


Langkah 4: Memeriksa Warna di Area Persimpangan

Jadi bagaimana cara memeriksa piksel yang tepat? Pertama-tama, kita memberikan warna kotak persimpangan ini warna hitam (Red = 0, Green = 0, Blue = 0). Kemudian, bayangan pesawat ruang angkasa yang lebih kecil akan dicat ke dalam kotak gelap ini sebagai hijau, dengan mode campuran ADD. Demikian pula, bayangan pesawat ruang angkasa alien yang stasioner yang lebih besar akan dicat merah.

Jadi sekarang, akan ada area merah dan hijau untuk pesawat ruang angkasa, dan hitam jika tidak ada area yang tumpang tindih. Namun, jika ada piksel dari dua bitmap ini yang tumpang tindih, ini akan digambar dengan warna kuning (Red = 255, Green = 255, Blue = 0). Kita menggunakan metode Bitmapdata.getColorBoundsRect untuk memeriksa keberadaan area ini.

Ini cuplikan di Main.as

Perhatikan bahwa kita menekan komponen Red dan Blue pada baris 113 untuk memaksimalkan Green untuk pesawat ruang angkasa kecil. Pada baris 112 kita melakukan hal yang sama dengan pesawat luar angkasa alien dengan komponen Blue dan Green.


Membandingkan Pendekatan

Jadi setelah menerima komentar tentang masalah kinerja mengenai deteksi tabrakan, saya memutuskan untuk melakukan beberapa pengujian cepat dan kotor pada pendekatan ini. Saya membuat 20 pesawat ruang angkasa musuh dan satu pesawat ruang angkasa pemain dan memeriksa tabrakan antara kapal satu pemain tersebut dengan yang 20 lainnya. Sprite ini dikemas ke dalam lingkungan yang sama untuk memaksa deteksi tabrakan untuk semua pendekatan agar memiliki perjalanan yang lengkap.

Pendekatan pertama adalah yang paling sederhana. BitmapData ditangkap saat inisiasi dan untuk setiap frame, deteksi tabrakan diperiksa menggunakan BitmapData.hitTest(). Untuk pendekatan kedua, BitmapData diperbarui setiap frame dan deteksi tabrakan dilakukan berdasarkan pada BitmapData yang diambil. Yang ketiga mengacu pada pendekatan yang disarankan oleh tutorial ini.

Jadi hasil untuk salah satu pengujian yang saya lakukan adalah sebagai berikut.

PerformanceTest memberikan hasil yang berbeda setiap kali saya menjalankan pengujian. Jadi saya menjalankannya beberapa kali dan memperoleh waktu rata-rata. Kesimpulan: metode tercepat adalah yang pertama, diikuti oleh pendekatan ketiga dan kemudian yang kedua.

Jadi menyimpan BitmapData untuk bitmap ketika mereka pertama kali diperkenalkan ke panggung dan memeriksa hitTest setiap frame setelahnya adalah benar-benar efisien, asalkan sprite ini tidak melakukan transformasi selain translation (seperti rotasi, skewing dan penskalaan) sepanjang waktu. Jika tidak, Anda akan dipaksa untuk mengadopsi pendekatan kedua atau ketiga, dan yang ketiga lebih efisien seperti yang ditunjukkan oleh gambar di atas.

Anda dapat melihat Collisions.as dan Results.as untuk skrip lengkapnya.


Mencari Metode yang Mahal

Saya memulai setelahnya untuk mencari baris kode tertentu yang menghabiskan lebih banyak waktu komputasi. Pendekatan kedua dan ketiga membutuhkan lebih banyak waktu, jadi saya memperoleh beberapa fungsi dari mereka, masing-masing rusak pada titik yang berbeda. Lihat salah satu hasil di bawah ini.

Yang pertama, kedua, dan ketiga mengacu pada pendekatan kedua pada breakpoint yang berbeda, dan yang keempat dan kelima mengacu pada pendekatan ketiga. Melihat hasil ketiga dan kelima kalinya, BitmapData.draw tampaknya membutuhkan banyak waktu komputasi. Dan waktu yang diambil untuk menggambar dengan pendekatan kedua tampaknya lebih mahal dalam waktu komputasi, yang membuat saya berpikir bahwa ukuran untuk BitmapData.draw agar beroperasi memanglah penting. Anda dapat memeriksa Collisions2.as dan Results2.as untuk skrip lengkapnya.

Satu hal yang saya rasa sedikit mengganggu adalah ketidakkonsistenan pengujian-pengujian ini - saya selalu tidak mendapatkan hasil waktu yang sama, meskipun mereka hampir mengikuti peringkat yang sama setiap saat. Jadi, cukup baik untuk melakukan perbandingan sederhana antar fungsi-fungsi.

Kesimpulan

Nah, terima kasih atas waktu Anda membaca tip kecil ini. Semoga ini bermanfaat. Tinggalkan komentar jika Anda tidak setuju dengan apa pun dalam tutorial ini. Saya ingin menanggapi umpan baliknya!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.