Cocos2D-x游戏开发之十九:瓦块地图之碰撞检测

昨天我们有了精灵和背景,并且精灵可以跑动了,但是我们不能让精灵无穷无尽地跑下去吧,于是今天我们要在地图上添加一些障碍物了;

首先打开精灵的TMX地图,然后我们自定义一个32X32像素的图片添加到图层中,然后设置此图层的属性为:“collidable” 值为“true”,下一步在地图中新建一个图层起名为“meta”现在发挥你的创造性把这些小东西添加此图层中保存即可。

接下来就该在code中做一些操作了,打开我们的Player类:

class Player :	public Entity
{
public:
	Player(void);
	~Player(void);
public:
	CREATE_FUNC(Player);
	virtual bool init();
	void run();
	virtual bool SetPlayerPosition(int x,int y) ;
	void SetViewPointByPosition();
	CCTMXTiledMap *m_map;
	void SetTMXTileMap(CCTMXTiledMap *map);
	CCTMXLayer *meta;
	CCPoint tileCoordForPosition(CCPoint point);
};

Player::Player(void)
{
}


Player::~Player(void)
{
}
bool Player::init()
{
	
	return true;
}
void Player::run()
{
CCSpriteFrameCache * freamCache = CCSpriteFrameCache::sharedSpriteFrameCache();
freamCache->addSpriteFramesWithFile("run.plist","run.png");
CCSpriteFrame *frame  = NULL;
CCArray *freamlist =CCArray::create();
for (int i =1; i <= 15 ; i++)
{

	frame = freamCache->spriteFrameByName(CCString::createWithFormat("run%d.png",i)->getCString());
	freamlist->addObject(frame);
}
CCAnimation *anination = CCAnimation::createWithSpriteFrames(freamlist);
anination->setLoops(-1);
anination->setDelayPerUnit(0.08f);
CCAnimate *animate = CCAnimate::create(anination);
m_sprite->runAction(animate);
}
void Player::SetViewPointByPosition()
{
	if (m_sprite == NULL)
	{
	return ;
	}
	CCLayer *parent = (CCLayer*)this->getParent();
	CCSize mapTiledNum =m_map->getMapSize();
	CCSize tiledSize = m_map->getTileSize();
	CCSize mapsize = CCSize::CCSize(mapTiledNum.width*tiledSize.width,mapTiledNum.height*tiledSize.height);

	CCSize visibleSize = CCDirector::sharedDirector()->getWinSize();
	CCPoint spritepoint = getPosition();

	float x = max(spritepoint.x,visibleSize.width/2);
	float y = max(spritepoint.y,visibleSize.height/2);

	x = min(x,mapsize.width-visibleSize.width/2);
	y = min(y,mapsize.height- visibleSize.height/2);

	CCPoint destPos = CCPoint::CCPoint(x,y);
    CCPoint centerpos = CCPoint::CCPoint(visibleSize.width/2,visibleSize.height/2);

	CCPoint viewpos = ccpSub(centerpos,destPos);

	parent->setPosition(viewpos);
}
bool Player::SetPlayerPosition(int x,int y)
{

	CCSize spritesize = m_sprite->getContentSize();
	CCPoint dspoint = CCPoint(x+spritesize.width/2,y);
	CCPoint tiledpos =tileCoordForPosition(ccp(dspoint.x,dspoint.y));
	CCLOG("tiled x = %f,y = %f",tiledpos.x,tiledpos.y);
	int tiledchild = meta->tileGIDAt(tiledpos);
	if(tiledchild != 0)
	{
		CCDictionary * propertydict = m_map->propertiesForGID(tiledchild);
		const CCString * prop = propertydict->valueForKey("collidable");
		if(prop->m_sString.compare("true") == 0)
		{
			return false;
		}
	}
	Entity::SetPlayerPosition(x,y);
	SetViewPointByPosition();
	return true;
}
void Player::SetTMXTileMap(CCTMXTiledMap *map)
{
	//CC_SAFE_RETAIN(map);
	//CC_SAFE_RELEASE(m_map);
	this->m_map = map;
	this->meta = m_map->layerNamed("meta");//设置图层不可见
	this->meta->setVisible(false);
	this->meta->retain();

}
 
 
//因为精灵的坐标是从左下角开始计算,而瓦块的坐标是从左上角开始计算的所以我们需要通过这个函数将精灵坐标转化为瓦块需要的坐标。
CCPoint Player::tileCoordForPosition(CCPoint pos)
{
CCSize mapTiledNum = m_map->getMapSize();
CCSize tiledSize = m_map->getTileSize();
int x = pos.x/tiledSize.width;
//转换为瓦块的个数横坐标 
int y = (640 - pos.y)/tiledSize.height;
//转换为瓦块的个数纵坐标
 if(x >0) { x-=1; } if(y >0) { y-=0; } return ccp(x,y);
}


这样我们的精灵在跑动的过程中就会遇到障碍物而跑不过去。

Cocos2D-x游戏开发之十九:瓦块地图之碰撞检测_第1张图片


你可能感兴趣的:(Cocos2D-x游戏开发之十九:瓦块地图之碰撞检测)