VisualFreeBasic游戏趣味编程_6.4_函数的定义与应用

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

FB 程序是由函数组成的,每一个FB程序都包含这样的结构:

Sub Form1_Shown(hWndForm As hWnd, UserData As Integer)
   Threaddetach ThreadCreate(Cast(Any Ptr, @游戏执行过程), hWndForm)   
End Sub
Sub 游戏执行过程(hWndForm As hWnd)

End Sub

在之前的章节中,我们已经调用了很多函数,比如,print()函数输出变量的值、fillcircle()函数画圆、abs()函数求绝对值等。我们也可以定义自己的函数并调用执行:

Sub 游戏执行过程(hWndForm As hWnd)
   printStars()
End Sub

Sub printStars() 
   Print "*****" 
End Sub

以上代码首先定义了函数Sub printStars()。其中,printStars为函数的名字,后面跟上圆括号,Sub 表示函数没有返回值。

End Sub是函数结束,从开始到结束是函数体,这里输出一行5个星号。

函数定义后,在主函数中printStars()调用函数,即执行了函数内部的所有语句。程序运行后输出:

练习题6-2:调用6-4-1.cpp中定义的函数,输出如下效果:
函数定义的括号内,还可以添加接受的参数,修改的代码如下,让用户设定要输出的星号的个数:

Sub 游戏执行过程(hWndForm As hWnd)
   Dim i As Long
   For i = 1 To 4
      printStars(i)
   Next
End Sub

Sub printStars(num As Long ) 
   Print String(num, "*")
End Sub

Sub printStars(num As Long )表示函数接受整型变量num为参数,函数内部输出一行num个星号。调用函数时,括号内写不同的数字,就可以输出对应数字个数的星号。主函数中利用for语句,可以依次输出1~5个星号。程序运行后输出:

*
**
***
****

函数也可以接受多个参数,参数间以逗号间隔。

Sub 游戏执行过程(hWndForm As hWnd)
    printStars("+",3)
    printStars("@",5)
    printStars("0",8)
End Sub

Sub printStars(ch As String , num As Long ) 
   Print String(num, ch)
End Sub

以上函数接受两个参数:ch为对应的字符、num为要输出的字符的个数。程序运行后,分别输出3个+、5个@、8个0。程序运行后输出:

+++
@@@@@
00000000

回顾求绝对值函数的用法:

Dim x As Long = abs( -3)
Print x 

以上代码将函数计算结果返回并赋给变量x。同样,我们自定义的函数也可以定义返回值。以下代码定义了函数maxfun(),即返回两个整数中的最大值。

Sub 游戏执行过程(hWndForm As hWnd)
   Dim result As Long = maxfun(3, 5)
   Print result 
End Sub

Function maxfun(x As Long ,y As Long ) As Long 
   Dim max As Long = x
   If x < y Then max = y
   Return max
End Function

程序运行后输出:5


函数定义Function maxfun() As Long中,尾部的As Long表示函数的返回值为整型。函数中首先求出参数x、y的最大值,赋给变量max。利用return max语句将计算结果max返回出来,同时退出maxfun()函数的运行。调用函数时,即可将函数的返回值赋给其他变量。

利用函数的返回值,也可以实现更复杂的功能,比如,以下代码可以求解3个数的最大值:

Dim result As Long = maxfun(maxfun(3,5),4)

提示
当我们要解决的问题比较复杂时,可以把问题分块,使得每一块功能相对独立,用一个独立的函数来实现。用好函数可以降低程序设计的复杂性、提高代码的可靠性,避免程序开发的重复劳动,并易于程序维护和功能扩充。

回顾6-3,求解两个点之间的距离是一个常见的功能,所以可以将其封装为函数,方便多次调用:

