鍍金池/ 教程/ Java/ 引擎坐標系,錨點和背景滾動
游戲暫停和觸摸屏蔽
游戲場景過渡
碰撞檢測
跨平臺移植和廣告植入
批次渲染
觸摸事件和優(yōu)先級
背景音樂和音效
別急,先處理好CCScene和CCLayer的關(guān)系
自定義敵機精靈
UFO層特殊道具
主角的登場和幀動畫
引擎坐標系,錨點和背景滾動
分數(shù)的本地存儲
子彈層的處理
搞個飛機來玩玩

引擎坐標系,錨點和背景滾動

飛機要起飛了,不過明眼人一看就知道起飛的不是飛機,是背景,相對運動引起的錯覺。

1.cocos2d-x引擎的坐標系

在這之前我們先了解一下cocos2d-x引擎中的坐標系:

(1)UI坐標系。這也是觸摸事件中使用的坐標系,原點在左上,坐標值往右下方向遞增。

(2)OpenGL坐標系。這是cocos2d-x中使用的坐標系。也是我們平常編程所使用的,原點在左下,坐標值往右上方向遞增。

UI坐標系和OpenGL坐標系之間的轉(zhuǎn)換是我們經(jīng)常要處理的,其實它們的縱坐標和即是屏幕的高。當然Cocos2d-x也提供了非常方便的轉(zhuǎn)換函數(shù)給我們使用。

    CCPoint CCDirector::convertToGL(const CCPoint& uiPoint)
    {
        CCSize s = m_obWinSizeInPoints;
        float newY = s.height - uiPoint.y;

        return ccp(uiPoint.x, newY);
    }

    CCPoint CCDirector::convertToUI(const CCPoint& glPoint)
    {
        CCSize winSize = m_obWinSizeInPoints;
        float oppositeY = winSize.height - glPoint.y;

        return ccp(glPoint.x, oppositeY);
    }

2.錨點

錨點在cocos2d-x引擎中是個很重要的概念,可以這么理解,錨點就是一個基準點。比如我們要把一個100x200的長方形放在屏幕上。

第一種情況

    m_sprite->setAnchorPoint(ccp(0.5,0.5));
    m_sprite->setPosition(ccp(300,300));

第二種情況

    m_sprite->setAnchorPoint(ccp(0,0));
    m_sprite->setPosition(ccp(300,300));

http://wiki.jikexueyuan.com/project/cocos2d-x-getting-real/images/3.1.jpeg" alt="" />

3.飛機要起飛了

不,背景要起飛了。

這里我們采用的辦法是讓2張一樣的背景循環(huán)進行滾動,然后通過每次滾動的時間間隔和像素間隔來控制背景滾動的速度,也就是飛機飛行的速度。注意圖1和圖2是一模一樣的,所以最后一步是用圖1替換了圖2。記住圖片的高度必須比屏幕高度高,不然在圖2走到(0,0)的時候會有黑邊出現(xiàn)。。。

http://wiki.jikexueyuan.com/project/cocos2d-x-getting-real/images/3.2.jpeg" alt="" />

    bool GameLayer::init()
    {
        bool bRet=false;
        do
        {
            CC_BREAK_IF(!CCLayer::init());

            //png加入全局cache中
            CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("shoot_background.plist");

            //加載background1,background1和background2是CCSprite*型成員變量
            background1=CCSprite::create(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("background.png"));
            background1->setAnchorPoint(ccp(0,0));
            background1->setPosition(ccp(0,0));
            this->addChild(background1);

            //加載background2
            background2=CCSprite::create(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("background.png"));
            background2->setAnchorPoint(ccp(0,0));
            background2->setPosition(ccp(0,background2->getContentSize().height-2));//這里減2的目的是為了防止圖片交界的黑線

            this->addChild(background2);

            //執(zhí)行任務(wù)計劃,實現(xiàn)背景滾動
            this->schedule(schedule_selector(GameLayer::backgroundMove),0.01f);

            bRet=true;
        } while (0);
        return bRet;
    }

    //背景滾動
    void GameLayer::backgroundMove(float dt)
    {
        background1->setPositionY(background1->getPositionY()-2);
        background2->setPositionY(background1->getPositionY()+background1->getContentSize().height-2);
        if (background2->getPositionY()==0)//要注意因為背景圖高度是842,所以每次減去2最后可以到達0,假如背景高度是841,那么這個條件永遠達不到,滾動失敗
        {
            background1->setPositionY(0);
        }
    }

把GameLayer層加入GameScene場景中,調(diào)試運行,背景滾動的還不錯,比較流暢。