[关闭]
@tangyikejun 2014-08-14T20:15:56.000000Z 字数 3318 阅读 2626

《忍者飞镖射幽灵》之对象管理

已发布
标签: Cocos2d-x 游戏 飞镖忍者


对具体游戏demo的分析,是学习Cocos2d-x引擎的最好方法。本文基于懒骨头的博文Cocos2dx游戏开发系列笔记3:牛刀小试->忍者飞镖射幽灵的Demo写就,可以移步了解详细解说以及下载源码。懒骨头应该是根据引擎包自带的SimpleGame项目写的,也可以看看,在samples目录下面。


配置环境:win7+Cocos2d-x.2.0.3+VS2012
目标读者:需了解游戏帧率以及回调函数的概念



一、引言

本文关于对象的管理基于这样一个问题:游戏中会不断产生幽灵来进攻忍者,怎样合理地管理许多个幽灵对象,避免占用系统过多的内存?Cocos2d-x引擎其实已经帮我们做了很多工作,管理对象的操作变得相当简单。

二、对象管理流程

1、思路

利用一个CCArray来管理所有幽灵对象。新的幽灵添加到CCArray中,死亡或者越过屏幕的幽灵移出CCArray。

说明:这一节中的代码均《忍者飞镖射幽灵》中的实际代码,并且只讨论幽灵相关的部分。这样处理是为了方便理解。读者莫被误导。

2、CCArray 的使用

  1. CCArray *enemyArray = new CCArray;//创建CCArray对象
  1. enemyArray->addObject(CCObject *);//添加需要管理的CCObject对象
  1. CCARRAY_FOREACH(_array_ , _obj_)//遍历CCArray列表中的每一个CCObject对象
  2. {
  3. //对_obj_进行操作
  4. }
  5. //以上,宏CCARRAY_FOREACH中,_array_为CCArray对象 ,_obj_为CCArray列表遍历过程中当前操作对象。
  1. enemyArray->removeObject(CCObject *);//移除对象
  1. delete ememyArray;//回收CCArray对象ememyArray

3、CCLayer 部分

虽然已经使用CCArray来管理幽灵,但是幽灵的显示仍需要通过CCLayer。

  1. layer->addChild(enemy);//CCLayer对象layer,CCSprite对象enemy
  1. layer->removeChild(enemy);

4、定时器部分

《忍者飞镖射幽灵》中用到了CCLayer下的两个定时器。

  1. myLayer->scheduleUpdate();//MyCCLayer对象myLayer,MyCCLayer继承自CCLayer,这条语句启用重载的update函数。
  1. void MyCCLayer::update(float dt)//每一帧自动调用一次,传入的dt为相邻帧的 实际 时间间隔
  2. {
  3. //具体更新操作
  4. }

  1. myLayer->schedule(schedule_selector(MyCCLayer::addEnemy),float);////参数1 用于设置回调函数,参数2 设置调用回调函数的时间间隔,秒为单位。
  1. void MyCCLayer::addEnemy(float dt)
  2. {
  3. //具体更新操作
  4. }

Tip:光标移到宏schedule_selector,按F12可以转到定义,查看回调函数的传入参数和返回值应当是什么。

三、具体代码

涉及对象管理的所有内容都在GameScene类中。下面我只贴出跟enemy对象有关的代码,并做一些删减。贴出的各个函数基本上按照程序的执行顺序书写。

1、GameScene.h

  1. class GameScene : public cocos2d::CCLayerColor
  2. {
  3. public:
  4. virtual bool init();
  5. void addTarget();
  6. void spriteMoveFinished(CCNode* sender);
  7. void gameLogic(float dt);
  8. virtual void update(float delta);
  9. };

2、GameScene.cpp

2.1 bool GameScene::init()

  1. enemyArray=new CCArray;
  2. this->schedule( schedule_selector(GameScene::gameLogic), 1.0 );
  3. this->scheduleUpdate();

2.2 void GameScene::gameLogic(float dt)

每隔1秒就会自动调用这个函数

  1. void GameScene::gameLogic(float dt)
  2. {
  3. this->addTarget();
  4. }

2.3 void GameScene::addTarget()

  1. //创建幽灵精灵
  2. CCSprite *target;
  3. target=CCSprite::create("guai/guai1.png",CCRectMake(0,0,80,72));
  4. //加入游戏图层
  5. this->addChild(target,0,1);//参数分别为子节点对象,z-order(值大的盖住值小的),tag
  6. //加入CCArray列表
  7. enemyArray->addObject(target);
  8. //设置动作,幽灵移动到屏幕对面后调用spriteMoveFinished自毁
  9. //创建一个CCMoveTo的动作
  10. CCFiniteTimeAction *actionMove=CCMoveTo::create((float)actualD,ccp(100-target->getContentSize().width,winSize.height/2));
  11. //创建一个回调函数
  12. CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create(this,callfuncN_selector(GameScene::spriteMoveFinished));
  13. //将MoveTo和回调函数用动作序列CCSequence包装后添加到target中
  14. target->runAction(CCSequence::create(actionMove,actionMoveDone,NULL));

2.4 void GameScene::update(float delta)

  1. CCArray *toDel=new CCArray;
  2. ...... //碰撞检测,将需要移除的幽灵添加到toDel列表中
  3. ......
  4. //处理死亡对象
  5. CCSprite *s;
  6. CCObject *o;
  7. CCARRAY_FOREACH(toDel,o)
  8. {
  9. s=dynamic_cast<CCSprite*>(o);//
  10. enemyArray->removeObject(s);
  11. this->removeChild(s);
  12. }

上面代码中dynamic_cast<Type-id>(expression)把expression转换成Type-id类型的对象。Type-id必须是类的指针、类的引用或者void*。

2.5 void GameScene::spriteMoveFinished(CCNode* sender)

  1. void GameScene::spriteMoveFinished(CCNode* sender)
  2. {
  3. CCSprite *sprite = (CCSprite *)sender;
  4. this->removeChild(sprite);
  5. enemyArray->removeObject(sprite);
  6. }

转载注明出处:https://www.zybuluo.com/tangyikejun/note/23878

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注