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语言中,函数和变量一样都需要先定义、后使用。
评论一下?