cocos2dx下的A星算法

来源:互联网 发布:yoast seo设置 编辑:程序博客网 时间:2024/05/01 23:43

        这是我根据这篇博文http://hi.baidu.com/wsapyoemdfacmqr/item/bdfb5c0a74c904d01ef0466d,来在cocos2dx上编写,这是最终的效果图:


红色的地方是运行轨迹,黑色是禁止区域,接下来是代码,请结合那篇博文观看:


首先创建地板类,必须要有x和y,还有根据那篇博文的h和g,这是h文件中的代码:

#include "cocos2d.h"

typedef enum _FloorState
{
    FloorGround,
    FloorRiver
} FloorState;

class Floor : public cocos2d::LayerColor
{
public:
    Floor();
    ~Floor(){}
    
    static int at(int x, int y);
    static Floor * create(const cocos2d::Color4B& color);
    bool initWithColor(const cocos2d::Color4B& color);
    
    int getF();
    
private:
    CC_SYNTHESIZE(int, _x, X);
    CC_SYNTHESIZE(int, _y, Y);
    
    CC_SYNTHESIZE(int, _h, H);
    CC_SYNTHESIZE(int, _g, G);
    
    CC_SYNTHESIZE(FloorState, _landForm, LandForm);
    
    CC_SYNTHESIZE(Floor *, _lastFloor, LastFloor);
};


基本上没有什么难度,另外,那个静态方法at使用了从数组中快速获取地板。

然后是cpp文件:

#include "Floor.h"

USING_NS_CC;

Floor::Floor()
{
    _x = 0;
    _y = 0;
    
    _h = -1;
    _g = -1;
    
    _lastFloor = NULL;
}

int Floor::at(int x, int y)
{
    return x + 28 * y;
}

Floor *Floor::create(const cocos2d::Color4B &color)
{
    Floor *_floor = new Floor();
    if ( _floor && _floor -> initWithColor( color ) )
    {
        _floor -> autorelease();
        return _floor;
    }
    
    delete _floor;
    _floor = NULL;
    return NULL;
}

bool Floor::initWithColor(const cocos2d::Color4B &color)
{
    if ( LayerColor::initWithColor(color, 39, 39) )
    {
        return true;
    }
    
    return false;
}

int Floor::getF()
{
    return _h + _g;
}


然后在运行的Layer中:

void MainScene::createGround()
{
    for (int y = 0; y < 18; y++)
    {
        for (int x = 0; x < 28; x++)
        {
            auto _floor = Floor::create( Color4B(255, 255, 255, 255) );
            _floor -> setPosition(x * (_floor -> getContentSize().width + 1), y * (_floor -> getContentSize().height + 1));
            _floor -> setX(x);
            _floor -> setY(y);
            _floor -> setLandForm( FloorGround );
            this -> addChild( _floor );
            
            if ( (x == 15 && y < 7) || (x == 3 && y < 10) || (y == 12 && x < 20) || (x == 5 && y > 8) || (x == 13 && y > 1) )
            {
                _floor -> setColor( Color3B(0, 0, 0) );
                _floor -> setLandForm( FloorRiver );
            }
            ground.pushBack( _floor );
        }
    }
}

其中,这个方法:_floor -> setLandForm( FloorRiver )使用来制造禁止区域

然后添加起点和终点:


    end = Floor::create( Color4B(0, 255, 255, 10) );
    end -> setPosition( (ground.at( Floor::at(24, 14) )) -> getPosition() );
    end -> setX(24);
    end -> setY(14);
    this -> addChild( end );
    
    origin = Floor::create( Color4B(255, 255, 0, 255) );
    origin -> setPosition( (ground.at( Floor::at(0, 0) )) -> getPosition() );
    origin -> setX(0);
    origin -> setY(0);
    origin -> setH( fabs((end -> getX() - origin -> getX())) + fabs( end -> getY() - origin -> getY() ) );
    origin -> setG(0);
    this -> addChild( origin );
    open.pushBack( origin );


在这些完成后,就是需要使用A*算法来计算出路径了

