1. 程式人生 > >【雷電】源代碼分析(二)-- 進入遊戲攻擊

【雷電】源代碼分析(二)-- 進入遊戲攻擊

engine 場景 aud 初始 cto onf 不變 addchild ems

效果圖:

技術分享

程序分析:

初始化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);
    
	//遊戲暫停button
    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;
    }


}


【雷電】源代碼分析(二)-- 進入遊戲攻擊