尊重开发者的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/17419275
<捕鱼达人>回顾
【cocos2d-x IOS游戏开发-捕鱼达人1】内容介绍
<城市跑酷>回顾
【cocos2d-x IOS游戏开发-城市跑酷1】跑酷游戏介绍
上节回顾
Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植10:Adding Coins and Rocks【添加金币和障碍物】
现在已经有了金币跟岩石,但是如何将它们添加到游戏中呢?
金币和石头都是元素对象,可以创建一个管理类,来管理地图中的元素;
创建一个ObjectManager.cpp的文件并将它添加到VS的项目中,将下面代码添加到里面:
为了管理两种元素,添加两个list容器用于保存金币和石头:
std::list<Rock*> m_vecRocksList; std::list<Coin*> m_vecCoinsList;
地图初始化对象的主要逻辑
1、创建两个随机数来确定哪个点创建金币或岩石
2、通过随机因素来计算每张地图中金币和岩石的 开始位置,将每个对象都添加到地图中
3、用金币来举个例子,如果金币的开始位置跟岩石的一样那么就要把它的点调得比石头高度高或者低于石头的底部
4、添加其他石头
具体实现看代码:
int initCoinNum = 7; float jumpRockHeight = Runner::getCrouchContentSize()->height + g_groundHight; float coinHeight = Coin::getContentSize()->height + g_groundHight; //创建两个随机数来确定哪个点创建金币或岩石 //random the center point of 7 coins. int randomCoinFactor = CCRANDOM_0_1()*(CCRANDOM_0_1()*2 + 1); int randomRockFactor = CCRANDOM_0_1()*(CCRANDOM_0_1()*2 + 1); float jumpRockFactor = 0; //通过随机因素来计算每张地图中金币和岩石的 开始位置,将每个对象都添加到地图中 float coinPoint_x = mapWidth/4 * randomCoinFactor+mapWidth*map; float RockPoint_x = mapWidth/4 * randomRockFactor+mapWidth*map; float coinWidth = Coin::getContentSize()->width; float rockWith = Rock::getContentSize()->width; float rockHeight = Rock::getContentSize()->height; float startx = coinPoint_x - coinWidth/2*11; float xIncrement = coinWidth/2*3; //add a rock Rock *rock = new Rock(spriteSheet, space, ccp(RockPoint_x, g_groundHight+rockHeight/2)); if ((NULL != rock) && (NULL != rock->shape)) { rock->setMap(map); m_vecRocksList.push_back(rock); } if(map == 0 && randomCoinFactor==1){ randomCoinFactor = 2; } //add coins for(int i = 0; i < initCoinNum; i++) { //用金币来举个例子,如果金币的开始位置跟岩石的一样那么就要把它的点调得 //比石头高度高或者低于石头的底部 if((startx + i*xIncrement > RockPoint_x-rockWith/2) &&(startx + i*xIncrement < RockPoint_x+rockWith/2)) { Coin *coin = new Coin(spriteSheet, space, ccp(startx + i*xIncrement, coinHeight+rockHeight)); coin->setMap(map); m_vecCoinsList.push_back(coin); } else { Coin *coin = new Coin(spriteSheet, space, ccp(startx + i*xIncrement, coinHeight)); if ((NULL != coin) && (NULL != coin->shape)) { coin->setMap(map); m_vecCoinsList.push_back(coin); } } } for(int i=1;i<4;i++){ if((i!=randomCoinFactor) && (i!=randomRockFactor)) { jumpRockFactor = i; } } //add jump rock float JumpRockPoint_x = mapWidth/4 * jumpRockFactor + mapWidth*map; Rock *jumpRock = new Rock(spriteSheet, space, ccp(JumpRockPoint_x, jumpRockHeight+rockHeight/2)); if ((NULL != jumpRock) && (NULL != jumpRock->shape)) { jumpRock->setMap(map); m_vecRocksList.push_back(jumpRock); }其中getContentSize是元素类中的一个静态方法,用于计算坐标;
每一次地图重载,地图中的对象要回收
/** remove all objects of the map * @param {int} */ //每一次地图重载,地图中的对象要回收 bool ObjectManager::recycleObjectOfMap(int map) { //清除金币 std::list<Coin*>::iterator it1 = m_vecCoinsList.begin(); std::list<Coin*>::iterator end1 = m_vecCoinsList.end(); for(;it1!=end1;++it1) { if((*it1)->_map == map) { (*it1)->removeFromParent(); m_vecCoinsList.erase(it1); break; } } //清除石头 std::list<Rock*>::iterator it2 = m_vecRocksList.begin(); std::list<Rock*>::iterator end2 = m_vecRocksList.end(); for(;it2!=end2;++it2) { if((*it2)->_map == map) { (*it2)->removeFromParent(); m_vecRocksList.erase(it2); break; } } return true; }
当游戏角色得到金币时,将这个金币从它的父类中和列表中移除
//当游戏角色得到金币时,将这个金币从它的父类中和列表中移除 void ObjectManager::removeCoin(Coin *obj) { if(obj){ obj->removeFromParent(); std::list<Coin*>::iterator it= m_vecCoinsList.begin(); for(;it!=m_vecCoinsList.end();++it){ if(*it == obj){ m_vecCoinsList.erase(it); delete (obj); //m_vecCoinsList.splice() break; } } } } /** remove specified object * @param {Rock *}Rock */ void ObjectManager::removeRock(Rock *obj) { if(obj){ obj->removeFromParent(); std::list<Rock*>::iterator it= m_vecRocksList.begin(); for(;it!=m_vecRocksList.end();++it){ if(*it == obj){ m_vecRocksList.erase(it); //obj->removeFromParent(); delete (obj); return; } } } }
定义新的类成员变量
ObjectManager *objectManager; static std::vector<cpShape> shapesToRemove;
objectManager = new ObjectManager(spriteSheet, space); objectManager->initObjectOfMap(1, map->getMapWidth());
cpSpaceAddCollisionHandler(this->space,SpriteTagRunner, SpriteTagCoin, PlayScene::collisionCoinBegin, NULL, NULL, NULL,NULL); cpSpaceAddCollisionHandler(space, SpriteTagRunner,SpriteTagRock, PlayScene::collisionRockBegin, NULL, NULL, NULL,NULL);在PlayLayer中添加两个碰撞回调函数
int PlayScene::collisionCoinBegin(cpArbiter *arbiter, cpSpace *space, void *unused) { CCLOG("collisionCoinBegin"); CP_ARBITER_GET_SHAPES(arbiter, a, b); shapesToRemove.push_back(*a); return 0; } int PlayScene::collisionRockBegin(cpArbiter *arbiter, cpSpace *space, void *unused) { CCLOG("collisionRockBegin"); bool rtn = runner->meetRock(); if (rtn == true) { gameStat = GameStatOver; CCLOG("Game Over"); } else { CP_ARBITER_GET_SHAPES(arbiter, a, b); shapesToRemove.push_back(*a); } return 0; }
// Simulation cpSpaceAddPostStepCallback for(unsigned int i = 0; i < shapesToRemove.size(); i++) { cpShape *shape = &shapesToRemove[i]; Coin *objCoin = objectManager->getCoinByShape(shape); if (NULL != objCoin) { //TODO add remove animation objectManager->removeCoin(objCoin); } Rock *objRock = objectManager->getRockByShape(shape); if (NULL != objRock) { //TODO add remove animation objectManager->removeRock(objRock); } }检查碰撞:
// check and reload mapbackgroundLayer if (true == map->checkAndReload(lastEyeX)) { //if (true == backgroundLayer->checkAndReload(lastEyeX)) { objectManager->recycleObjectOfMap(map->getCurMap() - 1); objectManager->initObjectOfMap(map->getCurMap() + 1, map->getMapWidth()); //level up runner->levelUp(); }
【跑酷源码素材】资源引用页:http://download.csdn.net/detail/danielzzu/6739365