首先从open数组中寻找F最小的地板;之后,将上下左右的地板做个判断,是否加入数组中,这部分放在一个死循环中,当加入的地板正是终点时,可以结束:

while (1)
    {
        Vector< Floor * >::iterator index = open.begin();
        Vector< Floor * >::iterator minF = index;
        for (; index != open.end(); index++)
        {
            if ( (*index) -> getF() < (*minF) -> getF() )
            {
                minF = index;
            }
        }
        
        Floor *_origin = (*minF);
        
        handleFloor(_origin, _origin -> getX(), _origin -> getY() - 1);
        handleFloor(_origin, _origin -> getX(), _origin -> getY() + 1);
        handleFloor(_origin, _origin -> getX() - 1, _origin -> getY());
        handleFloor(_origin, _origin -> getX() + 1, _origin -> getY());
        
        open.eraseObject( _origin );
        close.pushBack( _origin );
        _origin -> setColor( Color3B(0, 255, 0) );
        
        Floor *getEnd = open.at( open.size() - 1 );
        if ( getEnd -> getX() == end -> getX() && getEnd -> getY() == end -> getY() )
        {
            CCLOG("ENDG");
            return;
        }
    }

handleFloor函数是用来判断该地板是否能够加入数组中

void MainScene::handleFloor(Floor *_floor, int x, int y)
{
    if ( x < 0 || y < 0 )
    {
        return;
    }
    Floor *handle = ground.at( Floor::at(x, y) );
    handle -> setX(x);
    handle -> setY(y);
    handle -> setH( fabs((end -> getX() - handle -> getX())) + fabs( end -> getY() - handle -> getY() ) );
    handle -> setG( fabs((origin -> getX() - handle -> getX())) + fabs( origin -> getY() - handle -> getY() ) );
    JUDGE( handle, _floor );
}

#define JUDGE(__FLOOR__, __LAST__)    \
if ( !open.contains(__FLOOR__) && !close.contains(__FLOOR__) && __FLOOR__ -> getLandForm() != FloorRiver )  \
{ \
open.pushBack( __FLOOR__ ); \
__FLOOR__ -> setColor( Color3B(100, 100, 100) ); \
__FLOOR__ -> setLastFloor( __LAST__ );  \
}   \


之后,就是取出open数组终的最后一块地板,并可以获取这块地板的上一块地板,并将其颜色改变


    Floor *index = open.at( open.size() - 1 );
    
    while ( index -> getLastFloor() != NULL )
    {
        index -> setColor( Color3B(255, 0, 0) );
        index = index -> getLastFloor();
    }


在这里下载

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 生完孩子肚子越来越大怎么办 怀孕8个月肚子小怎么办 孕晚期胎儿不长怎么办 肚子上肉特别多怎么办 奶堵了有硬块怎么办 便秘5天肚子胀怎么办 上火大便拉不出来怎么办 大便拉不出来肚子痛怎么办 戒奶奶涨有硬块怎么办 忌奶的时候涨奶怎么办 娃儿隔奶,,奶涨怎么办 狗肚子很大很鼓怎么办 注册不了的二建怎么办 专升本没考过怎么办 警察乱拘留人该怎么办 玩英雄联盟太卡怎么办 一方离婚证丢了怎么办 遭遇呼死你软件怎么办 开车遇见碰瓷的怎么办 遇到碰瓷老人的怎么办 睿强遥控锁坏了怎么办 地暖分水器坏了怎么办 京东赠品无货怎么办 图书馆的书丢了怎么办 三次临牌用完了怎么办 m3u8文件只有10k怎么办 寿县到淮南高铁怎么办 冰箱停电肉臭了怎么办 新买冰箱有异味怎么办 海康用户被锁定怎么办 大华dss录像没了怎么办 燃气软管超过2米怎么办 中央空调进了水怎么办 车门被划了一道怎么办 镜前灯没有留线怎么办 永大电梯故障44怎么办 物业把电梯停了怎么办 捷信贷款还不起怎么办 c1驾驶证扣12分怎么办 打架被警察抓了怎么办 寄快递写错电话怎么办