添加全局变量记录食物的位置:
Dim Shared As Long food_i,food_j '食物的位置
在startup()函数中初始化食物的位置:
Sub startup(gg As yGDI) '初始化函数
Randomize
food_i = Rnd * (BLOCK_HEIGHT -5) + 2 ' 初始化随机食物位置
Randomize
food_j = Rnd * (BLOCK_WIDTH -5) + 2
在show()函数中在食物位置处绘制一个绿色的小方块:
Sub show(gg As yGDI) '绘制函数
gg.Brush BGR(0, 178, 0) '食物颜色为绿色
gg.DrawFrame food_j *BLOCK_SIZE, food_i *BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE ' 绘制食物小方块
程序运行后输出如图7-9所示。

当新蛇头碰到食物时,只需保留原蛇尾,不将最大值变为0,即可让蛇的长度加1,如图7-10所示。

在moveSnake()函数中修改代码,当吃到食物时,食物位置重新随机出现,蛇长度加1;当没有吃到食物时,旧蛇尾变成空白,蛇长度保持不变。
Blocks(newHead_i, newHead_j) = 1 ' 新蛇头位置数值为1
If food_j = newHead_j And food_i = newHead_i Then '如果新蛇头正好碰到食物
Randomize
food_i = Rnd * (BLOCK_HEIGHT -5) + 2 ' 初始化随机食物位置
Randomize
food_j = Rnd * (BLOCK_WIDTH -5) + 2
'不对旧蛇尾处理,相当于蛇的长度+1
Else '新蛇头没有碰到食物
Blocks(oldTail_i, oldTail_j) = 0 ' 旧蛇尾变成空白,不吃食物时蛇的长度保持不变
End If

