cocosdx里面A*算法的实现#ifndef __CAT_SPRITE_H__ #define __CAT_SPRITE_H__ #include "HelloWorldScene.h" #incl

CatSprite.CPP:

#include "CatSprite.h"
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"


USING_NS_CC;
using namespace CocosDenshion;


CatSprite::ShortestPathStep::ShortestPathStep() :
_position(Point::ZERO),
_gScore(0),
_hScore(0),
_parent(nullptr)
{
}


CatSprite::ShortestPathStep::~ShortestPathStep()
{
}


CatSprite::ShortestPathStep *CatSprite::ShortestPathStep::createWithPosition(const Point &pos)
{
ShortestPathStep *pRet = new ShortestPathStep();
if (pRet && pRet->initWithPosition(pos))
{
pRet->autorelease();
return pRet;
}
else
{
CC_SAFE_DELETE(pRet);
return nullptr;
}
}
bool CatSprite::ShortestPathStep::initWithPosition(const Point &pos)
{
bool bRet = false;
do
{
this->setPosition(pos);


bRet = true;
} while (0);


return bRet;
}


int CatSprite::ShortestPathStep::getFScore() const
{
return this->getGScore() + this->getHScore();
}


bool CatSprite::ShortestPathStep::isEqual(const CatSprite::ShortestPathStep *other) const
{
return this->getPosition() == other->getPosition();
}


std::string CatSprite::ShortestPathStep::getDescription() const
{
return StringUtils::format("pos=[%.0f;%.0f]  g=%d  h=%d  f=%d",
this->getPosition().x, this->getPosition().y,
this->getGScore(), this->getHScore(), this->getFScore());
}


CatSprite::CatSprite() :
    _numBones(0),
    _facingForwardAnimation(nullptr),
    _facingBackAnimation(nullptr),
    _facingLeftAnimation(nullptr),
    _facingRightAnimation(nullptr),
    _curAnimation(nullptr),
    _curAnimate(nullptr)
{
}


CatSprite::~CatSprite()
{
    CC_SAFE_RELEASE_NULL(_facingForwardAnimation);
    CC_SAFE_RELEASE_NULL(_facingBackAnimation);
    CC_SAFE_RELEASE_NULL(_facingLeftAnimation);
    CC_SAFE_RELEASE_NULL(_facingRightAnimation);
}


CatSprite *CatSprite::createWithLayer(HelloWorld *layer)
{
    CatSprite *pRet = new CatSprite();
    if (pRet && pRet->initWithLayer(layer))
    {
        pRet->autorelease();
        return pRet;
    }
    else
    {
        CC_SAFE_DELETE(pRet);
        return nullptr;
    }
}


bool CatSprite::initWithLayer(HelloWorld *layer)
{
    bool bRet = false;
    do 
    {
        CC_BREAK_IF(!this->initWithSpriteFrameName("cat_forward_1.png"));
        
        _layer = layer;
        
        _facingForwardAnimation = this->createCatAnimation("forward");
        _facingForwardAnimation->retain();
        _facingBackAnimation = this->createCatAnimation("back");
        _facingBackAnimation->retain();
        _facingLeftAnimation = this->createCatAnimation("left");
        _facingLeftAnimation->retain();
        _facingRightAnimation = this->createCatAnimation("right");
        _facingRightAnimation->retain();


        bRet = true;
    } while (0);


    return bRet;
}


