Senin, 11 Januari 2016

Program Deteksi Tumbukan / Tabrakan Dengan Sudut Vektor



Selamat Pagi, artikel kali ini akan membahas tentang deteksi tabrakan / tumbukan dengan menggunakan sudut vektor. Setelah sebelumnya ogut menulis artikel tentang algoritma deteksi tabrakan dengan sudut vektor, sekarang saatnya memberikan contoh program OpenGL-nya.


Algoritma tidak akan ogut bahas di sini, sehingga agar tidak bingung sebaiknya rekan-rekan membaca teorinya terlebih dahulu di link ini.


Tabrakan akan terjadi antara objek segitiga ABC dan titik P jika memenuhi 3 kondisi berikut ini:


Kondisi I : Sudut A° = Sudut AB° + Sudut AC°


Kondisi II : Sudut B° = Sudut BA° + Sudut BC°


Kondisi III : Sudut C° = Sudut CA° + Sudut CB°


Sudut antara dua vektor dapat Anda hitung dengan rumus tertentu, untuk mengetahuinya silahkan klik link ini.

Untuk membuat program deteksi tumbukan / tabrakan ini caranya mudah, perhatikanlah sebagian source code program ini.

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 VektorAC As Vektor_Properties
        Public VektorBA As Vektor_Properties
        Public VektorBC As Vektor_Properties
        Public VektorCA As Vektor_Properties
        Public VektorCB As Vektor_Properties

        Public Hit_Status As Boolean
    End Structure

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

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

        TitikPusatBonus0X = 150 : TitikPusatBonus0Y = 300

        '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

        TitikPusatBonus1X = -300 : TitikPusatBonus1Y = -100

 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 SudutA, SudutAB, SudutAC As Single
        Dim SudutB, SudutBA, SudutBC As Single
        Dim SudutC, SudutCA, SudutCB As Single

        Dim ToleransiSudut_Atas As Single
        Dim ToleransiSudut_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

                        'di Titik A
                        Bonus(j).VektorAB = Create_Vektor(Bonus(j).Ax, Bonus(j).Ay, Bonus(j).Bx, Bonus(j).By)
                        Bonus(j).VektorAC = Create_Vektor(Bonus(j).Ax, Bonus(j).Ay, Bonus(j).Cx, Bonus(j).Cy)
                        Vektor_AP = Create_Vektor(Bonus(j).Ax, Bonus(j).Ay, CenterX_Peluru, CenterY_Peluru)

                        SudutA = Sudut_Vektor(Bonus(j).VektorAB, Bonus(j).VektorAC)
                        SudutAB = Sudut_Vektor(Bonus(j).VektorAB, Vektor_AP)
                        SudutAC = Sudut_Vektor(Bonus(j).VektorAC, Vektor_AP)

                        ToleransiSudut_Bawah = SudutAB + SudutAC - Toleransi
                        ToleransiSudut_Atas = SudutAB + SudutAC + Toleransi

                        'jika bandingkan jumlah sudut AB dan sudut AC dengan sudut A
                        If SudutA <= ToleransiSudut_Atas And SudutA >= ToleransiSudut_Bawah Then

                            'kondisi pertama memenuhi, periksa dengan titik B
                            Bonus(j).VektorBA = Create_Vektor(Bonus(j).Bx, Bonus(j).By, Bonus(j).Ax, Bonus(j).Ay)
                            Bonus(j).VektorBC = Create_Vektor(Bonus(j).Bx, Bonus(j).By, Bonus(j).Cx, Bonus(j).Cy)
                            Vektor_BP = Create_Vektor(Bonus(j).Bx, Bonus(j).By, CenterX_Peluru, CenterY_Peluru)

                            SudutB = Sudut_Vektor(Bonus(j).VektorBA, Bonus(j).VektorBC)
                            SudutBA = Sudut_Vektor(Bonus(j).VektorBA, Vektor_BP)
                            SudutBC = Sudut_Vektor(Bonus(j).VektorBC, Vektor_BP)

                            ToleransiSudut_Bawah = SudutBA + SudutBC - Toleransi
                            ToleransiSudut_Atas = SudutBA + SudutBC + Toleransi

                            'jika bandingkan jumlah sudut BA dan sudut BC dengan sudut B
                            If SudutB <= ToleransiSudut_Atas And SudutB >= ToleransiSudut_Bawah Then

                                'kondisi kedus memenuhi, periksa dengan titik C
                                Bonus(j).VektorCA = Create_Vektor(Bonus(j).Cx, Bonus(j).Cy, Bonus(j).Ax, Bonus(j).Ay)
                                Bonus(j).VektorCB = Create_Vektor(Bonus(j).Cx, Bonus(j).Cy, Bonus(j).Bx, Bonus(j).By)
                                Vektor_CP = Create_Vektor(Bonus(j).Cx, Bonus(j).Cy, CenterX_Peluru, CenterY_Peluru)

                                SudutC = Sudut_Vektor(Bonus(j).VektorCA, Bonus(j).VektorCB)
                                SudutCA = Sudut_Vektor(Bonus(j).VektorCA, Vektor_CP)
                                SudutCB = Sudut_Vektor(Bonus(j).VektorCB, Vektor_CP)

                                ToleransiSudut_Bawah = SudutCA + SudutCB - Toleransi
                                ToleransiSudut_Atas = SudutCA + SudutCB + Toleransi

                                'jika bandingkan jumlah sudut CA dan sudut CB dengan sudut C
                                If SudutC <= ToleransiSudut_Atas And SudutC >= ToleransiSudut_Bawah Then
                                    'tiga kondisi memenuhi, jadi tabrakan etrjadi antara peluru dan segitiga/bonus
                                    Peluru_Fighter(i).GO_Active = False
                                    Bonus(j).Hit_Status = True
                                    Sound2.Play()
                                End If

                            End If 'If SudutB <= ToleransiSudut_Atas And SudutB >= ToleransiSudut_Bawah Then

                        End If 'If SudutA <= ToleransiSudut_Atas And SudutA >= ToleransiSudut_Bawah Then

                    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

Demikian rekan-rekan isi dari artikel kali ini, ogut berharap artikel ini berguna sebagai alternatif bagi rekan-rekan yang ingin belajar membuat game sendiri.

Salam


Heriady
heriady.yoh@gmail.com




Artikel terkait
Algoritma Deteksi Tabrakan Objek Game Dengan Sudut Vektor

Deteksi Tabrakan Game OpenGL (Segitiga dan Titik)

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