使用VB创建贪吃蛇
贪吃蛇作为一个经典游戏,在其开发成功后,有很长一段时间令很多人为之振奋,但随着时间的流逝,贪吃蛇也逐渐淡出人们的视野。本次,我利用VB重现贪吃蛇的创建。主要使用到的控件:Label标签,Command按钮,Timer控件。
以下为创建过程:
贪吃蛇作为一个游戏来说,主要分为6个部分:
- 地图创建部分;
- 地图坐标初始化部分;
- 食物创建部分;
- 贪吃蛇创建部分;
- 贪吃蛇移动控制部分;
- 贪吃蛇吃食物身体变化部分。
在创建之前,我们需要为我们需要的变量进行定义:
1 Private MapXy(4900) As xy '用于存放全部的地图坐标,这里以70*70为例 2 Private Snake() As xy '用于存放蛇的身体及头的坐标 3 Private SnakeLength As Long '用于存放蛇身体长度 4 Private wbtemp As xy '用于存放尾巴坐标及类型 5 Private Food As xy '用于保存食物的坐标 6 Private Alive As Boolean'用于判断是否活着 7 Private MapColors As Long 8 Private SnakeHeadColors As Long 9 Private SnakeBodyColors As Long 10 Private FoodColors As Long 11 Private MapCol As Long 12 Private MapTotal As Long 13 Private Key As Integer
地图的创建:
1 Private Function CreateMap(ByVal TotalNum As Long, ByVal ColNum As Long, ByVal MapInitColor As Long) As Boolean 'Create the game map,if create success then return true,else return false 2 On Error Resume Next 3 Dim i As Long 4 If TotalNum <= 2 Then 5 CreateMap = False 6 Exit Function 7 Else 8 Map(1).BackColor = MapInitColor '初始颜色 9 For i = 2 To TotalNum '创建了70*70的区域 10 DoEvents 11 Load Map(i) 12 Map(i).Width = Map(i - 1).Width 13 Map(i).Visible = True 14 If (i - ColNum - 1) Mod ColNum = 0 Then 15 Map(i).Top = Map(i - 1).Top + Map(1).Height + 1 16 Map(i).Left = Map(1).Left 17 Else 18 Map(i).Top = Map(i - 1).Top 19 Map(i).Left = Map(i - 1).Left + Map(1).Width + 1 20 End If 21 22 Next 23 CreateMap = True 24 End If 25 End Function
地图坐标初始化:
1 Private Sub MapXyInit() '地图坐标初始化 2 Dim i As Integer 3 For i = 1 To MapTotal 4 MapXy(i).lx = 0 '0是无障碍,1是障碍(包含蛇自身),2是食物 5 MapXy(i).X = Fix(i / (1 + MapCol)) + 1 'x坐标是除数+1 6 MapXy(i).Y = i - (MapXy(i).X - 1) * MapCol 'y做差 7 Map(i).BackColor = MapColors 8 Next 9 End Sub
创建食物Food:
1 Sub CreatFood() '创建食物 2 3 Randomize 4 a: 5 Food.X = Int(Rnd() * (MapCol - 1 + 1) + 1) '这是food的x坐标:1-MapCol 6 Food.Y = Int(Rnd() * (MapCol - 1 + 1) + 1) '这是food的y坐标:1-MapCol 7 8 If MapXy(((Food.X) - 1) * MapCol + Food.Y).lx = 1 Then '这里就以食物所在的位置是否为红就可以判断是不是在蛇身上 9 GoTo a 10 Else 11 MapXy(((Food.X) - 1) * MapCol + Food.Y).lx = 2 '表示创建了食物,类型是2 12 Map((((Food.X) - 1) * MapCol + Food.Y)).BackColor = FoodColors '食物的颜色是绿色 13 End If 14 15 End Sub
创建蛇:
1 Private Sub CreateSnake() '创建蛇自身 2 On Error Resume Next 3 SnakeLength = 1 4 ReDim Preserve Snake(SnakeLength) '重新定义蛇的长度 5 Randomize 6 Snake(SnakeLength).X = Int(Rnd() * (MapCol - 1 + 1) + 1) 7 Snake(SnakeLength).Y = Int(Rnd() * (MapCol - 1 + 1) + 1) 8 MapXy((Snake(SnakeLength).X - 1) * MapCol + Snake(SnakeLength).Y).lx = 1 '表示为有障碍 9 Map((Snake(SnakeLength).X - 1) * MapCol + Snake(SnakeLength).Y).BackColor = SnakeHeadColors 10 End Sub
蛇吃食物的身体变化:
1 Sub EatFood() '吃food的坐标变化 2 3 Dim i 4 5 Dim temp() As xy 6 7 If Snake(SnakeLength).X = Food.X And Snake(SnakeLength).Y = Food.Y Then '表示吃到食物 8 ReDim Preserve temp(SnakeLength + 1) '暂时存放 9 10 For i = 1 To UBound(Snake) 11 temp(i + 1) = Snake(i) 12 Next 13 14 temp(1) = wbtemp '将尾巴坐标置入 15 SnakeLength = SnakeLength + 1 16 ReDim Preserve Snake(SnakeLength) '重新改变长度 17 18 For i = 1 To SnakeLength 19 Snake(i) = temp(i) 20 Next 21 Call CreatFood 22 End If 23 24 End Sub
蛇身体的移动:
1 Private Function SnakeMove(a() As xy, b As xy) '这是蛇身体的移动 2 Dim i As Long 3 If UBound(a) > 1 Then 4 wbtemp = a(1) 5 Map((a(1).X - 1) * MapCol + a(1).Y).BackColor = MapColors '尾巴颜色黑 6 MapXy(((a(1).X - 1) * MapCol + a(1).Y)).lx = 0 7 For i = 1 To UBound(a) - 1 8 a(i) = a(i + 1) 9 Map((a(i).X - 1) * MapCol + a(i).Y).BackColor = SnakeBodyColors '尾巴红 10 Next 11 a(UBound(a)) = b 12 Map((b.X - 1) * MapCol + b.Y).BackColor = SnakeHeadColors '头颜色蓝 13 MapXy((b.X - 1) * MapCol + b.Y).lx = 1 14 Else '表明只有蛇头 15 wbtemp = a(UBound(a)) 16 Map((wbtemp.X - 1) * MapCol + (wbtemp.Y)).BackColor = MapColors '尾巴颜色黑 17 MapXy(((a(UBound(a)).X - 1) * MapCol + a(UBound(a)).Y)).lx = 0 18 a(UBound(a)) = b 19 Map((b.X - 1) * MapCol + b.Y).BackColor = SnakeHeadColors '头颜色蓝 20 MapXy((b.X - 1) * MapCol + b.Y).lx = 1 21 End If 22 EatFood 23 End Function
蛇在移动的前提下向上移动,这里注意墙和障碍物的定义,不能穿墙和穿越自己的身体:
1 Sub Move_Up() '向上移动 2 Dim g As xy 3 If Snake(SnakeLength).X > 1 Then 4 If MapXy((Snake(SnakeLength).X - 2) * MapCol + Snake(SnakeLength).Y).lx <> 1 Then 5 g.X = Snake(SnakeLength).X - 1 6 g.Y = Snake(SnakeLength).Y 7 SnakeMove Snake, g 8 Else 9 Alive = False 10 End If 11 12 Else 13 Alive = False 14 End If 15 16 End Sub
蛇向下移动:
1 Sub Move_Down() '向下移动 2 Dim g As xy 3 If Snake(SnakeLength).X < MapCol Then 4 If MapXy((Snake(SnakeLength).X) * MapCol + Snake(SnakeLength).Y).lx <> 1 Then 5 g.X = Snake(SnakeLength).X + 1 6 g.Y = Snake(SnakeLength).Y 7 SnakeMove Snake, g 8 Else 9 Alive = False 10 End If 11 12 Else 13 Alive = False 14 End If 15 16 End Sub
蛇向左移动:
1 Sub Move_Left() '向左移动 2 Dim g As xy 3 If Snake(SnakeLength).Y > 1 Then 4 If MapXy((Snake(SnakeLength).X - 1) * MapCol + Snake(SnakeLength).Y - 1).lx <> 1 Then 5 g.X = Snake(SnakeLength).X 6 g.Y = Snake(SnakeLength).Y - 1 7 SnakeMove Snake, g 8 Else 9 Alive = False 10 End If 11 12 Else 13 Alive = False 14 End If 15 16 End Sub
蛇向右移动:
1 Sub Move_Right() '向右移动 2 Dim g As xy 3 If Snake(SnakeLength).Y < MapCol Then 4 If MapXy((Snake(SnakeLength).X - 1) * MapCol + Snake(SnakeLength).Y + 1).lx <> 1 Then 5 g.X = Snake(SnakeLength).X 6 g.Y = Snake(SnakeLength).Y + 1 7 SnakeMove Snake, g 8 Else 9 Alive = False 10 End If 11 12 Else 13 Alive = False 14 End If 15 16 End Sub
下面给出一个70*70的地图下,贪吃蛇的初始定义实例:
在这里我们可以随便改变地图的颜色,蛇头的颜色,蛇身体的颜色,以及食物的颜色。
实例:
第一步:
1 Alive = True 2 MapColors = &HFF8080 '地图自己的颜色 3 SnakeHeadColors = vbBlue 4 SnakeBodyColors = vbRed 5 FoodColors = vbGreen 6 MapCol = 70 7 MapTotal = 4900 8 CreateMap MapTotal, MapCol, MapColors '创建地图 9 MapXyInit '地图坐标初始化 10 CreateSnake 11 CreatFood
第二步:
1 Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer) 2 Key = KeyCode 3 Select Case KeyCode 4 5 Case vbKeyA: 6 Move_Left 7 8 Case vbKeyD: 9 Move_Right 10 11 Case vbKeyW: 12 Move_Up 13 14 Case vbKeyS: 15 Move_Down 16 End Select 17 18 End Sub
这里的key是在接受键盘点击后的缓存,保证蛇在操作后有一个开始的方向,这位贪吃蛇游戏增加难度,如同给蛇一个初速度。
这里我们再使用时间控件,进行事件处理:
1 If SnakeLength <= 20 Then 2 Timer2.Interval = 900 3 End If 4 If SnakeLength > 100 Then 5 Timer2.Interval = 200 6 End If 7 If SnakeLength > 20 And SnakeLength <= 100 Then 8 Timer2.Interval = 500 9 End If 10 If Key <> 0 And Alive = True Then 11 Call Form_KeyDown(Key, 0) 12 End If
这里分别以蛇的长度作为速度的改变,20,100。
这基础之上,你还可以增加分数,例如我们使用时间控件,在事件中写入:
Label1.Caption = "Score:" & 90 + SnakeLength * 10 & " Length:" & SnakeLength
这就是在初始化得分100的前提下得分,并显示长度。
在此基础上一个完整的贪吃蛇就完成了。与一般不同的是,这个贪吃蛇的地图是label数组。移动全部在数组中。另外还需要我们定义一种新数据结构类型:
1 Type xy '二维坐标数据类型 2 X As Long 'x坐标 3 Y As Long 'y坐标 4 lx As Long '坐标的类型 5 End Type
如此,贪吃蛇就创建成功了。如下图: