cocos2dx打飞机项目笔记四:Enemy类和EnemyLayer类

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 };
View Code

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;
}
View Code

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 };
View Code

敌机的创建和子弹不同,还记得子弹的创建我是保证屏幕上只有一粒子弹的吧,敌机则不然,固定每隔多少时间就会创建

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 }
View Code

可以看得出,这两个方法其实放到Enemy类里也很正常完全没问题的,这个要看coder想怎么写了。另外,敌机飞出屏幕外时的删除和被子弹打中时爆炸的回收是不同,差一个爆炸效果,而子弹在这两种情况的处理是一样的。

原文地址:https://www.cnblogs.com/zouzf/p/3490577.html