void CatSprite::moveToward(const Point &target)
{
this->stopActionByTag(1);
Point fromTileCoord = _layer->tileCoordForPosition(this->getPosition());//其中"From"就是猫的方块坐标,"To"就是所点击的方块坐标。
Point toTileCoord = _layer->tileCoordForPosition(target);


if (fromTileCoord == toTileCoord)
{
CCLOG("You're already there! :P");
return;
}


if (!_layer->isValidTileCoord(toTileCoord) || _layer->isWallAtTileCoord(toTileCoord))
{
SimpleAudioEngine::getInstance()->playEffect("hitWall.wav");
return;
}


CCLOG("From: %f, %f", fromTileCoord.x, fromTileCoord.y);//其中"From"就是猫的方块坐标,"To"就是所点击的方块坐标。
CCLOG("To: %f, %f", toTileCoord.x, toTileCoord.y);
//bool pathFound = false;

_spOpenSteps.clear();
_spClosedSteps.clear();


// 首先,添加猫的方块坐标到open列表
this->insertInOpenSteps(ShortestPathStep::createWithPosition(fromTileCoord));


do
{
// 得到最小的F值步骤
// 因为是有序列表,第一个步骤总是最小的F值
ShortestPathStep *currentStep = _spOpenSteps.at(0);


// 添加当前步骤到closed列表
_spClosedSteps.pushBack(currentStep);


// 将它从open列表里面移除
// 需要注意的是,如果想要先从open列表里面移除,应小心对象的内存
_spOpenSteps.erase(0);


// 如果当前步骤是目标方块坐标,那么就完成了
if (currentStep->getPosition() == toTileCoord)
{
this->constructPathAndStartAnimationFromStep(currentStep);
_spOpenSteps.clear();
_spClosedSteps.clear();
break;
}


// 得到当前步骤的相邻方块坐标
PointArray *adjSteps = _layer->walkableAdjacentTilesCoordForTileCoord(currentStep->getPosition());
for (ssize_t i = 0; i < adjSteps->count(); ++i)
{
ShortestPathStep *step = ShortestPathStep::createWithPosition(adjSteps->getControlPointAtIndex(i));


// 检查步骤是不是已经在closed列表
if (this->getStepIndex(_spClosedSteps, step) != -1)
{
continue;
}


// 计算从当前步骤到此步骤的成本
int moveCost = this->costToMoveFromStepToAdjacentStep(currentStep, step);


// 检查此步骤是否已经在open列表
ssize_t index = this->getStepIndex(_spOpenSteps, step);


// 不在open列表,添加它
if (index == -1)
{
// 设置当前步骤作为上一步操作
step->setParent(currentStep);


// G值等同于上一步的G值 + 从上一步到这里的成本
int fdgd=currentStep->getGScore() + moveCost;
step->setGScore(currentStep->getGScore() + moveCost);


// H值即是从此步骤到目标方块坐标的移动量估算值
step->setHScore(this->computeHScoreFromCoordToCoord(step->getPosition(), toTileCoord));


// 按序添加到open列表
this->insertInOpenSteps(step);
}
else
{
// 获取旧的步骤,其值已经计算过
step = _spOpenSteps.at(index);


// 检查G值是否低于当前步骤到此步骤的值
if ((currentStep->getGScore() + moveCost) < step->getGScore())
{
// G值等同于上一步的G值 + 从上一步到这里的成本
step->setGScore(currentStep->getGScore() + moveCost);


// 因为G值改变了,F值也会跟着改变
// 所以为了保持open列表有序,需要将此步骤移除,再重新按序插入


// 在移除之前,需要先保持引用
step->retain();


// 现在可以放心移除,不用担心被释放
_spOpenSteps.erase(index);


// 重新按序插入
this->insertInOpenSteps(step);


// 现在可以释放它了,因为open列表应该持有它
step->release();
}
}
}
} while (_spOpenSteps.size() > 0);


if (_shortestPath.empty())
{
SimpleAudioEngine::getInstance()->playEffect("hitWall.wav");
}
}


void CatSprite::constructPathAndStartAnimationFromStep(CatSprite::ShortestPathStep *step)
{
_shortestPath.clear();


do
{
// 起始位置不要进行添加
if (step->getParent())
{
// 总是插入到索引0的位置,以便反转路径
_shortestPath.insert(0, step);
}
step = step->getParent();   // 倒退
} while (step);                 // 直到没有上一步


for (const ShortestPathStep *s : _shortestPath)
{
CCLOG("%s", s->getDescription().c_str());
}
this->popStepAndAnimate();
}
ssize_t CatSprite::getStepIndex(const cocos2d::Vector &steps, const CatSprite::ShortestPathStep *step)
{
for (ssize_t i = 0; i < steps.size(); ++i)
{
if (steps.at(i)->isEqual(step))
{
return i;
}
}
return -1;
}
void CatSprite::insertInOpenSteps(CatSprite::ShortestPathStep *step)
{
int stepFScore = step->getFScore();
ssize_t count = _spOpenSteps.size();
ssize_t i = 0;
for (; i < count; ++i)
{
int sdf= _spOpenSteps.at(i)->getFScore();
if (stepFScore <= _spOpenSteps.at(i)->getFScore())
{
break;
}
}
_spOpenSteps.insert(i, step);
}


int CatSprite::computeHScoreFromCoordToCoord(const Point &fromCoord, const Point &toCoord)
{
// 这里使用曼哈顿方法,计算从当前步骤到达目标步骤,在水平和垂直方向总的步数
// 忽略了可能在路上的各种障碍
return abs(toCoord.x - fromCoord.x) + abs(toCoord.y - fromCoord.y);
}


