|
|
埃及祖玛游戏编程模拟 (VB6)
【编程引子】
埃及祖玛游戏是一款老少皆宜的益智类游戏,主角是一只石青蛙,它会吐出各种颜色的小球。环绕着石青蛙的是载着小球的轨道,各种颜色的小球会沿着轨道向前滑动。石青蛙阻止小球滚进轨道终点的洞里的方法就是用吐出小球与轨道上的小球相结合,颜色相同且数量达到三个以上就会消除得分。小球消除后前面的小球后退并形成新的紧密相连的球串。今天我们就来编程模拟这款游戏。本文设计的游戏与原游戏相比,采用直线双轨道和纵向发球,降低了不规则轨道运动和任意角度发球的难度。
【编程分析】
一、球的形状
本文共设计了六种颜色不同的小球,如图1所示。发出的小球用图像框(Ball)表示并产生运动,轨道上的小球用图像框控件数组表示并形成运动,由于本文有两个轨道(最上方和最下方),所以我们需要两个图像框控件数组(Balls1、Balls2)来装载轨道上运动的小球。
二、轨道小球的形成和运动
轨道上表示小球的控件数组元素用Load方法自动加载,每个轨道上小球数量通过球的活动区域和球的宽度相除计算得到。每关游戏开始时,将轨道上的小球放置在最右侧,并随机选择不同颜色的球的图像粘贴到轨道上表示小球的图像控件数组中。游戏一开始,通过定时器的触发事件改变轨道上每个小球图像的Left值实现轨道上小球从右向左移动,当双轨上运动的最左边的小球任意一个达到活动区域最左侧时闯关失败。
三、发球控制
所有球都在图片框Pb所表示的区域内活动,因此,发出小球的动作在Pb的MouseDown事件中处理。发出的小球运动的初始垂直位置在Pb垂直方向的中心,发出小球的初始水平位置通过鼠标事件确定,即在Pb的MouseMove事件中动态改变发出小球的Left属性值。发出的小球有向上、向下两个运动方向,根据鼠标相对于发出小球的初始垂直位置而定,如果鼠标在小球初始位置的下方则向下运动,反之则向上运动,同时鼠标偏离初始垂直位置的距离代表发出小球的运动速度。发出的小球的两个方向的运动分别在两个定时器触发事件中通过改变其Top属性值而实现。
四、碰撞判断
当发出的小球运动到轨道处时,这个小球要自动加入到轨道小球队列中。如图2所示,当发出的小球的水平对称线(A)在轨道上某球水平对称线(H)左侧时,插入的位置为上方球的位置(K),如果发出的小球的水平对称线(B)在轨道上某球水平对称线(H)右侧时,插入的位置为上方球的位置的右侧球(K+1)的位置。为了插入一个小球,我们需要先将插入位置的图像逐一后移,再把发出小球的图像粘贴到插入位置。假设插入后的位置为K,则……、Balls(K+2).picture=Balls(K+1).picture、Balls(K+1).picture=Balls(K).picture、Balls(K).picture=Ball.picture。
五、球的消失
当发出的球插入轨道小球队列后,如果有三个或以上的同色小球相连,则这些相连的小球需要消失。从插入位置开始分别向左、右两侧检测是否与插入位置的球的图案相同,从而找到消除球的起止位置V1、V2,然后设置V1-V2之间的控件的Picture属性为LoadPicture("")实现图像清除。当小球消失后将轨道上所有表示小球的控件数组同时向后移动消除小球数量的总宽度,最后把V1后面的图像分别向前移动一个单位,直到V1处的图像不为空为止。
【编程实现】
一、界面设计
启动VB,向窗体添加一个图片框Pb(游戏区域),图像框数组Image1(0)~Image1(5)用来存放球的图案,命令按钮Command1(开始游戏),三个定时器Timer1(控制轨道小球运动)、Timer2(控制发球向上运动)、Timer3(控制发球向下运动),向Pb中添加图像框Ball(发球图案)、图像框数组元素Balls1(0)、Balls2(0)分别表示上、下轨道运动的小球,两天直线Line1、Line2(用来形成轨道)。设置所有球的Enabel属性为False,合理布局,参考程序运行图3。
二、程序代码
1、变量定义
Dim Num As Integer ’串球数量
Dim Games As Integer ’关数最大为10
Dim Color As Integer ’球的颜色数
Dim Bs As Integer ’发球速度
Dim GameRun As Boolean ’游戏状态
Dim Score As Integer ’成绩
2、程序初始化
Private Sub Form_Load()
’读取游戏关数,用VB的GetSetting函数从注册表中读取
Games = GetSetting(App.EXEName, App.Title, "Level", "1")
Num = Pb.Width \ Balls1(0).Width + 1
For i = 1 To Num ’加载控件
Load Balls1(i): Load Balls2(i)
Next
End Sub
3、游戏初始化,完成轨道小球的初始位置
Sub InitGame()
Randomize
Color = 3 + Games \ 3
For i = 0 To Num ’生成轨道串球
Balls1(i).Picture = Image1(Int(Rnd * Color)).Picture
If i > 0 Then Balls1(i).Left = Balls1(i - 1).Left + Balls1(0).Width
Balls1(i).Visible = False
’下轨道小球位置控制代码略
Next
Ball.Picture = Image1(Int(Rnd * Color)).Picture
Ball.Visible = True ’发球图案
End Sub
4、游戏开始
Private Sub Command1_Click()
Call InitGame
Timer1.Enabled = True
End Sub
5、轨道小球运动
Private Sub Timer1_Timer()
’注:下轨道小球运动代码略
If Balls1(0).Left > 0 And Balls2(0).Left > 0 Then
’移动速度Ms1控制,代码略
Balls1(0).Left = Balls1(0).Left - Ms1
For i = 1 To Num ’其它球随移
Balls1(i).Left = Balls1(i - 1).Left + Balls1(0).Width
Next
Else ’移到最左边
’停止游戏,并作未过关处理
End If
End Sub
6、确定发球的水平位置
Private Sub Pb_MouseMove(Button, Shift, X, Y)
’发出的小球在运动时不处理
If Timer2.Enabled = True Or Timer3.Enabled = True Then Exit Sub
’根据鼠标位置确定发出的水平位置
Ball.Left = X - Ball.Width \ 2
’超出游戏区域左边界的处理
If Ball.Left < 0 Then Ball.Left = 0
’右边界的处理,代码略
End Sub
7、发球控制
Private Sub Pb_MouseDown(Button, Shift, X, Y)
’根据鼠标位置确定发球运动方向
If Y <= Pb.Height \ 2 Then
Md = -1 ’向上
Else
Md = 1 ’向下
End If
’根据鼠标离发球位置的距离确定发出小球的运动速度
Bs = Abs(Y - Pb.Height \ 2) \ 15
If GameRun = True Then
’向上运动
If Md = -1 And Timer2.Enabled = False Then Timer2.Enabled = True
’向下运动,代码略
End If
End Sub
8、发球向上运动
Private Sub Timer2_Timer()
If Ball.Top > Line1.Y1 Then ’上升
If Ball.Top - Bs <= Line1.Y1 Then ’到顶
’暂停游戏,代码略
Ball.Top = Line1.Y1
K = -1 ’确定插入位置
For i = 0 To Num
’发球水平对称线
p = Ball.Left + Ball.Width \ 2
If … Then ’判断在哪个球,条件略
If … Then ’在左侧,条件略
K = i
Else
K = i + 1
End If
Exit For
End If
Next
If K >= 0 Then ’能碰撞
’产生音效
If Dir("pop.wav") <> "" Then sndPlaySound "pop.wav", &H0 Or &H1
’插入位置的小球依次后移
For s = Num To K + 1 Step -1
Balls1(s).Picture = Balls1(s - 1).Picture
Next
Balls1(K).Picture = Ball.Picture ’插入
’找消失的左右位置V1、V2,代码略
If V2 - V1 + 1 >= 3 Then ’有三个
’计分,代码略
’过关及结束处理,代码略
’消失的小球闪烁,代码略
’消失相连小球,代码略
’所有小球后退(V2-V1+1)个小球位置,代码略
’向前填充直到V1处图像非空
While Balls1(V1).Picture = LoadPicture("")
’填充,代码略
Wend
End If
End If
’继续游戏,代码略
Else ’向上运动
Ball.Top = Ball.Top - Bs
End If
End If
End Sub
9、发球向下运动
Private Sub Timer3_Timer()
’代码略
End Sub
【编程后记】
为了降低编程难度,本文采用了直线轨道,且用双轨道增加游戏难度,同时发球运动方向限制在垂直方向。游戏每关轨道上运动的速度逐步加快增加难度,同时根据鼠标纵向位置确定发球运动速度。在游戏过关时用SaveSetting函数保存游戏关数,下次可接着游戏玩。
|
|