首页 > 代码库 > 第一个项目(八)碰撞检测

第一个项目(八)碰撞检测

碰撞检测部分的代码写了有一整天,因为地图编辑器其实很不熟悉,所以走了很多弯路,把今天的代码和细节分享给大家

首先肯定要封装到函数里面,名字就叫pengzhuang()吧,这个函数写在自定义的update里面,每帧都执行检测。

因为我的障碍物都画在地图上,所以传统的矩形检测不能用,那个是精灵对精灵的,这个精灵和地图的交互实在头疼,如果要碰撞的话,肯定要检测坐标,但是cocos2dx的坐标原点和地图的原点是不一样的,一个左下,一个左上,所以要先写一个函数来换算,point_player_to_tile()

CCPoint Stage::point_player_to_tile(CCPoint pos)
{
	CCSize mapSize=map->getMapSize();
	CCSize tileSize=map->getTileSize();
	int x= pos.x/tileSize.width;
	int y= (640-pos.y)/tileSize.height;
	return ccp(x,y);
	
}
碰撞函数如下

void Stage::pengzhuang()
{

	CCSize PlayerSize=player->getContentSize();
	CCPoint PlayerPoint=player->getPosition();

	CCPoint P=ccp(PlayerPoint.x,PlayerPoint.y);
	CCPoint tilecoord = this->point_player_to_tile(P);//将坐标转换成tile坐标
	CCTMXLayer *layer = map->layerNamed("block2") ; //获取地图层
	int tilegid = layer->tileGIDAt(tilecoord);//获取图素GID值
	CCLOG("tilegid: %f %f", tilecoord.x,tilecoord.y);
	if (tilegid)
	{
		CCDictionary *properties  = map->propertiesForGID(tilegid)  ;//根据GID值获取图素属性键值集合
		if (properties)
		{
			const CCString *str = properties->valueForKey("ShiTou");//键值名称
			if (str && str->compare("true") == 0)    //如果键值是true
				player->runAction(getRunAction());
		}
	}
注释已经很清楚了,首先转换坐标,然后获得该坐标处的GId(该值为每个方块的唯一id,就像身份证),判断身份证存在与否,存在的话判断这个键值是不是ture。

如果都符合,就执行动作。

但是我就是很奇怪,这个判断是无效的,但是明明逻辑没问题,官网也是这么给的,于是一遍一遍的debug,才发现...............地图是向左滚的啊!!!方块的x坐标要加上滚出屏幕外的!!!!

于是在updat里面加入了帧值,每过一帧加一,然后用这个值乘以速度,乘积加上要判断点的x之和再除以小方块长,这才是小方块相对于地图的坐标。

CCPoint Stage::point_player_to_tile(CCPoint pos)
{


	CCSize mapSize=map->getMapSize();
	CCSize tileSize=map->getTileSize();
	int x= (map_time*10+pos.x)/tileSize.width;
	int y= (640-pos.y)/tileSize.height;

	return ccp(x,y);
	
}
这样和地图的交互就完成了,当然,我只是用一个点来做实验,因为是跑酷类游戏,主角的好多地方都可能发生碰撞,所以要多加几个点吧,能想到的暂时就这样,如果点太多了,反而帧率又下降了。


第一个项目(八)碰撞检测