int CatSprite::costToMoveFromStepToAdjacentStep(const ShortestPathStep *fromStep, const ShortestPathStep *toStep)
{
// 因为不能斜着走,而且由于地形就是可行走和不可行走的成本都是一样的
// 如果能够对角移动,或者有沼泽、山丘等等,那么它必须是不同的
return ((fromStep->getPosition().x != toStep->getPosition().x)//对角线为14,上下左右为10,根据勾股定理
&& (fromStep->getPosition().y != toStep->getPosition().y)) ? 14 : 10;
}
Animation *CatSprite::createCatAnimation(const char *animType)
{
    Animation *animation = Animation::create();
    for (int i = 1; i <= 2; ++i)
    {
        animation->addSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(StringUtils::format("cat_%s_%d.png", animType, i)));
    }
    animation->setDelayPerUnit(0.2f);
    return animation;
}


void CatSprite::runAnimation(Animation *animation)
{
    if (_curAnimation == animation)
    {
        return;
    }
    
    _curAnimation = animation;
    if (_curAnimate != nullptr)
    {
        this->stopAction(_curAnimate);
    }
    
    _curAnimate = RepeatForever::create(Animate::create(animation));
    this->runAction(_curAnimate);
}
void CatSprite::popStepAndAnimate()
{
Point currentPosition = _layer->tileCoordForPosition(this->getPosition());


if (_layer->isBoneAtTilecoord(currentPosition))
{
SimpleAudioEngine::getInstance()->playEffect("pickup.wav");
_numBones++;
_layer->showNumBones(_numBones);
_layer->removeObjectAtTileCoord(currentPosition);
}
else if (_layer->isDogAtTilecoord(currentPosition))
{
if (_numBones == 0)
{
_layer->loseGame();
return;
}
else
{
_numBones--;
_layer->showNumBones(_numBones);
_layer->removeObjectAtTileCoord(currentPosition);
SimpleAudioEngine::getInstance()->playEffect("catAttack.wav");
}
}
else if (_layer->isExitAtTilecoord(currentPosition))
{
_layer->winGame();
return;
}
else
{
SimpleAudioEngine::getInstance()->playEffect("step.wav");
}


// 检查是否仍有路径步骤需要前进
if (_shortestPath.size() == 0)
{
return;
}


// 得到下一步移动的步骤
ShortestPathStep *s = _shortestPath.at(0);


Point futurePosition = s->getPosition();
Point diff = futurePosition - currentPosition;
if (abs(diff.x) > abs(diff.y))
{
if (diff.x > 0)
{
this->runAnimation(_facingRightAnimation);
}
else
{
this->runAnimation(_facingLeftAnimation);
}
}
else
{
if (diff.y > 0)
{
this->runAnimation(_facingForwardAnimation);
}
else
{
this->runAnimation(_facingBackAnimation);
}
}


// 准备动作和回调
MoveTo *moveAction = MoveTo::create(0.4f, _layer->positionForTileCoord(s->getPosition()));
CallFunc *moveCallback = CallFunc::create(CC_CALLBACK_0(CatSprite::popStepAndAnimate, this));


// 移除步骤
_shortestPath.erase(0);


// 运行动作
Sequence *moveSequence = Sequence::create(moveAction, moveCallback, nullptr);
moveSequence->setTag(1);
this->runAction(moveSequence);
}


CatSprite.H:

#ifndef __CAT_SPRITE_H__
#define __CAT_SPRITE_H__
#include "HelloWorldScene.h"
#include "cocos2d.h"






class CatSprite : public cocos2d::Sprite
{

public:
class ShortestPathStep : public cocos2d::Object
{
public:
ShortestPathStep();
~ShortestPathStep();
//cocos2d::Vector _spOpenSteps;

static ShortestPathStep *createWithPosition(const cocos2d::Point &pos);
bool initWithPosition(const cocos2d::Point &pos);


int getFScore() const;
bool isEqual(const ShortestPathStep *other) const;
std::string getDescription() const;


CC_SYNTHESIZE(cocos2d::Point, _position, Position);
CC_SYNTHESIZE(int, _gScore, GScore);
CC_SYNTHESIZE(int, _hScore, HScore);
CC_SYNTHESIZE(ShortestPathStep*, _parent, Parent);
};




void constructPathAndStartAnimationFromStep(CatSprite::ShortestPathStep *step);
cocos2d::Vector _shortestPath;
void popStepAndAnimate();
cocos2d::Vector _spOpenSteps;
cocos2d::Vector _spClosedSteps;
    ssize_t getStepIndex(const cocos2d::Vector &steps, const CatSprite::ShortestPathStep *step);
int costToMoveFromStepToAdjacentStep(const ShortestPathStep *fromStep, const ShortestPathStep *toStep);
int computeHScoreFromCoordToCoord(const Point &fromCoord, const Point &toCoord);
void insertInOpenSteps(CatSprite::ShortestPathStep *step);
    CatSprite();
    ~CatSprite();
    
    static CatSprite *createWithLayer(HelloWorld *layer);
    bool initWithLayer(HelloWorld *layer);


    void moveToward(const cocos2d::Point &target);
    
    CC_SYNTHESIZE_READONLY(int, _numBones, NumBones);
    
private:
    cocos2d::Animation *createCatAnimation(const char *animType);
    void runAnimation(cocos2d::Animation *animation);
    
private:
    HelloWorld *_layer;
    cocos2d::Animation *_facingForwardAnimation;
    cocos2d::Animation *_facingBackAnimation;
    cocos2d::Animation *_facingLeftAnimation;
    cocos2d::Animation *_facingRightAnimation;
    cocos2d::Animation *_curAnimation;
    cocos2d::Action *_curAnimate;
};




#endif // __CAT_SPRITE_H__



HelloWorld.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__


#include "cocos2d.h"
using namespace cocos2d;
class CatSprite;


class HelloWorld : public cocos2d::Layer
{
public:
    HelloWorld();
    ~HelloWorld();
    
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();


    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();      
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);


    bool isWallAtTileCoord(const cocos2d::Point &tileCoord) const;
    bool isBoneAtTilecoord(const cocos2d::Point &tileCoord) const;
    bool isDogAtTilecoord(const cocos2d::Point &tileCoord) const;
    bool isExitAtTilecoord(const cocos2d::Point &tileCoord) const;
    cocos2d::Point tileCoordForPosition(const cocos2d::Point &position) const;
    cocos2d::Point positionForTileCoord(const cocos2d::Point &tileCoord) const;
    void removeObjectAtTileCoord(const cocos2d::Point &tileCoord);
    void winGame();
    void loseGame();
    void showNumBones(int numBones);
    bool isValidTileCoord(const cocos2d::Point &tileCoord) const;
    PointArray *walkableAdjacentTilesCoordForTileCoord(const Point &tileCoord) const;
private:
    bool isPropAtTileCoordForLayer(const char *prop, const cocos2d::Point &tileCoord, cocos2d::TMXLayer *layer) const;
    void setViewpointCenter(const cocos2d::Point &position);
    void showRestartMenu();
    void endScene();


    virtual void update(float delta) override;
    
private:
    cocos2d::TMXTiledMap *_tileMap;
    cocos2d::TMXLayer *_bgLayer;
    cocos2d::TMXLayer *_objectLayer;
    cocos2d::SpriteBatchNode *_batchNode;
    CatSprite *_cat;
    bool _gameOver;
    bool _won;
    cocos2d::LabelBMFont *_bonesCount;
};
本文来自:llkk890320的博客,原文网址:http://blog.csdn.net/llkk890320/article/details/25886653  

#endif

HelloWorld.cpp

#include "HelloWorldScene.h"
#include "CatSprite.h"
#include "SimpleAudioEngine.h"


USING_NS_CC;
using namespace CocosDenshion;


Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();


    // add layer as a child to scene
    scene->addChild(layer);


    // return the scene
    return scene;
}


HelloWorld::HelloWorld():
    _tileMap(nullptr),
    _bgLayer(nullptr),
    _objectLayer(nullptr),
    _batchNode(nullptr),
    _cat(nullptr),
    _gameOver(false),
    _won(false),
    _bonesCount(nullptr)
{
}


HelloWorld::~HelloWorld()
{
}


