森クマblog

スマートフォン向けアプリ開発者の奮闘記

【Cocos2d-x】エンドレス背景を実装する

こんにちはです。

「森でクマさんテラヤバス」の舞台は、そう、森。大森林ですよ。
ゲーム背景の森はエンドレスでスクロールします。
今日はこの背景エンドレスの原理を説明してみたいと思います!

①背景画像を1枚用意します。
f:id:shakeflower93:20151122233533p:plain
この背景画像は、横に並べるとつながるように調整します。
f:id:shakeflower93:20151122233558p:plain

②ゲーム画面上で、背景画像を2つ並べて、一緒にスクロールさせます。
f:id:shakeflower93:20151122233621p:plain
ただ、このままスクロールさせていくと、背景Aはいずれ画面左外に完全に出てしまうんですね。
そこで、背景Aが画面外に完全に出たタイミングで、すかさず背景Aを背景Bの右に回り込ませます。

そしてまたスクロールさせて、今度は背景Bが画面外に出たタイミングで、背景Bを背景Aの右に回り込ませます。
f:id:shakeflower93:20151122233638p:plain
このルーチンを繰り返すことで、エンドレス背景を実現することができます。

原理が分かったところで、Cocos2d-xで書かいてみるとこんな感じ↓
MainScene.cpp(抜粋)

bool MainScene::init()
{

    // 背景Aを画面左端に合わせて設置
    _bgA = Sprite::create(filename);
    _bgA->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
    _bgA->setPosition(Vec2(0,0));
    this->addChild(_bgA);
    
    // 背景Bを背景Aの右隣に設置
    _bgB = Sprite::create(filename);
    _bgB->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
    _bgB->setPosition(Vec2(_bgA->getContentSize().width,0));
    this->addChild(_bgB);

    // update関数を1フレームごとに呼び出す
    this->scheduleUpdate();
    
    return true;
}


void MainScene::update(float dt) {
    
    // 背景ABを毎フレームごとに5px左にスクロールする
    _bgA->setPositionX(_bgA->getPositionX() - 5);
    _bgB->setPositionX(_bgB->getPositionX() - 5);
    
    if (_bgB->getPositionX() < 0) {
        // 背景Aが画面左外に出きった場合、背景Aを背景Bの右隣に移す
        _bgA->setPositionX(_bgB->getPositionX() + _bgB->getContentSize().width);

        // 背景AとBの変数を入れ替える
        auto s = _bgB;
        _bgB = _bgA;
        _bgA = s;
    }
    
}

ちなみにCocos2d-xには、動く背景+遠近表現を簡単に実現できる「ParallaxNode」なるクラスもあります。