Jumat, 08 Januari 2016

Deteksi Tabrakan Game OpenGL (Segitiga dan Titik)



Selamat Pagi rekan-rekan sekalian, setelah sebelumnya ogut membahas tentang teori tabrakan objek segitiga dan titik dengan memanfaatkan luas segitiga, maka kali ini ogut akan mempersembahkan program contoh untuk teori tersebut.


Pada gambar di bawah rekan-rekan dapat melihat dua buah segitiga bonus dan peluru yang ditembakkan dari pesawat. Program akan mendeteksi jika peluru menabrak segitiga bonus maka bonus akan berubah warna menjadi merah.


Untuk mempermudah menerangkan algoritma program ogut membuat memberi nama untuk masing-masing titik korrdinat dan vektor yang akan digunakan untuk perhitungan luas segitiga. (Jika kurang jelas rekan-rekan bisa klik disini untuk membaca artikel tentang teorinya)


Titik segitiga ogut kasih dengan nama A, B, C dan titik peluru diberi nama P.


Vektor untuk menghitung luas segitiga biru ogut beri nama vektor AB dan vektor AP.


Vektor untuk menghitung luas segitiga hijau ogut beri nama vektor BC dan vektor BP.


Dan terakhir untuk menghitung luas segitiga kuning, ogut beri nama vektor CA dn vektor CP.

Gunakan proyeksi vektor untuk membantu menghitung tinggi segitiga, sehingga luas segitiga bisa dicari atau klik link ini untuk mengetahui cara mencari luas segitiga dengan vektor.


Berikut ini ogut sertakan potongan program  deteksi tabrakan objek segitiga dan titik.

Public Structure SegitigaObjek_Properties
        Public GO_Active As Boolean

        Public Ax As Single
        Public Ay As Single
        Public Bx As Single
        Public By As Single
        Public Cx As Single
        Public Cy As Single

        Public VektorAB As Vektor_Properties
        Public VektorBC As Vektor_Properties
        Public VektorCA As Vektor_Properties

        Public LuasSegitigaMerah As Single

        Public Hit_Status As Boolean
    End Structure

Public Sub SettingNilaiAwal()
        ...
        ...
        ...

        '======================
        'nilai awal untuk bonus
        '======================
        'Bonus(0)
        Bonus(0).Ax = 25 : Bonus(0).Ay = 225
        Bonus(0).Bx = 225 : Bonus(0).By = 225
        Bonus(0).Cx = 225 : Bonus(0).Cy = 475
        Bonus(0).Hit_Status = False

        Bonus(0).VektorAB = Create_Vektor(Bonus(0).Ax, Bonus(0).Ay, Bonus(0).Bx, Bonus(0).By)
        Bonus(0).VektorBC = Create_Vektor(Bonus(0).Bx, Bonus(0).By, Bonus(0).Cx, Bonus(0).Cy)
        Bonus(0).VektorCA = Create_Vektor(Bonus(0).Cx, Bonus(0).Cy, Bonus(0).Ax, Bonus(0).Ay)

        'Hitung lias Segitiga Merah
        Dim Vektor_Proyeksi As Vektor_Properties
        Dim Vektor_BA As Vektor_Properties
        Dim Vektor_Tinggi As Vektor_Properties
        Dim Tinggi_SegitigaMerah As Single

        Vektor_BA = Create_Vektor(Bonus(0).Bx, Bonus(0).By, Bonus(0).Ax, Bonus(0).Ay)

        Vektor_Proyeksi = Proyeksi_Vektor(Vektor_BA, Bonus(0).VektorBC)
        Vektor_Tinggi.i = Vektor_BA.i - Vektor_Proyeksi.i
        Vektor_Tinggi.j = Vektor_BA.j - Vektor_Proyeksi.j

        'tinggi segitiga merah
        Tinggi_SegitigaMerah = Panjang_Vektor(Vektor_Tinggi)
        'Luas segitiga merah
        Bonus(0).LuasSegitigaMerah = 0.5 * Tinggi_SegitigaMerah * Panjang_Vektor(Bonus(0).VektorBC)

        'Bonus(1)
        Bonus(1).Ax = -375 : Bonus(1).Ay = -175
        Bonus(1).Bx = -225 : Bonus(1).By = -175
        Bonus(1).Cx = -225 : Bonus(1).Cy = -25
        Bonus(1).Hit_Status = False

        'Rotasi Bonus 1
        Rotasi(Bonus(1).Ax, Bonus(1).Ay, -300, -100, -90)
        Rotasi(Bonus(1).Bx, Bonus(1).By, -300, -100, -90)
        Rotasi(Bonus(1).Cx, Bonus(1).Cy, -300, -100, -90)

        Bonus(1).VektorAB = Create_Vektor(Bonus(1).Ax, Bonus(1).Ay, Bonus(1).Bx, Bonus(1).By)
        Bonus(1).VektorBC = Create_Vektor(Bonus(1).Bx, Bonus(1).By, Bonus(1).Cx, Bonus(1).Cy)
        Bonus(1).VektorCA = Create_Vektor(Bonus(1).Cx, Bonus(1).Cy, Bonus(1).Ax, Bonus(1).Ay)

        'Hitung luas segitiga merah
        Vektor_BA = Create_Vektor(Bonus(1).Bx, Bonus(1).By, Bonus(1).Ax, Bonus(1).Ay)

        Vektor_Proyeksi = Proyeksi_Vektor(Vektor_BA, Bonus(1).VektorBC)
        Vektor_Tinggi.i = Vektor_BA.i - Vektor_Proyeksi.i
        Vektor_Tinggi.j = Vektor_BA.j - Vektor_Proyeksi.j

        'tinggi segitiga merah
        Tinggi_SegitigaMerah = Panjang_Vektor(Vektor_Tinggi)
        'Luas segitiga merah
        Bonus(1).LuasSegitigaMerah = 0.5 * Tinggi_SegitigaMerah * Panjang_Vektor(Bonus(1).VektorBC)


    End Sub

Private Sub Render_Peluru()
        Dim i As Integer
        Dim SkalaPro1, SkalaPro2 As Single
        Dim Vektor_AP As Vektor_Properties
        Dim Vektor_BP As Vektor_Properties
        Dim Vektor_CP As Vektor_Properties
        Dim Vektor_Proyeksi As Vektor_Properties
        Dim Vektor_Tinggi As Vektor_Properties
        Dim LuasSegitiga_Biru As Single
        Dim LuasSegitiga_Hijau As Single
        Dim LuasSegitiga_Kuning As Single
        Dim ToleransiLuas_Atas As Single
        Dim ToleransiLuas_Bawah 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 P)
                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
                    'proses deteksi tabrakan dengan bonus/segitiga dimulai
                    '=====================================================
                    For j = 0 To 1

                        'hitung luas segitiga biru
                        Vektor_AP = Create_Vektor(Bonus(j).Ax, Bonus(j).Ay, CenterX_Peluru, CenterY_Peluru)

                        Vektor_Proyeksi = Proyeksi_Vektor(Vektor_AP, Bonus(j).VektorAB)
                        Vektor_Tinggi.i = Vektor_AP.i - Vektor_Proyeksi.i
                        Vektor_Tinggi.j = Vektor_AP.j - Vektor_Proyeksi.j

                        LuasSegitiga_Biru = 0.5 * Panjang_Vektor(Bonus(j).VektorAB) * Panjang_Vektor(Vektor_Tinggi)

                        'hitung luas segitiga hijau
                        Vektor_BP = Create_Vektor(Bonus(j).Bx, Bonus(j).By, CenterX_Peluru, CenterY_Peluru)

                        Vektor_Proyeksi = Proyeksi_Vektor(Vektor_BP, Bonus(j).VektorBC)
                        Vektor_Tinggi.i = Vektor_BP.i - Vektor_Proyeksi.i
                        Vektor_Tinggi.j = Vektor_BP.j - Vektor_Proyeksi.j

                        LuasSegitiga_Hijau = 0.5 * Panjang_Vektor(Bonus(j).VektorBC) * Panjang_Vektor(Vektor_Tinggi)


                        'hitung luas segitiga kuning
                        Vektor_CP = Create_Vektor(Bonus(j).Cx, Bonus(j).Cy, CenterX_Peluru, CenterY_Peluru)

                        Vektor_Proyeksi = Proyeksi_Vektor(Vektor_CP, Bonus(j).VektorCA)
                        Vektor_Tinggi.i = Vektor_CP.i - Vektor_Proyeksi.i
                        Vektor_Tinggi.j = Vektor_CP.j - Vektor_Proyeksi.j

                        LuasSegitiga_Kuning = 0.5 * Panjang_Vektor(Bonus(j).VektorCA) * Panjang_Vektor(Vektor_Tinggi)


                        ToleransiLuas_Atas = LuasSegitiga_Biru + LuasSegitiga_Hijau + LuasSegitiga_Kuning + Toleransi
                        ToleransiLuas_Bawah = LuasSegitiga_Biru + LuasSegitiga_Hijau + LuasSegitiga_Kuning - Toleransi

                        If Bonus(j).LuasSegitigaMerah <= ToleransiLuas_Atas And Bonus(j).LuasSegitigaMerah >= ToleransiLuas_Bawah Then
                            'tabrakan terjadi antara segitiga dan peluru
                            Peluru_Fighter(i).GO_Active = False
                            Bonus(j).Hit_Status = True
                            Sound2.Play()
                        End If

                    Next

                Else
                    'non aktifkan peluru yang tidak di dalam area tembak
                    Peluru_Fighter(i).GO_Active = False
                End If
            End If

            If Peluru_Fighter(i).GO_Active Then
                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

            End If
        Next
    End Sub

Ok rekan-rekan ogut rasa cukup penjelasannya, sampai disini dulu ntar kita ngobrol lagi masalah game dan seputarnya....selamat mencoba

Salam game matematika


Heriady
heriady.yoh@gmail.com




Artikel terkait

Algoritma Deteksi Tabrakan Objek Game Dengan Sudut Vektor

Menghitung Luas Segitiga dengan Vektor

Teori Deteksi Tabrakan Objek Segitiga dan Titik

Deteksi Tabrakan dengan (Skala) Proyeksi Vektor

Mendeteksi Posisi dengan Vektor Proyeksi

Animasi Game 2D dengan Translasi

Deteksi Tabrakan dengan Panjang Vektor / Radius

Vektor R2