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

背筋を伸ばして深呼吸

折角なので専門知識を活かしたい

スマホゲームアプリの作り方 (ライブラリの話②)

コンポーネント指向 (riot.js)

htmlの開発で、riot.js を使用すると再利用可能なコンポーネントを作ることができます。前回、サンプルで作成した照明コンポーネントを今回のシステムに合わせて、作成していきます。

 

 

 

照明の機能について、以下のように設計しています。

照明コンポーネント

  • light.tag ... 照明の状態を管理(light-on, light-off の切り替え)
  • light-on.tag ... 照明の点灯画像
  • light-off.tag ... 照明の消灯画像
  • light-button.tag ... タッチ領域、照明のON/OFFを制御する
 light.tag
<light>
    <light-on if={ state=='on' }></light-on>
    <light-off if={ state=='off' }></light-off>

<script>
var self = this
slef.state = 'off'

obs.on('light', function(state) {
    self.state=(self.state=='off'?'on':'off')
    self.update()
})

</script>
</light>

 

light-on,light-offタグは、「if={ }」で表示/非表示を制御できます。

前回のサンプルでは、light内で画像の切り替えをしていたのですが、

例えばlight-offになったときだけ、タッチできる箇所を作るとなったときは、on, offで制御が分かれていた方がメンテしやすいので、状態毎にタグを作るようにしています。

 

あと、外部からのトリガーが発火したときは、画面の更新が行われないようですので、

self.update()を指定する必要があります。

 

light-button.tag

light-button.tagには、サンプル同様スイッチが押される度にトリガーが走るようにしています。

<light-button>
    <a onclick={ execute }></a>

<script>

/* イベント */
execute(e)
{
    obs.trigger('light')
}

</script>
</light-button>
照明の画像について

本来は、コンポーネント内でstyleを指定するため、照明の画像を指定するわけですが、

今回はコンポーネント内でstyleの指定を行いません。

 

理由は、各部屋によって、照明画像を切り替えたいからですね。

ボタンを押す度に、照明がONOFFする機能的な所は共通として使用して、見た目だけをcss側でlight-on,light-offに画像を当てはめます。

 

cssは以下のように指定します。

部屋A.css

light-on {
    background-image: url(/room_A/light_on.png);
}

部屋B.css

light-on {
    background-image: url(/room_B/light_on.png);
}

 

ゲームサウンドの実装

ゲームをやる上で、音があるかないかというのは、重要ですね。

ただ、スマホという限られたリソースの中で、いかに容量を抑えるかということが課題になるかと思います。

画像の読み込みを最小限にしたり、サウンドファイルの読み込みを最小限にするとかです

なので軽量化を行うのであれば、サウンドは不要かもしれません。このあたりは個人の好みですね。

 

ライブラリを探していたのですが、Howler.js というJavaScript動作のサウンドライブラリが良さそうです。

 

howlerjs.com

理由としては、

  • 軽量であること
  • JQueryを使用しないこと
  • Preload機能があること

 

Preloadとは

Preloadというのは、画面を表示したときにあらかじめ、サウンドファイルをダウンロードして読み込んでおく機能のことです。起動直後は、まだサウンドが必要ないのだけれど、ボタンを押してからサウンドファイルを読み込んだのでは、もたつくことがあるわけですが、それを防ぐことができます。ロードされた後は快適にゲームを行えるわけです。

 

sprite

Howler.jsの特徴的な機能として、sprite という設定があります。

これは、複数ある音を一つのファイルに結合して使用します。

 

以下のような書き方をします。

var sound = new Howl({
    src: ['/sound.mp3'],
    splite: {
        btn_sound1: [0, 1000],
        btn_sound2: [2000, 3000],
        btn_sound3: [4000, 5000]
    }
});

/* 音を鳴らす */
sound.play('btn_sound2');

 

例では、sound.mp3 ファイルの 2000ms - 3000ms のサウンドが切り取られて、音が出るわけです。

 

画像Preload ライブラリ

サウンドファイルのPreloadは、Holer.jsでできるのですが、そうなると画像のPreloadも必要になってきます。照明のボタンを切り替えても、画像が間に合っていないとゲームとしては致命的です。

 

次のライブラリを使用することにしました。

github.com

理由としては、

  • 軽量であること
  • JQueryを使用しないこと

 

preloadのライブラリは意外に多く、自作している人もいるようです。

ただ自分で自作すると、本当にPreloadされているか確認の仕方をどうしたらいいかよく分からなかったので、ライブラリに頼ることにしました。

ライブラリなら、何も考えなくてもやってくれるでしょう!

 

ただし、サウンドのプリロードと、画像のプリロードは別々の処理になっていますから、両方の完了イベントを拾うには、次のような書き方になります。

/* 画像のプリロード */
var imageLoaded = false;
var ip = new ImagePreloader();
ip.queue(['/light_on.png', '/light_off.png', '/light_button.png']);
ip.preload().then(function() {
    imageLoaded = ture;
    loaded();
});

/* サウンドのプリロード */
var soundLoaded = false;
var sound = new Howl({
    src: ['buttn.mp3'],
    preload: true
});

sound.once('load', function() {
    soundLoaded = true;
    loaded();
});

/* プリロード完了 */
function loaded()
{
    if (imageLoaded && soundLoaded)
    {
        // ロード完了後の処理
    }
}

 

起動時は、「Now Loading...」などの待ち処理を入れて、ロード完了後にゲームを開始するという流れになります。

 

まとめると

使用するライブラリとしては、以上かなと思っています。

 

riot.js

コンポーネント指向設計を行うライブラリ

pagetransition.js

ページ遷移にアニメーション効果を追加するライブラリ

(modernizer.js, animation.cssが含まれる)

howler.js

サウンドを流すライブラリ

ImagePreloader

画像プリロードを行うライブラリ

 

 

いずれも軽量であるライブラリを選択しました。

一番大きいライブラリが、「riot+compiler.min.js」で43kbですね。

上記すべてをあわせても、70kbほどです。