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

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. // 遍历CCArray的时候不能做增删操作,否则会出错
  5. // 这里分两步来完毕,第一次遍历,将要删除的对象存到一个暂时CCArray里
  6. // 第二步遍历暂时CCArray,将里面的对象从源数组里删掉,最后清空暂时数组
  7. CCARRAY_FOREACH(mCoins,itor)
  8. {
  9. Coin* coin = dynamic_cast<Coin*>(itor);
  10. if ((coin != NULL) && (coin->getMap() == mapIndex)) {
  11. tempCoins->addObject(coin);
  12. coin->destroy();
  13. }
  14. }
  15. CCARRAY_FOREACH(tempCoins,itor)
  16. {
  17. mCoins->fastRemoveObject(itor);
  18. }
  19. 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. void* bodyUserDataA = contact->GetFixtureA()->GetBody()->GetUserData();
  5. void* bodyUserDataB = contact->GetFixtureB()->GetBody()->GetUserData();
  6. if (bodyUserDataA && bodyUserDataB)
  7. {
  8. B2Sprite* contactA = static_cast<B2Sprite*>(bodyUserDataA);
  9. BaseObject* obj = NULL;
  10. if (contactA == mRunner->getRunnerSprite())
  11. {
  12. obj = static_cast<BaseObject*>(bodyUserDataB);
  13. }else
  14. {
  15. obj = static_cast<BaseObject*>(bodyUserDataA);
  16. }
  17. if (COINTAG == obj->getObjSprite()->getTag()) {
  18. ((Status*)(this->getParent()->getChildByTag(STATUSTAG)))->addCoin(1);
  19. mRemoveObjs->addObject(obj);
  20. SimpleAudioEngine::sharedEngine()->playEffect(pickUpCoins);
  21. }else if(ROCKTAG == obj->getObjSprite()->getTag())
  22. {
  23. mRunner->die();
  24. unscheduleUpdate();
  25. mState = GameOverState;
  26. GameOver* over = GameOver::create();
  27. this->getParent()->addChild(over);
  28. }
  29. }
  30. }

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

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

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

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

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

cocos2d-x游戏开发 跑酷(八) 对象管理 碰撞检測的更多相关文章

  1. 基于cocos2d-x的跑酷游戏,不同高度地面的碰撞检測demo,有兴趣能够看一看

    1. demo大致分为4个模块: 地图,角色,障碍 逻辑检測认为和不同高度地面的碰撞.1次跳和2连跳的实现. 代码链接:http://download.csdn.net/detail/zangleng ...

  2. iOS cocos2d 2游戏开发实战(第3版)书评

    2013是游戏爆发的一年,手游用户也是飞速暴增.虽然自己不做游戏,但也是时刻了解手机应用开发的新动向.看到CSDN的"写书评得技术图书赢下载分"活动,就申请了一本<iOS c ...

  3. cocos2d-x ios游戏开发初认识(八) 触摸事件与碰撞检測

    玩过植物大战僵尸都知道,要在草坪里放一朵向日葵或者其他的植物仅仅需触摸那个植物将其拖入到想要摆放的位置,这事实上就是这节要写的触摸事件.还能够发现当我们的僵尸出来的时候,我们的小豌豆会发子弹攻击僵尸, ...

  4. cocos2d-x 3.0游戏实例学习笔记 《跑酷》第七步--物理碰撞检測(1)

    说明:这里是借鉴:晓风残月前辈的博客,他是将泰然网的跑酷教程,用cocos2d-x 2.X 版本号重写的,眼下我正在学习cocos2d-X3.0 于是就用cocos2d-X 3.0重写,并做相关笔记 ...

  5. Cocos2d-x3.0游戏实例之《别救我》第七篇——物理世界的碰撞检測

    事实上我也非常吃惊-居然写到第七篇了,我估计也就是四篇的内容,感觉非常奇妙,我也不会非常唠叨什么吖);    // 0001 );   // 0001 ); // 0001 这样我们才干监听到它们的碰 ...

  6. 8、Cocos2dx 3.0三,找一个小游戏开发3.0存储器管理的版本号

    重开发人员的劳动成果,转载的时候请务必注明出处:http://blog.csdn.net/haomengzhu/article/details/27693365 复杂的内存管理 移动设备上的硬件资源十 ...

  7. 游戏开发设计模式之对象池模式(unity3d 示例实现)

    前篇:游戏开发设计模式之命令模式(unity3d 示例实现) 博主才学尚浅,难免会有错误,尤其是设计模式这种极富禅意且需要大量经验的东西,如果哪里书写错误或有遗漏,还请各位前辈指正. 原理:从一个固定 ...

  8. 【Unity3D游戏开发】之全局管理类的几种方式 (十六)

    如何在Unity中实现全局管理类?由于Unity脚本的运行机制和面向组件编程(COP)的思想,实现起来和普通的方式略有差别. 第一种方式是使用静态类.适合存储一些全局的变量,如游戏当前关卡.玩家得分等 ...

  9. Unity游戏开发中的内存管理_资料

    内存是手游的硬伤——Unity游戏Mono内存管理及泄漏http://wetest.qq.com/lab/view/135.html 深入浅出再谈Unity内存泄漏http://wetest.qq.c ...

随机推荐

  1. 【SQL SERVER】T-SQL 字符串前加 N 是什么意思

    比如 select @status = N'stopped' 那么其中的字符串 stopped 前面为什么要加 N 呢?而且我们发现有些地方加 N 与否都没有影响,有些地方又必须加 N. N 在这里表 ...

  2. 洛谷P4644 [USACO2005 Dec]Cleaning Shifts 清理牛棚 [DP,数据结构优化]

    题目传送门 清理牛棚 题目描述 Farmer John's cows, pampered since birth, have reached new heights of fastidiousness ...

  3. 【转】LoadRunner常见问题整理

    原文出自:http://blog.csdn.net/loadrunn/article/details/7886918 1.LR 脚本为空的解决方法: 1.去掉ie设置中的第三方支持取消掉 2.在系统属 ...

  4. Implementing x / 6 Using Only Bit Manipulations

    This is an interesting question from one of the lab assignments in Introduction to Computer Systems, ...

  5. springMVC接受对象集合,name数组

    这两天开发遇到一个很常见的问题,即使自己一直没遇见过,不过之前看过是实现接受对象集合的代码,只不过没注意罢了 推荐一篇文章 直接贴代码吧 public class Person { private S ...

  6. intellij idea 中文 汉化包 韩梦飞沙

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 汉化包 百度云盘 下载地址: https://pan.baidu.com/s/1hs6B ...

  7. 安卓 onTouch OnTouchEvent onChick 顺序

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 分发触摸事件 -> 在 触摸 时候 -> 在触摸事件时候->在点击时候 ...

  8. [BZOJ5427]最长上升子序列

    考虑O(n log n)的LIS求法,dp[i]表示到目前为止,长度为i的LIS的末尾最小是多少. 当当前数确定时直接用LIS的求法更新dp数组,当不确定时,由于这个数可以是任意数,所以可以接在任意上 ...

  9. python开发_tarfile_文档归档压缩|解压缩

    ''' python中的tarfile模块实现文档的归档压缩和解压缩 功能: 把工作空间下面的所有文件,打包生成一个tar文件 同时提供一个方法把该tar文件中的一些文件解压缩到 指定的目录中 ''' ...

  10. SpringMVC 3.1.1版本下的单元测试WEB-INF路径问题

    假设Spring配置文件为applicationContext.xml 一.Spring配置文件在类路径下面 在Spring的java应用程序中,一般我们的Spring的配置文件都是放在放在类路径下面 ...