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<CatSprite::ShortestPathStep *> &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<ShortestPathStep*> _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<ShortestPathStep*> _shortestPath;
void popStepAndAnimate();
cocos2d::Vector<ShortestPathStep*> _spOpenSteps;
cocos2d::Vector<ShortestPathStep*> _spClosedSteps;
ssize_t getStepIndex(const cocos2d::Vector<CatSprite::ShortestPathStep *> &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