ビルボードのアニメーション:Three.jsで3Dブラウザゲームを作る その4

サンプルプログラム

Nengaです。今回はビルボードのアニメーションをご紹介いたします。

ビルボードは3D空間上に2Dの絵を置きます。1枚の板で表現できるので処理の負荷が軽いことと,モデリングの手間なく短時間でモノを表現できる手軽さが特徴です。

3Dゲーム黎明期によく使われた技術で,「サガフロンティア」というゲームではキャラクターもビルボードで表現されていました。

常にカメラの方向を向くため,「一枚板」感はありません。

サンプルプログラムではこれをアニメーションさせ,ゆらめく炎を表現しました。

 

スポンサーリンク

サンプルプログラム:ビルボードのアニメーション

サンプルプログラムを置きましたのでダウンロードお願いいたします。↓

 <サンプルプログラムをダウンロード> 

 

ダウンロードいただけたら,zip展開の上,jsの中にある「script.js」をローカルサーバーで実行方お願いいたします。ローカルサーバーでの実行方法は下記記事のとおりです。

サンプルのデモはこちらになります。


↑タップでデモ開始です。

サンプルプログラムのビルボードのアニメーションについて

サンプルプログラムではビルボードを2体ロードしています。

そしてそれらをアニメーションさせております。2体のビルボードはそれぞれ個別に制御することが可能で,アニメーションを微妙に変えています。(後述いたします。)

BILLBOARDクラス

class BILLBOARD{//Ref: https://ics.media/tutorial-three/sprite/
    constructor(){
        this.amaterial = null;
        this.sprite = null;
        this.animID=0;
        this.animSpeed=1;
        this.animTimer=0;
    }
・・・

ビルボード関連クラスとして,BILLBOARDクラスを作ります。

N3Dlib-00.jsにあり,amaterialが絵を格納spriteが一枚板を格納animID・animSpeed・animTimerがアニメーション関連の情報を格納してます。

 

アニメーションの処理はプログラム中で定義しています。

        tickAnimFrame(frameTime){
        if(this.animID == 0)return;

        this.animTimer += frameTime*this.animSpeed;
        switch(this.animID){
            case 1://cx0~3に流れるアニメ
            if(this.animTimer>4)this.animTimer=0;//くりかえし this.animID=0;
            else this.material.map.offset.x = Math.floor(this.animTimer)*0.25;
            break;
            case 2://cx0~3~0に流れるアニメ
            if(this.animTimer>8)this.animTimer=0;//くりかえし this.animID=0;
            else if(this.animTimer>4)this.material.map.offset.x = Math.floor(-(4-this.animTimer))*0.25;
            else this.material.map.offset.x = Math.floor(this.animTimer)*0.25;
            break;
        }
    }
    startAnim(ID,animSpeed){
        this.animID=ID;
        this.animTimer=0;
        this.animSpeed=animSpeed;
    }
・・・

ここでthis.material.map.offset.xを操作しています。(188行目など)

これは,画像「item002.png」の画像のうち,表示する画像のx・y座標を指定しています。

左下が0,右上が1になります。y座標は下が0,上が1であることに気を付けてください。

毎フレームtickAnimFrame関数が呼び出され,時間経過で使用画像の座標を変えることによってアニメーションさせています。

 

また,アニメーションの方式もanimIDによって分けています。

animID

0:アニメーションオフ
1:画像x座標を0.00~0.75でアニメーション
2:画像x座標を0.00~0.75~0.00でアニメーション(反復)

BILLBOARDの使い方

script.jsの33~34行目で変数宣言しています。余裕をもって最大256体のビルボードを使えるよう用意しておきます。

※「そんなに余分に確保して大丈夫?」と感じるかもしれませんが,本当に使う分以外はカラのデータなので,掛かる負荷はほとんど増えません。(ループの回数が増えるくらい)

//ビルボード
let billBoardMax=256;
let billBoard=[];

初期化は68~70行目で行なっています。ループ文を使って256体をすべて初期化します。

    //ビルボードを初期化
    for(let i=0;i<billBoardMax;i++){
        billBoard[i]=new BILLBOARD();
    }

ビルボードのロードです。127~137行目で実施しています。

    //ビルボードをロード
    num=0;
    billBoard[num].loadTex(scene,’./data/item002.png’);
    billBoard[num].sprite.scale.set(1,1,1);
    billBoard[num].sprite.position.set(0.25,0.5,0);
    billBoard[num].startAnim(1,10);
・・・

ロード関数の後にそれぞれのビルボードについてスケールやポジションをセットします。

 

アニメーションの更新は276~280行目で行なっています。

    //ビルボードのアニメ更新
    for(let i=0;i<billBoardMax;i++){
        if(billBoard[i].material){
            billBoard[i].tickAnimFrame(frameTime);
        }
    }

for文で全ビルボードぶん実施します。

 

ビルボード描画のしくみ

このように,BILLBOARDクラスに絵・一枚板・アニメーション情報をまとめ,そのBILLBOARDクラスのインスタンスbillBoardを配列として宣言することで・・・

billBoard[0]:ビルボード①

billBoard[1]:ビルボード②

billBoard[2]:ビルボード③

・・・とビルボード情報を複数用意し,個別に制御できるようにしました。

 

まとめ

Three.jsでアニメーションするビルボードのサンプルと,使用方法をご紹介させていただきました。

(1)BILLBOARDクラスに絵・一枚板とアニメーション情報を格納します。

(2)BILLBOARDクラスのインスタンスbillboardを配列で複数作成します。

(3)billboard[0~256]に情報をセットし,それぞれを個別にコントロールできます。

 

アニメーションについては2パターン(一方向・反復)用意していますが,プログラムを追記すればオリジナルのパターンを追加できます。

(サンプルは4枚のアニメーションでしたが,たとえば8枚のアニメーションにしたり,フェードアウトさせたりできます。

 

お疲れさまでした。次回も何か機能追加して,ご紹介させていただきたく存じます。

サンプルプログラムの参考にさせていただいたサイト

・ICS Media 様(https://ics.media/tutorial-three/sprite/
 
 

Nenga

コメント

タイトルとURLをコピーしました