基于VB6.0射击游戏的实现
随着计算机技术的进步,计算机游戏也越来越普及,很多喜爱程序开发的读者朋友都向往游戏编程,但往往又觉得游戏编程序很复杂,高深莫测。诚然,象"帝国时代"、"反恐精英"这样的大型游戏需要写很复杂的程序来实现一些令人"头昏"的算法,需要熟悉DirectX开发知识。但是,对于一般的开发人员,完全可以利用所学的知识开发一些小的游戏,达到自娱自乐的目的。
HwZLinux联盟
本文介绍如何在Visual Basic6.0环境下开发射击小游戏,通过实现该小游戏可以帮助一些Visual Basic初学者加深对Visual Basic编程知识的理解,同时它也可以开拓初、中级开发爱好者的编程思路。该射击小游戏程序编译运行后的界面效果如图一所示:

HwZLinux联盟
图一、射击游戏界面图
在射击游戏中,安排了两个角色,相互之间可以开枪进行对射,同时为了丰富游戏的功能,游戏的场景中添加定时移动的仙人掌,为射击的双方角色提供保护功能。当其中一个角色中弹后,游戏终止,同时游戏人物角色的图标变更,表示角色死亡。为了实现上述的游戏,最初要作的是设计程序界面,按照游戏的需求,首先生成一个VB应用程序,在Form1上添加一个开始按钮btnStart,一个名为picDesert的Picture控件,该控件用来做为游戏的场景和其它控件的容器,在该控件上添加六个Image控件,分别用来显示游戏的角色、两个移动的仙人掌、分别向右、向左呼啸射击的子弹以及标志角色死亡的图标,它们的图象分别如下:

HwZLinux联盟
游戏角色

仙人掌

