Breakout Collision: Mendeteksi sisi tabrakan

10

Saya sedang menulis klon breakout (game pertama saya) dan saya benar-benar terjebak bagaimana saya mengetahui sisi mana dari batu bata itu dipukul.

Saya memiliki metode pendeteksian benturan yang terlihat seperti ini:

DetectCollision(Object a, Object b)

   x = distance(a.x, b.x);
   y = distance(a.y, b.y);

   if (x is smaller than the combined width &  y is smaller is than combined height {
       return true;
   }
return false;  

Ini berfungsi dengan sangat baik, tetapi saya perlu tahu sisi tabrakan, dan lokasi relatif terhadap pusat untuk merespons dengan benar.

Saya telah menghabiskan beberapa hari terakhir mengintip tapi tersesat.

pengguna590903
sumber

Jawaban:

13

Ini semua dapat diperoleh dari posisi bola relatif terhadap posisi batu bata yang bertabrakan dengannya.

Setelah Anda mendeteksi tabrakan:

if(ballPosition.y <= brickPosition.y - (brickHeight/2))
  //Hit was from below the brick

if(ballPosition.y >= brickPosition.y + (brickHeight/2))
  //Hit was from above the brick

if(ballPostion.x < brickPosition.x)
  //Hit was on left

if(ballPostion.x > brickPosition.x)
  //Hit was on right

Dua cek pertama untuk melihat apakah bola di atas atau di bawah batu bata. Jika tidak ada selain itu harus di sebelah bata, jadi periksa di sisi mana itu. Ini perlu dipasangkan agar sesuai dengan tempat Anda mengambil lokasi, yaitu brickPosition adalah pusat dari brick atau brickPosition adalah sudut kiri atas.

MichaelHouse
sumber
1
Tetapi bagaimana Anda menggunakan ini untuk memposisikan ulang pemain, karena pemain itu bergerak di dalam bata, banyak dari kondisi itu akan terpenuhi, dan jika Anda mereset x yang diinginkan ke tepi dinding, misalnya jika menekan tombol dari sebuah batu bata mengatur x yang diinginkan tepat di sebelah dinding, maka itu tidak akan benar-benar berfungsi karena ketika Anda memeriksa posisi teoritis karakter untuk melihat ke arah mana itu bertabrakan, beberapa kondisi ini akan terpenuhi, jadi bagaimana Anda akan gunakan ini untuk mengatur ulang pemain, apakah Anda perlu menambahkan yang lain di akhir setiap if)?
bluejayke
Sejauh yang saya tahu "pemain" dalam game jenis breakout adalah dayungnya. Dayung tidak bergerak di dalam batu bata, Anda juga tidak mengubah posisi dayung berdasarkan interaksi bola dengan batu bata. Jika itu yang Anda lakukan, Anda tidak perlu logika tambahan, hanya saja jangan memproses reposisi sampai Anda selesai melakukan semua tabrakan. Atau kembalikan begitu salah satu cek benar.
MichaelHouse
8

Anda bisa menggunakan Vector Math untuk menemukan sudut di antara mereka!

Inilah jawaban singkatnya:

ballToBrick = ballPosition - brickPosition;
ballToBrick.Normalize();
brickFacing = Vector2(0,1).Normalize();


float angle = acos( Dot(ballToBrick, brickFacing) );

Menghadapi Brick adalah vektor yang rumit, itu adalah "titik awal" dari perhitungan sudut. dan jika Anda ingin vektor mengarah ke atas, buatlah (0, 1), titik kiri (-1, 0), kanan (1, 0), arahkan ke bawah (0, -1). Dengan asumsi Anda berada di sumbu OpenGL, di mana atas dan kanan positif.

Jika Anda tidak tahu, inilah definisi dari setiap fungsi yang digunakan:

Vector2.Normalize()
{
    float length = squareroot(x * x + y * y);
    x = x / length;
    y = y / length;
    return this;
}

Dot(Vector2 a, Vector2 b)
{
    return a.x * b.x + a.y * b.y;
}

( https://en.wikipedia.org/wiki/Dot_product )

Referensi: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-2/

Gustavo Maciel
sumber