|
|
|
人工智能-基本组群 ——译:zh1110 你是否想过让一群对象移动,并使他们具有群体观念,就象鱼群或领头的水牛。 这有如下几个难点,他们必须有一定的行为规则:
#组群必须向一中心靠拢。
想一下场景...非洲的斑马群。斑马群有一只领头的,但是他们要与相邻的斑马保持距离,外面的斑马会向内靠拢(远离狮子). 我向你展示一个例子: 我们先创建对象"sheep"(我认为羊比较有趣). 让他们开始时随机分布,你可看到上图是运行后的结果. Private Type SHEEPTYPE sngX As Single 'X坐标 sngY As Single 'Y坐标 sngXSpeed As Single 'X方向速度 sngYSpeed As Single 'Y方向速度 End Type Dim mudtSheep() As SHEEPTYPE Const NUM_SHEEP = 19 '羊的数量 Const MIN_SEPERATION = 15 '相邻羊的最小距离 Dim i As Integer Dim j As Integer Dim blnSeperation As Boolean ReDim mudtSheep(NUM_SHEEP - 1) Randomize For i = 0 To UBound(mudtSheep) blnSeperation = False Do While Not (blnSeperation) mudtSheep(i).sngX = Rnd() * frmFlock.ScaleWidth mudtSheep(i).sngY = Rnd() * frmFlock.ScaleHeight blnSeperation = True For j = 0 To i - 1 If CalcDist(i, j) <= MIN_SEPERATION Then blnSeperation = False Exit For End If Next j Loop Next i
一小段代码就能显示这些羊群!首先我们为羊群数据建立UDT(用户自定义类型) 然后创建动态数组,数组尺寸通过 NUM_SHEEP 常量赋值 .用For loop 为每只羊分配启始的随机位置。为了不使羊重叠我们用了另外一个 For loop 检察它!
好,现在他们要靠成一群。继续代码! Private Function CalcDist(intIndex1 As Integer, intIndex2 As Integer) As Single CalcDist = Sqr((mudtSheep(intIndex1).sngX - mudtSheep(intIndex2).sngX) ^ 2 + (mudtSheep(intIndex1).sngY - mudtSheep(intIndex2).sngY) ^ 2) End Function 这段代码返回相邻羊的距离(通过他在数组中的索引).记住,我们还要保持羊的速度相近。 Const MAX_NOISE = 250 Dim sngXSum As Single Dim sngYSum As Single Dim sngXAvg As Single Dim sngYAvg As Single For j = 0 To UBound(mudtSheep) sngXSum = sngXSum + mudtSheep(j).sngX sngYSum = sngYSum + mudtSheep(j).sngY Next j sngXAvg = (sngXSum / NUM_SHEEP) + (Rnd() * MAX_NOISE) - (MAX_NOISE / 2) sngYAvg = (sngYSum / NUM_SHEEP) + (Rnd() * MAX_NOISE) - (MAX_NOISE / 2) 这段代码计算出所有羊的平均中心位置. 它加入了一些噪音,这样看上去羊会象是在拥挤的样子.减去(MAX_NOISE / 2)的理由是让波动位置正负平均,我们可取值 -125 到 125. 最后就是移动每一只羊向中心靠拢——根据它的 X 和 Y 速度。如果移动会引起一只羊侵犯另一只羊,移动要被停止. 看一下原代码 source code 如果您希望。 |