1、vb 俄罗斯方块设计程序及分析* 俄罗斯方块DIY * 键盘控制方法:1.左右光标键控制方块左右移动;2.上光标键控制方块顺时针旋转90度;3.下光标键控制方块加速向下移动。设计过程:(一) 在VB6.0中新建一个标准EXE工程(二) 建立一个窗体,窗体属性设置如下: 名称 = frmErs Caption = 俄罗斯方块1.12(三) 在窗体上添加两个图片框,属性设置如下: (1)名称 = picPlay AutoRedraw = TrueBackColor= &H00FF0000&蓝色 (2)名称 = picNext AutoRedraw = TrueBackColor= &H00FF00
2、00&蓝色(四) 在窗体上再添加一个标签,属性设置如下: 名称 = lblFenShu (五) 用菜单编辑器制作如下菜单: (1)一级菜单项:标题 = 文件(&F)名称 = mnuSet 下属二级菜单项:标题 = 退出名称 = mnuExit (2)一级菜单项:标题 = 帮助(&H)名称 = mnuHelp 下属二级菜单项:标题 = 操作提示名称 = mnuTopic(六) 在窗体代码窗口输入如下代码:Option ExplicitPrivate Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)按键代码传入Main()主程序中gKey
3、Ref = KeyCodeEnd SubPrivate Sub Form_Load()Me.Top=0Me.KeyPreview = TruepicPlay.ScaleMode = 3PixelpicNext.ScaleMode = 3PixelEnd SubPrivate Sub Form_Unload(Cancel As Integer)EndEnd SubPrivate Sub mnuExit_Click()退出Unload MeEnd SubPrivate Sub mnuTopic_Click()Dim Msg As StringMsg = 键盘控制方法: & vbCrLfMsg =
4、Msg & 1.左右光标键控制方块左右移动; & vbCrLfMsg = Msg & 2.上光标键控制方块顺时针旋转90度; & vbCrLfMsg = Msg & 3.下光标键控制方块加速向下移动。 & vbCrLf & vbCrLfMsg = Msg & 福建南平 梁远海 20000年10月提供 & vbCrLfMsg = Msg & E-Mail: dayangMsgBox Msg, vbOKOnly + vbQuestion, Me.CaptionEnd SubPrivate Sub picPlay_KeyDown(KeyCode As Integer, Shift As Intege
5、r)按键代码传入Main()主程序中gKeyRef = KeyCodeEnd Sub(七) 添加一个新模块moudel1,并输入如下代码:Option ExplicitPublic gKeyRef As Integer 游戏操作按键码值全局变量Dim mErsBar(0 To 8) As Long 俄罗斯方块形状定义,数组下标分配如下:+-+-+-+| 0 | 1 | 2 |+-+-+-+| 7 | 8 | 3 |+-+-+-+| 6 | 5 | 4 |+-+-+-+ 之所以这样定义,是为了方便方块类型设置和旋转判断 数组元素取值为:是空白 = 0,是方块构件 = 1Dim mErsPD(2,
6、 2) As Long 将二维坐标系转化为mErsBar()对应下标,以进行方块移动的判断 数组元素取值如下:mErsPD mErsPD mErsPD(0, 0)=0 (1, 0)=1 (2, 0)=2(0, 1)=7 (1, 1)=8 (2, 1)=3(0, 2)=6 (1, 2)=5 (2, 2)=4 应用样式:If mErsBar(mErsPD(x,y) = 0 Then .Dim mPlayWindow()As Long 运动小窗口的屏幕状况数组 数组大小在子程序NewSatrt()中根据mPlayKuan,mPlayGao的值重定义 即 ReDim mPlayWindow(-1 To
7、 mPlayKuan + 2, 1 To mPlayGao + 2) As Long 取上面的下标范围是为了方块运动判断设计上的方便, 方块实际运动范围在(1,1)-(mPlayKuan,mPlayGao)之间 数组元素取值为:是空白 = 0,是方块构件 0,初始值 = -9Dim mPlayKuan As Long, mPlayGao As Long 运动小窗口的相对宽度(容纳方块小构件的列数)和相对高度(容纳方块小构件的行数)Dim mPlayMovX As Long, mPlayMovY As Long 运动小窗口内方块移动中所处位置的左上角相对坐标Dim mPlayX_SIZE As
8、Long, mPlayY_SIZE As Long 运动小窗口内方块小构件实际宽度和高度Dim mPlayBkColor As Long 运动小窗口背景色Dim mNextX_SIZE As Long, mNextY_SIZE As Long 预览小窗口内方块小构件实际宽度和高度Dim mNextBkColor As Long 预览小窗口背景色Private Sub BarDef(ByVal k As Long)定义方块形状子程序Dim j As LongDim a1 As Long, a2 As LongDim a3 As Long, a4 As LongFor j = 0 To 8: mE
9、rsBar(j) = 0: Next jSelect Case kCase 0 长条a1 = 0: a2 = 2: a3 = -1: a4 = -1Case 1 小块1*1a1 = 1: a2 = 1: a3 = -1: a4 = -1Case 2 7字a1 = 0: a2 = 2: a3 = 7: a4 = 7Case 3 反7字a1 = 0: a2 = 3: a3 = -1: a4 = -1Case 4 凹字a1 = 0: a2 = 3: a3 = 7: a4 = 7Case 5 凸字a1 = 0: a2 = 2: a3 = 8: a4 = 8Case 6 2字a1 = 1: a2 = 1
10、: a3 = 6: a4 = 8Case 7 反2字a1 = 1: a2 = 2: a3 = 7: a4 = 8Case 8 墙角a1 = 1: a2 = 3: a3 = -1: a4 = -1Case 9田字a1 = 0: a2 = 1: a3 = 7: a4 = 8Case Else 大块3*3(有出现即类型序号超出k值)a1 = 0: a2 = 8: a3 = -1: a4 = -1End SelectFor j = a1 To a2: mErsBar(j) = 1: Next jIf a3 -1 And a4 -1 Then For j = a3 To a4: mErsBar(j) =
11、 1: Next jEnd IfEnd SubPrivate Sub BarViewPlay(ByVal BarMode As Long)在运动小窗口内显示或消隐方块的子程序Dim i As Long, j As LongFor i = 0 To 2For j = 0 To 2 If mErsBar(mErsPD(j, i) = 1 ThenCall SmallBarPlay(mPlayMovX + j, mPlayMovY + i, BarMode)mPlayWindow(mPlayMovX + j, mPlayMovY + i) = BarMode End IfNext jNext iEn
12、d SubPrivate Sub BarViewNext(ByVal BarMode As Long)在预览小窗口内展现下一轮方块的子程序Dim i As Long, j As LongFor i = 0 To 2清除旧方块For j = 0 To 2 Call SmallBarNext(j + 2, i + 2, 0)Next jNext iFor i = 0 To 2显示新方块For j = 0 To 2 If mErsBar(mErsPD(j, i) = 1 ThenCall SmallBarNext(j + 2, i + 2, BarMode) End IfNext jNext iEn
13、d SubSub Delay(ByVal dd As Double) 延时子程序 Dim tt As Double tt = Timer + dd Do: Loop Until Timer = ttEnd SubPrivate Sub LineTestAndClear(CleanToTal As Long)方块停止下落后对各行是否积满进行测试和作相应处理的子程序Dim x As LongDim y As LongDim y1 As LongDim ValTmp As LongDim Count As LongDim CleanAdd As LongDim tt As LongDim UpPD
14、As LongDim DownPD As LongDim MinBetween As LongDim PW() As LongCleanAdd = 0y = mPlayGao统计每行方块构件数并作相应处理的两个步骤:Do步骤之一:统计本行已容纳的方块构件数 Count = 0 For x = 1 To mPlayKuanIf mPlayWindow(x, y) 0 Then Count = Count + 1 Next x步骤之二:如果本行积满则分三小步处理: If Count = mPlayKuan Then第一步:行积满计数CleanAdd = CleanAdd + 1第二步:上方各行向下
15、搬移If y 1 Then For y1 = y To 2 Step -1For x = 1 To mPlayKuan ValTmp = mPlayWindow(x, y1 - 1) Call SmallBarPlay(x, y1, ValTmp) mPlayWindow(x, y1) = ValTmpNext x Next y1 y = y + 1End If第三步:清除顶行冗余For x = 1 To mPlayKuan Call SmallBarPlay(x, 1, 0) mPlayWindow(x, 1) = 0Next xDoEvents End If y = y - 1Loop U
16、ntil y 0 ThenCall LocMe(PW(), x, y, -1) End If Next x步骤之三:从找到的第一个悬空方块构件出发遍历所有与本构件相邻的构件并标记为-2 tt = 0 For y = mPlayGao - 1 To 1 Step -1For x = 1 To mPlayKuan If PW(x, y) 0 ThenCall LocMe(PW(), x, y, -2)tt = -1Exit For End IfNext xIf tt = -1 Then Exit For Next y 步骤之四:没有悬空方块则退出循环 If tt -1 Then Exit Do 步
17、骤之五:计算标记为-2的悬空方块与下方的方块的最小垂直距离MinBetween MinBetween = mPlayGao For x = 1 To mPlayKuanUpPD = 0For y = mPlayGao - 1 To 1 Step -1 If PW(x, y) = -2 Then UpPD = y: Exit ForNext yIf UpPD 0 Then DownPD = mPlayGao + 1 For y = UpPD + 1 To mPlayGao If PW(x, y) = -1 Or PW(x, y) 0 Then DownPD = y: Exit For Next
18、y ValTmp = DownPD - UpPD - 1 If ValTmp 0 And ValTmp 0) Then Exit Subtt = 0Do If y 1 Then y = y - 1: GoSub Loc1: y = y + 1 If x mPlayKuan Then x = x + 1: GoSub Loc1: x = x - 1 If y 1 Then x = x - 1: GoSub Loc1: x = x + 1 If tt = 0 Then PW(x, y) = NumVal: Exit Do tt = tt - 1 x = DingWei(tt, 1) y = Din
19、gWei(tt, 2)LoopExit SubLoc1:If PW(x, y) 0 Then PW(x, y) = NumVal DingWei(tt, 1) = x DingWei(tt, 2) = y tt = tt + 1End IfReturnEnd SubPrivate Sub Main()主程序Dim Speed As Double方块运动速度控制Dim iKey As Integer按键代码Dim FenShu As Long 计算得分Dim CleanToTal As Long 本轮积满而被清除的行数统计Dim BarMode As Long方块显示模式Dim k1 As Lo
20、ng 本轮将出现的方块类型序号Dim k2 As Long 下一轮将出现的方块类型序号Dim DefColor As Long 标签前景色Dim StrMsg As String 标签信息Dim Ref As Integer 游戏结束对话框返回值frmErs.ShowRESTART:游戏开始FenShu = 0CleanToTal = 0GoSub JiFenmPlayKuan = 12 方块运动小窗口的宽度(列数)设置(建议 6=mPlayKuan=50)mPlayGao = 19方块运动小窗口的高度(行数)设置(建议 6=mPlayGao=50)Call NewStartRandomize
21、 Timer 方块类型有10种,序号为0-9,在BarDef()子程序中定义k2 = Int(Rnd * 10)Dok1 = k2k2 = Int(Rnd * 10)BarMode = Int(Rnd * 3) + 1Call BarDef(k2)定义下一轮方块Call BarViewNext(BarMode)预览下一轮方块Call BarDef(k1)定义本轮方块mPlayMovX = (mPlayKuan + 1) 2mPlayMovY = 1If MovDownTest() = False Then Exit DogKeyRef = 0Do Call BarViewPlay(BarMode) 显现本轮方块 Speed = Timer + 0.4 DoDoEvents 以便从frmErs的键盘事件中传回按键代码gKeyRefiKey = gKeyRefIf iKey 0 Then gKeyRef = 0 Select Case iKey Case vbKeyLeft 左光标键Call BarViewPlay(0)If MovLeftTest() = Tru
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1