VisualFreeBasic游戏趣味编程_6.3_新圆不和已有圆相交

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

假设有两个圆,其圆心坐标分别为(x1,y1)、(x2,y2),半径分别为r1、r2,如图6-4所示。

记录两个圆心之间距离的平方dist2 = (x1−x2)(x1−x2)+(y1−y2)(y1−y2)。当两个圆正好相切时,圆心距离平方r2 = (r1+r2)(r1+r2)。当dist2<r2时,两个圆相交。

每次随机生成一个新圆后,首先与所有已经生成的圆比较,如果和任何一个圆相交,则重新生成一个新圆;如果新圆和所有已生成的圆都不相交,则循环结束,将此新圆添加到数组中。完整代码参看

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 = Int(Rnd * (圆的最大半径 - 圆的最小半径 + 1)) + 圆的最小半径 '新圆的半径
         For i = 0 To 圆的个数 -1
            Dim dist2 As Long = (圆心x(i) - x) * (圆心x(i) - x) + (圆心y(i) - y) * (圆心y(i) - y)
            Dim r2    As Long = (半径(i) + r)  * (半径(i) + r)
            If (dist2 < r2) Then ' 如果已有圆和新圆相交
               Exit For '跳出循环,此时i<圆的个数
            End If
         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 100
   Next
End Sub

程序运行后输出如图

评论一下?

OωO
取消