public class AntPopulationSystem:USystem
{
public override void Init ()
{
base.Init ();
this.AddRequestComponent (typeof(AntPopulationComponent));
}
public override void Update (UEntity uEntity)
{
// Debug.Log ("UpdateAntSystem");
base.Update (uEntity);
// InfluenceMap.getInstance ().Show (4);
List<AntPopulation> tList = uEntity.GetComponent<AntPopulationComponent> ().mAntPopulationSet;
for (int i = 0; i < AntPopulation.mNowListCount; i++)
{
if (tList [i].isStartFind)
{
UpdateAntPopulation (tList [i]);
}
}
}
private void UpdateAntPopulation(AntPopulation pAntPopulation)
{
// Debug.Log ("UpdateAntPopulation");
Ant[] tAnts = pAntPopulation.mAnts;
for (int i = 0; i < tAnts.Length; i++)
{
tAnts [i].mPositionIndex = InfluenceMap.getInstance ().getTilefromPosition (new Vector2(tAnts[i].mAIRT.transform.position.x,tAnts[i].mAIRT.transform.position.z));
tAnts [i].Add (tAnts[i].mPositionIndex);
if (tAnts [i].mInfoFood > 0.0f)
tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.green;
else if (tAnts [i].mInfoHome > 0.0f)
tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.blue;
else
tAnts [i].mAIRT.GetComponent<MeshRenderer> ().material.color = Color.red;
if (tAnts [i].mNowTarget == NowTarget.FOOD)
{
OnFood (tAnts[i],pAntPopulation);
}
else if (tAnts [i].mNowTarget == NowTarget.HOME)
{
OnHome (tAnts[i],pAntPopulation);
}
}
}
private void OnFood(Ant pAnt,AntPopulation ap)
{
Vector2 v1 = new Vector2 (pAnt.mAIRT.transform.position.x,pAnt.mAIRT.transform.position.z);
Vector2 v2 = new Vector2 (pAnt.mNowPositionTarget.x,pAnt.mNowPositionTarget.z);
float dis = Vector2.Distance (v1,v2);
if (pAnt.mNowPositionTarget == Vector3.zero || dis < 0.35f)
{
if(pAnt.mInfoHome>0.0f)
UpdatePheromone (ap.mInfluenceHomeTag,pAnt.mInfoHome,ap.mRadiationRiaus,pAnt.mPositionIndex,1000,pAnt.mClosedArray.Count);
GameObject g_target = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagDistination);
GameObject g_home = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagHome);
if(g_target != null)
{
pAnt.mInfoHome = -1.0f;
pAnt.mInfoFood = 200.0f;
pAnt.mNowTarget = NowTarget.HOME;
pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
pAnt.mClosedArray.Clear ();
pAnt.mLastDir = Vector2.zero;
return;
}
if (g_home != null)
{
pAnt.mInfoFood = -1.0f;
pAnt.mInfoHome = 200.0f;
}
pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
//Debug.Log (pAnt.mNowPositionTarget.ToString());
}
else
{
Vector3 offset = pAnt.mNowPositionTarget - pAnt.mAIRT.transform.position;
offset.Normalize ();
offset.y = 0;
pAnt.mAIRT.transform.Translate (offset*Time.deltaTime*6);
}
}
private void OnHome(Ant pAnt,AntPopulation ap)
{
Vector2 v1 = new Vector2 (pAnt.mAIRT.transform.position.x,pAnt.mAIRT.transform.position.z);
Vector2 v2 = new Vector2 (pAnt.mNowPositionTarget.x,pAnt.mNowPositionTarget.z);
float dis = Vector2.Distance (v1,v2);
//Debug.Log ("OnHome");
if (pAnt.mNowPositionTarget == Vector3.zero || dis < 0.35f)
{
if(pAnt.mInfoFood>0.0f)
UpdatePheromone (ap.mInfluenceDistinationTag,pAnt.mInfoFood,ap.mRadiationRiaus,pAnt.mPositionIndex,1000,pAnt.mClosedArray.Count);
GameObject g_target = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagDistination);
GameObject g_home = FindTarget (pAnt.mAIRT.transform.position,pAnt.mObserverDistance,ap.mTagHome);
if (g_home != null)
{
pAnt.mInfoFood = -1.0f;
pAnt.mInfoHome = 200.0f;
pAnt.mNowTarget = NowTarget.FOOD;
pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
pAnt.mClosedArray.Clear ();
pAnt.mLastDir = Vector2.zero;
return;
}
if (g_target != null)
{
pAnt.mInfoFood = 200.0f;
pAnt.mInfoHome = -1.0f;
}
pAnt.mNowPositionTarget = ComputeDirction (pAnt,ap);
}
else
{
Vector3 offset = pAnt.mNowPositionTarget - pAnt.mAIRT.transform.position;
offset.Normalize ();
offset.y = 0;
pAnt.mAIRT.transform.Translate (offset*Time.deltaTime*6);
}
}
private GameObject FindTarget(Vector3 mCenter,float riaus,string code)
{
Collider[] tAllCollider = Physics.OverlapSphere (mCenter,riaus);
GameObject tg = null;
foreach (Collider c in tAllCollider)
{
if (c.tag == code)
{
tg = c.transform.gameObject;
break;
}
}
return tg;
}
private float Gauss(Vector2 v)
{
return Mathf.Exp(-(v.x*v.x/2.0f+v.y*v.y/2.0f));
}
private void UpdatePheromone(string code,float f,int radioriaus,Vector2 center,float max,int pGoingTile)
{
int index = InfluenceMap.getInstance ().mDictionary [code];
int ti = Mathf.Clamp ((int)center.x,0,InfluenceMap.getInstance ().wtileCount-1);
int tj = Mathf.Clamp ((int)center.y,0,InfluenceMap.getInstance ().htileCount-1);
if(pGoingTile<radioriaus)
InfluenceMap.getInstance ().IMData [index] [ti] [tj] += f * (1-(float)pGoingTile/(float)radioriaus);
if (InfluenceMap.getInstance ().IMData [index] [ti] [tj] > max)
InfluenceMap.getInstance ().IMData [index] [ti] [tj] = max;
}
private Vector3 ComputeDirction(Ant pAnt,AntPopulation ap)
{
Vector3 result = Vector3.zero;
Vector2 resultNineGrid = Vector2.zero;
int index = -1;
if (pAnt.mNowTarget == NowTarget.FOOD)
index = InfluenceMap.getInstance ().mDictionary [ap.mInfluenceDistinationTag];
else
index = InfluenceMap.getInstance ().mDictionary [ap.mInfluenceHomeTag];
float tMax = InfluenceMap.getInstance ().getMax (pAnt.mPositionIndex,1,index);
if (tMax > 0.0f)
{
//Debug.Log (pAnt.mNowTarget.ToString()+" "+tMax+" infoFood:"+pAnt.mInfoFood+" infoHome"+pAnt.mInfoHome);
float minusRate = 0.02f;
if (Random.Range (0.0f, 1.0f) < minusRate)
{
int RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
if (pAnt.mLastDir != Vector2.zero)
resultNineGrid = pAnt.mLastDir;
float minusRate_ = 0.2f;
if (Random.Range (0.0f, 1.0f) < minusRate_)
{
RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
resultNineGrid = resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
}
int count = 0;
while ((InfluenceMap.getInstance().isWall(resultNineGrid+pAnt.mPositionIndex)||pAnt.Contains(resultNineGrid+pAnt.mPositionIndex))&&count<10)
{
RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
count++;
}
}
else
{
float sum = 0.0f;
for (int i = 0; i < InfluenceMap.getInstance ().NineGrid.Length; i++)
{
Vector2 delta = InfluenceMap.getInstance ().NineGrid [i];
Vector2 real = pAnt.mPositionIndex + delta;
if(real.x>=0&&real.x<InfluenceMap.getInstance().wtileCount&&real.y>=0&&real.y<InfluenceMap.getInstance().htileCount)
sum += InfluenceMap.getInstance ().IMData [index] [(int)real.x] [(int)real.y];
}
for (int i = 0; i < InfluenceMap.getInstance ().NineGrid.Length; i++)
{
Vector2 delta = InfluenceMap.getInstance ().NineGrid [i];
Vector2 real = pAnt.mPositionIndex + delta;
float tRate = 0.0f;
if(real.x>=0&&real.x<InfluenceMap.getInstance().wtileCount&&real.y>=0&&real.y<InfluenceMap.getInstance().htileCount)
tRate = InfluenceMap.getInstance ().IMData [index] [(int)real.x] [(int)real.y] / sum;
if (Random.Range (0.0f, 1.0f) < tRate&&!pAnt.Contains(delta+pAnt.mPositionIndex)&&!InfluenceMap.getInstance().isWall(delta+pAnt.mPositionIndex))
{
resultNineGrid = new Vector2 (delta.x,delta.y);
// Debug.Log (pAnt.Contains(delta+pAnt.mPositionIndex));
break;
}
}
}
}
else
{
int RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
if (pAnt.mLastDir != Vector2.zero)
resultNineGrid = pAnt.mLastDir;
float minusRate_ = 0.2f;
if (Random.Range (0.0f, 1.0f) < minusRate_)
{
RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
resultNineGrid = resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
}
int count = 0;
while ((InfluenceMap.getInstance().isWall(resultNineGrid+pAnt.mPositionIndex)||pAnt.Contains(resultNineGrid+pAnt.mPositionIndex))&&count<10)
{
RandomIndex = Random.Range(0,InfluenceMap.getInstance().NineGrid.Length);
resultNineGrid = InfluenceMap.getInstance ().NineGrid [RandomIndex];
count++;
}
//Debug.Log (pAnt.Contains(resultNineGrid+pAnt.mPositionIndex));
}
pAnt.mLastDir = new Vector2 (resultNineGrid.x,resultNineGrid.y);
float tx = pAnt.mPositionIndex.x + resultNineGrid.x;
float ty = pAnt.mPositionIndex.y + resultNineGrid.y;
tx = Mathf.Clamp (tx,0,InfluenceMap.getInstance().wtileCount-1);
ty = Mathf.Clamp (ty,0,InfluenceMap.getInstance().htileCount-1);
Vector2 tile = new Vector2 (tx,ty);
// Debug.Log (pAnt.Contains(tile));
result = InfluenceMap.getInstance ().GetPositionByTile (tile);
return result;
}
}
一开始的结果:
经过一段时间,开始往浅蓝和那个绿色箱子中间聚拢。
再过一段时间,已经是几乎所有都在一起聚拢。