飛機(jī)要起飛了,不過明眼人一看就知道起飛的不是飛機(jī),是背景,相對運(yùn)動(dòng)引起的錯(cuò)覺。
在這之前我們先了解一下cocos2d-x引擎中的坐標(biāo)系:
(1)UI坐標(biāo)系。這也是觸摸事件中使用的坐標(biāo)系,原點(diǎn)在左上,坐標(biāo)值往右下方向遞增。
(2)OpenGL坐標(biāo)系。這是cocos2d-x中使用的坐標(biāo)系。也是我們平常編程所使用的,原點(diǎn)在左下,坐標(biāo)值往右上方向遞增。
UI坐標(biāo)系和OpenGL坐標(biāo)系之間的轉(zhuǎn)換是我們經(jīng)常要處理的,其實(shí)它們的縱坐標(biāo)和即是屏幕的高。當(dā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);
}
錨點(diǎn)在cocos2d-x引擎中是個(gè)很重要的概念,可以這么理解,錨點(diǎn)就是一個(gè)基準(zhǔn)點(diǎn)。比如我們要把一個(gè)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));
不,背景要起飛了。
這里我們采用的辦法是讓2張一樣的背景循環(huán)進(jìn)行滾動(dòng),然后通過每次滾動(dòng)的時(shí)間間隔和像素間隔來控制背景滾動(dòng)的速度,也就是飛機(jī)飛行的速度。注意圖1和圖2是一模一樣的,所以最后一步是用圖1替換了圖2。記住圖片的高度必須比屏幕高度高,不然在圖2走到(0,0)的時(shí)候會有黑邊出現(xiàn)。。。
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ù)計(jì)劃,實(shí)現(xiàn)背景滾動(dòng)
this->schedule(schedule_selector(GameLayer::backgroundMove),0.01f);
bRet=true;
} while (0);
return bRet;
}
//背景滾動(dòng)
void GameLayer::backgroundMove(float dt)
{
background1->setPositionY(background1->getPositionY()-2);
background2->setPositionY(background1->getPositionY()+background1->getContentSize().height-2);
if (background2->getPositionY()==0)//要注意因?yàn)楸尘皥D高度是842,所以每次減去2最后可以到達(dá)0,假如背景高度是841,那么這個(gè)條件永遠(yuǎn)達(dá)不到,滾動(dòng)失敗
{
background1->setPositionY(0);
}
}
把GameLayer層加入GameScene場景中,調(diào)試運(yùn)行,背景滾動(dòng)的還不錯(cuò),比較流暢。
更多建議: