Selasa, 07 Juli 2015

Deteksi Tabrakan dengan Proyeksi Vektor

Dari dalam kamar kecil ogut (bukan toilet) yang selalu berantakan karena baju latihan selalu ngak diberesin...salam sejahterah selalu...tak terasa waktu terus berlalu...dan urusan nge-blog tetep jalan terus...sekarang saatnya...berterima kasih sama Bang Victor (baca vektor, plesetan dari vektor) karena...


Pagi rekan-rekan sekalian, sebelum ogut memulai cerita kita hening sejenak untuk mengucapkan terima kasih kepada Bang Victor, karena abang satu ini yang bisa bikin program di blog ini jalan. Ok kita hening sejenak ya...(pasti ada yang ngak mau hening sejenak...hehehe)

Artikel kali ini akan bercerita tentang deteksi tabrakan dengan menggunakan  proyeksi vektor. Proyeksi vektor sudah pernah dibahas pada artikel sebelumnya, jadi ogut ngak mau bahas lagi, tetapi ogut akan memberikan contoh program kongkritnya.

Pada gambar di bawah terlihat pesawat Fighter menembakkan peluru ke arah objek Bonus, dengan proyeksi vektor tabrakan antara peluru dan objek bisa terdeteksi.


Contoh proyeksi vektor


Berikut kode program yang penting-penting yang harus Anda perhatikan.

Tentukan nilai awal objek (Bonus) yang ingin ditabrak 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 = -GlControl1.Width
        Area_Tembak_Xmax = GlControl1.Width
        Area_Tembak_Ymin = -GlControl1.Height
        Area_Tembak_Ymax = GlControl1.Height

        '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)

        '======================
        'nilai awal untuk bonus
        '======================
        'Bonus(0)
        Bonus(0).Ax = 25 : Bonus(0).Ay = 225
        Bonus(0).Bx = 175 : Bonus(0).By = 225
        Bonus(0).Cx = 175 : Bonus(0).Cy = 375
        Bonus(0).Dx = 25 : Bonus(0).Dy = 375
        Bonus(0).Hit_Status = False
        '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).Dx = -375 : Bonus(1).Dy = -25
        Bonus(1).Hit_Status = False

        'create VektorBonusA
        VektorBonusA.i = Bonus(0).Bx - Bonus(0).Ax
        VektorBonusA.j = 0
        'create VektorBonusB
        VektorBonusB.i = 0
        VektorBonusB.j = Bonus(0).Dy - Bonus(0).Ay

        LVektorBonusA = Panjang_Vektor(VektorBonusA)
        LVektorBonusB = Panjang_Vektor(VektorBonusB)
    End Sub

Hitung tabrakan peluru dengan objek Bonus.

    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
                    'proses deteksi tabrakan dengan bonus dimulai
                    '============================
                    For j = 0 To 1
                        'create vektor peluru
                        VektorPeluru = Create_Vektor(Bonus(j).Ax, Bonus(j).Ay, CenterX_Peluru, CenterY_Peluru)
                        'hitung skala proyeksi
                        SkalaPro1 = Dot_Product(VektorPeluru, VektorBonusA) / (LVektorBonusA * LVektorBonusA)
                        SkalaPro2 = Dot_Product(VektorPeluru, VektorBonusB) / (LVektorBonusB * LVektorBonusB)

                        If (SkalaPro1 >= 0 And SkalaPro1 <= 1 And SkalaPro2 >= 0 And SkalaPro2 <= 1) Then
                            '=====================
                            'peluru menabrak bonus
                            '=====================
                            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

Dan render objek Bonus.

    Private Sub Render_Bonus()
        Dim i As Integer

        For i = 0 To 1
            GL.Enable(EnableCap.Blend)
            GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.Zero)

            'Mask
            GL.BindTexture(TextureTarget.Texture2D, BonusBMP_Mask)
            GL.Begin(BeginMode.Quads)
            GL.TexCoord2(0.0, 0.0) : GL.Vertex2(Bonus(i).Ax, Bonus(i).Ay)
            GL.TexCoord2(1.0, 0.0) : GL.Vertex2(Bonus(i).Bx, Bonus(i).By)
            GL.TexCoord2(1.0, 1.0) : GL.Vertex2(Bonus(i).Cx, Bonus(i).Cy)
            GL.TexCoord2(0.0, 1.0) : GL.Vertex2(Bonus(i).Dx, Bonus(i).Dy)
            GL.End()

            GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One)

            If Bonus(i).Hit_Status Then
                Bonus(i).Hit_Status = False
                'tekstur
                GL.BindTexture(TextureTarget.Texture2D, BonusBMP_Red)
            Else
                'tekstur
                GL.BindTexture(TextureTarget.Texture2D, BonusBMP)
            End If
            GL.Begin(BeginMode.Quads)
            GL.TexCoord2(0.0, 0.0) : GL.Vertex2(Bonus(i).Ax, Bonus(i).Ay)
            GL.TexCoord2(1.0, 0.0) : GL.Vertex2(Bonus(i).Bx, Bonus(i).By)
            GL.TexCoord2(1.0, 1.0) : GL.Vertex2(Bonus(i).Cx, Bonus(i).Cy)
            GL.TexCoord2(0.0, 1.0) : GL.Vertex2(Bonus(i).Dx, Bonus(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(Bonus(i).Ax, Bonus(i).Ay)
                GL.Vertex2(Bonus(i).Bx, Bonus(i).By)
                GL.Vertex2(Bonus(i).Cx, Bonus(i).Cy)
                GL.Vertex2(Bonus(i).Dx, Bonus(i).Dy)
                GL.End()
            End If
        Next
    End Sub

Bagaimana rekan-rekan, jangan berterima kasih ama ogut tapi ama Bang Victor ya...karena berkat jasanya ini program bisa jalan.

Update 2 Jan 2016

Contoh manfaat proyeksi vektor lainnya.



Sampai jumpa lagi di deteksi tabrakan berikutnya


Heriady
heriady.yoh@gmail.com




Artikel terkait

Mendeteksi Posisi dengan Vektor Proyeksi

Animasi Game 2D dengan Translasi

Deteksi Tabrakan dengan Panjang Vektor / Radius

Vektor R2