-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
296 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
#include "AstarLayer.h" | ||
|
||
using namespace cocos2d; | ||
|
||
static AStar* _instance = nullptr; | ||
|
||
ANode* ANode::create() | ||
{ | ||
ANode* node = new ANode(); | ||
if (node && node->init()) { | ||
node->autorelease(); | ||
return node; | ||
} | ||
else { | ||
CC_SAFE_DELETE(node); | ||
return nullptr; | ||
} | ||
} | ||
|
||
bool ANode::init() | ||
{ | ||
if (!Node::init()) { | ||
return false; | ||
} | ||
drawNode = DrawNode::create(); | ||
setType(Type::kNormal); | ||
this->addChild(drawNode); | ||
this->setContentSize(Size(aWidth, aWidth)); | ||
this->setAnchorPoint(Vec2(0.5, 0.5)); | ||
return true; | ||
} | ||
|
||
bool ANode::setType(Type type) | ||
{ | ||
Color4F color; | ||
switch (type) | ||
{ | ||
case ANode::Type::kNormal: | ||
color = Color4F::MAGENTA; | ||
break; | ||
case ANode::Type::kWall: | ||
color = Color4F(0x8b/255.0f, 0x57/255.0f, 0x42/255.0f, 1); | ||
break; | ||
case ANode::Type::kSrc: | ||
color = Color4F(0x41/255.0f, 0x69/255.0f, 0xE1/255.0f, 0.8); | ||
break; | ||
case ANode::Type::kDst: | ||
color = color = Color4F(0x22 / 255.0f, 0x8B / 255.0f, 0x22 / 255.0f, 0.8); | ||
break; | ||
case ANode::Type::kAddOpen: | ||
color = Color4F::BLUE; | ||
break; | ||
case ANode::Type::kAddClose: | ||
color = Color4F(0xF0/255.0f, 0x80/255.0f, 0x80/255.0f, 1); | ||
break; | ||
default: | ||
color = Color4F::MAGENTA; | ||
break; | ||
} | ||
drawNode->clear(); | ||
drawNode->drawSolidRect(Vec2(0, 0), Vec2(aWidth, aWidth), color); | ||
drawNode->drawRect(Vec2(0, 0), Vec2(aWidth, aWidth), Color4F::ORANGE); | ||
return true; | ||
} | ||
|
||
///////////////////////////////////////////////// | ||
|
||
void AstarNode::calcValue(AstarNode* dst) | ||
{ | ||
int v = abs(parent->row - row) + abs(parent->col - col); | ||
if (v == 1) { | ||
gValue = parent->gValue + 10; | ||
} | ||
else { | ||
gValue = parent->gValue + 14; | ||
} | ||
hValue = abs(dst->col - col) + abs(dst->row - row); | ||
} | ||
|
||
//////////////////////////////////////////////// | ||
|
||
Scene* AstarLayer::createScene() | ||
{ | ||
Scene* scene = Scene::create(); | ||
AstarLayer* layer = AstarLayer::create(); | ||
scene->addChild(layer); | ||
return scene; | ||
} | ||
|
||
AstarLayer* AstarLayer::create() | ||
{ | ||
AstarLayer* layer = new (std::nothrow) AstarLayer(); | ||
if (layer && layer->init()) { | ||
layer->autorelease(); | ||
return layer; | ||
} | ||
else { | ||
delete layer; | ||
layer = nullptr; | ||
return nullptr; | ||
} | ||
} | ||
|
||
bool AstarLayer::init() | ||
{ | ||
if (!Layer::init()) { | ||
return false; | ||
} | ||
auto winSize = Director::getInstance()->getVisibleSize(); | ||
|
||
auto bgLayer = LayerColor::create(Color4B(0x12, 0x12, 0x12, 0xff)); | ||
bgLayer->setPosition(Vec2(0, 0)); | ||
this->addChild(bgLayer); | ||
ANode* temp = ANode::create(); | ||
float startx = (winSize.width - maxcol * temp->getContentSize().width)/2; | ||
float starty = (winSize.height - maxrow * temp->getContentSize().height) / 2; | ||
auto nsize = temp->getContentSize(); | ||
for (int i = 0; i < maxcol; i++) { | ||
for (int j = 0; j < maxrow; j++) { | ||
auto node = ANode::create(); | ||
node->setPosition(startx + (i+0.5)*nsize.width, starty + (j+0.5)*nsize.height); | ||
this->addChild(node); | ||
mNodes[j][i] = node; | ||
} | ||
} | ||
|
||
src = AstarNode(10, 3); | ||
dst = AstarNode(3, 21); | ||
|
||
mNodes[src.row][src.col]->setType(ANode::Type::kSrc); | ||
mNodes[dst.row][dst.col]->setType(ANode::Type::kDst); | ||
|
||
for (int row = 4; row < maxrow; row++) { | ||
mNodes[row][5]->setType(ANode::Type::kWall); | ||
} | ||
|
||
for (int row = 3; row < maxrow-3; row++) { | ||
mNodes[row][10]->setType(ANode::Type::kWall); | ||
} | ||
|
||
for (int row = 0; row < maxrow - 4; row++) { | ||
mNodes[row][18]->setType(ANode::Type::kWall); | ||
} | ||
|
||
return true; | ||
} | ||
//////////////////////////// | ||
|
||
AStar* AStar::getInstance() | ||
{ | ||
if (_instance == nullptr) { | ||
_instance = new AStar(); | ||
} | ||
return _instance; | ||
} | ||
|
||
void AStar::init(AstarNode(&astarNodes)[maxrow][maxcol], AstarLayer* astar) | ||
{ | ||
std::swap(nodes, astarNodes); | ||
layer = astar; | ||
} | ||
|
||
bool AStar::find(AstarNode src, AstarNode dst, std::vector<AstarNode*> &list) | ||
{ | ||
std::vector<AstarNode*> queue; | ||
|
||
memset(openlist, 0, sizeof(openlist)); | ||
memset(closelist, 0, sizeof(closelist)); | ||
|
||
queue.push_back(&nodes[src.row][src.col]); | ||
|
||
while (!queue.empty()) { | ||
auto it = queue.begin(); | ||
for (auto iter = queue.begin(); iter != queue.end(); iter++) { | ||
if ((*it)->getFValue() > (*iter)->getFValue()) { | ||
it = iter; | ||
} | ||
} | ||
auto node = *it; | ||
queue.erase(it); | ||
closelist[node->row*maxcol + node->col] = true; | ||
|
||
int row = node->row + 1; | ||
int col = node->col; | ||
|
||
if (isValid(row, col) && !isUnwalkable(row, col)) { | ||
if (openlist[row*maxcol + col]) { | ||
if (nodes[row][col].gValue > node->gValue + 10) | ||
{ | ||
nodes[row][col].parent = node; | ||
nodes[row][col].calcValue(&dst); | ||
} | ||
} | ||
else { | ||
nodes[row][col].parent = node; | ||
nodes[row][col].calcValue(&dst); | ||
queue.push_back(&nodes[row][col]); | ||
} | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool AStar::isUnwalkable(int row, int col) | ||
{ | ||
return layer->getNode(row, col)->getType == ANode::Type::kWall; | ||
} | ||
|
||
bool AStar::isValid(int row, int col) | ||
{ | ||
if (row >= 0 && row < maxrow && col >= 0 && col < maxcol) { | ||
return !closelist[row * maxcol + col]; | ||
} | ||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#ifndef _ASTAR_LAYER_H_ | ||
#define _ASTAR_LAYER_H_ | ||
#include "cocos2d.h" | ||
|
||
class ANode : public cocos2d::Node { | ||
public: | ||
enum class Type { | ||
kNormal, | ||
kWall, | ||
kSrc, | ||
kDst, | ||
kAddOpen, | ||
kAddClose, | ||
}; | ||
static ANode* create(); | ||
virtual bool init() override; | ||
bool setType(Type type); | ||
Type getType() { return aType; } | ||
private: | ||
cocos2d::DrawNode *drawNode; | ||
Type aType; | ||
int aWidth = 40; | ||
}; | ||
|
||
struct AstarNode { | ||
AstarNode* parent; | ||
int hValue; | ||
int gValue; | ||
int row; | ||
int col; | ||
|
||
int getFValue() { return hValue + gValue; } | ||
void calcValue(AstarNode* dst); | ||
|
||
AstarNode() :AstarNode(0, 0) { | ||
|
||
} | ||
AstarNode(int r, int c) : | ||
row(r), col(c), parent(nullptr), hValue(0), gValue(0) | ||
{ | ||
|
||
} | ||
}; | ||
|
||
const int maxrow = 15; | ||
const int maxcol = 23; | ||
|
||
class AstarLayer : public cocos2d::Layer { | ||
public: | ||
|
||
static AstarLayer* create(); | ||
static cocos2d::Scene* createScene(); | ||
virtual bool init() override; | ||
|
||
ANode* getNode(int row, int col) { return mNodes[row][col]; } | ||
private: | ||
ANode* mNodes[maxrow][maxcol]; | ||
AstarNode src; | ||
AstarNode dst; | ||
|
||
}; | ||
|
||
class AStar { | ||
public: | ||
static AStar* getInstance(); | ||
|
||
bool find(AstarNode src, AstarNode dst, std::vector<AstarNode*> &list); | ||
|
||
void init(AstarNode (&astarNodes)[maxrow][maxcol], AstarLayer* astarLayer); | ||
|
||
private: | ||
bool isValid(int row, int col); | ||
bool isUnwalkable(int row, int col); | ||
AstarLayer* layer = nullptr; | ||
AstarNode nodes[maxrow][maxcol]; | ||
bool openlist[maxrow*maxcol]; | ||
bool closelist[maxrow*maxcol]; | ||
}; | ||
|
||
#endif |