【cocos2d-x入门实战】微信飞机大战之八:自定义敌机精灵

原创作品,转载请标明http://blog.csdn.net/jackystudio/article/details/11890969

发现CSDN上传的gif图不能动。。。有招没?

飞机可以控制飞行,并且发射子弹,那没有敌机怎么行?

敌机共有3种类型,分别为Enemy1,Enemy2和Enemy3,按大小排列,从程序角度看来,它们的本质都是一样的。因此可以从同一个实体中继承出来,不同点在于:

A.图像不一样

B.生命值不一样

C.移动速度和出现频率不一样

D.第三种敌机也就是最大的敌机,在飞行的过程中带有动画效果。

这里以最小的敌机(Enemy1)为例。


1.有生命的敌机

自定义的敌机类是少不了的,但是要从CCNode继承还是CCSprite继承,那就要看实际需要了,从CCNode继承灵活度会高一点,但是也麻烦一点,从CCSprite继承就会相对简单一点,但是灵活度就低了。建议还是从CCNode继承,这里选择从CCNode继承。Enemy相当于一个容器,可以绑定一个精灵。

#include "Enemy.h"
Enemy::Enemy(void)
{
    m_sprite=NULL;//m_sprite是CCSprite指针,用来绑定敌机
    m_life=0;//生命值
}


Enemy::~Enemy(void)
{
}

Enemy* Enemy::create()
{
    Enemy* pRet=new Enemy;
    pRet->autorelease();
    return pRet;
}


void Enemy::bindSprite(CCSprite* sprite,int life)//绑定敌机,并传入生命值
{
    m_sprite=sprite;
    m_life=life;
    this->addChild(m_sprite);
}


CCSprite* Enemy::getSprite()
{
    return m_sprite;
}


int Enemy::getLife()//获取生命
{
    return m_life;
}


void Enemy::loseLife()//生命值-1
{
    m_life--;
}


CCRect Enemy::getBoundingBox()//获取敌机大小
{
    CCRect rect=m_sprite->boundingBox();
    CCPoint pos=this->convertToWorldSpace(rect.origin);
    CCRect enemyRect(pos.x,pos.y,rect.size.width,rect.size.height);
    return enemyRect;
}


2.敌机的随机初始位置和速度

在EnemyLayer中添加3种敌机,敌机出现的位置和飞行速度是随机值,从我们设定的范围中得出,敌机的回收机制同子弹层的处理是一样的,采用CCArray管理,这里不再赘诉。

void EnemyLayer::addEnemy1(float dt)
{
    //调用绑定敌机1
    Enemy* enemy1=Enemy::create();
    enemy1->bindSprite(CCSprite::create(enemy1SpriteFrame),ENEMY1_MAXLIFE);

    //随机初始位置
    CCSize enemy1Size=enemy1->getSprite()->getContentSize();
    CCSize winSize=CCDirector::sharedDirector()->getWinSize();
    int minX=enemy1Size.width/2;
    int maxX=winSize.width-enemy1Size.width/2;
    int rangeX=maxX-minX;
    int actualX=(rand()%rangeX)+minX;

    enemy1->setPosition(ccp(actualX,winSize.height+enemy1Size.height/2));
    this->addChild(enemy1);
    this->m_pAllEnemy1->addObject(enemy1);

    //随机飞行速度
    float minDuration,maxDuration;

    //根据游戏难度给minDuration,maxDuration赋值

    int rangeDuration=maxDuration-minDuration;
    int actualDuration=(rand()%rangeDuration)+minDuration;

    CCFiniteTimeAction* actionMove=CCMoveTo::create(actualDuration,ccp(actualX,0-enemy1->getSprite()->getContentSize().height/2));
    CCFiniteTimeAction* actionDone=CCCallFuncN::create(this,callfuncN_selector(EnemyLayer::enemy1MoveFinished));

    CCSequence* sequence=CCSequence::create(actionMove,actionDone);
    enemy1->runAction(sequence);
}


3.敌机爆炸

敌机在与子弹碰撞后,会产生爆炸效果,也就是一串帧动画,动画结束后,敌机消失,同时进行回收处理。这里的animate如果能加入动画缓冲池,效率会更高。

//敌机爆炸
void EnemyLayer::enemy1Blowup(Enemy* enemy1)
{
    CCAnimation* animation=CCAnimationCache::sharedAnimationCache()->animationByName("Enemy1Blowup");//动画事先加入动画池
    CCAnimate* animate=CCAnimate::create(animation);
    CCCallFuncND* removeEnemy1=CCCallFuncND::create(this,callfuncND_selector(EnemyLayer::removeEnemy1),(void*)enemy1);
    CCSequence* sequence=CCSequence::create(animate,removeEnemy1);
    enemy1->getSprite()->runAction(sequence);//运行爆炸动画并回收
}

4.EnemyLayer敌机层的其他接口

//移除单架敌机1
void EnemyLayer::removeEnemy1(CCNode* pTarget, void* data)
{
    Enemy* enemy1=(Enemy*)data;
    if (enemy1!=NULL)
    {
        m_pAllEnemy1->removeObject(enemy1);
        this->removeChild(enemy1,true);
    }
}

//移除所有敌机,干嘛用?还记得有个ufo炸弹全屏秒么。。。
void EnemyLayer::removeAllEnemy1()
{
    CCObject* obj;
    CCARRAY_FOREACH(m_pAllEnemy1,obj)
    {
        Enemy* enemy1=(Enemy*)obj;
        if (enemy1->getLife()>0)
            {
                enemy1Blowup(enemy1);
            }
    }
}
void EnemyLayer::removeAllEnemy()
{
    removeAllEnemy1();
    removeAllEnemy2();
    removeAllEnemy3();
}


5.超大型敌机的飞行动画

这里简单采用帧动画,单独执行,也可以使用CCSpawn类来实现同时动画效果

enemy3SpriteFrame_1=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy3_n1.png");
enemy3SpriteFrame_2=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy3_n2.png");
CCAnimation* animation=CCAnimation::create();//创建帧动画
animation->setDelayPerUnit(0.2f);
animation->addSpriteFrame(enemy3SpriteFrame_1);
animation->addSpriteFrame(enemy3SpriteFrame_2);
CCAnimate* animate=CCAnimate::create(animation);
enemy3->getSprite()->runAction(CCRepeatForever::create(animate));//采用CCRepeaterForever不断重复动画

好了,把EnemyLayer也添加进GameLayer,运行一下,敌机满天飞了,控制你的手指头移动主角飞机进行射击,我了个去,死不了是闹哪样。。。。

这不废话!最最重要的碰撞检测还没加入呢!

效果图


评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值