VisualFreeBasic游戏趣味编程_7.4_控制小蛇向4个方向移动

2026-1-22 / 0 评论 / 37 阅读

变量oldHead_i、oldHead_j存储移动前的蛇头位置(对应元素在二维数组中的行号、列号),newHead_i、newHead_j存储移动后的蛇头位置。小蛇向上移动,只需把新蛇头的坐标设为旧蛇头的上方即可,如图7-6所示。

在7-3代码的基础上修改代码就可以让小蛇向上移动:

newHead_i = oldTail_j -1 '向上移动

进一步, 我们让玩家用键盘控制小蛇的移动。除了上、下、左、右键外,很多游戏使用A、S、D、W键控制游戏角色的移动,如图7-7所示。

定义字符变量moveDirection表示小蛇运动方向,在moveSnake()函数中对其值进行判断,取'a'向左运动、'd'向右运动、'w'向上运动、's'向下运动:

   Dim moveDirection As String '小蛇移动方向
   If (moveDirection = "a") Then newHead_j = oldHead_j -1 ' 向左移动
   If (moveDirection = "d") Then newHead_j = oldHead_j + 1 '向右移动
   If (moveDirection = "w") Then newHead_i = oldHead_i -1 ' 向上移动
   If (moveDirection = "s") Then newHead_i = oldHead_i + 1 ' 向下移动

除了if语句,FB语言还提供了if-else双选择语句

Sub 游戏执行过程(hWndForm As hWnd)
   Dim x As Long = 7
   If x Mod 2 = 0 Then 
      Print  x & "是偶数"
   Else
      Print x & "奇数" 
   End If 
End Sub

程序运行后输出:7是奇数
if语句首先判断条件 x Mod 2 = 0 是否满足,如果条件满足,就执行if后面的 Print x & "是偶数"语句;如果条件不满足,则执行else之后的Print x & "奇数"语句。
提示
else不能单独出现,必须和if配套使用。


当有一系列条件要判断时,FB语言还提供了多条件的if语句,以下代码把百分制得分转换为五级评分标准。

Sub 游戏执行过程(hWndForm As hWnd)
   Dim 文本 As CWSTR = AfxInputBox(hWndForm,,,"数字输入","输入 1到 100 的数字","100",260)
   Dim x As Long = Val(文本)
   If x>=90 Then 
      Print "优秀"
   ElseIf x>=80 Then
      Print "良好"
   ElseIf x>=70 Then
      Print "中等"
   ElseIf x>=60 Then
      Print "及格"
   Else
      Print "不及格"
   End If 
End Sub

其中,AfxInputBox 等待用户键盘输入整数,按回车键后赋给变量x。

代码首先判断得分是否大于等于90,如果条件满足,就输出“优秀”;

否则,判断得分是否大于等于80,如果条件满足,说明得分在80~89之间,就输出“良好”;

否则,判断得分是否大于等于70,如果条件满足,说明得分在70~79之间,就输出“中等”;

否则,判断得分是否大于等于60,如果条件满足,说明得分在60~69之间,就输出“及格”;

否则,就说明得分小于60,输出“不及格”。

利用else语句,我们可以改进小蛇运动的控制代码,减少不必要的重复判断:

   If (moveDirection = "a") Then 
      newHead_j = oldHead_j -1 ' 向左移动
   ElseIf (moveDirection = "d") Then
      newHead_j = oldHead_j + 1 '向右移动
   ElseIf (moveDirection = "w") Then
      newHead_i = oldHead_i -1 ' 向上移动
   ElseIf (moveDirection = "s") Then
      newHead_i = oldHead_i + 1 ' 向下移动
   End If 

练习题7-2:身体质量指数(Body Mass Index,BMI)是衡量人体肥胖程度的重要标准,读者可以搜索相应的计算方法与标准,尝试编写程序判断体重是否正常。输入样例,程序运行后输出如下。

在updateWithInput()函数中获得用户按键输入,如果是A、S、D、W键之一,就更新moveDirection变量,执行moveSnake()函数让小蛇向对应方向移动:

Sub updateWithInput(moveDirection As String) ' 和输入有关的更新
   If IsKeyPress(&H57) Then
      moveDirection = "上"
   ElseIf IsKeyPress(&H53) Then
      moveDirection = "下"
   ElseIf IsKeyPress(&H41) Then
      moveDirection = "左"
   ElseIf IsKeyPress(&H44) Then
      moveDirection = "右"
   End If
End Sub

全部源码

#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 ' 二维数组,用于记录所有的游戏数据

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)
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.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 ' 向左移动
      If newHead_j < 0 Then newHead_j = BLOCK_WIDTH -1
   ElseIf (moveDirection = "右") Then
      newHead_j = oldHead_j + 1 '向右移动
      If newHead_j >= BLOCK_WIDTH Then newHead_j = 0
   ElseIf (moveDirection = "上") Then
      newHead_i = oldHead_i -1 ' 向上移动
      If newHead_i < 0 Then newHead_i = BLOCK_HEIGHT -1
   ElseIf (moveDirection = "下") Then
      newHead_i = oldHead_i + 1 ' 向下移动
      If newHead_i >= BLOCK_HEIGHT Then newHead_i = 0
   End If

   Blocks(newHead_i, newHead_j) = 1 ' 新蛇头位置数值为1
   Blocks(oldTail_i, oldTail_j) = 0 ' 旧蛇尾位置变成空白

End Sub

Sub updateWithoutInput(moveDirection As String) '与输入无关的更新
   moveSnake(moveDirection) '调用小蛇移动函数
   Sleep 100  '暂停若干毫秒
End Sub

Sub updateWithInput(moveDirection As String) ' 和输入有关的更新
   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

评论一下?

OωO
取消