VisualFreeBasic游戏趣味编程_8.5_旋转的传播

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

当鼠标点中一个小圆圈时,小圆圈顺时针旋转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

评论一下?

OωO
取消