代码建议给变量,函数,类命名的时候尽量规范一些
贪吃蛇用到的算法中两个关键的地方:
1:用数组或者其他数据结构保存蛇身体的位置,当蛇向前移动的时候,要注意迭代的关系。
2:当下达移动命令的时候,是改变了它下次移动的方向,而不是现在立刻就移动。
下面是代码
Public Class 贪吃蛇
Dim MySnake As Snake
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If MySnake IsNot Nothing Then
MySnake.ChangeDirection(e) '蛇改变方向
End If
End Sub
Private WithEvents Mytimer As New Timer With {.Enabled = False, .Interval = 50} '设置一个timer控件变量并且用来接收事件
Sub tick() Handles Mytimer.Tick '时间到了之后
PictureBox1.Image = MySnake.MyBitmap '显示对象里面的图片
End Sub
Private Sub 开始ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 开始ToolStripMenuItem.Click
MySnake = New Snake
Mytimer.Enabled = True '开始菜单点击之后就开始游戏了]
End Sub
End Class
Public Class Snake '蛇类
'基于坐标系系统
Private MyWidth As Integer = 100 '图片的宽度
Private MyHeight As Integer = 100 '长度
Public MyBitmap As New Bitmap(MyWidth, MyHeight) '定义图片变量,大小是100*100
Private MyGraphics As Graphics '定义绘图场景对象
Private sound As New System.Media.SoundPlayer(My.Resources.吃苹果) '声音对象,从资源文件中加载
Public Counter As Integer = 0
Private Enum 方向 '蛇的方向的枚举,上下左右
上
下
左
右
End Enum
Private m_count As Integer
Private Property Count() As Integer '蛇的长度,以个为单位
Get
Return m_count
End Get
Set(value As Integer)
m_count = value
End Set
End Property
Private m_Direction As 方向 '私有变量,当前方向
Private Event 改变方向()
''' <summary>
''' '方向属性
''' </summary>
''' <returns></returns>
Private Property Direction() As 方向 '只有当改变的方向和当前方向垂直,才会发生方向的变化
Get
Return m_Direction
End Get
Set(ByVal value As 方向)
If value = 方向.上 Or value = 方向.下 Then
If m_Direction = 方向.右 Or m_Direction = 方向.左 Then
m_Direction = value
'RaiseEvent 改变方向()
End If
End If
If value = 方向.右 Or value = 方向.左 Then
If m_Direction = 方向.上 Or m_Direction = 方向.下 Then
m_Direction = value
'RaiseEvent 改变方向()
End If
End If
End Set
End Property
Private m_location() As Point '点属性
Private Property Location(index As Integer) As Point '点坐标
Get
Return m_location(index)
End Get
Set(ByVal value As Point)
If value.X = MyWidth Then value.X = 0 '这里设置了当蛇到达边界之后就会到另一边,和手机上的贪吃蛇差不多的效果
If value.Y = MyHeight Then value.Y = 0
If value.X = -5 Then value.X = MyWidth - 5
If value.Y = -5 Then value.Y = MyHeight - 5
m_location(index) = value
End Set
End Property
Private Sub StepOne() '走一步
EVERchange = True
If Location(0) = MyApple.site Then '如果碰到了苹果,那么长度+1,播放声音
Counter += 1 '分数/?
sound.Play()
Count += 1
ReDim Preserve m_location(Count - 1) '重新定义数组,
For i As Integer = Count - 2 To 0 Step -1 '迭代数组的位置,把苹果的点给第一个数组元素,然后其他元素往后退
Location(i + 1) = Location(i)
Next
' If Location(Count - 1).X = 0 Then Stop '这个是调试的时候用的额
Location(0) = MyApple.site '
RaiseApple() '生成新的苹果
Else
For i As Integer = Count - 1 To 1 Step -1 '如果没有碰到苹果那么也是让第一个元素往前前进一步,去掉最后一个元素,然后迭代赋值
Location(i) = Location(i - 1)
Next
Location(0) = HeadSite
End If
Dim over As Boolean = False
For i As Integer = 4 To Count - 1 '遍历蛇的每个方块,如果咬到了自己就会游戏结束
If Location(0) = Location(i) Then
myTimer.Enabled = False
over = True
End If
Next
If over = True Then
MessageBox.Show("游戏结束,总分数是" & CStr(Counter))
Else
DrawSnakeAndApple()
End If
End Sub
Private ReadOnly Property HeadSite As Point '调转方向之后只是产生新的位置并没有真正移动过去'为了防止在按键的时候产生会加快速度
Get
Dim tempPoint As Point = m_location(0)
Select Case Direction
Case 方向.上
tempPoint.Y = m_location(0).Y - 5
Case 方向.下
tempPoint.Y = m_location(0).Y + 5
Case 方向.左
tempPoint.X = m_location(0).X - 5
Case 方向.右
tempPoint.X = m_location(0).X + 5
End Select
Return tempPoint
End Get
End Property
Private Sub GameOver() '如果游戏结束就会弹出提示框提示游戏结束
MessageBox.Show("游戏结束")
End Sub
Private Sub DrawSnakeAndApple() '画所有的蛇和苹果和背景
MyGraphics = Graphics.FromImage(MyBitmap) '绘图场景是图片属性,那么对绘图场景的操作就会体现在位图上
MyGraphics.Clear(Color.FromArgb(255, 127, 39))
For i As Integer = 0 To Count - 1 'fillrectangle方法可以填充一个矩形
MyGraphics.FillRectangle(Brushes.Black, New Rectangle(m_location(i), New Size(5, 5)))
Next
MyGraphics.DrawImage(My.Resources.苹果, MyApple.site.X, MyApple.site.Y, MyApple.Size.Width, MyApple.Size.Height)
End Sub
Sub New() '实例化的时候(构造函数)
RaiseApple() '生成一个新的苹果
ReDim m_location(2) '蛇的位置,大小是3
m_location(0) = New Point(6 * 10, 65)
m_location(1) = New Point(6 * 10, 70)
m_location(2) = New Point(6 * 10, 75)
m_count = 3
DrawSnakeAndApple() '画图
End Sub
Private MyApple As apple '定义一个苹果对象
Private UsableLoction() As Point '可用的点,就是当前没有蛇的位置
Private Function GetUsableLoction() As Point '私有方法,获得空的位置
Dim find As Boolean
Dim x As Integer
Dim y As Integer
Do
find = False
x = CInt(Rnd() * (MyWidth \ 5 - 2) + 1) * 5
y = CInt(Rnd() * (MyWidth \ 5 - 2) + 1) * 5
For i As Integer = 0 To Count - 1
If New Point(x, y) = Location(i) Then
find = True
End If
Next
Loop Until find = False '随机生成一个位置,如果位置可用就不再生成,否则就循环生成下去,如果采用找出所有点的方法,那么就会遍历很多空格,占用了内存很多
Return New Point(x, y) '函数返回xy坐标
End Function
Private Sub RaiseApple() '生成一个新的苹果
MyApple = New apple With {.site = GetUsableLoction(), .Size = New Size(5, 5)}
End Sub
Private WithEvents myTimer As New Timer With {.Enabled = True, .Interval = 150} '计时器接收事件
Private Sub tick() Handles myTimer.Tick
StepOne()
End Sub '到时间就会走一步
Private EVERchange As Boolean = False '这个是当蛇走一步才响应改变方向
Public Sub ChangeDirection(e As KeyEventArgs) '改变方向的事件
If EVERchange = True Then '如果上一步是用户点击了改变方向,那么就会触发事件,为了避免频繁的改变方向
Select Case e.KeyCode
Case Keys.Up
Direction = Snake.方向.上
Case Keys.Down
Direction = Snake.方向.下
Case Keys.Left
Direction = Snake.方向.左
Case Keys.Right
Direction = Snake.方向.右
End Select
End If
EVERchange = False
End Sub
End Class
Public Class apple '苹果类
Private m_Site As Point
Public Property site() As Point '坐标
Get
Return m_Site
End Get
Set(ByVal value As Point)
m_Site = value
End Set
End Property
Private M_Size As Size '大小,暂时没用
Public Property Size() As Size
Get
Return M_Size
End Get
Set(ByVal value As Size)
M_Size = value
End Set
End Property
End Class
这里用到了一些图片资源,可以参看如何使用vs提供的图片资源编辑器。vb.net使用图片资源和图片编辑器的方法