Jumat, 17 Juli 2015

Manfaat Sudut Vektor

Pagi hari di Hari Raya Kemenangan...

Update 1 Jan 2016




Selamat pagi semuanya, sebelum memulai artikel ini ogut ucapkan Selamat Lebaran bagi rekan-rekan yang merayakannya, semoga Rahmat Tuhan Yang Maha Esa selalu melimpahi kita semua.

Pada pagi ini ogut akan membagi ilmu vektor kembali kepada rekan-rekan sekalian, begitu besar manfaat vektor untuk pemrograman game. Dan kali ini ogut akan memberikan contoh manfaat sudut vektor.

Program implementasi yang ogut sertakan akan tampak seperti gambar di bawah ini, canon akan selalu mengarahkan moncongnya ke pesawat lalu menembaknya.

Teori tentang sudut vektor pernah dibahas pada artikel terdahulu, jadi silahkan klik link yang telah disediakan untuk membaca artikel sudut vektor.


Teori Sudut Vektor
Pada gambar di bawah terlihat dua buah objek game berupa pesawat (fighter) dan canon. Pesawat dikontrol oleh user (pemain game) sedangkan canon dikontrol oleh komputer.


Agar canon dapat menembak tepat sasaran ke arah pesawat maka moncong canon harus diarahkan ke pesawat.

Pada gambar  dapat Anda lihat vektor moncong canon dan vektor target membentuk sudut Ө˚, agar moncong canon mengarah ke pesawat maka sudut vektor ini harus diperkecil dengan cara merotasi moncong canon.


Untuk membantu proses rotasi moncong canon agar mengarah tepat ke sasaran diperlukan dua buah vektor bantu yaitu vektor timur dan vektor barat.


Implementasi Sudut Vektor
Program contoh yang disertakan pada artikel ini banyak diterapkan pada game bertipe shoot them up, walaupun objek game yang digunakan berbeda-beda tetapi dasar perhitungan matematikanya sama.

Di bawah ini ogut sertakan kode program yang harus Anda perhatikan untuk membuat program sudut vektor, source lengkap dapat Anda download dengan cara klik pada link yang telah ogut sediakan.

Tentukan nilai awal objek.

    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
        Fighter.Hit_Status = False

        'vektor fighter A
        VektorFighterA.i = Fighter.Bx - Fighter.Ax
        VektorFighterA.j = Fighter.By - Fighter.Ay
        'vektor fighter B
        VektorFighterB.i = Fighter.Dx - Fighter.Ax
        VektorFighterB.j = Fighter.Dy - Fighter.Ay
        'panjang vektor
        LVektorFighterA = Panjang_Vektor(VektorFighterA)
        LVektorFighterB = Panjang_Vektor(VektorFighterB)

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

        'Timer peluru canon
        Timer_PeluruC.TDelay = 500 '0.5 detik
        Timer_PeluruC.TGetFirst = True

        'CanonBody
        CanonBody.Ax = -90 : CanonBody.Ay = -530
        CanonBody.Bx = 90 : CanonBody.By = -530
        CanonBody.Cx = 90 : CanonBody.Cy = -355
        CanonBody.Dx = -90 : CanonBody.Dy = -355
        'CanonMoncong
        CanonMoncong.Ax = -55 : CanonMoncong.Ay = -450
        CanonMoncong.Bx = 55 : CanonMoncong.By = -450
        CanonMoncong.Cx = 55 : CanonMoncong.Cy = -250
        CanonMoncong.Dx = -55 : CanonMoncong.Dy = -250
        'pusat rotasi moncong canon
        CanonMoncong.PusatRotasiX = 0
        CanonMoncong.PusatRotasiY = -400

        CanonMoncong.Fire_Flag = False

        'peluru canon
        Dim i As Integer
        For i = 0 To 29
            Peluru_Canon(i).GO_Active = False
        Next
        Speed_PeluruC = 15.5

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

        'vektor Barat dan vektor Timur(panjang vektor = 1 satuan)
        VBarat.i = -1 : VBarat.j = 0
        VTimur.i = 1 : VTimur.j = 0
    End Sub

Arahkan moncong Canon ke Fighter.

    Private Sub Render_Canon()
        Dim SudutTarget As Single
        Dim SudutMoncongC As Single
        Dim Sudut_Rotasi_Moncong As Double

        'create vektor target
        Titik_Pusat_Fighter(CenterFighterX, CenterFighterY)
        VTarget = Create_Vektor(CanonMoncong.PusatRotasiX, CanonMoncong.PusatRotasiY, CenterFighterX, CenterFighterY)
        'cari sudut target
        SudutTarget = Sudut_Vektor(VTarget, VTimur)

        'create vektor moncong canon
        VMoncongCanon = Create_Vektor(CanonMoncong.Ax, CanonMoncong.Ay, CanonMoncong.Dx, CanonMoncong.Dy)
        If SudutTarget < 90.0# Then
            '====================
            'gunakan vektor timur
            '====================
            SudutMoncongC = Sudut_Vektor(VMoncongCanon, VTimur)

            'toleransi sudut = 1 derajat
            If Math.Abs(SudutMoncongC - SudutTarget) <= 1.0# Then
                'moncong canon sudah mengarah ke fighter
                Sudut_Rotasi_Moncong = 0

                If CanonMoncong.Fire_Flag = True Then
                    'canon menembak
                    Reload_PeluruC()
                    Sound1.Play()
                    CanonMoncong.Fire_Flag = False
                End If
            Else
                'moncong canon perlu dirotasi agar
                'mengarah ke fighter
                If SudutMoncongC > SudutTarget Then
                    'rotasi searah jarum jam
                    Sudut_Rotasi_Moncong = -1.5
                Else
                    Sudut_Rotasi_Moncong = 1.5
                End If
            End If

        Else
            '====================
            'gunakan vektor barat
            '====================
            SudutTarget = Sudut_Vektor(VTarget, VBarat)
            SudutMoncongC = Sudut_Vektor(VMoncongCanon, VBarat)

            'toleransi sudut = 1 derajat
            If Math.Abs(SudutMoncongC - SudutTarget) <= 1.0# Then
                'moncong canon sudah mengarah ke fighter
                Sudut_Rotasi_Moncong = 0

                If CanonMoncong.Fire_Flag = True Then
                    'canon menembak
                    Reload_PeluruC()
                    Sound1.Play()
                    CanonMoncong.Fire_Flag = False
                End If
            Else
                'moncong canon perlu dirotasi agar
                'mengarah ke fighter
                If SudutMoncongC > SudutTarget Then
                    'rotasi berlawanan arah jarum jam
                    Sudut_Rotasi_Moncong = 1.5
                Else
                    Sudut_Rotasi_Moncong = -1.5
                End If
            End If
        End If

        'rotasi mocong canon
        Rotasi(CanonMoncong.Ax, CanonMoncong.Ay, CanonMoncong.PusatRotasiX, CanonMoncong.PusatRotasiY, Sudut_Rotasi_Moncong)
        Rotasi(CanonMoncong.Bx, CanonMoncong.By, CanonMoncong.PusatRotasiX, CanonMoncong.PusatRotasiY, Sudut_Rotasi_Moncong)
        Rotasi(CanonMoncong.Cx, CanonMoncong.Cy, CanonMoncong.PusatRotasiX, CanonMoncong.PusatRotasiY, Sudut_Rotasi_Moncong)
        Rotasi(CanonMoncong.Dx, CanonMoncong.Dy, CanonMoncong.PusatRotasiX, CanonMoncong.PusatRotasiY, Sudut_Rotasi_Moncong)

        'CanonMoncong
        GL.Enable(EnableCap.Blend)
        GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.Zero)

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

        GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One)
        'BMP
        GL.BindTexture(TextureTarget.Texture2D, CanonMoncongBMP)
        GL.Begin(BeginMode.Quads)
        GL.TexCoord2(0.0, 0.0) : GL.Vertex2(CanonMoncong.Ax, CanonMoncong.Ay)
        GL.TexCoord2(1.0, 0.0) : GL.Vertex2(CanonMoncong.Bx, CanonMoncong.By)
        GL.TexCoord2(1.0, 1.0) : GL.Vertex2(CanonMoncong.Cx, CanonMoncong.Cy)
        GL.TexCoord2(0.0, 1.0) : GL.Vertex2(CanonMoncong.Dx, CanonMoncong.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(CanonMoncong.Ax, CanonMoncong.Ay)
            GL.Vertex2(CanonMoncong.Bx, CanonMoncong.By)
            GL.Vertex2(CanonMoncong.Cx, CanonMoncong.Cy)
            GL.Vertex2(CanonMoncong.Dx, CanonMoncong.Dy)
            GL.End()
        End If

        'CanonBody
        GL.Enable(EnableCap.Blend)
        GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.Zero)

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

        GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One)
        'BMP
        GL.BindTexture(TextureTarget.Texture2D, CanonBodyBMP)
        GL.Begin(BeginMode.Quads)
        GL.TexCoord2(0.0, 0.0) : GL.Vertex2(CanonBody.Ax, CanonBody.Ay)
        GL.TexCoord2(1.0, 0.0) : GL.Vertex2(CanonBody.Bx, CanonBody.By)
        GL.TexCoord2(1.0, 1.0) : GL.Vertex2(CanonBody.Cx, CanonBody.Cy)
        GL.TexCoord2(0.0, 1.0) : GL.Vertex2(CanonBody.Dx, CanonBody.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(CanonBody.Ax, CanonBody.Ay)
            GL.Vertex2(CanonBody.Bx, CanonBody.By)
            GL.Vertex2(CanonBody.Cx, CanonBody.Cy)
            GL.Vertex2(CanonBody.Dx, CanonBody.Dy)
            GL.End()
        End If
    End Sub

    Private Sub Reload_PeluruC()
        Dim i As Integer
        Dim Temp_Vektor As Vektor_Properties

        Temp_Vektor = Create_Vektor(CanonMoncong.Dx, CanonMoncong.Dy, CanonMoncong.Cx, CanonMoncong.Cy)

        For i = 0 To 29
            If Peluru_Canon(i).GO_Active = False Then
                Peluru_Canon(i).GO_Active = True
                'isi koordinat peluru canon
                Peluru_Canon(i).Ax = CanonMoncong.Dx + (0.5 * Temp_Vektor.i) - 10
                Peluru_Canon(i).Ay = CanonMoncong.Dy + (0.5 * Temp_Vektor.j) - 10
                Peluru_Canon(i).Bx = Peluru_Canon(i).Ax + 20
                Peluru_Canon(i).By = Peluru_Canon(i).Ay
                Peluru_Canon(i).Cx = Peluru_Canon(i).Bx
                Peluru_Canon(i).Cy = Peluru_Canon(i).By + 20
                Peluru_Canon(i).Dx = Peluru_Canon(i).Ax
                Peluru_Canon(i).Dy = Peluru_Canon(i).Cy

                '=============================================
                'setting vektor peluru canon,
                'karena peluru canon harus mengarah ke fighter
                'maka vektor peluru diisi dengan vaktor target
                '=============================================
                Temp_Vektor = Normalisasi_Vektor(VTarget)

                Peluru_Canon(i).Vektor.i = Temp_Vektor.i * Speed_PeluruC
                Peluru_Canon(i).Vektor.j = Temp_Vektor.j * Speed_PeluruC

                i = 30
            End If
        Next
    End Sub

Update 1 Jab 2016

Artikel lain yang menggunakan vektor untuk menyelesaikan perhitungan matematikanya, Vektor Pantul, Membuat Missile dan Tanjakan Turunan.




Bagaimana rekan-rekan? Besar sekali manfaat vektor untuk pemrograman game, contoh program pada artikel ini juga membuktikannya. Dan bagi rekan-rekan yang mempunyai ide tentang manfaat vektor bagi pemrogramann game, ogut akan menerima dengan senang hati, karena berbagi itu indah.

Salam Vektor R2 dan R3


Heriady
heriady.yoh@gmail.com




Artikel terkait

Matematika Vektor R2

Vektor Pantul

Tidak ada komentar:

Posting Komentar