void Enemy::ChangeDirection() { /*** central target point reached, set the position at the center of the target tile (for change direction correctly) ***/ if(mShortestPathArray.size() != 0 ) { //set the position at the center of the target tile this->mEntitySprite->setPosition( PathPlanner::GetInstance()->GetLevelMap()->positionForTileCoord(mEntityTile) ); //Get the next step to move to ShortestPathStep* step = mShortestPathArray.at(0); mTargetTile = step->GetTilePosition(); this->mDirection = ccpSub( mTargetTile, mEntityTile); // -m-Dir.y because the tile y is opposite of the cocos2d coordinate !!! IMPORTANT!!! mDirection.y *= -1; mShortestPathArray.erase(mShortestPathArray.begin()); mIsInCenterOfTile = true; } else mHasReachedTarget = true; //new random movement }
CCArray* PathPlanner::Calculate_A_Star(CCPoint source, CCPoint dest) { // bool isPathFound = false; bool forceStop = false; // 1. Insert the intial position in openList ShortestPathStep* tmp = new ShortestPathStep(source); tmp->autorelease(); this->InsertInOpenSteps(tmp); do { // 1. get the Lowest F cost in the open list //because the list is ordered, the lowest is the first ShortestPathStep* currentStep = dynamic_cast<ShortestPathStep*>(mOpenSteps->objectAtIndex(0)); //2. Add the current in the closed list mClosedSteps->addObject(currentStep); //3. remove from the open list mOpenSteps->removeObjectAtIndex(0); //check if is the current = destination, we have DONE! if(currentStep->GetTilePosition().equals(dest) ) { // create the path and start the move action and animation mOpenSteps->release(); this->mOpenSteps = NULL; mClosedSteps->release(); this->mClosedSteps = NULL; return this->constructPathAndStartAnimationFromStep(currentStep); } //4. Get adj tile coord of the current step std::vector<CCPoint> tmpAdjArray = m_pLevelMap->GetWalkableAdjacentTiles(currentStep->GetTilePosition()); std::vector<CCPoint>::iterator iter; for(iter = tmpAdjArray.begin(); iter < tmpAdjArray.end(); iter++) { CCPoint p = *iter; ShortestPathStep* step = new ShortestPathStep(p); // 4.1 // Check if the step isn't already in the closed set CCObject* iterSteps; CCARRAY_FOREACH(mClosedSteps, iterSteps) { ShortestPathStep *tmpStep = dynamic_cast<ShortestPathStep*>(iterSteps); if(step->isEqualTile(tmpStep)) { step->release(); forceStop = true; break; } } if(forceStop) { forceStop = false; continue; } //4.2 //Compute the cost from the current to the step int moveCost = CostToMoveFromStep(currentStep, step); //4.3 //check if the step is already in the open list //int indexStep = mOpenSteps->indexOfObject(step); int indexStep = -1; bool isPresent = false; iterSteps = NULL; CCARRAY_FOREACH(mOpenSteps, iterSteps) { indexStep++; ShortestPathStep *tmpStep = dynamic_cast<ShortestPathStep*>(iterSteps); if(step->isEqualTile(tmpStep)) { isPresent = true; break; } } if(!isPresent) { //4.4 // Add it, set parent step->SetParent(currentStep); //4.5 // set the G score step->SetGScore(currentStep->GetGScore() + moveCost); //4.6 // compute the H score, with manhattan step->SetHScore(this->ComputeH_Score(step->GetTilePosition(), dest)); //4.7 //now add in Open list, in correct position this->InsertInOpenSteps(step); //done, release the step step->release(); } else //already in the open list, recalculate the Fscore { step->release(); step = NULL; //get the old step step = dynamic_cast<ShortestPathStep*>(mOpenSteps->objectAtIndex(indexStep)); //5. Check if the old G score is lower than that step if( (currentStep->GetGScore() + moveCost) < step->GetGScore()) { //so we change the G score step->SetGScore(currentStep->GetGScore() + moveCost); // Because the G Score has changed, the F score may have changed too // So to keep the open list ordered we have to remove the step, and re-insert it with // the insert function which is preserving the list ordered by F score // We have to retain it before removing it from the list step->retain(); // Now we can removing it from the list without be afraid that it can be released mOpenSteps->removeObjectAtIndex(indexStep); // Re-insert it with the function which is preserving the list ordered by F score this->InsertInOpenSteps(step); step->release(); } } }