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

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

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

【偽スペースハリアー】地面の横縞をとりあえず表示。まだ真っ白だけど。

cocos2d iPhoneアプリ スペースハリアー TravelShooting JP

スペースハリアープロジェクトを引き続き進めています。
今回は手前にスクロールする横縞を表示します。
まだ地面のチェッカー模様は実現できていませんが、縦方向へのスクロールが完成しました。

横縞はスプライトで表示しますが、CCSpriteのpositionやscaleで位置やサイズを調整するのは非常に困難です。従いまして、今回もスプライトの4隅の位置の座標を計算し、その結果をCCSpriteのquadプロパティに入れて表示してあげます。前回の
【Sprite Kit vs cocos2d】パフォーマンス対決(最終戦) どっちを使うか決めました! - 夏までにiPhone アプリつくってみっか!
でも書きましたが、quadプロパティはread-onlyなので自分でセッターを実装する必要があります。

なお、セッターはこんな感じです。

-(void) setQuad:(ccV3F_C4B_T2F_Quad) newQuad
{
    quad_ = newQuad;
}

横縞に話を戻します。
横縞は15本のスプライトのオブジェクトをZ方向に等間隔に並べています。これを画面のy座標でどの位置になるかを計算し、スプライトのquadに入れます。
y座標の位置はz座標だけでなく地平線の位置の影響も受けます。

画面上のy座標 = 地平線のy座標 - 地平線のy座標 * 画面のz座標 / オブジェクトのz座標

という計算式でオブジェクトの画面上のy座標を求めています。
この計算式が3D計算的に正しいかどうかは知りません。
画面のz座標は仮想的なパラメーターで、表示を確認しながら調度いい値を探します。
なお、この値を小さくすると遠近感が強調されます。

縞オブジェクト表示部分のプログラムです。

- (void)update:(ccTime)delta
{
    ccV3F_C4B_T2F_Quad quad = self.quad;
    
    // 四隅のy座標を計算
    CGFloat bottomY = [self groundYWithZPos:self.zPos];
    quad.bl.vertices.y = bottomY;
    quad.br.vertices.y = bottomY;

    CGFloat topY = [self groundYWithZPos:self.zPos + self.stripeWidth];
    quad.tl.vertices.y = topY;
    quad.tr.vertices.y = topY;

    self.quad = quad;
}

- (CGFloat)groundYWithZPos:(CGFloat)zPos
{
    CGFloat horizonY = [Scene3D sharedScene3D].horizonY;
    return (horizonY - horizonY*[Scene3D sharedScene3D].screenZ/zPos);
}

計算上、地平線は無限遠にあるので横縞を増やして行ってもなかなかそこまで到達しません。
縞の数は15本もあれば十分なので逆に地平線の表示位置を少し下げて横縞の位置に合わせました。

横縞が画面手前に消えた後はオブジェクトを解放せずにz座標を遠方に戻して再利用しています。

次回は、横縞に色をつけて地面をチェッカー模様にします。