cheka.jp 超不定期で更新する写真達。お口直しにどうぞ。

【ゲームを作ろう】5日目!画面スクロールを考える

味気ない画面とおさらばする為に画面スクロールのロジックを考えてみました。
色々実験しながら良い方法を模索してみます。

今回は単純に画像を重ねてスクロールする方法。

スクロール1

重ねてスクロール

必要な画像を適当に準備します。
iPhone4対応の為に640×2024のサイズで画像を作成します。
*2048×2048以上のテクスチャは表示エラーになるため

また、処理が煩雑にならないように専用のクラスも準備します。

#include "cocos2d.h"
class ScrollBgSprite : public cocos2d::Sprite
{
public:
    //現在の画像タグ
    static int imgTag;
    //スクロール回数
    static int scrollCount;
    //背景の生成
    static void createGameBg(cocos2d::Layer* layer,cocos2d::Size frame);
};
#include "ScrollBgSprite.h"

USING_NS_CC;

/*
 背景画像の生成
 */
void ScrollBgSprite::createGameBg(cocos2d::Layer* layer,cocos2d::Size frame)
{
    //最初は1枚目を右下に配置する
    if(ScrollBgSprite::scrollCount == 0)
    {
        //スクロール画像を追加
        Sprite* bg_sprite = Sprite::create(CreateImageName::createBgImage("bg_game_0_0",frame,false));
        bg_sprite->setAnchorPoint(Point(0,0));
        bg_sprite->setPosition(0,0);
        MoveTo* moveTo = MoveTo::create( frame.height/960*12*Director::getInstance()->getContentScaleFactor(),Point(0, (bg_sprite->getContentSize().height*-1) ));
        cocos2d::CallFunc *moveToDone = CallFunc::create([bg_sprite,layer,frame]()
                                                         {
                                                             ScrollBgSprite::createGameBg(layer,frame);
                                                             bg_sprite->removeFromParent();
                                                         });
        bg_sprite->runAction(Sequence::create(moveTo, moveToDone, NULL));
        //レイヤーに追加
        layer->addChild(bg_sprite,0);
        ScrollBgSprite::scrollCount++;
    }
    //背景の作成
    int bg_number = ScrollBgSprite::getLevel();
    int tag = 0;
    if(ScrollBgSprite::imgTag==0)
    {
        tag = 1;
        ScrollBgSprite::imgTag = 1;
    }
    else
    {
        ScrollBgSprite::imgTag = 0;
    }
    Sprite* bg_sprite = Sprite::create(CreateImageName::createBgImage(StringUtils::format("bg_game_%d_%d",bg_number,tag),frame,false));
    bg_sprite->setAnchorPoint(Point(0,0));
    bg_sprite->setPosition(0,bg_sprite->getContentSize().height);
    //アニメーション
    MoveTo* moveTo = MoveTo::create( frame.height/960*12*2*Director::getInstance()->getContentScaleFactor(),Point(0, (bg_sprite->getContentSize().height*-1) ));
    cocos2d::CallFunc *moveToDone = CallFunc::create([bg_sprite,layer,frame]()
                                                     {
//                                                         CCLOG(" scrollCount=%d ",ScrollBgSprite::scrollCount);
                                                         ScrollBgSprite::scrollCount++;
                                                         ScrollBgSprite::createGameBg(layer,frame);
                                                         bg_sprite->removeFromParent();

                                                     });
    bg_sprite->runAction(Sequence::create(moveTo, moveToDone, NULL));
    //レイヤーに追加
    layer->addChild(bg_sprite,0);
}

/*
 現在の画像タグ
 */
int ScrollBgSprite::imgTag = 0;

/*
 スクロールカウント
 */
int ScrollBgSprite::scrollCount = 0;

ポイントと解説

*画像生成は独自に実装したCreateImageNameクラスに移譲しています。
1つめのポイントは画像を2つ並べてMoveTo後に2枚目を追加する箇所です。
MoveToが完了したら、自分自身を呼び出して2枚目以降の画像を追加します。
この処理によって複数の画像を永久的にスクロールさせることが出来ます。

2つめのポイントはMoveToに必要な時間の計算です。
960pxの縦幅をDurationを12でスクロールするのを基準に、それぞれの解像度でも同じ速さでスクロールするように丸め込みます。

3つめのポイントはScrollBgSprite::scrollCountです。
この回数を目安に各レベルごとの背景を準備することが可能になります。

懸念点

画像の繋ぎ目に隙間が開いてしまうようです。
下のレイヤーにスクロールしない背景を置いて繋ぎ目がわからないようにすることを検討していますが、他の方法が無いか模索中です。

Add a Comment

メールアドレスが公開されることはありません。