论坛的首页
勇芳的软件
教程和帮助
VisualFreeBasic编程文档
勇芳系列软件帮助说明教程
留言或交流
登录
搜索
登录
搜索
勇芳
累计撰写
330
篇文章
累计收到
0
条评论
首页
栏目
论坛的首页
勇芳的软件
教程和帮助
VisualFreeBasic编程文档
勇芳系列软件帮助说明教程
留言或交流
登录
包含标签 【编程】 的文章
2026-1-22
VisualFreeBasic游戏趣味编程_9.6_多关卡的实现
为了实现多个关卡的游戏,首先利用宏定义设定关卡数目: #define LEVEL_TOTALNUM 3 '一共多少关卡 假设一共有3关,则可以设定2维字符数组levels,存储这3关的所有地图数据: Dim Shared level(LEVEL_TOTALNUM -1, B_NUM -1) As ZString * B_NUM + 1 = _ {_ {"wwwwwwww", "wwwtbeew", "weeeeeew", "weeeeeew", "weeeeeew", "weepaeew", "weeewwww", "wwwwwwww"}, _ '第1关 {"wwwwwwww", "wwweewww", "wpetbwww", "weeebeww", "wewteeww", "weeeeeww", "weepwwww", "wwwwwwww"}, _ '第2关 {"wwwwwwww", "wwpeewww", "weeweeww", "webabeww", "weeteeww", "wwetewww", "wwwwwwww", "wwwwwwww"} _ '第3关 } 定义currentLevelNum表示当前玩到第几关,二维数组level存储正在玩的这一关的地图数据,则可以在startup()函数中进行初始化: Sub startup() '初始化函数 Dim i As Long, j As Long For i = 0 To B_NUM -1 '首先获得当前关的地图数据 level(i) = levels(currentLevelNum, i) Next 在update()函数中,如果当前关卡完成,就将currentLevelNum加1,并调用startup()开始下一关的初始化: If (achievedNum = targetNum) Then ' 如果完成当前关卡了 show() '调用显示信息,显示游戏胜利画面 If (currentLevelNum < LEVEL_TOTALNUM -1) Then currentLevelNum += 1 ' 进入下一关 startup() ' 开始下一关卡的初始化 End If End If 在show()函数中,如果还有未完成的关卡,显示将要开始第几关游戏;如果所有关卡都完成了,提示游戏胜利: gg.Font "黑体", 20 gg.SetColor BGR(0, 255, 255) 'GDI的颜色值。 gg.DrawString 300, 30, "第" & currentLevelNum + 1 & "关" gg.Font "黑体", 11 gg.DrawString 265, 230, "按空格键重玩当前关" If (achievedNum = targetNum) And currentLevelNum = LEVEL_TOTALNUM -1 Then ' 如果完成目标个数等于目标个数 gg.Font "黑体", 30 gg.SetColor BGR(0, 255, 255) 'GDI的颜色值。 gg.DrawString 15, 100, "游 戏 胜 利" End If 另外,在update()函数中添加代码,按空格键可以重玩当前关卡: If IsKeyPress(VK_SPACE) Then pp = 1 startup() Return 读者可以尝试设计更多关卡,游戏第1关~第5关,完整代码参看后面 Type Player ' 结构体,用于记录玩家位置 i As Long j As Long End Type #define B_SIZE 32 ' 方块大小 #define B_NUM 8 ' 方块个数,一共8*8个方块 #define LEVEL_TOTALNUM 5 '一共多少关卡 '用字符型二维数组存储地图数据 'e: empty w: wall t: target b: box a: achieved p:player '全局变量定义 Dim Shared levels(LEVEL_TOTALNUM -1, B_NUM -1) As ZString * B_NUM + 1 = _ {_ {"wwwwwwww", "wwwtbeew", "weeeeeew", "weeeeeew", "weeeeeew", "weepaeew", "weeewwww", "wwwwwwww"}, _ '第1关 {"wwwwwwww", "wwweewww", "wpetbwww", "weeebeww", "wewteeww", "weeeeeww", "weepwwww", "wwwwwwww"}, _ '第2关 {"wwwwwwww", "wwpeewww", "weeweeww", "webabeww", "weeteeww", "wwetewww", "wwwwwwww", "wwwwwwww"}, _ '第3关 {"wwwwwwww", "wwwwwwww", "weeeewww", "weeettew", "webbbpew", "weewetww", "wwwwwwww", "wwwwwwww"}, _ '第4关 {"wwwwwwww", "wwwwwwww", "wwteewww", "weewebpw", "weewewew", "weaeebtw", "weeeewww", "wwwwwwww"} _ '第5关 } Dim Shared level(B_NUM -1) As ZString * B_NUM + 1 Dim Shared Players As player '玩家全局变量 Dim Shared As Long targetNum, achievedNum '目标位置个数、完成目标个数 Dim Shared As Long currentLevelNum ' 当前玩到第几关 Sub startup() '初始化函数 Dim i As Long, j As Long For i = 0 To B_NUM -1 '首先获得当前关的地图数据 level(i) = levels(currentLevelNum, i) Next 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 gg.Font "黑体", 20 gg.SetColor BGR(0, 255, 255) 'GDI的颜色值。 gg.DrawString 300, 30, "第" & currentLevelNum + 1 & "关" gg.Font "黑体", 11 gg.DrawString 265, 230, "按空格键重玩当前关" If (achievedNum = targetNum) And currentLevelNum = LEVEL_TOTALNUM-1 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 And IsKeyPress(VK_SPACE) = 0 Then pp = 0 End If Else If IsKeyPress(VK_SPACE) Then pp = 1 startup() Return ElseIf 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 If (achievedNum = targetNum) Then ' 如果完成当前关卡了 If (currentLevelNum < LEVEL_TOTALNUM -1) Then currentLevelNum += 1 ' 进入下一关 achievedNum =0 startup() ' 开始下一关卡的初始化 End If End If 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
2026年-1月-22日
82 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_9.5_游戏胜利判断
当玩家把所有箱子推到目标位置时游戏胜利,如图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
2026年-1月-22日
50 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_9.4_元素更新的实现
假设键盘控制游戏角色向右移动,根据其右侧目标位置、再右侧位置的元素,有表9-2所示情况。 根据用户的不同输入,变量goal_i、goal_j存储游戏角色移动的目标位置, goalNext_i、goalNext_j存储目标位置再向前的一个位置。根据表9-2,共有6种情况会移动游戏角色及更新关卡元素,在update()函数中实现相应的处理: 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 End If End If End Sub 读者可以自己更改代码,看看是否和预料的结果一样。如果不同,自己试着排除错误。
2026年-1月-22日
80 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_9.3_键盘控制游戏角色移动
为了实现键盘控制游戏角色移动,首先定义结构体用于记录玩家位置: Type Player ' 结构体,用于记录玩家位置 i As Long j As Long End Type 定义全局变量player储存游戏角色的位置: Dim Shared Players As player '玩家全局变量 在初始化时,找到二维数组level中值为'p'的元素,得到玩家位置赋给变量player,再把元素值变成'e': Sub startup() '初始化函数 Dim i As Long, j As Long For i = 0 To B_NUM -1 '遍历关卡二维数组数据 For j = 1 To B_NUM If Mid(level(i), j, 1) = "p" Then '找到地图中player的位置 Players.i = i '设定player的位置 Players.j = j Mid(level(i), j, 1) = "e" '把地图元素变成空白empty Exit For, For '连续跳出2个循环 End If Next Next End Sub 其中 Mid 语句/函数 是读取或设置字符串中的字符 修改show()函数,根据player中存储的位置,绘制出玩家图案: 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 在update()函数中,根据用户按下的A、S、D、W键,控制角色向左、下、右、上移动: 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 ' 上 Players.i = Players.i -1 pp = 1 ElseIf IsKeyPress(&H53) Then ' 下 Players.i = Players.i + 1 pp = 1 ElseIf IsKeyPress(&H41) Then ' 左 Players.j = Players.j -1 pp = 1 ElseIf IsKeyPress(&H44) Then ' 右 Players.j = Players.j + 1 pp = 1 End If End If End Sub 读者可以自己更改代码,看看是否和预料的结果一样。如果不同,自己试着排除错误。
2026年-1月-22日
63 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_9.2_应用字符数组存储关卡数据
推箱子游戏效果如图9-4所示。 图9-4中的“推箱子”游戏一共有表9-1所示的几种元素。 表9-1 元素图片 功能描述 英文名称 缩写字符 空白区域:玩家可以穿过,箱子可以推上去 empty 'e' 墙:玩家不能经过,箱子不能推过去 wall 'w' 箱子:在前方没有障碍物的情况下,玩家可以推动 box 'b' 空白目标:需要玩家将箱子推上去 target 't' 完成目标:一个箱子在目标上的叠加状态 achieved 'a' 游戏角色:可以键盘控制移动,推动箱子到达目标 player 'p' 我们可以采用二维字符数组的形式描述关卡地图数据。用表9-1中对应的缩写字符,图9-4的地图可以表示为: Dim level(63) As String = _ {"w", "w", "w", "w", "w", "w", "w", "w", _ "w", "w", "w", "t", "b", "e", "e", "w", _ "w", "e", "e", "e", "e", "e", "e", "w", _ "w", "e", "e", "e", "e", "e", "e", "w", _ "w", "e", "e", "e", "e", "e", "e", "w", _ "w", "e", "e", "p", "a", "e", "e", "w", _ "w", "e", "e", "e", "w", "w", "w", "w", _ "w", "w", "w", "w", "w", "w", "w", "w"} 用字符串的形式对二维数组初始化,代码可写为: Dim level(7) As String = {"wwwwwwww", "wwwtbeew", "weeeeeew", "weeeeeew", "weeeeeew", "weepaeew", "weeewwww", "wwwwwwww"} dim level(7) 是有8个数据,0~7 8个。 定义全局变量level储存地图数据,在show()函数中根据level的值绘制出表9-1中的对应图案,完整代码如9-2所示。 #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"} Sub startup() '初始化函数 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 Chr(level(i) [j]) = "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 Chr(level(i) [j]) = "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 Chr(level(i) [j]) = "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 Chr(level(i) [j]) = "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 Chr(level(i) [j]) = "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 Chr(level(i) [j]) = "p" Then 'player 元素是玩家,绘制一个人脸图案 '一个红色圆脸 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 End If Next Next gg.Redraw End Sub Sub updateWithoutInput() '与输入无关的更新 Sleep 10 '暂停若干毫秒 End Sub Sub updateWithInput(hWndForm As hWnd, gg As ygdi) ' 和输入有关的更新 End Sub Sub 游戏执行过程(hWndForm As hWnd) Dim gg As yGDI = hWndForm startup() Do show(gg) updateWithInput(hWndForm, gg) updateWithoutInput() Loop End Sub
2026年-1月-22日
45 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_第9章_“推箱子”游戏
在本章我们将探讨如何编写“推箱子”游戏,即玩家通过键盘控制游戏角色将所有黄色箱子推到白色方块处,效果如图9-1所示。 在本章我们将探讨如何编写“推箱子”游戏,即玩家通过键盘控制游戏角色将所有黄色箱子推到白色方块处,效果如图9-1所示。
2026年-1月-22日
53 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_8.6_操作步数与旋转度数
首先定义全局变量step记录还剩下的操作步数,score记录一共旋转的度数: Dim Shared 步数 As Long '还剩下的操作步数 Dim Shared 得分 As Long '得分,也就是一共旋转了多少度 在startup( )函数中进行初始化: Sub startup() '初始化函数 步数 = 10 ' 一共可以操作10步 得分 = 0 ' 初始为0度 在show()函数中输出相关的文字信息: gg.Font "黑体", 24 gg.SetColor BGR(255,255,255) 'GDI的颜色值。 gg.DrawString 280,60, 步数 & " 步" gg.DrawString 280, 100, 得分 & " 度" gg.Font "黑体", 10 gg.DrawString 10,245, "点击一个圆圈 其指针顺时针旋转90度之后 指向的指针依次旋转" 每旋转一次,得分增加90度: Sub rotateRound(i As Long, j As Long) 得分 +=90 update()函数中鼠标每操作一次,step减1: 步数 -=1 完整代码如下 Type Round '定义结构体,用来表示带角度指示的小圆圈 As Long x, y '小圆圈的圆心坐标 As Long r ' 小圆圈半径 angleNum As Long ' 对应的角度种类,只能是0、90、180、270,表示对应的4个角度值 End Type '全局变量定义 Dim Shared Rounds(4, 4) As Round '定义结构体变量 Dim Shared 步数 As Long '还剩下的操作步数 Dim Shared 得分 As Long '得分,也就是一共旋转了多少度 Sub startup() '初始化函数 步数 = 10 ' 一共可以操作10步 得分 = 0 ' 初始为0度 Dim i As Long Dim j As Long For i = 0 To 4 For j = 0 To 4 Rounds(i, j).x = j * 45 + 45 '设定小圆圈的圆心坐标 Rounds(i, j).y = i * 45 + 45 Rounds(i, j).r = 15 '设定小圆圈的半径 Rounds(i, j).angleNum = 270 Next Next End Sub Sub show(gg As yGDI) '绘制函数 gg.Cls BGR(0, 0, 0) '背景为黑色 Dim i As Long Dim j As Long '对所有小圆圈遍历 For i = 0 To 4 For j = 0 To 4 gg.Pen 1, BGR(255, 255, 255) '设置圆圈颜色为白灰色 gg.Brush '无填充 gg.DrawEllipse Rounds(i, j).x - Rounds(i, j).r, Rounds(i, j).y - Rounds(i, j).r, Rounds(i, j).r * 2, Rounds(i, j).r * 2 '画小圆圈 '用三角函数,画出这根红线 gg.Pen 1, BGR(255, 51, 51) 'GDI的颜色值。 gg.DrawLine Rounds(i, j).x, Rounds(i, j).y, Rounds(i, j).x + Rounds(i, j).r *Cos(Rounds(i, j).angleNum * (3.1415926 / 180)), _ Rounds(i, j).y + Rounds(i, j).r *Sin(Rounds(i, j).angleNum * (3.1415926 / 180)) Next Next gg.Font "黑体", 24 gg.SetColor BGR(255,255,255) 'GDI的颜色值。 gg.DrawString 280,60, 步数 & " 步" gg.DrawString 280, 100, 得分 & " 度" gg.Font "黑体", 10 gg.DrawString 10,245, "点击一个圆圈 其指针顺时针旋转90度之后 指向的指针依次旋转" gg.Redraw End Sub Sub updateWithoutInput() '与输入无关的更新 Sleep 10 '暂停若干毫秒 End Sub Sub rotateRound(i As Long, j As Long) 得分 +=90 If i >= 0 And j >= 0 And i < 5 And j < 5 Then Rounds(i, j).angleNum += 90 If Rounds(i, j).angleNum >= 360 Then Rounds(i, j).angleNum = 0 End If End Sub Sub updateWithInput(hWndForm As hWnd, gg As ygdi) ' 和输入有关的更新 Static pp As Long '预防鼠标一直按住,造成一直点击 If IsKeyPress(VK_LBUTTON) Then '鼠标左键点击 If pp = 0 Then pp = 1 '表示鼠标按下 Dim ps As Point GetCursorPos(@ps) '获取鼠标在屏幕的位置 MapWindowPoints HWND_DESKTOP, hWndForm, @ps, 1 '将鼠标位置从屏幕转换到游戏窗口的位置 ps.x = DpiUnScaleI(ps.x) '响应系统DPI ps.y = DpiUnScaleI(ps.y) Dim clicked_i As Long = Int(ps.y -45) / 45 Dim clicked_j As Long = int(ps.x -45) / 45 If clicked_i >= 0 And clicked_j >= 0 And clicked_i < 5 And clicked_j < 5 And 步数>0 Then '表示点中圆圈 步数 -= 1 rotateRound(clicked_i, clicked_j) '把当前圆圈顺时针旋转90度 Dim indexes(1) As Long = {clicked_i, clicked_j} '数组存储点击小圆圈的行列序号 While GetNextIndexes(indexes()) show(gg) Sleep 800 rotateRound(indexes(0), indexes(1)) Wend End If End If Else pp = 0 '表示鼠标放开 End If End Sub ' 获得当前圆圈指向的下一个圆圈的序号 ' 当前圆圈序号存储在数组int indexes[2]中,下一个圆圈序号也存储在这个数组中 ' 如果有下一个指向的圆圈,则返回1;如果指向边界了,则返回0 Function GetNextIndexes(indexes() As Long) As Long Dim i As Long = indexes(0) '当前圆圈的i、j序号 dim j as long = indexes(1) ' 根据当前圆圈的角度,获得下一个小圆圈的序号 If (Rounds(i,j).angleNum = 0) Then ' 指向右边的小圆圈 j += 1 ' right ElseIf (Rounds(i,j).angleNum = 90) Then ' 指向下边的小圆圈 i += 1 ' down ElseIf (Rounds(i,j).angleNum = 180) Then _ ' 指向左边的小圆圈 j -= 1 ' left ElseIf (Rounds(i,j).angleNum = 270) Then _ ' 指向上边的小圆圈 i -= 1 ' up End If indexes(0) = i ' 在数组中更新指向的下一个圆圈的序号 indexes(1) = j If (i >= 0 And i < 5 And j >= 0 And j < 5) Then ' 如果序号没有越界 Return 1 ' 说明指向了一个圆圈,返回1 Else Return 0 ' 没有指向有效圆圈,返回0 End If End Function Sub 游戏执行过程(hWndForm As hWnd) Dim gg As yGDI = hWndForm startup() Do show(gg) updateWithInput(hWndForm, gg) updateWithoutInput() Loop End Sub
2026年-1月-22日
37 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_8.5_旋转的传播
当鼠标点中一个小圆圈时,小圆圈顺时针旋转90度,然后其指向的下一个圆圈继续旋转90度,如此迭代下去,直到不指向任何小圆圈为止(此时指向边界),如图8-7所示。 首先定义一维数组indexes存储被鼠标点中的小圆圈在二维数组rounds中的行列序号: Dim indexes(1) As Long '数组存储点击小圆圈的行列序号 定义函数int GetNextIndexes(int indexes[2]),根据当前小圆圈的序号indexes[0]、indexes[1]和当前小圆圈的角度angleNum,首先求出其指向的小圆圈的序号。如果指向的小圆圈超出边界,函数返回0;如果指向一个有效的小圆圈,就把其序号更新到数组indexes中,函数返回1。 ' 获得当前圆圈指向的下一个圆圈的序号 ' 当前圆圈序号存储在数组int indexes[2]中,下一个圆圈序号也存储在这个数组中 ' 如果有下一个指向的圆圈,则返回1;如果指向边界了,则返回0 Function GetNextIndexes(indexes() As Long) As Long Dim i As Long = indexes(0) '当前圆圈的i、j序号 dim j as long = indexes(1) ' 根据当前圆圈的角度,获得下一个小圆圈的序号 If (Rounds[i][j].angleNum = = 0) Then ' 指向右边的小圆圈 j += 1 ' right ElseIf (Rounds[i][j].angleNum = 3) Then ' 指向下边的小圆圈 i += 1 ' down ElseIf (Rounds[i][j].angleNum = 2) Then _ ' 指向左边的小圆圈 j -= 1 ' left ElseIf (rounds[i][j].angleNum = 1) Then _ ' 指向上边的小圆圈 i -= 1 ' up End If indexes(0) = i ' 在数组中更新指向的下一个圆圈的序号 indexes(1) = j If (i >= 0 And i < 5 And j >= 0 And j < 5) Then ' 如果序号没有越界 Return 1 ' 说明指向了一个圆圈,返回1 Else Return 0 ' 没有指向有效圆圈,返回0 End If End Function 循环调用GetNextIndexes( )函数,即实现了旋转的迭代传播: Dim indexes(1) As Long={clicked_i, clicked_j} '数组存储点击小圆圈的行列序号 While GetNextIndexes(indexes()) rotateRound(indexes(0),indexes(1)) show(gg) Sleep 800 Wend 完整代码 Type Round '定义结构体,用来表示带角度指示的小圆圈 As Long x, y '小圆圈的圆心坐标 As Long r ' 小圆圈半径 angleNum As Long ' 对应的角度种类,只能是0、90、180、270,表示对应的4个角度值 End Type '全局变量定义 Dim Shared Rounds(4, 4) As Round '定义结构体变量 Sub startup() '初始化函数 Dim i As Long Dim j As Long For i = 0 To 4 For j = 0 To 4 Rounds(i, j).x = j * 45 + 45 '设定小圆圈的圆心坐标 Rounds(i, j).y = i * 45 + 45 Rounds(i, j).r = 15 '设定小圆圈的半径 Rounds(i, j).angleNum = 270 Next Next End Sub Sub show(gg As yGDI) '绘制函数 gg.Cls BGR(0, 0, 0) '背景为黑色 Dim i As Long Dim j As Long '对所有小圆圈遍历 For i = 0 To 4 For j = 0 To 4 gg.Pen 1, BGR(255, 255, 255) '设置圆圈颜色为白灰色 gg.Brush '无填充 gg.DrawEllipse Rounds(i, j).x - Rounds(i, j).r, Rounds(i, j).y - Rounds(i, j).r, Rounds(i, j).r * 2, Rounds(i, j).r * 2 '画小圆圈 '用三角函数,画出这根红线 gg.Pen 1, BGR(255, 51, 51) 'GDI的颜色值。 gg.DrawLine Rounds(i, j).x, Rounds(i, j).y, Rounds(i, j).x + Rounds(i, j).r *Cos(Rounds(i, j).angleNum * (3.1415926 / 180)), _ Rounds(i, j).y + Rounds(i, j).r *Sin(Rounds(i, j).angleNum * (3.1415926 / 180)) Next Next gg.Redraw End Sub Sub updateWithoutInput() '与输入无关的更新 Sleep 10 '暂停若干毫秒 End Sub Sub rotateRound(i As Long, j As Long) If i >= 0 And j >= 0 And i < 5 And j < 5 Then Rounds(i, j).angleNum += 90 If Rounds(i, j).angleNum >= 360 Then Rounds(i, j).angleNum = 0 End If End Sub Sub updateWithInput(hWndForm As hWnd,gg As ygdi ) ' 和输入有关的更新 Static pp As Long '预防鼠标一直按住,造成一直点击 If IsKeyPress(VK_LBUTTON) Then '鼠标左键点击 If pp = 0 Then pp = 1 '表示鼠标按下 Dim ps As Point GetCursorPos(@ps) '获取鼠标在屏幕的位置 MapWindowPoints HWND_DESKTOP, hWndForm, @ps, 1 '将鼠标位置从屏幕转换到游戏窗口的位置 ps.x = DpiUnScaleI(ps.x) '响应系统DPI ps.y = DpiUnScaleI(ps.y) Dim clicked_i As Long = Int(ps.y -45) / 45 Dim clicked_j As Long = int(ps.x -45) / 45 rotateRound(clicked_i, clicked_j) '把当前圆圈顺时针旋转90度 Dim indexes(1) As Long={clicked_i, clicked_j} '数组存储点击小圆圈的行列序号 While GetNextIndexes(indexes()) rotateRound(indexes(0),indexes(1)) show(gg) Sleep 800 Wend End If Else pp = 0 '表示鼠标放开 End If End Sub ' 获得当前圆圈指向的下一个圆圈的序号 ' 当前圆圈序号存储在数组int indexes[2]中,下一个圆圈序号也存储在这个数组中 ' 如果有下一个指向的圆圈,则返回1;如果指向边界了,则返回0 Function GetNextIndexes(indexes() As Long) As Long Dim i As Long = indexes(0) '当前圆圈的i、j序号 dim j as long = indexes(1) ' 根据当前圆圈的角度,获得下一个小圆圈的序号 If (Rounds(i,j).angleNum = 0) Then ' 指向右边的小圆圈 j += 1 ' right ElseIf (Rounds(i,j).angleNum = 90) Then ' 指向下边的小圆圈 i += 1 ' down ElseIf (Rounds(i,j).angleNum = 180) Then _ ' 指向左边的小圆圈 j -= 1 ' left ElseIf (Rounds(i,j).angleNum = 270) Then _ ' 指向上边的小圆圈 i -= 1 ' up End If indexes(0) = i ' 在数组中更新指向的下一个圆圈的序号 indexes(1) = j If (i >= 0 And i < 5 And j >= 0 And j < 5) Then ' 如果序号没有越界 Return 1 ' 说明指向了一个圆圈,返回1 Else Return 0 ' 没有指向有效圆圈,返回0 End If End Function Sub 游戏执行过程(hWndForm As hWnd) Dim gg As yGDI = hWndForm startup() Do show(gg) updateWithInput(hWndForm, gg) updateWithoutInput() Loop End Sub
2026年-1月-22日
45 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_8.4_函数的参数传递
在本节我们介绍一般变量、数组元素、数组名作为函数参数的几种情况。输入并运行以下代码: Sub fun(a As Long) a += 1 Print a End Sub Sub 游戏执行过程(hWndForm As hWnd) Dim x As Long = 1 Print x fun(x) Print x End Sub 程序运行后输出: 1 2 1 程序从主函数开始运行,首先定义变量x并初始化为1,print x 输出1。 接着执行fun(x) 进入fun()函数,为变量a分配内存空间,将实际参数x的值赋给形式参数a。执行fun()函数内部的语句a+=1 ,print a 输出2。fun()运行结束后,收回变量a的内存空间。 回到主函数中,x的值没有改变,print x 仍然输出1。 一般变量作为函数的参数,这种调用方式称为单向值调用,函数内形式参数的值改变不会影响主函数中对应实际参数的值。 以下代码将数组元素传递给函数: Sub fun(i As Long,j As Long ) i += 1 j+=1 End Sub Sub 游戏执行过程(hWndForm As hWnd) Dim x(1) As Long = {1,2} Print x(0),x(1) fun(x(0),x(1)) Print x(0),x(1) End Sub 程序运行后输出: 1 2 1 2 数组元素作为函数实际参数的用法和一般变量作为实际参数的用法一样,都是单向的值传递。 为了能在函数中修改实际参数的值,我们可以把数组名作为参数进行传递。输入并运行以下代码: Sub fun(a() As Long) a(0) = 3 a(1) = 4 End Sub Sub 游戏执行过程(hWndForm As hWnd) Dim x(1) As Long = {1,2} Print x(0),x(1) fun( x() ) Print x(0),x(1) End Sub 程序运行后输出: 1 2 3 4 在下一节我们将讲解利用数组作为函数的参数,实现圆圈旋转的迭代传播。
2026年-1月-22日
42 阅读
0 评论
VisualFreeBasic编程文档
2026-1-22
VisualFreeBasic游戏趣味编程_8.3_被鼠标点击后旋转
鼠标点击位置的坐标为(m.x,m.y),根据图8-3中5行5列小圆圈的坐标设置(代码8-1-2.cpp),被鼠标点中的小圆圈在二维数组rounds中的行、列序号为: Dim clicked_i As Long = Int(ps.y -45)/45 Dim clicked_j As Long = int(ps.x -45)/45 被点中的小圆圈需要顺时针旋转90度,如图8-6所示。 只需要将其angleNum值依次+90即可: Rounds(i, j).angleNum += 90 If Rounds(i, j).angleNum >= 360 Then Rounds(i, j).angleNum = 0 其中“+=”为复合运算符,x += 1等价于x = x ++ 1。 练习题8-2:写出以下程序并运行结果。 Dim a As Long = 1 a += 4 Print a a -= 2 Print a a *= 3 Print a a /= 2 Print a a Mod= 3 Print a 把小圆圈顺时针旋转的功能封装在函数rotateRound( )中,修改代码如下: Sub updateWithInput(hWndForm As hWnd) ' 和输入有关的更新 Static pp As Long '预防鼠标一直按住,造成一直点击 If IsKeyPress(VK_LBUTTON) Then '鼠标左键点击 If pp = 0 Then pp = 1 '表示鼠标按下 Dim ps As Point GetCursorPos(@ps) '获取鼠标在屏幕的位置 MapWindowPoints HWND_DESKTOP, hWndForm, @ps, 1 '将鼠标位置从屏幕转换到游戏窗口的位置 ps.x = DpiUnScaleI(ps.x) '响应系统DPI ps.y = DpiUnScaleI(ps.y) Dim clicked_i As Long = Int(ps.y -45) / 45 Dim clicked_j As Long = int(ps.x -45) / 45 rotateRound(clicked_i, clicked_j) '把当前圆圈顺时针旋转90度 End If Else pp = 0 '表示鼠标放开 End If End Sub
2026年-1月-22日
39 阅读
0 评论
VisualFreeBasic编程文档
1
2
3
4
5