Selamat Pagi rekan-rekan, teman-teman, kang mas kang mas, mbak mbak sekalian...kembali lagi ogut ngeblog nih karena ide ini harus di bagikan kepada Anda Anda sekalian. Kali ini ogut akan menjelaskan tentang mendeteksi posisi dengan menggunakan proyeksi vektor. Pada artikel sebelumnya proyeksi vektor pernah dibahas beserta contohnya sehingga tidak akan dibahas ulang dan kali ini ogut akan memberikan implementasi atau contoh program game-nya. Matematika vektor yes, narkoba no...(iklan dikit)
Program yang akan ogut bagikan akan tampak seperti gambar di bawah ini. Peluru yang ditembakkan oleh pesawat Fighter hanya aktif di dalam kotak hitam saja, setelah melewati kotak hitam peluru akan mati atau tidak aktif. Mengubah status peluru menjadi tidak aktif sangat bermanfaat karena peluru yang tidak aktif tidak perlu diproses translasi dan render, sehingga dapat menghemat pemakaian memory dan mempercepat laju program. Bagaimana cara mendeteksi posisi peluru yang ada di dalam kotak hitam dan yang berada di luar kotak hitam?
Teori Skala Proyeksi Vektor
Pada gambar di atas terlihat titik P yang berada di dalam sebuah persegipanjang ABCD, untuk membuktikan bahwa posisi titik P berada di dalam persegipanjang dapat digunakan tiga vektor bantu yaitu vektor a, vektor b dan vektor p.
Jika vektor p diproyeksikan ke vektor a maka skala proyeksi akan bernilai antara 0(nol) sampai 1.
Demikian pula jika vektor p diproyeksikan ke vektor b maka skala proyeksi akan bernilai antara 0(nol) sampai 1.
Penting!
Titik P berada di dalam persegipanjang ABCD jika skala proyeksi vektor p ke vektor a dan vektor b keduanya bernilai antara 0(nol) sampai 1(0 ≤ skala proyeksi ≤ 1).
Dengan menggunakan skala proyeksi vektor seperti contoh di atas maka sebuah titik koordinat dapat terdeteksi posisinya, teori inilah yang akan menjadi pedoman untuk diterapkan pada pemrograman game.
Ok selesai teorinya sekarang saatnya programming.
Tentukan nilai awal untuk Fighter dan peluru.
Public Sub SettingNilaiAwal()
'fighter
Fighter.Ax = 420 : Fighter.Ay = 120
Fighter.Bx = 580 : Fighter.By = 120
Fighter.Cx = 580 : Fighter.Cy = 280
Fighter.Dx = 420 : Fighter.Dy = 280
Fighter.d_X = 25
Fighter.d_Y = 25
Fighter.Index_Tekstur = 1
Indeks_Tekstur_Fighter = 1
Delay_Tekstur_Fighter = 1
Plus_Indeks_Tekstur_Fighter = True
'=================================
'cos 45 = 0.7071, sin 45 = 0.7071
'buat 8 buah vektor fighter dengan
'menggunakan aturan trigonometri
'=================================
'arah utara
Vektor_Fighter(0).i = 0 : Vektor_Fighter(0).j = Fighter.d_Y
'arah timur laut
Vektor_Fighter(1).i = Fighter.d_X * 0.7071
Vektor_Fighter(1).j = Fighter.d_Y * 0.7071
'arah timur
Vektor_Fighter(2).i = Fighter.d_X : Vektor_Fighter(2).j = 0
'arah tenggara
Vektor_Fighter(3).i = Fighter.d_X * 0.7071
Vektor_Fighter(3).j = -Fighter.d_Y * 0.7071
'arah selatan
Vektor_Fighter(4).i = 0 : Vektor_Fighter(4).j = -Fighter.d_Y
'arah barat daya
Vektor_Fighter(5).i = -Fighter.d_X * 0.7071
Vektor_Fighter(5).j = -Fighter.d_Y * 0.7071
'arah barat
Vektor_Fighter(6).i = -Fighter.d_X : Vektor_Fighter(6).j = 0
'arah barat laut
Vektor_Fighter(7).i = -Fighter.d_X * 0.7071
Vektor_Fighter(7).j = Fighter.d_Y * 0.7071
Dim i As Integer
'Peluru Fighter
For i = 0 To 98
Peluru_Fighter(i).GO_Active = False
Next
Counter_Delay_Peluru = 99
'area tembak
Area_Tembak_Xmin = -500
Area_Tembak_Xmax = 500
Area_Tembak_Ymin = -300
Area_Tembak_Ymax = 300
'create vektorA
VektorA.i = Area_Tembak_Xmax - Area_Tembak_Xmin
VektorA.j = 0
'create vektorB
VektorB.i = 0
VektorB.j = Area_Tembak_Ymax - Area_Tembak_Ymin
LVektorA = Panjang_Vektor(VektorA)
LVektorB = Panjang_Vektor(VektorB)
End Sub
Tekan tombol 'F' untuk mengisi peluru (reload).
Private Sub Tekan_Keyboard()
...
...
...
'===========================
'tombol 'f' untuk rapid fire
'===========================
If (GetKeyState(Keys.F) And &H1000) Then
If Counter_Delay_Peluru >= 6 Then
Reload_Peluru()
Sound1.Play()
Counter_Delay_Peluru = 0
Else
Counter_Delay_Peluru = Counter_Delay_Peluru + 1
End If
End If
End Sub
Private Sub Reload_Peluru()
Dim i, j As Integer
For j = 1 To 3
For i = 0 To 98
If Peluru_Fighter(i).GO_Active = False Then
Peluru_Fighter(i).GO_Active = True
'isi koordinat peluru
Peluru_Fighter(i).Ax = Fighter.Ax - 20
Peluru_Fighter(i).Ay = ((Fighter.Dy - Fighter.Ay) / 2) + Fighter.Ay - 10
Peluru_Fighter(i).Bx = Peluru_Fighter(i).Ax + 20
Peluru_Fighter(i).By = Peluru_Fighter(i).Ay
Peluru_Fighter(i).Cx = Peluru_Fighter(i).Bx
Peluru_Fighter(i).Cy = Peluru_Fighter(i).By + 20
Peluru_Fighter(i).Dx = Peluru_Fighter(i).Ax
Peluru_Fighter(i).Dy = Peluru_Fighter(i).Cy
'================================
'setting vektor peluru
'cos 15 = 0.9659, sin 15 = 0.2588
'================================
If j = 1 Then
Peluru_Fighter(i).Vektor.i = -26.5629
Peluru_Fighter(i).Vektor.j = 7.1175
End If
If j = 2 Then
Peluru_Fighter(i).Vektor.i = -27.5
Peluru_Fighter(i).Vektor.j = 0.0#
End If
If j = 3 Then
Peluru_Fighter(i).Vektor.i = -26.5629
Peluru_Fighter(i).Vektor.j = -7.1175
End If
i = 99
End If
Next
Next
End Sub
Render / display peluru dan jika peluru berada di luar area ubah statusnya menjadi non aktif.
Private Sub Render_Peluru()
Dim i As Integer
Dim SkalaPro1, SkalaPro2 As Single
For i = 0 To 98
If Peluru_Fighter(i).GO_Active Then
'=====================================================
'periksa apakah peluru di dalam area tembak atau tidak
'=====================================================
'hitung titik pusat peluru
Titik_Pusat_Poligon(Peluru_Fighter(i), CenterX_Peluru, CenterY_Peluru)
'create vektor peluru
VektorPeluru = Create_Vektor(Area_Tembak_Xmin, Area_Tembak_Ymin, CenterX_Peluru, CenterY_Peluru)
'hitung skala proyeksi
SkalaPro1 = Dot_Product(VektorPeluru, VektorA) / (LVektorA * LVektorA)
SkalaPro2 = Dot_Product(VektorPeluru, VektorB) / (LVektorB * LVektorB)
If (SkalaPro1 >= 0 And SkalaPro1 <= 1 And SkalaPro2 >= 0 And SkalaPro2 <= 1) Then
'============================
'peluru berada di area tembak
'============================
GL.Enable(EnableCap.Blend)
GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.Zero)
'Mask
GL.BindTexture(TextureTarget.Texture2D, Peluru_FBMP_Mask)
GL.Begin(BeginMode.Quads)
GL.TexCoord2(0.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Ax, Peluru_Fighter(i).Ay)
GL.TexCoord2(1.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Bx, Peluru_Fighter(i).By)
GL.TexCoord2(1.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Cx, Peluru_Fighter(i).Cy)
GL.TexCoord2(0.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Dx, Peluru_Fighter(i).Dy)
GL.End()
GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One)
'BMP
GL.BindTexture(TextureTarget.Texture2D, Peluru_FBMP)
GL.Begin(BeginMode.Quads)
GL.TexCoord2(0.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Ax, Peluru_Fighter(i).Ay)
GL.TexCoord2(1.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Bx, Peluru_Fighter(i).By)
GL.TexCoord2(1.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Cx, Peluru_Fighter(i).Cy)
GL.TexCoord2(0.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Dx, Peluru_Fighter(i).Dy)
GL.End()
GL.Disable(EnableCap.Blend)
If CheckBox2.Checked = True Then
'warna merah untuk garis
GL.BindTexture(TextureTarget.Texture2D, Red)
GL.Begin(BeginMode.LineLoop)
GL.Vertex2(Peluru_Fighter(i).Ax, Peluru_Fighter(i).Ay)
GL.Vertex2(Peluru_Fighter(i).Bx, Peluru_Fighter(i).By)
GL.Vertex2(Peluru_Fighter(i).Cx, Peluru_Fighter(i).Cy)
GL.Vertex2(Peluru_Fighter(i).Dx, Peluru_Fighter(i).Dy)
GL.End()
End If
'=================================
'translasi peluru dengan vektornya
'=================================
Peluru_Fighter(i).Ax = Peluru_Fighter(i).Ax + Peluru_Fighter(i).Vektor.i
Peluru_Fighter(i).Bx = Peluru_Fighter(i).Bx + Peluru_Fighter(i).Vektor.i
Peluru_Fighter(i).Cx = Peluru_Fighter(i).Cx + Peluru_Fighter(i).Vektor.i
Peluru_Fighter(i).Dx = Peluru_Fighter(i).Dx + Peluru_Fighter(i).Vektor.i
Peluru_Fighter(i).Ay = Peluru_Fighter(i).Ay + Peluru_Fighter(i).Vektor.j
Peluru_Fighter(i).By = Peluru_Fighter(i).By + Peluru_Fighter(i).Vektor.j
Peluru_Fighter(i).Cy = Peluru_Fighter(i).Cy + Peluru_Fighter(i).Vektor.j
Peluru_Fighter(i).Dy = Peluru_Fighter(i).Dy + Peluru_Fighter(i).Vektor.j
Else
'non aktifkan peluru yang tidak di dalam area tembak
Peluru_Fighter(i).GO_Active = False
End If
End If
Next
End Sub
Tuntas sudah penjelasan tentang mendeteksi posisi dengan menggunakan vektor proyeksi, bagaimana mantap ya vektor bisa dipakai buat macam-macam, kadang bisa buat menghitung jarak, sudut antara dua objek dan lain-lain. Nanti pada artikel berikutnya ogut akan membahas tentang deteksi tabrakan dengan vektor, sabar ya, tunggu saja tanggal mainnya.
Salam matematika vektor rekan-rekan
Heriady
heriady.yoh@gmail.com
Artikel terkait
Animasi dengan Translasi dan Rotasi
|
|
Animasi Game 2D dengan Translasi
|
|
Teknik masking pada OpenTK 2D
|
|
Vektor R2
|
Tidak ada komentar:
Posting Komentar