zoukankan      html  css  js  c++  java
  • cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检測

    对象管理类的原理是这种:

    ObjectManager类是一个单例类,全局仅仅有一个对象实例存在。初始化的时候创建两个数组CCArray来保存金币和岩石。为什么要保存,由于在地图重载的时候。要销毁看不见的那些对象。金币和岩石是随机加入的,每一个金币和岩石都有一个地图索引,就是说它是在第几个地图上的,删除的时候依据这个来删除。

    我的博客:http://blog.csdn.net/dawn_moon,欢迎转载

    CCArray有个遍历的宏CCARRAY_FOREACH。假设你在遍历的时候进行增删的操作就会导致错误,这里我用了一个暂时的CCArray来保存要删除的对象。然后再遍历这个暂时数组对源数组进行删除,最后清空暂时数组。

    1. CCArray* tempCoins = CCArray::create();  
    2. CCArray* tempRocks = CCArray::create();  
    3. CCObject* itor;  
    4.   
    5. // 遍历CCArray的时候不能做增删操作,否则会出错  
    6. // 这里分两步来完毕,第一次遍历,将要删除的对象存到一个暂时CCArray里  
    7. // 第二步遍历暂时CCArray,将里面的对象从源数组里删掉,最后清空暂时数组  
    8. CCARRAY_FOREACH(mCoins,itor)  
    9. {  
    10.     Coin* coin = dynamic_cast<Coin*>(itor);  
    11.     if ((coin != NULL) && (coin->getMap() == mapIndex)) {  
    12.         tempCoins->addObject(coin);  
    13.         coin->destroy();  
    14.     }  
    15. }  
    16.   
    17. CCARRAY_FOREACH(tempCoins,itor)  
    18. {  
    19.     mCoins->fastRemoveObject(itor);  
    20. }  
    21.   
    22. tempCoins->removeAllObjects();  

    这个类在PlayScene的init里面初始化:

    1. ObjectManager* ObjM= ObjectManager::sharedObjectManager();  
    2. ObjM->initManager(spriteBatch, mWorld);  
    3. ObjM->setObjectToMap(1, mMapManager->getMapWidth());  

    然后在PlayScene的update里面加入金币和岩石。

    1. // 假设发生地图重载。就回收废的金币和岩石,加入新的金币和岩石  
    2. if (mMapManager->chechReloadMap(mLastEyeX)) {  
    3.     ObjectManager::sharedObjectManager()->recycleObjectOfMap(mMapManager->getCurMapIndex() - 1);  
    4.     ObjectManager::sharedObjectManager()->setObjectToMap(mMapManager->getCurMapIndex() + 1, mMapManager->getMapWidth());  
    5. }  

    好了。看碰撞检測。box2d的碰撞检測由物理世界维护,物理世界能知道全部发生的碰撞事件,并用一个回调来处理。我们要自己处理碰撞检測。就要实现这个回调b2ContactListener

    让PlayScene继承这个类。实现里面的一个函数BeginContact。然后给world设置碰撞监听器

    mWorld->SetContactListener(this);

    看下碰撞检測的实现:

    1. void PlayScene::BeginContact(b2Contact *contact)  
    2. {  
    3. //    CCLog("begin contact!");  
    4.       
    5.     void* bodyUserDataA = contact->GetFixtureA()->GetBody()->GetUserData();  
    6.     void* bodyUserDataB = contact->GetFixtureB()->GetBody()->GetUserData();  
    7.       
    8.     if (bodyUserDataA && bodyUserDataB)  
    9.     {  
    10.         B2Sprite* contactA = static_cast<B2Sprite*>(bodyUserDataA);  
    11.         BaseObject* obj = NULL;  
    12.         if (contactA == mRunner->getRunnerSprite())  
    13.         {  
    14.             obj = static_cast<BaseObject*>(bodyUserDataB);  
    15.         }else  
    16.         {  
    17.             obj = static_cast<BaseObject*>(bodyUserDataA);  
    18.         }  
    19.           
    20.         if (COINTAG == obj->getObjSprite()->getTag()) {  
    21.             ((Status*)(this->getParent()->getChildByTag(STATUSTAG)))->addCoin(1);  
    22.             mRemoveObjs->addObject(obj);  
    23.             SimpleAudioEngine::sharedEngine()->playEffect(pickUpCoins);  
    24.         }else if(ROCKTAG == obj->getObjSprite()->getTag())  
    25.         {  
    26.             mRunner->die();  
    27.             unscheduleUpdate();  
    28.             mState = GameOverState;  
    29.             GameOver* over = GameOver::create();  
    30.             this->getParent()->addChild(over);  
    31.         }  
    32.           
    33.     }  
    34. }  

    碰撞发生后,通过body的用户数据来进行辨别。这个用户数据userData是一个void*指针。存放用户的不论什么数据。在做物理精灵的时候对它进行设置,就是为了这个时候用的。

    地板的userData是NULL,所以假设这个userData不为NULL的话。那么它要么是Runner要么是金币要么是岩石。

    Runner的userData是一个B2Sprite。金币和岩石的userData都是BaseObject的子类,所以做类型转换。再用tag来区分金币和岩石。假设是金币,就加入到一个CCArray里面。然后在update里面做清除,假设是岩石,就GameOver了。

    分数和跑酷的距离是一个单独的CCLayer。由于PlayScene是一个无限的Layer。所以分数要单独出来,不然它会跑出屏幕。GameOver是一个CCLayerColor,由于要做一个有透明度的层。表示游戏结束了。

    图我就不上了。稍后放出源代码。

  • 相关阅读:
    HDU 1317 XYZZY(floyd+bellman_ford判环)
    UVa 10791 最小公倍数的最小和(唯一分解定理)
    UVa 12169 不爽的裁判
    UVa 11582 巨大的斐波那契数!(幂取模)
    POJ 1142 Smith Numbers(分治法+质因数分解)
    HDU 1595 find the longest of the shortest
    UVa 11090 在环中
    UVa 10917 林中漫步
    UVa 11374 机场快线
    POJ 1503 Integer Inquiry
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6730775.html
Copyright © 2011-2022 走看看