📄 basghostai.bas
字号:
Attribute VB_Name = "basGhostAI"
Option Explicit
Sub AIGhostMonsters()
Dim HitWall As Boolean
Dim XD2 As Integer
Dim YD2 As Integer
Dim Xs2 As Integer
Dim Ys2 As Integer
Dim X As Integer
Dim Y As Integer
Dim back As Integer
Dim nLoop As Integer
Dim Px As Integer
Dim Py As Integer
' Loop untuk setiap 4 Ghost
For nLoop = 1 To 4
' untuk masing-masing Ghost
With Ghost(nLoop)
' Simpan Posisi Ghost
Sprite(nLoop).OXpos = .Xpos - 16
Sprite(nLoop).OYpos = .Ypos - 16
HitWall = False
' Periksa apakah Ghost dalam permainan atau tidak
' Jika tidak dalam permainan Ghost masih dalam kotak (kandang) dan mempunyai rutin/rule yang berbeda
If .InGame = False Then
If .Ypos = 224 Or .Ypos = 240 Then ' Jika Ghost berada di bagian atas atau bawah dari kotak
If .Direction < 2 Then ' Periksa Jika Ghost ke atas atau ke bawah dan tidak ke kanan atau ke kiri
.Direction = 1 - .Direction ' Balikkan arah ghost sehingga tidak keluar kotak (pembatalan)
.Eyesonly = False ' Matikan Eyesonly(hanya tampil mata) jika ghost habis dimakan
End If
End If
' Hantu akan bergerak memantul 2 x sebelum boleh meninggalkan kotak
If .Xpos = 224 And .Ypos = 224 Then ' Ghost berada di bagian atas kotak (pintu keluar)
.Ycounter = .Ycounter + 1
If .Ycounter > 1 Then
.Direction = 0 ' Ke atas dan keluar dari kotak setelah memantul turun 1 x
End If
End If
If .Xpos = 192 And Ghost(3).InGame Then
.Direction = 3 ' Ghost sebelah kiri bergerak ke kanan menuju tengah kotak(Jika Ghost kanan sudah di permainan)
End If
If .Xpos = 256 And Ghost(2).InGame Then
.Direction = 2 ' Ghost sebelah kanan bergerak ke kiri menuju tengah kotak(Jika Ghost tengah sudah di permainan)
End If
If .Xpos = 224 And .Direction > 1 Then ' Apakah Ghost akan menuju tengah
.Direction = 0 ' Gerakkan Ghost keatas dan keluar dari kotak setelah memantul
End If
' Jika ghost sudah keluar kotak dan mulai dalam permainan (pemosisian)
If .Ypos = 184 Then
.Offset = 8
.Direction = 2 + Rnd
.InGame = True
End If
End If
' Ini adalah prosedur jika Ghost dalam permainan
If .InGame = True Then
' Periksa jika ghost sudah kembali ke kotak untuk pemulihan setelah dimakan pacman
If .Xpos = 224 And .Ypos = 184 And .Eyesonly Then
.Speed = .Speed / 2 ' memperlambat gerak ghost menjadi normal
.InGame = False ' ghost tidak dalam permainan lagi
.Direction = 1 ' arahkan ghost untuk bergerak ke bawah
End If
' Test untuk arah jika ghost menyerbu cell dimana pacman yang berada
If .Offset = 0 Then
X = .Xpos \ 16 ' posisi x (per langkah) dari ghost
Y = .Ypos \ 16 ' posisi y (per langkah) dari ghost
Px = Pacman.Xpos \ 16 'posisi x (per langkah) dari pacman
Py = Pacman.Ypos \ 16 'posisi y (per langkah) dari pacman
If nLoop = 2 Then ' ghost 2: mengamati 1 langkah sebelum posisi pacman
If Abs(Px - X) + Abs(Py - Y) > 2 Then
Px = Px + XD(Pacman.Direction) * 4
Py = Py + XD(Pacman.Direction) * 4
End If
End If
If nLoop = 3 Then ' ghost 3: mengamati lebih jauh dari pengamatan ghost 2 sebelum posisi pacman
If Abs(Px - X) + Abs(Py - Y) > 3 Then
Px = Px + XD(Pacman.Direction) * 8
Py = Py + XD(Pacman.Direction) * 8
End If
End If
If nLoop = 4 Then ' ghost 4: mengamati lebih jauh dari pengamatan ghost 3 sebelum posisi pacman
If Abs(Px - X) + Abs(Py - Y) > 4 Then
Px = Px + XD(Pacman.Direction) * 12
Py = Py + XD(Pacman.Direction) * 12
End If
End If
' jika ghost dalam state setelah dimakan(eyesonly)
' arahkan menuju bagian atas (pintu keluar) kotak asal
' dan menjauhi pacman
If .Eyesonly Then
Px = 224 \ 16
Py = 184 \ 16
End If
' Jika ghost melalui sebuah persimpangan ( T, L, atau perempatan)
If PacLevel(X, Y).Junction Then
XD2 = Abs(Px - X) ' jarak dari pacman atau kotak asal ghost
YD2 = Abs(Py - Y)
Xs2 = Sgn(Px - X) ' arah dari pacman atau kotak asal relatif terhadap ghost
Ys2 = Sgn(Py - Y)
' jika ghost dalam keadaan siap dimakan maka balikkan arahnya
' menjauhi sasaran sebelumnya
If .PPTimer > 0 Then
Xs2 = -Xs2
Ys2 = -Ys2
End If
' buat ghost dalam state menabrak dinding dulu, sehingga mencari alternatif langkah
' dengan arah yang berbeda
HitWall = True
'variable 'back' di bawah merupakan arah kebalikan dari arah ghost
'sebagai pengecualian alternatif arah agar tidak kembali ke titik semula
back = Rev(.Direction)
'pemilihan arah ghost berdasarkan kemungkinan jalan
'dan jika ada jalan, buat ghost dalam state tidak menabrak dinding.
If Ys2 < 0 And PacLevel(X, Y).JUp And back <> 0 Then .Direction = 0: HitWall = False ' ke atas
'dimana JUp = ada jalan naik
If Ys2 > 0 And PacLevel(X, Y).JDown And back <> 1 Then .Direction = 1: HitWall = False ' ke bawah
If Xs2 < 0 And PacLevel(X, Y).Jleft And back <> 2 Then .Direction = 2: HitWall = False ' ke kanan
If Xs2 > 0 And PacLevel(X, Y).Jright And back <> 3 Then .Direction = 3: HitWall = False ' ke kiri
'jika membentur dinding(tidak memenuhi kriteria diatas karena arah relatifnya tidak diketahui=0)
If HitWall = True Then
If Ys2 = 0 Then ' jika pacman/kotak dan ghost pada posisi Y yang sama
If PacLevel(X, Y).JUp And back <> 0 Then .Direction = 0: HitWall = False 'ke atas
If PacLevel(X, Y).JDown And back <> 1 Then .Direction = 1: HitWall = False 'ke bawah
End If
If Xs2 = 0 Then ' jika pacman/kotak dan ghost pada posisi X yang sama
If PacLevel(X, Y).Jleft And back <> 2 Then .Direction = 2: HitWall = False 'ke kanan
If PacLevel(X, Y).Jright And back <> 3 Then .Direction = 3: HitWall = False 'ke kiri
End If
End If
'jika membentur dinding(tidak memenuhi semua kriteria diatas). kunci:Ys2 dan Xs2
If HitWall = True Then
If PacLevel(X, Y).JUp And back <> 0 Then .Direction = 0: HitWall = False
If PacLevel(X, Y).JDown And back <> 1 Then .Direction = 1: HitWall = False
If PacLevel(X, Y).Jleft And back <> 2 Then .Direction = 2: HitWall = False
If PacLevel(X, Y).Jright And back <> 3 Then .Direction = 3: HitWall = False
End If
End If
End If
End If
' perlambatan waktu dari 1 jika ghost dalam state siap dimakan
' dan bergerak dengen setengah kecepatan (gerak,berhenti,gerak,berhenti.....)
.DelayTime = 1 - .DelayTime
If .PPTimer > 0 And .DelayTime = 0 Then
HitWall = True ' menghentikan gerak ghost
End If
' jika ghost bisa bergerak maka gerakkan
If HitWall = False Then
.Xpos = .Xpos + XD(.Direction) * .Speed
.Ypos = .Ypos + YD(.Direction) * .Speed
.Offset = (.Offset + OffDir(.Direction) * .Speed + 16) Mod 16
If .Xpos > 416 Then .Xpos = .Xpos - 416
If .Xpos < 16 Then .Xpos = .Xpos + 416
End If
' jika ghost dalam posisi siap dimakan, kurangi timernya
If .PPTimer > 0 Then
.PPTimer = .PPTimer - 1
End If
End With
' Pengaturan sprite ghost
With Sprite(nLoop)
.NXpos = Ghost(nLoop).Xpos - 16
.NYpos = Ghost(nLoop).Ypos - 16
.XSprite = (nLoop - 1) * 32
.YSprite = Ghost(nLoop).Direction * 32
End With
Next nLoop
End Sub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -