效果图:
程序分析:
初始化GameLayer场景触摸,背景、音乐、UI及定时间器
bool GameLayer::init()
{
if (!CCLayer::init()) {
return false;
}
// 开启触摸
this->setTouchEnabled(true);
// 创建数组,需要retain一下
play_bullet = CCArray::create();
play_bullet->retain();
enemy_bullet = CCArray::create();
enemy_bullet->retain();
enemy_items = CCArray::create();
enemy_items->retain();
m_state = statePlaying;//游戏开始,状态为0
Enemy::sharedEnemy();//缓存敌军飞船
Effect::sharedExplosion();//爆炸动画缓存
Config::sharedConfig()->resetConfig();//初始化分数为0、命数3条
winSize = CCDirector::sharedDirector()->getWinSize();
m_levelManager = new LevelManager(this);
//初始化背景
initBackground();
m_screenRec = CCRectMake(0, 0, winSize.width, winSize.height + 10);
// 创建score
m_lbScore = CCLabelBMFont::create("Score:0", s_arial14_fnt);
m_lbScore->setAnchorPoint(ccp(1, 0));
m_lbScore->setAlignment(kCCTextAlignmentRight);//右对齐
addChild(m_lbScore, 1000);
m_lbScore->setPosition(winSize.width - 5, winSize.height - 30);
// ship life
CCTexture2D *shipTexture = CCTextureCache::sharedTextureCache()->addImage(s_ship01);
CCSprite *life = CCSprite::createWithTexture(shipTexture, CCRectMake(0, 0, 60, 38));
life->setScale(0.6);
life->setPosition(ccp(30,winSize.height-23));
addChild(life, 1, 5);
// 显示生命条数
char lifecount[2];
sprintf(lifecount, "%d",Config::sharedConfig()->getLifeCount());
m_lifeCount = CCLabelTTF::create(lifecount, "Arial", 20);
m_lifeCount->setPosition(ccp(60, winSize.height-20));
m_lifeCount->setColor(ccc3(255,0, 0));
addChild(m_lifeCount, 1000);
// 创建飞船
m_ship = Ship::create();
addChild(m_ship, m_ship->getZoder(), 1001);
//游戏暂停按钮
CCMenuItemImage *pause = CCMenuItemImage::create("pause.png", "pause.png", this, menu_selector(GameLayer::doPause));
pause->setAnchorPoint(ccp(1, 0));
pause->setPosition(ccp(winSize.width, 0));
CCMenu *menu = CCMenu::create(pause, NULL);
menu->setAnchorPoint(ccp(0, 0));
addChild(menu, 1, 10);
menu->setPosition(CCPointZero);
// 调 update函数
scheduleUpdate();
// 每秒调一次 scoreCounter函数
schedule(schedule_selector(GameLayer::scoreCounter), 1);
if (Config::sharedConfig()->getAudioState()) {//背景音乐
SimpleAudioEngine::sharedEngine()->playBackgroundMusic(s_bgMusic, true);
}
return true;
}
//主角出场, (主角)飞船创建、发射子弹、复活动画
bool Ship::init()
{
// super init first
if ( !CCSprite::init() )
{
return false;
}
// 初始化飞船
CCTexture2D * shipTextureCache = CCTextureCache::sharedTextureCache()->addImage(s_ship01);
CCRect rec = CCRectMake(0, 0, 60, 38);
this->initWithTexture(shipTextureCache, rec);
this->setPosition(m_appearPosition);
//创建飞船动画
CCSpriteFrame *frame0 = CCSpriteFrame::createWithTexture(shipTextureCache, CCRectMake(0, 0, 60, 38));
CCSpriteFrame *frame1 = CCSpriteFrame::createWithTexture(shipTextureCache, CCRectMake(60, 0, 60, 38));
CCArray *animFrames = CCArray::create();
animFrames->addObject(frame0);
animFrames->addObject(frame1);
CCAnimation *animation = CCAnimation::createWithSpriteFrames(animFrames, 0.1);
CCAnimate *animate = CCAnimate::create(animation);
this->runAction(CCRepeatForever::create(animate));
// 子弹发射
this->schedule(schedule_selector(Ship::shoot), 0.16);
// 复活动画,由大变小
this->m_canBeAttack = false;
CCSprite *ghostSprite = CCSprite::createWithTexture(shipTextureCache, CCRectMake(0, 45, 60, 38));
ccBlendFunc cbl = {GL_SRC_ALPHA, GL_ONE};
ghostSprite->setBlendFunc(cbl);
ghostSprite->setScale(8);
ghostSprite->setPosition(ccp(this->getContentSize().width / 2, 12));
this->addChild(ghostSprite, 3000, 99999);
ghostSprite->runAction(CCScaleTo::create(0.5, 1, 1));
// 复活飞船需要闪烁出场
CCBlink *blinks = CCBlink::create(3, 9);
CCCallFuncN *makeBeAttack = CCCallFuncN::create(this, callfuncN_selector(Ship::makeAttack));
this->runAction(CCSequence::create(CCDelayTime::create(0.5), blinks, makeBeAttack, NULL));
return true;
}
飞船的左右子弹发射
//飞船左右攻击子弹 0.16'一次
void Ship::shoot(float dt)
{
//右边攻击子弹
int offset = 13;//子弹相对飞船的偏移量
CCPoint position = this->getPosition();//飞船坐标
CCSize contentSize = this->getContentSize();
Bullet *bullet_a = new Bullet(m_bulletSpeed, "W1.png", 1);//子弹构造
if (bullet_a) {
bullet_a->autorelease();
play_bullet->addObject(bullet_a);
this->getParent()->addChild(bullet_a, bullet_a->m_zorder, 901);
bullet_a->setPosition(ccp(position.x + offset, position.y + 3 + contentSize.height * 0.3));//子弹的由近至远, x轴不变, 跟随飞船移动
}else{
delete bullet_a;
bullet_a = 0;
}
//左边攻击子弹
Bullet *bullet_b = new Bullet(m_bulletSpeed, "W1.png", 1);
if (bullet_b) {
bullet_b->autorelease();
play_bullet->addObject(bullet_b);
this->getParent()->addChild(bullet_b, bullet_b->m_zorder, 901);
bullet_b->setPosition(ccp(position.x - offset, position.y + 3 + contentSize.height * 0.3));
}else{
delete bullet_b;
bullet_a = 0;
}
}