cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检测
2014-05-22 15:03
501 查看
对象管理类的原理是这样的:
ObjectManager类是一个单例类,全局只有一个对象实例存在。初始化的时候创建两个数组CCArray来保存金币和岩石。为什么要保存,因为在地图重载的时候,要销毁看不见的那些对象。金币和岩石是随机添加的,每个金币和岩石都有一个地图索引,就是说它是在第几个地图上的,删除的时候根据这个来删除。
我的博客:http://blog.csdn.net/dawn_moon,欢迎转载
CCArray有个遍历的宏CCARRAY_FOREACH,如果你在遍历的时候进行增删的操作就会导致错误,这里我用了一个临时的CCArray来保存要删除的对象,然后再遍历这个临时数组对源数组进行删除,最后清空临时数组。
[cpp] view
plaincopyprint?
CCArray* tempCoins = CCArray::create();
CCArray* tempRocks = CCArray::create();
CCObject* itor;
// 遍历CCArray的时候不能做增删操作,否则会出错
// 这里分两步来完成,第一次遍历,将要删除的对象存到一个临时CCArray里
// 第二步遍历临时CCArray,将里面的对象从源数组里删掉,最后清空临时数组
CCARRAY_FOREACH(mCoins,itor)
{
Coin* coin = dynamic_cast<Coin*>(itor);
if ((coin != NULL) && (coin->getMap() == mapIndex)) {
tempCoins->addObject(coin);
coin->destroy();
}
}
CCARRAY_FOREACH(tempCoins,itor)
{
mCoins->fastRemoveObject(itor);
}
tempCoins->removeAllObjects();
这个类在PlayScene的init里面初始化:
[cpp] view
plaincopyprint?
ObjectManager* ObjM= ObjectManager::sharedObjectManager();
ObjM->initManager(spriteBatch, mWorld);
ObjM->setObjectToMap(1, mMapManager->getMapWidth());
然后在PlayScene的update里面添加金币和岩石,
[cpp] view
plaincopyprint?
// 如果发生地图重载,就回收废的金币和岩石,添加新的金币和岩石
if (mMapManager->chechReloadMap(mLastEyeX)) {
ObjectManager::sharedObjectManager()->recycleObjectOfMap(mMapManager->getCurMapIndex() - 1);
ObjectManager::sharedObjectManager()->setObjectToMap(mMapManager->getCurMapIndex() + 1, mMapManager->getMapWidth());
}
好了,看碰撞检测。box2d的碰撞检测由物理世界维护,物理世界能知道所有发生的碰撞事件,并用一个回调来处理。我们要自己处理碰撞检测,就要实现这个回调b2ContactListener
让PlayScene继承这个类,实现里面的一个函数BeginContact,然后给world设置碰撞监听器
mWorld->SetContactListener(this);
看下碰撞检测的实现:
[cpp] view
plaincopyprint?
void PlayScene::BeginContact(b2Contact *contact)
{
// CCLog("begin contact!");
void* bodyUserDataA = contact->GetFixtureA()->GetBody()->GetUserData();
void* bodyUserDataB = contact->GetFixtureB()->GetBody()->GetUserData();
if (bodyUserDataA && bodyUserDataB)
{
B2Sprite* contactA = static_cast<B2Sprite*>(bodyUserDataA);
BaseObject* obj = NULL;
if (contactA == mRunner->getRunnerSprite())
{
obj = static_cast<BaseObject*>(bodyUserDataB);
}else
{
obj = static_cast<BaseObject*>(bodyUserDataA);
}
if (COINTAG == obj->getObjSprite()->getTag()) {
((Status*)(this->getParent()->getChildByTag(STATUSTAG)))->addCoin(1);
mRemoveObjs->addObject(obj);
SimpleAudioEngine::sharedEngine()->playEffect(pickUpCoins);
}else if(ROCKTAG == obj->getObjSprite()->getTag())
{
mRunner->die();
unscheduleUpdate();
mState = GameOverState;
GameOver* over = GameOver::create();
this->getParent()->addChild(over);
}
}
}
碰撞发生后,通过body的用户数据来进行辨别。这个用户数据userData是一个void*指针,存放用户的任何数据。在做物理精灵的时候对它进行设置,就是为了这个时候用的。
地板的userData是NULL,所以如果这个userData不为NULL的话,那么它要么是Runner要么是金币要么是岩石。Runner的userData是一个B2Sprite,金币和岩石的userData都是BaseObject的子类,所以做类型转换。再用tag来区分金币和岩石。如果是金币,就添加到一个CCArray里面,然后在update里面做清除,如果是岩石,就GameOver了。
分数和跑酷的距离是一个单独的CCLayer,因为PlayScene是一个无限的Layer,所以分数要单独出来,不然它会跑出屏幕。GameOver是一个CCLayerColor,因为要做一个有透明度的层,表示游戏结束了。
图我就不上了,稍后放出源码。
ObjectManager类是一个单例类,全局只有一个对象实例存在。初始化的时候创建两个数组CCArray来保存金币和岩石。为什么要保存,因为在地图重载的时候,要销毁看不见的那些对象。金币和岩石是随机添加的,每个金币和岩石都有一个地图索引,就是说它是在第几个地图上的,删除的时候根据这个来删除。
我的博客:http://blog.csdn.net/dawn_moon,欢迎转载
CCArray有个遍历的宏CCARRAY_FOREACH,如果你在遍历的时候进行增删的操作就会导致错误,这里我用了一个临时的CCArray来保存要删除的对象,然后再遍历这个临时数组对源数组进行删除,最后清空临时数组。
[cpp] view
plaincopyprint?
CCArray* tempCoins = CCArray::create();
CCArray* tempRocks = CCArray::create();
CCObject* itor;
// 遍历CCArray的时候不能做增删操作,否则会出错
// 这里分两步来完成,第一次遍历,将要删除的对象存到一个临时CCArray里
// 第二步遍历临时CCArray,将里面的对象从源数组里删掉,最后清空临时数组
CCARRAY_FOREACH(mCoins,itor)
{
Coin* coin = dynamic_cast<Coin*>(itor);
if ((coin != NULL) && (coin->getMap() == mapIndex)) {
tempCoins->addObject(coin);
coin->destroy();
}
}
CCARRAY_FOREACH(tempCoins,itor)
{
mCoins->fastRemoveObject(itor);
}
tempCoins->removeAllObjects();
这个类在PlayScene的init里面初始化:
[cpp] view
plaincopyprint?
ObjectManager* ObjM= ObjectManager::sharedObjectManager();
ObjM->initManager(spriteBatch, mWorld);
ObjM->setObjectToMap(1, mMapManager->getMapWidth());
然后在PlayScene的update里面添加金币和岩石,
[cpp] view
plaincopyprint?
// 如果发生地图重载,就回收废的金币和岩石,添加新的金币和岩石
if (mMapManager->chechReloadMap(mLastEyeX)) {
ObjectManager::sharedObjectManager()->recycleObjectOfMap(mMapManager->getCurMapIndex() - 1);
ObjectManager::sharedObjectManager()->setObjectToMap(mMapManager->getCurMapIndex() + 1, mMapManager->getMapWidth());
}
好了,看碰撞检测。box2d的碰撞检测由物理世界维护,物理世界能知道所有发生的碰撞事件,并用一个回调来处理。我们要自己处理碰撞检测,就要实现这个回调b2ContactListener
让PlayScene继承这个类,实现里面的一个函数BeginContact,然后给world设置碰撞监听器
mWorld->SetContactListener(this);
看下碰撞检测的实现:
[cpp] view
plaincopyprint?
void PlayScene::BeginContact(b2Contact *contact)
{
// CCLog("begin contact!");
void* bodyUserDataA = contact->GetFixtureA()->GetBody()->GetUserData();
void* bodyUserDataB = contact->GetFixtureB()->GetBody()->GetUserData();
if (bodyUserDataA && bodyUserDataB)
{
B2Sprite* contactA = static_cast<B2Sprite*>(bodyUserDataA);
BaseObject* obj = NULL;
if (contactA == mRunner->getRunnerSprite())
{
obj = static_cast<BaseObject*>(bodyUserDataB);
}else
{
obj = static_cast<BaseObject*>(bodyUserDataA);
}
if (COINTAG == obj->getObjSprite()->getTag()) {
((Status*)(this->getParent()->getChildByTag(STATUSTAG)))->addCoin(1);
mRemoveObjs->addObject(obj);
SimpleAudioEngine::sharedEngine()->playEffect(pickUpCoins);
}else if(ROCKTAG == obj->getObjSprite()->getTag())
{
mRunner->die();
unscheduleUpdate();
mState = GameOverState;
GameOver* over = GameOver::create();
this->getParent()->addChild(over);
}
}
}
碰撞发生后,通过body的用户数据来进行辨别。这个用户数据userData是一个void*指针,存放用户的任何数据。在做物理精灵的时候对它进行设置,就是为了这个时候用的。
地板的userData是NULL,所以如果这个userData不为NULL的话,那么它要么是Runner要么是金币要么是岩石。Runner的userData是一个B2Sprite,金币和岩石的userData都是BaseObject的子类,所以做类型转换。再用tag来区分金币和岩石。如果是金币,就添加到一个CCArray里面,然后在update里面做清除,如果是岩石,就GameOver了。
分数和跑酷的距离是一个单独的CCLayer,因为PlayScene是一个无限的Layer,所以分数要单独出来,不然它会跑出屏幕。GameOver是一个CCLayerColor,因为要做一个有透明度的层,表示游戏结束了。
图我就不上了,稍后放出源码。
相关文章推荐
- cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检测
- cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检測
- 【cocos2d-x IOS游戏开发-城市跑酷16】碰撞检测:撞墙 or 从房子上掉下来
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理
- cocos2d-x ios游戏开发初认识(八) 触摸事件与碰撞检测
- cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测
- Cocos2d-x碰撞检测原理与英雄要打死怪物--之游戏开发《赵云要格斗》(7)
- [cocos2d-x][游戏开发]通过cocos2d-x实现简易飞机大战 08.游戏界面 碰撞检测
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测上
- Cocos2d-x 3.2 lua飞机大战开发实例(三)道具的掉落,碰撞检测,声音,分数,爆炸效果,完善游戏的功能细节
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测上
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测下
- 基于cocos2d-x的跑酷游戏,不同高度地面的碰撞检测demo,有兴趣可以看一看
- Cocos2D-x游戏开发之十九:瓦块地图之碰撞检测
- cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测
- 【cocos2d-x游戏开发】物体的碰撞检测
- cocos2d-x游戏开发系列教程-坦克大战游戏之子弹的碰撞检测处理
- cocos2d-x游戏开发系列教程-坦克大战游戏之坦克和地图碰撞的检测下
- 如何用cocos2d-x来开发简单的Uphone游戏:(三) 射击子弹 & 碰撞检测
- 如何用cocos2d-x来开发简单的Uphone游戏:(三) 射击子弹 & 碰撞检测