読者です 読者をやめる 読者になる 読者になる

夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【偽スペースハリアー】地面のチェッカー模様を完全再現

スペースハリアー cocos2d TravelShooting JP

前回はスプライトでスペースハリアー風の地面の横縞を作りました。
しかしながらスプライトに動く縞模様をつけるのは無理っぽいことに気がつきました。
そこで、逆転の発想で地面全体から横縞以外の部分を抜く事にしました。
その後ろに別の色の地面を重ね合わせるとその部分が手前の地面の抜けた部分から見えるという寸法です。

つまり、このような穴あきの背景を作り、
f:id:takujidev:20131111195946p:plain:w400
その後ろに別の色の背景を置き
f:id:takujidev:20131111195954p:plain:w400
重ね合わせるとこのようにチェッカー模様の地面が出来上がります。
f:id:takujidev:20131111195959p:plain:w400

左右のスクロールと地平線の上下動は2つの背景をシンクロさせて動かします。
手前へスクロールさせるには手前の地面の帯の部分(穴じゃない部分)を動かします。

動いている様子を動画でどうぞ。画面左下の表示からわかるとおり60pfsで動作しています。

iPhone4Sで実行したときに負荷はこのようになっていて、まだまだ余裕があります。
f:id:takujidev:20131111202216j:plain

ストライプ状に穴があいた地面を作る処理はこのようになっています。
前回はストライプをスプライトのノードとして生成しましたが、今回は座標の情報だけあれば十分なので構造体を作って縞の本数(STRIPE_COUNT)分の配列に入れています。

-(void) visit {
    // 位置に[self convertToWorldSpace:CGPointZero]を足す必要があるらしいが、今回は原点基準
    // のオブジェクトなので省略
    // 座標はcontentScaleFactorを掛けてpointからpixelにした値を使用
    for (int i = 0; i < STRIPE_COUNT; i++) {
        glEnable(GL_SCISSOR_TEST);
        glScissor(stripes[i].originX,
                  stripes[i].originY,
                  stripes[i].width,
                  stripes[i].height);
        [super visit];
        glDisable(GL_SCISSOR_TEST);
    }
}

visitメソッドを上書きしてglScissorで矩形領域を指定すると、子ノードのその部分だけが表示されます。for文で回すと複数の領域を指定できますが、glEnable, glScissor, [super visit], glDisableは全てforループ内に入れる必要があります。
ここで使用する座標はポイントではなくピクセルなので、retinaの場合は2倍にする必要があります。

空が真っ暗で寂しい感じがするので、次回は空と多重スクロールする遠景を表示したいと思います。