呼啸的子弹
角色击中标志
为了使程序中的仙人掌、游戏角色和射击时发射的子弹可以移动,需要向项目中添加定时器tmrMouseCnt和Timer1,在这两个定时响应函数中完成不同对象的移动功能。在游戏运行后,为了使用户可以通过键盘和鼠标来操作游戏的角色,实现射击的功能,需要添加鼠标消息和键盘消息处理函数。例如,对于角色1来说,可以通过上下键来移动,空格键来射击,对于角色2来说,鼠标左右键控制移动,双击实现射击。在射击过程中,要处理两个细节,一个细节是子弹与仙人掌及角色的区域重叠问题,当子弹与仙人掌重叠时让子弹隐藏起来,与角色重叠时表示击中目标,游戏结束。这里需要判断何时两个区域有重叠,解决这个问题的方法是使用API函数IntersectRect,用它来判断两个区域是否有重叠。另一个细节是子弹射击过程中需要添加"呼啸"的声音和击中目标时添加人物惨叫的声音,来达到逼真的效果,为了实现这个功能,需要向程序中添加语音文件(程序中的语音文件分别为:BANG.WAV和OH!!.WAV),然后通过API函数sndPlaySound来实现。另外,在对象移动的过程中,需要注意移动到边缘位置的情况处理。 HwZLinux联盟
程序的具体实现代码如下: HwZLinux联盟
SHOOTOUT.BAS HwZLinux联盟
Option Explicit HwZLinux联盟
' Data type required by the IntersectRect function HwZLinux联盟
Type tRect HwZLinux联盟
Left As Long HwZLinux联盟
Top As Long HwZLinux联盟
Right As Long HwZLinux联盟
Bottom As Long HwZLinux联盟
End Type HwZLinux联盟
' Windows API rectangle functions HwZLinux联盟
Declare Function IntersectRect Lib "user32" (lpDestRect As tRect, lpSrc1Rect As tRect, lpSrc2Rect As tRect) As Long HwZLinux联盟
' Functions and constants used to play sounds. HwZLinux联盟
Declare Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long HwZLinux联盟
' Constant used with sndPlaySound function HwZLinux联盟
Global Const SND_ASYNC = &H1 HwZLinux联盟
'---------------------------------------------------------- HwZLinux联盟
' SHOOTOUT.FRM HwZLinux联盟
Option Explicit HwZLinux联盟
' KeyCodes for keyboard action. HwZLinux联盟
Const KEY_SPACE = &H20 HwZLinux联盟
Const KEY_UP = &H26 HwZLinux联盟
Const KEY_DOWN = &H28 HwZLinux联盟
' Number of Twips to move player on each key or mouse event. HwZLinux联盟
Const PlayerIncrement = 45 HwZLinux联盟
' Constants for mouse action. HwZLinux联盟
Const NO_BUTTON = 0 HwZLinux联盟
Const LBUTTON = 1 HwZLinux联盟
Const RBUTTON = 2 HwZLinux联盟
' Boolean that indicates if mouse button has been pressed down. HwZLinux联盟
Dim MouseButtonDown As Integer HwZLinux联盟
' Number of bullets either player can have in use at one time. HwZLinux联盟
Const NUM_BULLETS = 6 HwZLinux联盟
' Booleans indicating if player 0 or player 1 have just fired. HwZLinux联盟
Dim GunFired(0 To 1) As Integer
' Start the game by enabling the main timer and hiding the start button. HwZLinux联盟
Private Sub btnStart_Click() HwZLinux联盟
Timer1.Enabled = True HwZLinux联盟
btnStart.Visible = False HwZLinux联盟
End Sub
' Check if the two Images intersect, using the IntersectRect API call. HwZLinux联盟
Private Function Collided(imgA As Image, imgB As Image) As Integer HwZLinux联盟
Dim A As tRect HwZLinux联盟
Dim B As tRect HwZLinux联盟
Dim ResultRect As tRect HwZLinux联盟
' Copy information into tRect structure HwZLinux联盟
A.Left = imgA.Left HwZLinux联盟
A.Top = imgA.Top HwZLinux联盟
B.Left = imgB.Left HwZLinux联盟
B.Top = imgB.Top HwZLinux联盟
' Calculate the right and bottoms of rectangles needed by the API call. HwZLinux联盟
A.Right = A.Left + imgA.Width - 1 HwZLinux联盟
A.Bottom = A.Top + imgA.Height - 1 HwZLinux联盟
B.Right = B.Left + imgB.Width - 1 HwZLinux联盟
B.Bottom = B.Top + imgB.Height - 1 HwZLinux联盟
' IntersectRect will only return 0 (false) if the HwZLinux联盟
' two rectangles do NOT intersect. HwZLinux联盟
Collided = IntersectRect(ResultRect, A, B) HwZLinux联盟
End Function
' Double-clicking the mouse fires Player 1's gun. HwZLinux联盟
Private Sub Form_DblClick() HwZLinux联盟
Dim rc As Integer HwZLinux联盟
If Not Timer1.Enabled Then Exit Sub HwZLinux联盟
GunFired(1) = True HwZLinux联盟
rc = sndPlaySound(App.Path & "\BANG.WAV", SND_ASYNC) HwZLinux联盟
End Sub
' This event handles Player 0's game action via the keyboard. HwZLinux联盟
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) HwZLinux联盟
Dim rc As Integer HwZLinux联盟
Static InKeyDown As Integer HwZLinux联盟
If Not Timer1.Enabled Then Exit Sub HwZLinux联盟
If InKeyDown Then Exit Sub HwZLinux联盟
InKeyDown = True HwZLinux联盟
DoEvents HwZLinux联盟
Select Case KeyCode HwZLinux联盟
Case KEY_UP HwZLinux联盟
imgPlayer(0).Top = imgPlayer(0).Top - PlayerIncrement HwZLinux联盟
If imgPlayer(0).Top < 0 Then imgPlayer(0).Top = 0 HwZLinux联盟
Case KEY_SPACE HwZLinux联盟
GunFired(0) = True HwZLinux联盟
rc = sndPlaySound(App.Path & "\BANG.WAV", SND_ASYNC) HwZLinux联盟
Case KEY_DOWN HwZLinux联盟
imgPlayer(0).Top = imgPlayer(0).Top + PlayerIncrement HwZLinux联盟
If imgPlayer(0).Top > (picDesert.ScaleHeight - HwZLinux联盟
imgPlayer(0).Height) Then HwZLinux联盟
imgPlayer(0).Top = picDesert.ScaleHeight - HwZLinux联盟
imgPlayer(0).Height HwZLinux联盟
End If HwZLinux联盟
End Select HwZLinux联盟
InKeyDown = False HwZLinux联盟
End Sub
Private Sub Form_Load() HwZLinux联盟
Dim i As Integer HwZLinux联盟
Timer1.Interval = 22 HwZLinux联盟
Timer1.Enabled = False HwZLinux联盟
MouseButtonDown = NO_BUTTON HwZLinux联盟
For i = 1 To NUM_BULLETS - 1 HwZLinux联盟
Load imgLBullet(i) HwZLinux联盟
Load imgRBullet(i) HwZLinux联盟
Next HwZLinux联盟
End Sub
Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single) HwZLinux联盟
MouseButtonDown = Button HwZLinux联盟
End Sub
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single) HwZLinux联盟
MouseButtonDown = NO_BUTTON HwZLinux联盟
End Sub
' The main game timer. HwZLinux联盟
Private Sub Timer1_Timer() HwZLinux联盟
Const CactusIncrement = 30 HwZLinux联盟
Const BulletIncrement = 300 HwZLinux联盟
Const NumCacti = 2
Dim i As Integer HwZLinux联盟
Dim rc As Integer HwZLinux联盟
' Move the roving cacti. HwZLinux联盟
For i = 0 To NumCacti - 1 HwZLinux联盟
imgCactus(i).Top = imgCactus(i).Top - CactusIncrement HwZLinux联盟
If imgCactus(i).Top < -imgCactus(i).Height Then HwZLinux联盟
imgCactus(i).Top = picDesert.Height HwZLinux联盟
End If HwZLinux联盟
Next HwZLinux联盟
' Did player 0 fire a bullet? HwZLinux联盟
If GunFired(0) Then HwZLinux联盟
GunFired(0) = False HwZLinux联盟
' Find a spare (invisible) bullet. HwZLinux联盟
For i = 0 To NUM_BULLETS - 1 HwZLinux联盟
If Not imgLBullet(i).Visible Then HwZLinux联盟
imgLBullet(i).Top = imgPlayer(0).Top HwZLinux联盟
imgLBullet(i).Left = imgPlayer(0).Left + HwZLinux联盟
(imgPlayer(0).Width / 2) HwZLinux联盟
imgLBullet(i).Visible = True HwZLinux联盟
Exit For HwZLinux联盟
End If HwZLinux联盟
Next HwZLinux联盟
End If HwZLinux联盟
' Did player 1 fire a bullet? HwZLinux联盟
If GunFired(1) Then HwZLinux联盟
GunFired(1) = False HwZLinux联盟
' Find a spare (invisible) bullet. HwZLinux联盟
For i = 0 To NUM_BULLETS - 1 HwZLinux联盟
If Not imgRBullet(i).Visible Then HwZLinux联盟
imgRBullet(i).Top = imgPlayer(1).Top HwZLinux联盟
imgRBullet(i).Left = imgPlayer(1).Left - HwZLinux联盟
(imgPlayer(1).Width / 2) HwZLinux联盟
imgRBullet(i).Visible = True HwZLinux联盟
Exit For HwZLinux联盟
End If HwZLinux联盟
Next HwZLinux联盟
End If HwZLinux联盟
' Move Visible Bullets HwZLinux联盟
For i = 0 To NUM_BULLETS - 1 HwZLinux联盟
' Move player 0's bullets. HwZLinux联盟
If imgLBullet(i).Visible Then HwZLinux联盟
imgLBullet(i).Left = imgLBullet(i).Left + BulletIncrement HwZLinux联盟
If Collided(imgLBullet(i), imgCactus(0)) Then HwZLinux联盟
imgLBullet(i).Visible = False HwZLinux联盟
ElseIf Collided(imgLBullet(i), imgCactus(1)) Then HwZLinux联盟
imgLBullet(i).Visible = False HwZLinux联盟
ElseIf imgLBullet(i).Left > picDesert.ScaleWidth Then HwZLinux联盟
imgLBullet(i).Visible = False HwZLinux联盟
ElseIf Collided(imgLBullet(i), imgPlayer(1)) Then HwZLinux联盟
imgLBullet(i).Visible = False HwZLinux联盟
imgPlayer(1).Picture = imgRIP.Picture HwZLinux联盟
Timer1.Enabled = False HwZLinux联盟
rc = sndPlaySound(App.Path & "\OH!!.WAV", SND_ASYNC) HwZLinux联盟
End If HwZLinux联盟
End If HwZLinux联盟
' Move player 1's bullets. HwZLinux联盟
If imgRBullet(i).Visible Then HwZLinux联盟
imgRBullet(i).Left = imgRBullet(i).Left - BulletIncrement HwZLinux联盟
If Collided(imgRBullet(i), imgCactus(0)) Then HwZLinux联盟
imgRBullet(i).Visible = False HwZLinux联盟
ElseIf Collided(imgRBullet(i), imgCactus(1)) Then HwZLinux联盟
imgRBullet(i).Visible = False HwZLinux联盟
ElseIf imgRBullet(i).Left < -imgRBullet(i).Width Then HwZLinux联盟
imgRBullet(i).Visible = False HwZLinux联盟
ElseIf Collided(imgRBullet(i), imgPlayer(0)) Then HwZLinux联盟
imgRBullet(i).Visible = False HwZLinux联盟
imgPlayer(0).Picture = imgRIP.Picture HwZLinux联盟
Timer1.Enabled = False HwZLinux联盟
rc = sndPlaySound(App.Path & "\OH!!.WAV", SND_ASYNC) HwZLinux联盟
End If HwZLinux联盟
End If HwZLinux联盟
Next HwZLinux联盟
End Sub
' Handle Player 1's movement (up and down). HwZLinux联盟
Private Sub tmrMouseCntl_Timer() HwZLinux联盟
If Not Timer1.Enabled Then Exit Sub HwZLinux联盟
Select Case MouseButtonDown HwZLinux联盟
Case RBUTTON HwZLinux联盟
imgPlayer(1).Top = imgPlayer(1).Top - PlayerIncrement HwZLinux联盟
If imgPlayer(1).Top < 0 Then imgPlayer(1).Top = 0 HwZLinux联盟
Case LBUTTON HwZLinux联盟
imgPlayer(1).Top = imgPlayer(1).Top + PlayerIncrement HwZLinux联盟
If imgPlayer(1).Top > (picDesert.ScaleHeight - HwZLinux联盟
imgPlayer(1).Height) Then HwZLinux联盟
imgPlayer(1).Top = picDesert.ScaleHeight - HwZLinux联盟
imgPlayer(1).Height HwZLinux联盟
End If HwZLinux联盟
End Select HwZLinux联盟
End Sub
HwZLinux联盟
文章的上述内容对射击游戏中的各个实现功能进行了详细的介绍,读者朋友可以根据文章中的程序代码自己动手实验一下。本程序在Windows2000、Visual Basic6.0环境下编译通过,运行正常。
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论