發(fā)現(xiàn)CSDN上傳的gif圖不能動。。。有招沒?
飛機可以控制飛行,并且發(fā)射子彈,那沒有敵機怎么行?
敵機共有3種類型,分別為Enemy1,Enemy2和Enemy3,按大小排列,從程序角度看來,它們的本質(zhì)都是一樣的。因此可以從同一個實體中繼承出來,不同點在于:
A.圖像不一樣
B.生命值不一樣
C.移動速度和出現(xiàn)頻率不一樣
D.第三種敵機也就是最大的敵機,在飛行的過程中帶有動畫效果。
這里以最小的敵機(Enemy1)為例。
自定義的敵機類是少不了的,但是要從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;
}
在EnemyLayer中添加3種敵機,敵機出現(xiàn)的位置和飛行速度是隨機值,從我們設(shè)定的范圍中得出,敵機的回收機制同子彈層的處理是一樣的,采用CCArray管理,這里不再贅訴。
void EnemyLayer::addEnemy1(float dt)
{
//調(diào)用綁定敵機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;
//根據(jù)游戲難度給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);
}
敵機在與子彈碰撞后,會產(chǎn)生爆炸效果,也就是一串幀動畫,動畫結(jié)束后,敵機消失,同時進行回收處理。這里的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);//運行爆炸動畫并回收
}
//移除單架敵機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();
}
這里簡單采用幀動畫,單獨執(zhí)行,也可以使用CCSpawn類來實現(xiàn)同時動畫效果
enemy3SpriteFrame_1=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy3_n1.png");
enemy3SpriteFrame_2=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("enemy3_n2.png");
CCAnimation* animation=CCAnimation::create();//創(chuàng)建幀動畫
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,運行一下,敵機滿天飛了,控制你的手指頭移動主角飛機進行射擊,我了個去,死不了是鬧哪樣。。。。
這不廢話!最最重要的碰撞檢測還沒加入呢!
效果圖
更多建議: