不要な要素は削除しよう

enchant.jsでは画面に追加した要素はプログラムの変数とは別の存在になっているようで、削除の手続きをしてあげないと消えないようです。少量だと問題ないですが多くなると実行処理の負担になってたりします。なので不要になったものはきちんと削除してあげましょう。

とはいえ、例えば敵キャラを倒したりするたびにそのキャラの要素を削除する必要はないです。敵キャラなどは状態を「死」にしておいて画面外に放りだしておけばOKです。要素を削除したり新たに生成するのは結構負担が大きいようなのでメインループ内では基本使わない方が良いと思います。

要素の削除が必要になってくるのはシーンの切り替えなどの時です。例えば会話シーンなどを作ってゲーム画面に出した後にその要素をちゃんと削除せずにいるとずっとその要素は残り続けます。そしてまた別の会話シーンで要素を生成して、また別の会話シーンで・・とやっていると使った要素が蓄積されてそのうち処理が重くなってきます。

なのでシーン切り替えの時はいらなくなったシーンをしっかり削除しましょう。

上記の関数をシーンを切り替える際に消したいシーンを引数にして呼び出してやります。これでシーン内の子要素はすべて削除できます。そして最後に

シーン自体も削除してやれば完了です。

こんな感じでシーン切り替えの際にシーンの子要素をすべて削除してシーンもその後に消してやればきれいさっぱり消えてなくなってくれます。

画面のフェードアウト処理

ゲームを作っていて画面遷移時に絶対欲しいのがフェードアウト処理です。このフェードアウト処理がないと突然画面が切り替わり、あまりにも不自然に感じてしまいます。

フェードアウト処理はopacityという透明度のプロパティを使います。これは1が不透明(見える)で0が透明(見えない)です。なので簡単に説明すると黒い画像を用意してこれが透明から不透明に変わっていけばフェードアウトしていっているように見えるわけです。

サンプルプログラム

まず、

のように画面サイズとともに色を指定してFadeOutクラスを作成します(色を指定できるようにしているので白や赤など状況によって使い分けられます)。

initializeでは指定の色とサイズのコンテキストの作成などの初期化処理をします。

startメソッドはフェードアウトを開始したい場所に書きます。

doメソッドはメインループ内に書いておきます。isStartフラグがtrueになるとフェードアウトを開始します。ループ毎に指定されたスピードでフェードアウトします。終わったらtrueを返します。

 

以上の方法で簡単にフェードアウトさせることができます(‘ω’)ノ

バーチャルキーパッドの作り方

スマホ向けゲームを作っていると指でポチポチするだけの単純なゲームになりがちです(批判してるわけではないですよ。ただ類似ゲームばかり・・・)

なので今回はバーチャルキーパッドを自作します。しかも、自分で言うのも何ですが、これ結構すごいです。ブラウザ上でも同時押しとか普通にできちゃいます(私ができるようにしたわけではなく、できるということが分かっただけなんですが(^^;))。ここではenchant.jsでの作り方ですが基本ノウハウが分かれば違う環境でも簡単に作ることができると思うので興味のある方は是非読んでいってください。

ちなみに今回の内容はスマホでの使用が前提ですが、キーボードでも操作可能です。矢印キーとZ、Xキーで操作できるようにします。というか、キーボードでの操作とくっつけてしまうことが一番の肝です!!

用意するもの

f:id:inwan:20180326203607p:plain
方向キー用の画像とA・Bボタン用の画像を用意します。大きさは好きにしてください。私のは方向キーは300px、ボタンは150pxで作ってます。(上の画像は方向キーボタンとボタンが押された状態のものです)

各ボタンの変数

まずはバーチャルパッドではなく、キー入力から説明します。
キーの入力はGameオブジェクトのinput要素に保存されます。方向キーはinput.right、input.left、input.up、input.downにそれぞれ押したらtrue、押されていなければfalseが入ります。ボタンはちょっと違って、あらかじめ

でaボタンにキーボードのボタンを結び付けます。90はZキーのアスキーコードです。違うボタンが良ければアスキーコードを調べて変えてください(‘ω’)ノ
こっちのボタンも方向キーと同様な感じでinput.aにtrueまたはfalseが入ります。

方向入力

方向の入力を簡単に判断できるようにビット演算的な感じで上なら「0001」、右なら「0010」、下「0100」、左「1000」にして数値を当てはめます。

予約語的な感じで作っておくとわかりやすくてよいです。
であとは押されたボタンの数値を足すと方向が出ます。

あとはswitch文で分岐を作ってやればOK。これで左右同時押しなどおかしな入力は無視できます。

ボタンの判定

ボタンの判定は単純に

でOKです。ただし、完ぺきではありません。なぜかというと、いつ押したか、いつ離したか、押したままなのか、離したままなのかということが分からないからです。

なのでもう一つ、直前のボタンの状態を所持する変数を作っておきます

で、ボタンの処理のたびに前回はどうだったか?という分岐を書いてやると今押したのか、押したままだったのかということが分かるということです(‘ω’)ノ

バーチャルキーパッド

さて、ここからやっとバーチャルキーパッドの話になります(´∀`)とりあえず画面の好きなところに用意した画像を表示させてください。
で、実はこれは私が最初javascriptを勉強し始めるときに読んだ田中賢一郎さんの「ゲームで学ぶjavascript入門」参考にしています。

なのでプログラムを丸パクリに書いてしまうわけにもいかないのでここはサラッと説明します(;’∀’)

まず、マウスのクリック位置のevent.x、event.yとキーパッド画像の中心からの距離を出します。そしてそれの絶対値を出します。すると下図のようなグラフで考えられるようになります。

f:id:inwan:20180326213749p:plain
キーパッドの中心を原点として、x座標、y座標を比較してx > yなら右、y > xなら上と判断できます。で、あとはxとyが+かーかで左右、または上下の判断をします(わかるかな(^^;))
ちなみに、この方法だと2x > yとか2y > xとかの条件で8方向も簡単に作れます。

バーチャルキーパッドをキー入力に合わせる

で、最後にバーチャルパッドをキー入力に合わせるようにします。そうするとキー入力の処理のプログラムを書くだけで済みます。

こんな感じで単純にaボタンがクリックされたらキーボード入力の対応ボタンをtrueにしてやるだけです。タッチエンドでfalse。
方向キーの場合はTOUCH_MOVEでも入力できるようにしておくとグリグリ操作できるようになります(´∀`)
あ、あと押した方向キーが分かるようにボタンが光るようにするには、ボタンが一つ押された画像を用意して押されたボタンごとにrotationで角度を変えてやると全方向の画像を用意しなくても済みます。

と、こんな感じで私は自分のバーチャルキーパッドを作ってみました(*´ω`)興味のある方は一度お試しくださいまし。

あとがき

enchant.jsではスマホで2か所同時にタッチすることはできないので、こういうキーパッドでの入力はうまくいかないと思っていました(enchant.jsでキーパッド使ってるゲーム見たことない・・)。なのでただ単純にポチポチして遊ぶスマホゲームみたいなものしか作らないと思ってました。
ところが「秘密警察ギャボリン第二話」の開発中に遊んでるときに「ダッシュボタン」を押しながら「ジャンプボタン」がしっかり反応することを発見!!!「いけるやん!!( *´艸`)」ってテンション上がって自作でバーチャルキーパッドを作ってしまいましたとさ。めでたし、めでたし。。
ということです(笑)

enchant.jsでのBGMの再生の方法

今回はenchant.jsでのBGMの再生についてです。基本的には以前紹介した効果音の鳴らし方と同様に

で再生します。しかし、上記の方法では1回最後まで再生するとそこで音楽再生が終わってしまいます。ゲームのBGMなのだから自動でループ再生してくれないと困りますねよね。

ってことでBGMのループ再生を可能にしてくれる方法がこちら。

詳しいことはわからないのですが、srcというプロパティがスマホにはあってPCには無いようなので処理を変える必要があります。

srcプロパティを持っているスマホでは

この一行を再生時に書いておくだけで自動でループ再生してくれます。問題はPCです。

PCではメインループの中にplay()メソッドを書いておく必要があります。ただし、直接メソッドを書いてしまうとトラブルを引き起こします(演奏停止したいけどplay()メソッドのせいで停止できない、とか)。

なので演奏状態を管理するフラグを用意して再生中のみにループ再生してくれるようにしました。

名前もloopにして何をしてる処理か一目瞭然です(´∀`)

enchant.jsで効果音を鳴らす

enchant.jsでは音を鳴らす基本的な方法はこんな感じになってます。

これで音が鳴ります。clone()は複製する処理で、なくても音は鳴らせますが同じ音を重ねて鳴らすことができません。

音を鳴らしたい場所に上の2行を書けばいくらでも音を鳴らせるんですが、同じ音を鳴らすならデータの引き当ては一回で済ませたいところです。

ということで、以下のようなクラスを作ってみました。

set()で引数に音楽データとともに同時再生数の限度数も渡します。これで必要な数のクローンを先に作ってしまいます。

再生時は順繰りにデータを再生します。しかし、同時再生数が最大数になるとそれ以上再生できなくなり、鳴っている音が消えて再生可能な空きが出るまで次の再生が始まりません。

クローンを作る数は敵キャラの爆発など同時再生が多発するものは多く、あまり同時に発生しない効果音は少な目に作ると良いと思います。

ただし、一度再生するだけなら一番最初に説明した2行で十分です。必要に応じて使ってください(‘ω’)ノ

画像などのデータの一括読み込み

preload()関数

enchant.jsのデータの読み込みをするpreload()という関数について、ちょっとでも楽になる方法の紹介です。

データの読み込みを本やサイトで調べるとだいたい

のように書かれているけど、こうすると後で違うファイル名の画像にしたりするときに結構めんどくさい。

で、このpreload()関数は配列で渡すことができるようなので先に作っておく。JSONで表記しておくとわかりやすい。

読み込みは配列で一括。すごい楽ちん。

画像を使う場所で以下のように指定する。

と、まぁこんな感じでファイル名ではなくキーで指定するからわかりやすいし、ファイル名が変わっても修正は上の配列部分を変えるだけで済むので楽ちん。