完整代码
#define BLOCK_HEIGHT 17 ' 高度上一共30个小格子
#define BLOCK_WIDTH 27 ' 宽度上一共40个小格子
#define BLOCK_SIZE 15 ' 每个小格子的长宽大小
'全局变量定义
Dim Shared Blocks(BLOCK_HEIGHT -1, BLOCK_WIDTH -1) As Long ' 二维数组,用于记录所有的游戏数据
Dim Shared isFailure As Long '是否游戏失败
Dim Shared As Long food_i,food_j '食物的位置
Sub startup(gg As yGDI) '初始化函数
Dim i As Long, j As Long
Blocks(BLOCK_HEIGHT / 2, Int(BLOCK_WIDTH / 2)) = 1 '画面中间画蛇头,数字为1
For i = 1 To 4
Blocks(BLOCK_HEIGHT / 2, Int(BLOCK_WIDTH / 2) - i) = i + 1 '向左依次4个蛇身,数值依次为2、3、4、5
Next
gg.Pen 1, BGR(255, 255, 255)
Randomize
food_i = Rnd * (BLOCK_HEIGHT -5) + 2 ' 初始化随机食物位置
Randomize
food_j = Rnd * (BLOCK_WIDTH -5) + 2
End Sub
Sub show(gg As yGDI) '绘制函数
gg.Cls
Dim i As Long, j As Long
'对二维数组所有元素遍历
For i = 0 To BLOCK_HEIGHT -1
For j = 0 To BLOCK_WIDTH -1
If Blocks(i, j) > 0 Then
gg.Brush HSBtoRGB_Gdi(HSB(Blocks(i, j) * 10, 90, 100, 255)) '根据元素值设定填充颜色
Else
gg.Brush BGR(165, 165, 165) 'GDI的颜色值。
End If
gg.DrawFrame j *BLOCK_SIZE, i *BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE
Next
Next
gg.Brush BGR(0, 178, 0) '食物颜色为绿色
gg.DrawFrame food_j *BLOCK_SIZE, food_i *BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE ' 绘制食物小方块
If isFailure Then
gg.Font "黑体", 50, True
gg.SetColor BGR(204, 0, 0) 'GDI的颜色值。
gg.DrawString 60, 50, "游戏失败"
End If
gg.Redraw
End Sub
Sub moveSnake(moveDirection As String) ' 移动小蛇及相关处理函数
Dim i As Long, j As Long
For i = 0 To BLOCK_HEIGHT -1 '对行遍历
For j = 0 To BLOCK_WIDTH -1 '对列遍历
If Blocks(i, j) > 0 Then '大于0的为小蛇元素
Blocks(i, j) += 1 '让其+1
End If
Next
Next
Dim As Long oldTail_i, oldTail_j, oldHead_i, oldHead_j '定义变量,存储旧蛇尾、旧蛇头坐标
Dim mm As Long '用于记录最大值
For i = 0 To BLOCK_HEIGHT -1 '对行遍历
For j = 0 To BLOCK_WIDTH -1 '对列遍历
If mm < Blocks(i, j) Then '如果当前元素值比max大
mm = Blocks(i, j) '更新max的值
oldTail_i = i ' 记录最大值的坐标,就是旧蛇尾的位置
oldTail_j = j
End If
If Blocks(i, j) = 2 Then '找到数值为2
oldHead_i = i ' 数值为2恰好是旧蛇头的位置
oldHead_j = j '
End If
Next
Next
Dim newHead_i As Long = oldHead_i ' 设定变量存储新蛇头的位置
Dim newHead_j As Long = oldHead_j
If (moveDirection = "左") Then
newHead_j = oldHead_j -1 ' 向左移动
ElseIf (moveDirection = "右") Then
newHead_j = oldHead_j + 1 '向右移动
ElseIf (moveDirection = "上") Then
newHead_i = oldHead_i -1 ' 向上移动
ElseIf (moveDirection = "下") Then
newHead_i = oldHead_i + 1 ' 向下移动
End If
Print newHead_j, BLOCK_WIDTH
'当小蛇碰到画面边界时
If newHead_i >= BLOCK_HEIGHT Or newHead_i < 0 Or newHead_j >= BLOCK_WIDTH Or newHead_j < 0 Then
isFailure = 1
Return
End If
'当蛇头与蛇自身发生碰撞时
If Blocks(newHead_i, newHead_j) > 0 Then
isFailure = 1
Return
End If
Blocks(newHead_i, newHead_j) = 1 ' 新蛇头位置数值为1
If food_j = newHead_j And food_i = newHead_i Then '如果新蛇头正好碰到食物
Randomize
food_i = Rnd * (BLOCK_HEIGHT -5) + 2 ' 初始化随机食物位置
Randomize
food_j = Rnd * (BLOCK_WIDTH -5) + 2
'不对旧蛇尾处理,相当于蛇的长度+1
Else '新蛇头没有碰到食物
Blocks(oldTail_i, oldTail_j) = 0 ' 旧蛇尾变成空白,不吃食物时蛇的长度保持不变
End If
End Sub
Sub updateWithoutInput(moveDirection As String) '与输入无关的更新
If isFailure Then Return
Static waitIndex As Long = 1 ' 静态局部变量,初始化时为1
waitIndex += 1 '每一帧+1
If waitIndex =10 Then '等于10才执行,这样小蛇每隔10帧移动一次
moveSnake(moveDirection) '调用小蛇移动函数
waitIndex =1 '再变成1
End If
Sleep 10 '暂停若干毫秒
End Sub
Sub updateWithInput(moveDirection As String) ' 和输入有关的更新
If isFailure Then Return
If IsKeyPress(&H57) Then
moveDirection = "上"
ElseIf IsKeyPress(&H53) Then
moveDirection = "下"
ElseIf IsKeyPress(&H41) Then
moveDirection = "左"
ElseIf IsKeyPress(&H44) Then
moveDirection = "右"
End If
End Sub
Sub 游戏执行过程(hWndForm As hWnd)
Dim gg As yGDI = hWndForm
startup(gg) '初始化函数,仅执行一次
Dim moveDirection As String ="右" '小蛇移动方向
Do
show(gg) ' 进行绘制
updateWithInput(moveDirection) ' 和输入有关的更新
updateWithoutInput(moveDirection) ' 和输入无关的更新
Loop
End Sub
评论一下?