Deteksi Tumbukan

Deteksi Tumbukan atau Collision Detection adalah teknik untuk mendeteksi tumbukan antara dua buah objek. Dalam ActionScript, cara termudah untuk mendeteksi terjadinya tumbukan adalah dengan menggunakan MovieClip.hitTest(). Namun, cara ini memiliki kekurangan dalam hal akurasi, apalagi jika Anda menggunakannya dengan onEnterFrame.

Kali ini saya akan coba menjelaskan cara untuk membuat collision detection yang efisien dengan menggunakan rumus-rumus Matematika antara lain Phytagoras dan trigonometri.

hitTest()

hitTest() adalah sebuah method yang dimiliki oleh MovieClip yang dapat digunakan untuk mendeteksi apakah sebuah MovieClip menyentuh ( hit ) MovieClip yang lain atau sebuah koordinat (x,y).

Perlu diketahui, setiap MovieClip memiliki batas yang tidak tampak berupa segi empat. Batas ini disebut bounding box . Jadi hitTest() sesungguhnya mendeteksi pertemuan antar bounding box , bukan konten atau isi MovieClip. Contohnya seperti gambar berikut ini, kedua bola “bertumbukan” walaupun secara visual tidak:

movieclip bounding box

Secara umum, hitTest() dapat digunakan untuk tiga macam collision detection, yaitu:

  1. MovieClip dengan MovieClip: clipA.hitTest(clipB)
  2. MovieClip dengan sebuah titik (Point) : clipA.hitTest(x,y)
  3. MovieClip dengan bagian MovieClip lain yang visible : clipA.hitTest(ClipB._x , clipB._y, true)

Cara no.3 di atas cukup akurat, tapi hanya mendeteksi apakah registration point clipB berada di dalam bounding box clipA. Cara ini tidak efisien dan sangat membebani CPU jika banyak MovieClip yang terlibat.

Tapi bukan berarti hitTest() nggak berguna sama sekali lho. Method ini masih cocok untuk collision detection sederhana dan melibatkan objeck dengan bentuk geometri sederhana. Atau kalau Anda nggak keberatan mengorbankan CPU untuk mendapatkan skrip yang lebih ringkas, silakan gunakan hitTest(). Kalo nggak tau caranya, silakan baca Manual Flash. :-D

Deteksi Tumbukan dengan Menghitung Jarak

Ok, sekarang saya jelaskan bagaimana collision detection dengan menghitung jarak antara dua objek berbentuk lingkaran (bola).

Pertama, kita perlu tahu diameter atau jari-jari masing-masing lingkaran. Kemudian kita ukur jaraknya ( distance ). Jika jaraknya kurang dari jumlah jari-jari kedua lingkaran tersebut, maka bisa dikatakan kedua objek bertumbukan. Lihat gambar berikut:

Cara ngukur jarak

Dari gambar di atas, kita bisa menghitung jarak antara kedua bola dengan rumus Phytagoras:

dx = ball2_mc._x – ball1_mc._x
dy = ball2_mc._y – ball1_mc._y;
d = Math.sqrt(dx*dx + dy*dy)

Collision terjadi jika d kurang dari r1 + r2. Perhatikan bahwa bounding box tidak berperan disini.

Sekarang kita coba dengan ActionScript. Buat dua buah MovieClip, beri nama masing-masing ball1_mc & ball2_mc. Tuliskan skrip berikut di frame 1:

Actionscript:
  1. var intID:Number = setInterval(detectCollision,30);
  2. ball1_mc.startDrag(true);
  3. var r1:Number = ball1_mc._width/2;
  4. var r2:Number = ball2_mc._width/2;
  5. function detectCollision(){
  6. var dx:Number = ball2_mc._x-ball1_mc._x
  7. var dy:Number = ball2_mc._y-ball1_mc._y;
  8. var d:Number = Math.sqrt(dx*dx+dy*dy);
  9. if(d < class="br0">){
  10. trace("HIT");
  11. }
  12. };

Jika Anda ingin tahu beda antara teknik di atas dengan teknik yang menggunakan hitTest() , ganti ubah function detectCollision dengan :

Actionscript:
  1. function detectCollision() {
  2. if (ball1_mc.hitTest(ball2_mc)) {
  3. trace("HIT");
  4. }
  5. }

Di bawah ini contoh swf yang saya buat dengan hitTest():

Coba gerakkan ball1_mc (bola biru) mendekati ball2_mc dari arah diagonal. Anda akan lihat bahwa dengan menggunakan hitTest(), biarpun secara visual kedua bola belum bersentuhan, tumbukan telah terdeteksi karena bounding box kedua movieclip sudah bersentuhan.

Bandingkan dengan yang menggunakan perhitungan jarak berikut ini:

Tumbukan Garis dengan Garis

Gimana kalo kita ingin mendeteksi tumbukan sebuah objek dengan objek lain berbentuk garis? Misalnya seperti gambar di bawah ini :

collision with a line

Caranya agak mbulet , tapi jangan kuatir, nggak perlu gelar S3 untuk memahaminya :-)

Ok, kalo kita lihat gambar di atas, sepertinya bakal banyak rumus yang terlibat. Memang betul, khususnya rumus transformasi koordinat.

Kalau garisnya horisontal atau vertikal kita hanya perlu menghitung jarak antara garis dengan pusat koordinat bola. Kalau jarak ini sama dengan atau kurang dari jari-jari bola, maka terjadi tumbukan.

Gampang sekali kan? Tapi gimana kalo garisnya miring?

Salah satu caranya adalah membuat proyeksi menghitung posisi relatif bola dengan sebuah titik yang … dst dst dst . Cara ini susah, saya juga nggak ngerti.

Cara lain adalah memutar sistem koordinat atau Stage sedemikian rupa sehingga garis menjadi sumbu X ( y = 0 ) dan selanjutnya untuk mendeteksi tumbukan, caranya sama dengan mendeteksi tumbukan antara bola dengan sumbu X. Lihat gambar di bawah ini:

tumbukan dengan garis miring - A
tumbukan dengan garis miring - B

Gambar A adalah sistem sebenarnya. Gambar B adalah proyeksinya ( sumbu X & Y diputar ) dan ini yang kita pakai untuk mendeteksi terjadinya tumbukan.

Catatan – Siapa yang diputar? Sistem koordinat atau stage? Tergantung dari mana Anda melihatnya. Kalau acuan kita adalah sistem koordinat ( sumbu X & Y stasioner ), yang diputar adalah Stage. Sebaliknya, kalau acuan kita adalah Stage, maka yang diputar adalah sistem koordinatnya (sumbu X & Y ). Nggak masalah, hanya beda sedikit ( detilnya bisa dibaca dalam sebuah artikel di Wikipedia dengan judul Coordinate Rotation ) . Di sini saya menjadikan Stage sebagai acuannya, jadi yang diputar adalah Sumbu X & Y.

Ok, pertama Anda harus tahu rumus untuk menghitung titik koordinat baru (rx,ry) sebuah objek yang terhadap sumbu X & Y yang diputar dengan sudut sebesar T derajat. Rumusnya adalah:

rx = x*cos(T) + y*sin(T)
ry = y*cos(T) – x*sin(T)

Karena garis miring menjadi sumbu X baru, maka rx nggak kita gunakan.

Sekarang buat sebuah file .fla baru dengan sebuah MovieClip berbentuk garis bernama line_mc, sebuah bola bernama ball_mc , dan dynamic textfield bernama hitStatus_txt . Ingat, registration point bola harus berada di tengah. Kalo Anda agak males, silaken donlod file collision-with-line-start.zip (Flash 8/9). Hasil akhirnya bisa didonlod di sini .

Seperti biasa, tulis skrip di frame 1 layer “script”. Mulai dengan bagian inisialiasi :

Actionscript:
  1. line_mc._rotation = 45;
  2. //konversi sudut ke radian
  3. var sudut:Number = line_mc._rotation * Math.PI/180;
  4. var cosSudut:Number = Math.cos(sudut);
  5. var sinSudut:Number = Math.sin(sudut);
  6. //jari-jari bola
  7. var ball_r:Number = ball_mc._height/2;
  8. var intID:Number = setInterval(detectCollision, 30);
  9. ball_mc.startDrag(true);

Nggak ada yang spesial dalam skrip di atas. Yang perlu diingat adalah operasi trigonometri dalam class Math dilakukan dengan terhadap sudut dengan satuan Radian, jadi sudut antara line_mc dengan sumbu X harus dikonversi ke radian dulu.

Kita lanjutkan dengan detectCollision().

Actionscript:
  1. function detectCollision(){
  2. //jarak bola terhadap registration point line_mc
  3. var dx:Number = ball_mc._x &#8211; line_mc._x
  4. var dy:Number = ball_mc._y &#8211; line_mc._y;
  5. //koordinat bola hasil rotasi sistem koordinat
  6. var xr:Number = dx * cosSudut + dy * sinSudut;
  7. var yr:Number = Math.abs(dy * cosSudut &#8211; dx * sinSudut);
  8. if(yr < ball_r ){
  9. hitStatus_txt.text = &#8220;Hit!”;
  10. }else{
  11. hitStatus_txt.text = &#8220;No Hit”;
  12. }
  13. }

baris 3 – 4 – Kita anggap koordinat dari line_mc adalah titik (0,0), jadi posisi bola dihitung terhadap titik ini.

baris 7 – 8 – ini bagian utama skrip kita. xr dan yr adalah koordinat baru ball_mc setelah sumbu X dan Y diputar sebesar 45 derajat. Karena kita saya ingin deteksi dilakukan terhadap gerakan ball_mc dari kedua sisi line_mc, maka kita saya gunakan Math.abs() agar nilai yr selalu positif sehingga dapat dibandingkan dengan jari-jari ball_mc.

baris 10 – 13 – karena sekarang line_mc menjadi sumbu X, maka deteksi tumbukan cukup dilakukan dengan membandingkan yr dengan jari-jari ball_mc. Jika lebih kecil, terjadi tumbukan.

Ini contoh .swf yang saya buat dengan metode di atas :

Nah, gitu caranya deteksi tumbukan. Nggak susah-susah amat, kan? Di artikel/tutorial mendatang, saya akan jelaskan bagaimana mengkombinasikan deteksi tumbukan dengan fisika ( gravitasi) misalnya untuk membuat simulasi pantulan bola, dsb.

Demikian.
Semoga bermanfaat. Amin.

Comments

Popular posts from this blog

Makalah pembiayaan pendidikan

Fungsi Gelombang dan Probabilitas

contoh soal persamaan gelombang