' 求解两个点之间的距离
Function Dist2Points(x1 As Long, y1 As Long, x2 As Long, y2 As Long) As Long
   Dim result As Long
   result = Sqr((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
   Return result
End Function

其中,sqr()为求平方根函数

进一步,定义函数判断图6-4中的两个圆是否相交,其中调用了刚定义的Dist2Points()函数。如果相交则返回1,函数退出;否则返回0。

' 判断两个圆是否相交
Function isTwoCirclesIntersect(x1 As Long, y1 As Long,r1 As Long , x2 As Long, y2 As Long, r2 As Long ) As Long
   If (Dist2Points(x1, y1, x2, y2) < r1 + r2) Then Return 1 Else Return 0
End Function

生成两个数之间的随机整数也是一个常见的功能,可以封装为函数:

'生成[min,max]之间的随机整数
Function randBetweenMinMax(小 As Long, 大 As Long) As Long
   Randomize 
   Dim r As Long = int(Rnd * (大 - 小 + 1)) + 小
   Return r
End Function

利用上面定义的3个函数改进6.3节的代码,程序的结构会更加清晰,也更容易理解:

' 判断两个圆是否相交
Function isTwoCirclesIntersect(x1 As Long, y1 As Long,r1 As Long , x2 As Long, y2 As Long, r2 As Long ) As Long
   If (Dist2Points(x1, y1, x2, y2) < r1 + r2) Then Return 1 Else Return 0
End Function
' 求解两个点之间的距离
Function Dist2Points(x1 As Long, y1 As Long, x2 As Long, y2 As Long) As Long
   Dim result As Long
   result = Sqr((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
   Return result
End Function
'生成[min,max]之间的随机整数
Function randBetweenMinMax(小 As Long, 大 As Long) As Long
   Randomize 
   Dim r As Long = int(Rnd * (大 - 小 + 1)) + 小
   Return r
End Function
Sub 游戏执行过程(hWndForm As hWnd)
   Dim gg           As yGDI = hWndForm
   Dim 圆心x(99)    As Long '数组存储所有圆心的x坐标
   Dim 圆心y(99)    As Long '数组存储所有圆心的y坐标
   Dim 半径(99)     As Long '数组存储所有圆的半径
   Dim 圆的个数     As Long = 0
   Dim 游戏W        As Long = DpiScaleI(Form1.ScaleWidth) '游戏区的尺寸
   Dim 游戏H        As Long = DpiScaleI(Form1.ScaleHeight)
   Dim 圆的最小半径 As Long = 5
   Dim 圆的最大半径 As Long = 40
   Dim circleNum    As Long  ' 生成的圆的个数
   Dim As Long x, y, r       ' 新增圆的圆心坐标、半径
   Dim isNewCircleOK As Long '用于判断新生成的圆是否OK
   '生成圆,把数据保存在数组中
   Dim i As Long
   While 圆的个数 < 100 '当圆的个数小于100时,循环运行
      isNewCircleOK = 0 ' 假设开始不OK
      While isNewCircleOK = 0 ' 当新生成的圆不OK时,重复生成新圆进行比较
         x = Int(Rnd *游戏W) '新圆的圆心x坐标
         y = Int(Rnd *游戏H) '新圆的圆心y坐标                '
         r =randBetweenMinMax(圆的最小半径,圆的最大半径) '新圆的半径
         For i = 0 To 圆的个数 -1
            If isTwoCirclesIntersect(圆心x(i),圆心y(i),半径(i),x,y,r) Then Exit For  ' 如果已有圆和新圆相交跳出循环,此时i<圆的个数
         Next
         If (i = 圆的个数) Then ' 如果上面for语句都不跳出,说明i等于circleNum
            isNewCircleOK = 1 ' 这个新生成的圆和已有圆都不相交
         End If
      Wend
      圆心x(圆的个数) = x   '把新圆的圆心坐标添加到数组中
      圆心y(圆的个数) = y
      半径(圆的个数)  = r    '把新圆的半径添加到数组中
      圆的个数        += 1  '圆的个数+1
   Wend
   gg.Pen 1, BGR(105, 105, 105) 'GDI的颜色值。
   gg.Brush BGR(204, 204, 0) 'GDI的颜色值。
   For 圆的个数 = 1 To 100
      gg.Cls
      For i = 0 To 圆的个数 -1
         gg.DrawEllipse 圆心x(i) - 半径(i), 圆心y(i) - 半径(i), 半径(i) * 2, 半径(i) * 2
      Next
      gg.DrawString 10, 10, Str(圆的个数)
      gg.Redraw
      Sleep 50
   Next 
End Sub

提示

在FFB语言中,函数和变量一样都需要先定义、后使用。

评论一下?

OωO
取消