bool HelloWorld::init()
{
    bool bRet = false;
    do
    {
        CC_BREAK_IF(!CCLayer::init());


        _tileMap = TMXTiledMap::create("CatMaze.tmx");
        this->addChild(_tileMap);


        Point spawnTileCoord(24, 0);
        Point spawnPos = this->positionForTileCoord(spawnTileCoord);
        this->setViewpointCenter(spawnPos);


        SimpleAudioEngine::getInstance()->playBackgroundMusic("SuddenDefeat.mp3", true);
        SimpleAudioEngine::getInstance()->preloadEffect("pickup.wav");
        SimpleAudioEngine::getInstance()->preloadEffect("catAttack.wav");
        SimpleAudioEngine::getInstance()->preloadEffect("hitWall.wav");
        SimpleAudioEngine::getInstance()->preloadEffect("lose.wav");
        SimpleAudioEngine::getInstance()->preloadEffect("step.wav");
        SimpleAudioEngine::getInstance()->preloadEffect("win.wav");


        _bgLayer = _tileMap->getLayer("Background");
        _objectLayer = _tileMap->getLayer("Objects");


        SpriteFrameCache::getInstance()->addSpriteFramesWithFile("CatMaze.plist");
        _batchNode = SpriteBatchNode::create("CatMaze.png");
        _tileMap->addChild(_batchNode);
        _cat = CatSprite::createWithLayer(this);
        _cat->setPosition(spawnPos);
        _batchNode->addChild(_cat);


        _bonesCount = LabelBMFont::create("Bones: 0", "Arial.fnt");
        _bonesCount->setPosition(400, 30);
        this->addChild(_bonesCount);


        auto listener = EventListenerTouchOneByOne::create();
        listener->setSwallowTouches(true);
        listener->onTouchBegan = [this](Touch *touch, Event *event){
            if (_gameOver)
            {
                return false;
            }


            Point touchLocation = _tileMap->convertTouchToNodeSpace(touch);
            _cat->moveToward(touchLocation);
            return true;
        };
        _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);


        this->scheduleUpdate();


        bRet = true;
    } while (0);
    return bRet;
}


bool HelloWorld::isWallAtTileCoord(const Point &tileCoord) const
{
    return this->isPropAtTileCoordForLayer("Wall", tileCoord, _bgLayer);
}


bool HelloWorld::isBoneAtTilecoord(const Point &tileCoord) const
{
    return this->isPropAtTileCoordForLayer("Bone", tileCoord, _objectLayer);
}


bool HelloWorld::isDogAtTilecoord(const Point &tileCoord) const
{
    return this->isPropAtTileCoordForLayer("Dog", tileCoord, _objectLayer);
}


bool HelloWorld::isExitAtTilecoord(const Point &tileCoord) const
{
    return this->isPropAtTileCoordForLayer("Exit", tileCoord, _objectLayer);
}


Point HelloWorld::tileCoordForPosition(const Point &position) const//猫的方块坐标
{
    int x = position.x / _tileMap->getTileSize().width;
    int y = ((_tileMap->getMapSize().height * _tileMap->getTileSize().height) - position.y) / _tileMap->getTileSize().height;
CCLOG("%d    %d  catPosition",x,y);
    return Point(x, y);
}


Point HelloWorld::positionForTileCoord(const Point &tileCoord) const
{
    int x = (tileCoord.x * _tileMap->getTileSize().width) + _tileMap->getTileSize().width / 2;//getTileSize().width/height分别以像素为单位得出一块的宽度和高度
    int y = (_tileMap->getMapSize().height * _tileMap->getTileSize().height) -
            (tileCoord.y * _tileMap->getTileSize().height) - _tileMap->getTileSize().height / 2;//etMapSize().width/height分别得出在x轴方向上总的块数,在y轴方向上总的块数
    return Point(x, y);
}


void HelloWorld::removeObjectAtTileCoord(const Point &tileCoord)
{
    _objectLayer->removeTileAt(tileCoord);
}


void HelloWorld::winGame()
{
    _gameOver = true;
    _won = true;
    SimpleAudioEngine::getInstance()->playEffect("win.wav");
    this->endScene();
}


void HelloWorld::loseGame()
{
    _gameOver = true;
    _won = false;
    SimpleAudioEngine::getInstance()->playEffect("lose.wav");
    this->endScene();
}


void HelloWorld::showNumBones(int numBones)
{
    _bonesCount->setString(StringUtils::format("Bones: %d", numBones));
}


bool HelloWorld::isPropAtTileCoordForLayer(const char *prop, const Point &tileCoord, TMXLayer *layer) const
{
    if (!this->isValidTileCoord(tileCoord))
    {
        return false;
    }
    
    int gid = layer->getTileGIDAt(tileCoord);
    Value properties = _tileMap->getPropertiesForGID(gid);
    if (properties.isNull())
    {
        return false;
    }
    return properties.asValueMap().find(prop) != properties.asValueMap().end();
}


