var A_star_algorithm = cc.Class.extend({
ctor:function()
{
this._direction = [{x:-1,y:0},{x:0,y:1},{x:1,y:0},{x:0,y:-1}];
this._baseId =0;
},
SetPoints:function(posList,startPos,endPos)
{
if (posList)
{
this._posList = posList;
}
this._startPos = startPos;
this._endPos = endPos;
if ((!endPos) ||(!startPos))
{
return
}
this._Init();
},
StartSearch:function()
{
var startTime = Date.now()
var endTime = startTime;
HHLog("startFindTime::"+startTime+"\n");
if(!this._GetStartPosItem() || !this._GetEndPosItem())return;
while (this._GetOpenList().length>0)
{
this._SortListByF(this._GetOpenList())
var curItem = this._GetOpenList()[0];
this._RemoveItemFromList(curItem,this._GetOpenList());
this._InsertItemToList(curItem,this._GetCloseList());
if (!this._CheckIfItemEqual(curItem,this._GetEndPosItem()))
{
this._StartFind(curItem);
}
else
{
var paths = [];
var item = curItem;
var parent = item.GetParent();
while(parent)
{
paths.unshift(item);
item = item.GetParent()
parent = item.GetParent();
}
if (this._CheckIfItemEqual(item,this._GetStartPosItem()))
{
paths.unshift(item);
this._pathList = paths;
HHLog("a_star_algorithm_find---success\n");
}
else
{
HHLog("a_star_algorithm_find---not find a path to destPos");
}
break;
}
}
if (this.GetPath().length==0)
{
HHLog("a_star_algorithm_find---not find a path to destPos");
}
endTime = Date.now();
HHLog("startFindTime::"+endTime+"\n");
HHLog("timeCost::::::::"+(endTime-startTime)+"\n");
},
GetPath:function()
{
var pathList =[];
for (var i=0;i
{
var item = this._pathList[i];
pathList.push(item.GetPos());
}
return pathList;
},
GetPosList:function()
{
return this._posList;
},
GetPosItemList:function()
{
return this._posItemList;
},
GetPosItemByPos:function(pos)
{
var item = null;
var posItemList = this.GetPosItemList();
for (var i =0;i
{
var temp = posItemList[i].GetPos();
if (pos.x == temp.x && pos.y == temp.y)
{
item = posItemList[i];
break;
}
}
return item;
},
_Init:function()
{
this._openList = [];
this._closeList = [];
this._startPosItem = null;
this._endPosItem = null;
this._pathList = [];
this._posItemList = [];
this._baseId =0;
this._curPosItem = null;
this._CreatePosItemList();
this._InsertItemToList(this._GetStartPosItem(),this._GetOpenList());
},
_StartFind:function(curPosItem)
{
this._SetCurPosItem(curPosItem);
var curPosItem = this._GetCurPosItem();
var endPosItem = this._GetEndPosItem();
var curPos = curPosItem.GetPos();
var endPos = endPosItem.GetPos();
var direction = this._direction;
for (var i =0;i
{
var nextPos = cc.pAdd(curPos,direction[i]);
var item = this.GetPosItemByPos(nextPos);
var isInOpenList = this._CheckIfItemInList(item,this._GetOpenList());
var isInCloseList = this._CheckIfItemInList(item,this._GetCloseList());
if (item)
{
if(!isInOpenList && !isInCloseList)
{
var h = this.GetHValue(nextPos,endPos);
var g = curPosItem.GetG()+1;
item.SetG(g);
item.SetH(h);
item.SetParent(curPosItem);
this._InsertItemToList(item,this._GetOpenList());
}
}
}
},
_GetStartPosItem:function()
{
return this._startPosItem;
},
_GetEndPosItem:function()
{
return this._endPosItem;
},
_SortListByF:function(list)
{
if(list.length<=1)return;
list.sort(function(a,b)
{
return a.GetF()- b.GetF();
})
},
_GetCloseList:function()
{
return this._closeList;
},
_GetOpenList:function()
{
return this._openList;
},
_GetEndPosItem:function()
{
return this._endPosItem;
},
_GetCurPosItem:function()
{
return this._curPosItem;
},
_SetCurPosItem:function(posItem)
{
this._curPosItem = posItem;
},
_InsertItemToList:function(item,list)
{
if(item)
{
list.push(item);
}
},
_RemoveItemFromList:function(item,list)
{
var index = null;
for (var i in list)
{
var temp = list[i];
if (temp.GetId() == item.GetId())
{
list.splice(i,1);
}
}
},
_CheckIfItemEqual:function(cmp_a,cmp_b)
{
var isEqual = false;
if (cmp_a && cmp_b)
{
isEqual = (cmp_a.GetId() == cmp_b.GetId())
}
return isEqual;
},
_GetId:function()
{
return this._baseId++;
},
_CheckIfItemInList:function(item,checkList)
{
var isIn = false;
if (!item) return isIn;
for (var i =0;i
{
var temp = checkList[i];
if (item.GetId() == temp.GetId())
{
isIn = true;
break;
}
}
return isIn;
},
//曼哈顿长度
GetHValue:function(startPos=cc.p(0,0),endPos=cc.p(0,0))
{
var temp = cc.pSub(startPos,endPos);
var h = Math.abs(temp.x)+Math.abs(temp.y);
return h;
},
_CreatePosItem:function(pos,g,h,parent)
{
return PosItem.create(pos,g,h,parent);
},
_CreatePosItemList:function()
{
var posList = this.GetPosList();
for (var i =0;i
{
var pos = posList[i];
var posItem = this._CreatePosItem(pos,0,0,null);
posItem.SetId(this._GetId());
this._posItemList.push(posItem);
if (!this._startPosItem && (pos.x == this._startPos.x && pos.y == this._startPos.y))
{
this._startPosItem = posItem;
}
if (!this._endPosItem && (pos.x == this._endPos.x && pos.y == this._endPos.y))
{
this._endPosItem = posItem;
}
}
},
})
var PosItem = cc.Class.extend({
ctor:function(pos,g=0,h=0,parent=null)
{
this._pos = pos;
this._g = g;
this._h = h;
this._parent =parent;
this._id = 0;
},
SetId:function(id)
{
this._id = id;
},
GetId:function()
{
return this._id;
},
SetParent:function(parent)
{
if (parent)
{
this._parent = parent
}
},
GetPos:function()
{
return this._pos;
},
GetParent:function()
{
return this._parent;
},
SetG:function(g)
{
this._g = g;
},
SetH:function(h)
{
this._h = h;
},
GetG:function()
{
return this._g;
},
GetH:function()
{
return this._h;
},
GetF:function()
{
return this.GetG()+this.GetH();
},
})
PosItem.create = function(pos,g,h,parent)
{
return new this(pos,g,h,parent);
}