当玩家把所有箱子推到目标位置时游戏胜利,如图9-6所示。

首先定义全局变量存储地图中目标位置的个数、完成目标的个数:
Dim Shared As Long targetNum,achievedNum '目标位置个数、完成目标个数
在startup()函数中对二维数组进行遍历,如果地图元素为target或achieved,则将目标个数targetNum加1:
Sub startup() '初始化函数
Dim i As Long, j As Long
targetNum = 0 ' 目标个数,初始为0
For i = 0 To B_NUM -1 '遍历关卡二维数组数据
For j = 0 To B_NUM -1
If Mid(level(i), j + 1, 1) = "p" Then '找到地图中player的位置
Players.i = i '设定player的位置
Players.j = j
Mid(level(i), j + 1, 1) = "e" '把地图元素变成空白empty
ElseIf Mid(level(i), j + 1, 1) = "t" Or Mid(level(i), j + 1, 1) = "a" Then ' 如果元素是target或achieved
targetNum += 1 '目标个数+1
End If
Next
Next
End Sub
在update( )函数中统计元素更新后的完成目标个数:
Dim i As Long, j As Long
achievedNum = 0 ' 完成目标个数,初始为0
For i = 0 To B_NUM -1 '遍历关卡二维数组数据
For j = 0 To B_NUM -1
If Mid(level(i), j + 1, 1) = "a" Then ' 如果元素是achieved
achievedNum += 1 '完成目标个数+1
End If
Next
Next
如果完成目标个数等于目标个数,在show( )函数中显示游戏胜利信息:
If (achievedNum = targetNum) Then ' 如果完成目标个数等于目标个数
gg.Font "黑体", 30
gg.SetColor BGR(0,255,255) 'GDI的颜色值。
gg.DrawString 15,100,"游 戏 胜 利"
End If
读者可以自己更改代码,看看是否和预料的结果一样。如果不同,自己试着排除错误。
完整代码如下:
Type Player ' 结构体,用于记录玩家位置
i As Long
j As Long
End Type
#define B_SIZE 32 ' 方块大小
#define B_NUM 8 ' 方块个数,一共8*8个方块
'用字符型二维数组存储地图数据
'e: empty w: wall t: target b: box a: achieved p:player
'全局变量定义
Dim Shared level(B_NUM -1) As ZString * B_NUM + 1 = {"wwwwwwww", "wwwtbeew", "weeeeeew", "weeeeeew", "weeeeeew", "weepaeew", "weeewwww", "wwwwwwww"}
Dim Shared Players As player '玩家全局变量
Dim Shared As Long targetNum, achievedNum '目标位置个数、完成目标个数
Sub startup() '初始化函数
Dim i As Long, j As Long
targetNum = 0 ' 目标个数,初始为0
For i = 0 To B_NUM -1 '遍历关卡二维数组数据
For j = 0 To B_NUM -1
If Mid(level(i), j + 1, 1) = "p" Then '找到地图中player的位置
Players.i = i '设定player的位置
Players.j = j
Mid(level(i), j + 1, 1) = "e" '把地图元素变成空白empty
ElseIf Mid(level(i), j + 1, 1) = "t" Or Mid(level(i), j + 1, 1) = "a" Then ' 如果元素是target或achieved
targetNum += 1 '目标个数+1
End If
Next
Next
End Sub
Sub show(gg As yGDI) '绘制函数
gg.Cls BGR(150, 150, 150) '灰色背景。
Dim i As Long, j As Long
For i = 0 To B_NUM -1 '遍历关卡二维数组数据
For j = 0 To B_NUM -1
If Mid(level(i), j+1, 1) = "e" Then 'empty元素是空白区域
gg.Pen 0, 0 '框
gg.Brush BGR(150, 150, 150) '绘制灰色地面
gg.DrawFrame j *B_SIZE, i *B_SIZE, B_SIZE, B_SIZE
ElseIf Mid(level(i), j+1, 1) = "w" Then 'wall元素是墙
gg.Pen 1, BGR(120, 120, 120) '框
gg.Brush BGR(155, 0, 0) '绘制淡红色、灰色线的方框
gg.DrawFrame j *B_SIZE, i *B_SIZE, B_SIZE, B_SIZE
ElseIf Mid(level(i), j+1, 1) = "b" Then 'box元素是可移动的箱子
gg.Pen 1, BGR(150, 150, 150) '框
gg.Brush BGR(255, 255, 0) '绘制一个黄色的方块
gg.DrawFrame j *B_SIZE, i *B_SIZE, B_SIZE, B_SIZE
ElseIf Mid(level(i), j+1, 1) = "t" Then 'target元素是目标
gg.Pen 0, 0 '框
gg.Brush BGR(255, 255, 255)
gg.DrawFrame(j + 0.25) *B_SIZE, (i + 0.25) *B_SIZE, B_SIZE * 0.5, B_SIZE * 0.5
ElseIf Mid(level(i), j+1, 1) = "a" Then 'achieved 元素是已完成目标
gg.Pen 0, 0 '框
gg.Brush BGR(255, 255, 0) '绘制一个黄色的方块
gg.DrawFrame j *B_SIZE, i *B_SIZE, B_SIZE, B_SIZE
gg.Pen 1, BGR(150, 150, 150) '框
gg.Brush BGR(255, 255, 255)
gg.DrawFrame(j + 0.25) *B_SIZE, (i + 0.25) *B_SIZE, B_SIZE * 0.5, B_SIZE * 0.5
ElseIf Mid(level(i), j+1, 1) = "p" Then 'player 元素是玩家,绘制一个人脸图案
End If
Next
Next
i = Players.i
j = Players.j
'一个红色圆脸
gg.Pen 0, 0 '框
gg.Brush BGR(255, 0, 0) '一个红色圆脸
gg.DrawEllipse(j + 0.1) *B_SIZE, (i + 0.1) *B_SIZE, B_SIZE * 0.8, B_SIZE * 0.8
'两个黑色眼睛
gg.Brush BGR(90, 90, 90) 'GDI的颜色值。
gg.DrawEllipse(j + 0.2) *B_SIZE, (i + 0.35) *B_SIZE, B_SIZE * 0.25, B_SIZE * 0.25
gg.DrawEllipse(j + 0.55) *B_SIZE, (i + 0.35) *B_SIZE, B_SIZE * 0.25, B_SIZE * 0.25
'一个深灰色嘴巴
gg.DrawFrame(j + 0.3) *B_SIZE, (i + 0.7) *B_SIZE, B_SIZE * 0.4, B_SIZE * 0.1
If (achievedNum = targetNum) Then ' 如果完成目标个数等于目标个数
gg.Font "黑体", 30
gg.SetColor BGR(0,255,255) 'GDI的颜色值。
gg.DrawString 15,100,"游 戏 胜 利"
End If
gg.Redraw
End Sub
Sub updateWithoutInput() '与输入无关的更新
Sleep 10 '暂停若干毫秒
End Sub
Sub updateWithInput(hWndForm As hWnd, gg As ygdi) ' 和输入有关的更新
Static pp As Long '预防一直按下,造成一直移动
If pp = 1 Then
If IsKeyPress(&H57) = 0 And IsKeyPress(&H53) = 0 And IsKeyPress(&H41) = 0 And IsKeyPress(&H44) = 0 Then
pp = 0
End If
Else
If IsKeyPress(&H57) Then ' 上
pp = 1
ElseIf IsKeyPress(&H53) Then ' 下
pp = 1
ElseIf IsKeyPress(&H41) Then ' 左
pp = 1
ElseIf IsKeyPress(&H44) Then ' 右
pp = 1
End If
If pp = 1 Then
Dim goal_i As Long = players.i ' 移动的目标位置
Dim goal_j As Long = players.j
Dim goalNext_i As Long = goal_i '目标位置再向前的一个位置
Dim goalNext_j As Long = goal_j
' 根据用户的不同按键输入,获得目标位置、再向前的一个位置
If IsKeyPress(&H57) Then ' 上
goal_i = Players.i - 1 ' 目标位置在玩家位置的下边
goalNext_i = goal_i - 1 ' 目标的下一个位置,在其再下边
ElseIf IsKeyPress(&H53) Then ' 下
goal_i = Players.i + 1 ' 目标位置在玩家位置的下边
goalNext_i = goal_i + 1 ' 目标的下一个位置,在其再下边
ElseIf IsKeyPress(&H41) Then ' 左
goal_j = Players.j -1 ' 目标位置在玩家位置的左边
goalNext_j = goal_j -1 ' 目标的下一个位置,在其再左边
ElseIf IsKeyPress(&H44) Then ' 右
goal_j = Players.j + 1 ' 目标位置在玩家位置的右边
goalNext_j = goal_j + 1 ' 目标的下一个位置,在其再右边
End If
'根据不同地图元素的情况,判断如何移动角色和更新地图元素
If Mid(level(goal_i), goal_j + 1, 1) = "e" Or Mid(level(goal_i), goal_j + 1, 1) = "t" Then
'如果目标位置是empty,或者target
Players.i = goal_i
Players.j = goal_j
ElseIf Mid(level(goal_i), goal_j + 1, 1) = "b" And Mid(level(goalNext_i), goalNext_j + 1, 1) = "e" Then
' 如果目标位置是box,再前面一个是empty
Players.i = goal_i ' 玩家移动到目标位置
Players.j = goal_j
Mid(level(goal_i), goal_j + 1, 1) = "e" ' 目标位置变成empty
Mid(level(goalNext_i), goalNext_j + 1, 1) = "b" ' 再前面变成box
ElseIf Mid(level(goal_i), goal_j + 1, 1) = "b" And Mid(level(goalNext_i), goalNext_j + 1, 1) = "t" Then
' 如果目标位置是box,再前面一个是target
Players.i = goal_i ' 玩家移动到目标位置
Players.j = goal_j
Mid(level(goal_i), goal_j + 1, 1) = "e" ' 目标位置变成empty
Mid(level(goalNext_i), goalNext_j + 1, 1) = "a" '再前面变成achieved
ElseIf Mid(level(goal_i), goal_j + 1, 1) = "a" And Mid(level(goalNext_i), goalNext_j + 1, 1) = "e" Then
'如果目标位置是achieved,再前面一个是empty
Players.i = goal_i ' 玩家移动到目标位置
Players.j = goal_j
Mid(level(goal_i), goal_j + 1, 1) = "t" ' 目标位置变成target
Mid(level(goalNext_i), goalNext_j + 1, 1) = "b" ' 再前面变成box
ElseIf Mid(level(goal_i), goal_j + 1, 1) = "a" And Mid(level(goalNext_i), goalNext_j + 1, 1) = "t" Then
'如果目标位置是achieved,再前面一个是target
Players.i = goal_i ' 玩家移动到目标位置
Players.j = goal_j
Mid(level(goal_i), goal_j + 1, 1) = "t" ' 目标位置变成target
Mid(level(goalNext_i), goalNext_j + 1, 1) = "a" ' 再前面变成achieved
Else '其他情况都推不动
Return ' 不做任何处理,函数直接返回
End If
Dim i As Long, j As Long
achievedNum = 0 ' 完成目标个数,初始为0
For i = 0 To B_NUM -1 '遍历关卡二维数组数据
For j = 0 To B_NUM -1
If Mid(level(i), j + 1, 1) = "a" Then ' 如果元素是achieved
achievedNum += 1 '完成目标个数+1
End If
Next
Next
End If
End If
End Sub
Sub 游戏执行过程(hWndForm As hWnd)
Dim gg As yGDI = hWndForm
startup()
Do
show(gg)
updateWithInput(hWndForm, gg)
updateWithoutInput()
Loop
End Sub
评论一下?