博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cocos2dx下的A星算法
阅读量:6375 次
发布时间:2019-06-23

本文共 4267 字,大约阅读时间需要 14 分钟。

        这是我依据这篇博文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();
    }

在这里

你可能感兴趣的文章
(转)Spring并发访问的线程安全性问题(高度总结)
查看>>
解决Activity启动黑屏和设置android:windowIsTranslucent不兼容activity切换动画的问题
查看>>
TextBox 英文文档
查看>>
linux系统调用函数---12
查看>>
C#开发SQLServer的Geometry和Geography存储
查看>>
GPUImage API文档之GPUImageInput协议
查看>>
EBS R12.2应用层关闭脚本的执行过程
查看>>
js:深闭包(范围:上)
查看>>
使用POI导入小数变成浮点数异常
查看>>
Logistic Regression的几个变种
查看>>
PopupMenu消失(Dismiss)抓住
查看>>
Determining if a point lies on the interior of a polygon
查看>>
在 Angular 中实现搜索关键字高亮
查看>>
[Javascript ] Array methods in depth - sort
查看>>
司机福利!Uber即将可以自己选目的地接单啦!
查看>>
MOGODB REDIS
查看>>
HDU 1231:最大连续子序列(DP)
查看>>
[java] java 中Unsafe类学习
查看>>
HDU 1231——最大连续子序列(DP)
查看>>
P1739 表达式括号匹配
查看>>