Cocos2d-X游戏【泰然网《跑酷》】JS到C++移植11:添加金币和障碍物到地图中

尊重开发者的劳动成果,转载的时候请务必注明出处: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;
			}
		}
	}
}

一切都搞定了,现在唯一剩下的事就是PlayScene.cpp中进行整合了;

定义新的类成员变量

ObjectManager *objectManager;
	static std::vector<cpShape> shapesToRemove;

在init()函数中添加下面的代码:

	objectManager = new ObjectManager(spriteSheet, space);
	objectManager->initObjectOfMap(1, map->getMapWidth());

在initPhysics()中设置chipmunk 的CollisionHandler

	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;
}

然后返回update()函数做如下更改:

	// 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


你可能感兴趣的:(C++,移植,cocos2d-x,游戏开发,跑酷)