bool HelloWorld::isValidTileCoord(const Point &tileCoord) const
{
    if (tileCoord.x < 0 || tileCoord.y < 0 ||
        tileCoord.x >= _tileMap->getMapSize().width ||
        tileCoord.y >= _tileMap->getMapSize().height)
    {
        return false;
    }
    else
    {
        return true;
    }
}


void HelloWorld::setViewpointCenter(const Point &position)
{
    Size winSize = Director::getInstance()->getWinSize();


    int x = MAX(position.x, winSize.width / 2);
    int y = MAX(position.y, winSize.height / 2);
    x = MIN(x, (_tileMap->getMapSize().width * _tileMap->getTileSize().width) - winSize.width / 2);
    y = MIN(y, (_tileMap->getMapSize().height * _tileMap->getTileSize().height) - winSize.height / 2);
    Point actualPosition(x, y);


    Point centerOfView(winSize.width / 2, winSize.height / 2);
    Point viewPoint = centerOfView - actualPosition;


    _tileMap->setPosition(viewPoint);
}


void HelloWorld::showRestartMenu()
{
    Size winSize = Director::getInstance()->getWinSize();


    const char *message;
    if (_won)
    {
        message = "You win!";
    }
    else
    {
        message = "You lose!";
    }


    LabelBMFont *label = LabelBMFont::create(message, "Arial.fnt");
    label->setScale(0.1f);
    label->setPosition(winSize.width / 2, winSize.height * 0.6f);
    this->addChild(label);


    LabelBMFont *restartLabel = LabelBMFont::create("Restart", "Arial.fnt");
    MenuItemLabel *restartItem = MenuItemLabel::create(restartLabel, [](Object *sender){
        Director::getInstance()->replaceScene(TransitionZoomFlipX::create(0.5f, HelloWorld::createScene()));
    });
    restartItem->setScale(0.1f);
    restartItem->setPosition(winSize.width / 2, winSize.height * 0.4f);


    Menu *menu = Menu::createWithItem(restartItem);
    menu->setPosition(Point::ZERO);
    this->addChild(menu);


    restartItem->runAction(ScaleTo::create(0.5f, 1.0f));
    label->runAction(ScaleTo::create(0.5f, 1.0f));
}


void HelloWorld::endScene()
{
    _cat->runAction(Sequence::create(ScaleBy::create(0.5f, 3.0f),
                                     DelayTime::create(1.0f),
                                     ScaleTo::create(0.5f, 0.0f),
                                     CallFunc::create(CC_CALLBACK_0(HelloWorld::showRestartMenu, this)),
                                     nullptr));
    _cat->runAction(RepeatForever::create(RotateBy::create(0.5f, 360.0f)));
}


void HelloWorld::update(float delta)
{
    this->setViewpointCenter(_cat->getPosition());
}


PointArray *HelloWorld::walkableAdjacentTilesCoordForTileCoord(const Point &tileCoord) const//tileCoord为当前坐标,也就是猫所在的位置


{
PointArray *tmp = PointArray::create(8);


bool t = false;
bool l = false;
bool b = false;
bool r = false;


// 上
Point p(tileCoord.x, tileCoord.y - 1);
if (this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
t = true;
}


// 左
p.setPoint(tileCoord.x - 1, tileCoord.y);
if (this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
l = true;
}


// 下
p.setPoint(tileCoord.x, tileCoord.y + 1);
if (this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
b = true;
}


// 右
p.setPoint(tileCoord.x + 1, tileCoord.y);
if (this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
r = true;
}


// 左上
p.setPoint(tileCoord.x - 1, tileCoord.y - 1);
if (t && l && this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
}


// 左下
p.setPoint(tileCoord.x - 1, tileCoord.y + 1);
if (b && l && this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
}


// 右上
p.setPoint(tileCoord.x + 1, tileCoord.y - 1);
if (t && r && this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
}


// 右下
p.setPoint(tileCoord.x + 1, tileCoord.y + 1);
if (b && r && this->isValidTileCoord(p) && !this->isWallAtTileCoord(p))
{
tmp->addControlPoint(p);
}


return tmp;
}

本文来自llkk890320的博客,原文网址:http://blog.csdn.net/llkk890320/article/details/25886653

你可能感兴趣的:(cocosdx里面A*算法的实现#ifndef __CAT_SPRITE_H__ #define __CAT_SPRITE_H__ #include "HelloWorldScene.h" #incl)