Enemy类没什么内容,就create和init方法,根据参数来创建不同的敌机,头文件代码如下:
1 //飞机的类型 2 enum planeType {smallPlane, midPlane, bigPlane}; 3 4 class Enemy : public CCSprite 5 { 6 7 public: 8 9 void loseLife(); 10 11 CC_SYNTHESIZE(float, m_speed, Speed); 12 CC_SYNTHESIZE(int, m_life, Life); 13 CC_SYNTHESIZE(int, m_score, Score); 14 CC_SYNTHESIZE(planeType, m_type, Type); 15 16 ~Enemy(); 17 virtual bool init(planeType type, CCTexture2D* texture); 18 static Enemy* create(planeType type, CCTexture2D* texture); 19 20 };
create和init方法实现如下:
Enemy* Enemy::create(planeType type, CCTexture2D* texture) { Enemy *pRet = new Enemy(); if (pRet && pRet->init(type, texture)) { pRet->autorelease(); return pRet; } else { delete pRet; pRet = NULL; return NULL; } } bool Enemy::init(planeType type, CCTexture2D* texture) { bool bRet = false; do { const char* fileName; float score = 0; int life = 0; float speed = 0; int random_speed = rand() % 6 + 2; switch (type) { case bigPlane: fileName = "enemy3_n1.png"; life = 15; score = 100; break; case midPlane: fileName = "enemy2.png"; life = 8; score = 50; break; case smallPlane: fileName = "enemy1.png"; life = 1; score = 10; break; default: break; } ; CC_BREAK_IF(!CCSprite::initWithSpriteFrameName(fileName)); this->m_score = score; this->m_life = life; this->m_speed = 50*random_speed; this->m_type = type; bRet = true; } while (0); return bRet; }
EnemyLayer类则负责敌机除了创建之外的所有工作,包括开始启动创建方法、停止创建、移除敌机、敌机爆炸等。头文件:
1 class EnemyLayer : public cocos2d::CCLayer 2 { 3 4 protected: 5 6 CCSize designResolutionSize; 7 CCSpriteBatchNode* batchNode; 8 9 public: 10 11 CCArray *m_enemys; 12 13 EnemyLayer(void); 14 ~EnemyLayer(void); 15 virtual bool init(); 16 17 void startTakeEnemys(float dt); 18 void stopTakeEnemy(void); 19 20 void EnemyMoveToFinish(CCNode* pSender); 21 void removeEnemy(CCNode* pTarget, void* enemy); 22 void removeAllEnmeys(); 23 24 void addEnemy(float dt); 25 26 void bomb(CCNode* pSender); 27 28 CREATE_FUNC(EnemyLayer); 29 };
敌机的创建和子弹不同,还记得子弹的创建我是保证屏幕上只有一粒子弹的吧,敌机则不然,固定每隔多少时间就会创建
1 void EnemyLayer::startTakeEnemys(float dt) 2 { 3 4 float delay = 1.0f;//多少秒后调用 5 float interval = 0.3f;//调用时间间隔 6 this->schedule(schedule_selector(EnemyLayer::addEnemy), interval, kCCRepeatForever, delay); 7 }
addEnemy和bomb方法实现:
1 void EnemyLayer::addEnemy(float dt) 2 { 3 if (true) 4 { 5 int seed = 19; 6 int random_planeType = rand() % seed + 1;//1~19 7 planeType type; 8 9 Enemy* enemy = NULL; 10 11 //按概率随机生成大中小三种敌机,或者不产生 12 //big 13 if (random_planeType % 19 == 0) 14 { 15 type = bigPlane; 16 SimpleAudioEngine::sharedEngine()->playEffect("music/big_spaceship_flying.wav",false); 17 } 18 //mid 19 else if(random_planeType % 5 == 0) 20 { 21 type = midPlane; 22 } 23 //small 24 else if(random_planeType % 2 == 0) 25 { 26 type = smallPlane; 27 } 28 // no 29 else 30 { 31 return; 32 } 33 34 enemy = Enemy::create(type, this->batchNode->getTexture()); 35 36 37 //初始位置(随机) 38 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 39 float x = rand() % (int)(winSize.width - (int)enemy->boundingBox().size.width * 2) + enemy->boundingBox().size.width; 40 float y = winSize.height - enemy->boundingBox().size.height/2; 41 42 CCPoint position = ccp(x,y); 43 44 enemy->setPosition(position); 45 this->m_enemys->addObject(enemy); 46 batchNode->addChild(enemy); 47 48 //敌机的运动轨迹CCDirector::sharedDirector()->getWinSize() 49 float length = enemy->getContentSize().height + designResolutionSize.height;//飞行距离,超出屏幕即结束 50 float velocity = 10/1;//飞行速度:420pixel/sec 51 float realMoveDuration = length/enemy->getSpeed();//飞行时间 52 53 CCFiniteTimeAction* actionMove = CCMoveTo::create(realMoveDuration,ccp(x, -enemy->getContentSize().height)); 54 CCFiniteTimeAction* actionDone = CCCallFuncN::create(this,callfuncN_selector(EnemyLayer::EnemyMoveToFinish));//回调一个敌机结束处理函数 55 56 CCSequence* sequence = CCSequence::create(actionMove,actionDone,NULL); 57 58 enemy->runAction(sequence); 59 60 } 61 62 } 63 64 65 void EnemyLayer::bomb(CCNode* pSender) 66 { 67 68 CCAnimation *animationBomb = NULL; 69 Enemy *enemy = (Enemy*) pSender; 70 char bombMusciName[64]; 71 72 if (enemy->getType() == bigPlane) 73 { 74 sprintf(bombMusciName, "music/enemy3_down.wav"); 75 animationBomb = CCAnimationCache::sharedAnimationCache()->animationByName("animation_Enemy3Bomb"); 76 } 77 else if(enemy->getType() == midPlane) 78 { 79 sprintf(bombMusciName, "music/enemy2_down.wav"); 80 animationBomb = CCAnimationCache::sharedAnimationCache()->animationByName("animation_Enemy2Bomb"); 81 } 82 else if(enemy->getType() == smallPlane) 83 { 84 sprintf(bombMusciName, "music/enemy1_down.wav"); 85 animationBomb = CCAnimationCache::sharedAnimationCache()->animationByName("animation_Enemy1Bomb"); 86 } 87 88 SimpleAudioEngine::sharedEngine()->playEffect(bombMusciName, false);//开始播放背景音效,false表示不循环 89 90 CCActionInterval *action = CCScaleTo::create(0.5f, pSender->getScale() + 0.05f); 91 CCCallFuncND *funcND = CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy),(void*)pSender); 92 CCFiniteTimeAction* seq = CCSequence::create(CCAnimate::create(animationBomb), funcND, NULL); 93 94 pSender->stopAllActions(); 95 pSender->runAction(seq); 96 97 }
可以看得出,这两个方法其实放到Enemy类里也很正常完全没问题的,这个要看coder想怎么写了。另外,敌机飞出屏幕外时的删除和被子弹打中时爆炸的回收是不同,差一个爆炸效果,而子弹在这两种情况的处理是一样的。