碰撞检测部分的代码写了有一整天,因为地图编辑器其实很不熟悉,所以走了很多弯路,把今天的代码和细节分享给大家
首先肯定要封装到函数里面,名字就叫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); }
这样和地图的交互就完成了,当然,我只是用一个点来做实验,因为是跑酷类游戏,主角的好多地方都可能发生碰撞,所以要多加几个点吧,能想到的暂时就这样,如果点太多了,反而帧率又下降了。
时间: 2024-10-18 13:03:54