void FloatingSprite::moveStepByStep() { if(_FoundPathSteps.empty()){ return; } PathStep* step = _FoundPathSteps.at(0); Point stepPos = _HelloLayer->getPositionForTileCoord(step->getPosition()); MoveTo* moveAction = MoveTo::create(0.3f, stepPos); CallFunc* moveCallback = CallFunc::create(CC_CALLBACK_0(FloatingSprite::moveStepByStep, this)); _FoundPathSteps.erase(0); Sequence* moveSeq = Sequence::create(moveAction,moveCallback, NULL); moveSeq->setTag(TAG_FOR_MOVING); this->runAction(moveSeq); if(_FoundPathSteps.empty()){ _HelloLayer->setPlayerPosition(stepPos); _HelloLayer->setViewPointCenter(stepPos); } }
//This is the function for A-star pathfinding and moving void FloatingSprite::moveTowardTarget(const Point &target) { if(!_HelloLayer){ return; } //Stop current movint action and start a new pathfinding this->stopActionByTag(TAG_FOR_MOVING); Point fromTileCoord = _HelloLayer->getTileCoordForPosition(this->getPosition()); Point toTileCoord = _HelloLayer->getTileCoordForPosition(target); if(fromTileCoord == toTileCoord){ log("It's already there"); return; } if((_HelloLayer->isBlockageTile(toTileCoord)) || !(_HelloLayer->isValidTile(toTileCoord))){ log("Target [%f,%f] is unaccessible",toTileCoord.x, toTileCoord.y); return; } log("From: %f, %f", fromTileCoord.x, fromTileCoord.y); log("To: %f, %f", toTileCoord.x, toTileCoord.y); _OpenSteps.clear(); _ClosedSteps.clear(); _FoundPathSteps.clear(); //Add current position(start position) this->insertInOpenSteps(PathStep::createWithPosition(fromTileCoord)); do{ //1. get the top step in open steps array, push it to close steps array, then check the step PathStep* currentStep = _OpenSteps.at(0); _ClosedSteps.pushBack(currentStep); _OpenSteps.erase(0); //current step is the target to move, finished //log("%s",currentStep->getDescription().c_str()); if(currentStep->getPosition() == toTileCoord){ PathStep* tmpStep = currentStep; log("Path found"); //Got the path, start moving to the target point buildFoundedPathSteps(tmpStep); moveStepByStep(); _OpenSteps.clear(); _ClosedSteps.clear(); break; } //Check all adjacent tiles, put it into open steps array according to the F score PointArray* adjSteps = _HelloLayer->accessibleTilesAdjacentToTileCoord(currentStep->getPosition()); for(ssize_t i = 0; i < adjSteps->count(); i++){ PathStep* step = PathStep::createWithPosition(adjSteps->getControlPointAtIndex(i)); //log("%s",step->getDescription().c_str()); if(this->getStepIndex(_ClosedSteps,step) != -1){ //the step is already in the closed steps, ignore continue; } int moveCost = this->calcCostFromStepToAdjacent(currentStep, step); ssize_t openIndex = this->getStepIndex(_OpenSteps, step); if(openIndex == -1){ //this step is not in the open steps array, calc scores and put it into the array step->setParent(currentStep); step->setGScore(currentStep->getGScore() + moveCost); step->setHScore(this->calcHScoreFromCoordToCoord(step->getPosition(), toTileCoord)); this->insertInOpenSteps(step); }else{ step = _OpenSteps.at(openIndex); //this step is already in the open steps array ,recalc scores and refine the score and parent if((currentStep->getGScore() + moveCost) < step->getGScore()){ //Fix me: why not set parent? step->setParent(currentStep); step->setGScore(currentStep->getGScore() + moveCost); step->retain(); _OpenSteps.erase(openIndex); this->insertInOpenSteps(step); step->release(); } } } }while(_OpenSteps.size() > 0); if(_FoundPathSteps.empty()){ log("Cannot find a path to the destination"); } }