bool AstarFlexible::search() { //如果开始和结束点是同一点、终点超出范围,不必寻路。 if (isEnd(m_start->getX(),m_start->getY())|| isOut(m_end->getX(),m_end->getY())){ return false; } while (m_openSeq->count()) { //取得下一个搜索点 getNext(); removeFromOpen(m_current); //添加到closes addToClose(m_current->getX(),m_current->getY()); //处理相邻结点 if(checkNearby()){ return true; } } return false; }
// 将_open列表的1号object移到_close列表末尾 void Astar::fromOpenToClose() { AstarItem* temp = (AstarItem*)_open->getObjectAtIndex(1); _close->addObject(temp); removeFromOpen(); }
void AStar::createPath(Vec3f startPos, Vec3f endPos, levelGraph *level) { //no need to process this situation if(startPos == endPos) { return; } /*startPos[0] = (startPos[0] - level->levelMask->startingOffset[0]) / level->levelMask->scaleX; startPos[1] = 0.0f; startPos[2] = (startPos[2] - level->levelMask->startingOffset[2]) / level->levelMask->scaleZ; endPos[0] = (endPos[0] - level->levelMask->startingOffset[0]) / level->levelMask->scaleX; endPos[1] = 0.0f; endPos[2] = (endPos[2] - level->levelMask->startingOffset[2]) / level->levelMask->scaleZ; */ start = findNodeInGraph(startPos, level); goal = findNodeInGraph(endPos, level); //if goal is in collision zone, return so game does not freeze if(goal->neighbor[0] == NULL && goal->neighbor[1] == NULL && goal->neighbor[2] == NULL && goal->neighbor[3] == NULL) { //cout << "ERROR, goal is in collision zone" << endl; return; } open.push_back(start); //while lowest ranked node's postion in the open list is not equal to the goal's position //if it is equal we are done finding our path while(open.front()->pos != goal->pos) { current = open.front(); //cout<< current->pos << endl; //############################################################################################################## removeFromOpen(open.front()); //open.clear(); //put node in closed so we dont reprocess a node that we already processed closed.push_back(current); //process current's neighbors to look for the right path for(int i = 0; i < 4; i++) { if(current->neighbor[i] != NULL) { //float cost = g(current) + movementCost(current->neighbor[i]); ////if neighbor in open and cost less than g(neighbor) //if(inOpen(current->neighbor[i]) && cost < g(current->neighbor[i])) ////if(inOpen(current->neighbor[i]) && h(current) < h(current->neighbor[i])) //{ // //remove neighbor from open, because new path is better // removeFromOpen(current->neighbor[i]); // cout << "GGGGG" << endl; //} ////if neighbor in closed and cost less than g(neighbor) //else if(inClosed(current->neighbor[i]) && cost < g(current->neighbor[i])) ////else if(inClosed(current->neighbor[i]) && h(current) < h(current->neighbor[i])) //{ // removeFromClosed(current->neighbor[i]); // cout << "AAAA" << endl; //} //if neighbor not in closed and neighbor not in open if((!inOpen(current->neighbor[i])) && (!inClosed(current->neighbor[i]))) { open.push_back(current->neighbor[i]); current->neighbor[i]->rank = g(current->neighbor[i]) + h(current->neighbor[i]); current->neighbor[i]->parent = current; } } } //*******************SORT*********************************************// //bubble sort int check = open.size(); //ERROR check if(check > 1) { //sort open list from lowest rank to highest for(unsigned int counter = 0; counter < check; counter++) { list<node*>::iterator k = open.end(); k--; list<node*>::iterator m = open.end(); m--; m--; unsigned int countEnd = check - 1; while(countEnd > counter) { if((*k)->rank < ((*m)->rank)) { node *temp; temp = new node(); temp = (*k); (*k) = (*m); (*m) = temp; temp = NULL; delete temp; } if(countEnd-1 != counter) { k--; m--; } countEnd--; } } //optimizes pathfinding by shinking open list to fewer nodes to sort if(open.size() > 20) { unsigned int openSize = check / 2; list<node*>::iterator k = open.end(); k--; //remove some of the highest ranked nodes to make open list process faster for(unsigned int counter = 0; counter < openSize; counter++) { //put node in closed so we dont reprocess a node that we already processed closed.push_back((*k)); removeFromOpen((*k)); k = open.end(); k--; } } } else { //cout << "ERROR, open list in AStarPathFinding.h contains zero elements, NPC start point is in collision zone. " << endl; //clear the open and closed lists so they are ready for the next iteration open.clear(); closed.clear(); if(!firstTime) { //clear the path list from the previous determined path path.clear(); } return; } //*************************************************************************************************/ } //reconstruct path from goal to start by following parent pointers getPath( startPos, endPos, level->levelMask); //clear the open and closed lists so they are ready for the next iteration open.clear(); closed.clear(); }