使用VB创建贪吃蛇

       贪吃蛇作为一个经典游戏,在其开发成功后,有很长一段时间令很多人为之振奋,但随着时间的流逝,贪吃蛇也逐渐淡出人们的视野。本次,我利用VB重现贪吃蛇的创建。主要使用到的控件:Label标签,Command按钮,Timer控件。

以下为创建过程:

贪吃蛇作为一个游戏来说,主要分为6个部分:

  1. 地图创建部分;
  2. 地图坐标初始化部分;
  3. 食物创建部分;
  4. 贪吃蛇创建部分;
  5. 贪吃蛇移动控制部分;
  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

如此,贪吃蛇就创建成功了。如下图:

posted @ 2017-02-04 22:17  onedayismway  阅读(906)  评论(0编辑  收藏  举报