サウンドを鳴らすサウンドをどうするか?本稿のために作成したモグラクラスは,1匹1匹のモグラが独立して動くように作っている。必要な数だけのモグラを生成して,パネルに取り付ければ,あとは勝手にモグラが動く仕掛けだ。 となれば,サウンドを鳴らす時も1匹1匹のモグラが勝手に鳴いてくれるというのがベストだろう。モグラクラスのコンストラクタでサウンドをロードして,叩かれたりしたときに鳴く,というコードを書けばいいだけの話……だと思うかもしれないが,それではうまくいかない。 モグラクラスのコンストラクタでサウンドをロードして鳴くようにしたとしよう。たとえば画面に9匹のモグラを出すと,9匹のモグラが,それぞれ独立してサウンドをロード,鳴く形になる。しかしこの方法では非常に無駄が多い上に(携帯の機種にもよると思うが)リソース不足に陥って機能しない可能性がありそうなのだ。 iアプリのサウンドは,若干だがクリティカルな面があるように見える。サウンドを鳴らしだすと,ちょっとしたことでエラーを発生させて落ちたりするなど,不安定さの原因になってしまうのだ。 それだけに,できればサウンドは個別のモグラでロードするのではなく,モグラ全体で1つのサウンドを共有して鳴かすようにしたほうが安全だろうと考えた。しかし,モグラ自体の設計は個別に動くように作っている。サウンドだけを1つに統合するには,どうしたらいいのだろうか? 考えられるのはstaticの利用だ。staticで宣言したメソッドやメンバー変数は,クラスの各インスタンスで共有される。サウンド部分だけstaticで宣言すれば,モグラが何匹になっても1つのサウンドで済ますことができ,リソースの消費を抑えられるだろう。 やや余談だが,予備知識的に知っておくと便利なJavaの機能の1つに,static初期化ブロックがある。今回は利用しなかったが,参考のために説明を加えておきたい。 普通,クラスの初期化はコンストラクタで行う。次のような具合だ。
class MoguraBody ... { しかし,staticで宣言されたメンバー変数は,コンストラクタでは初期化できない。staticで宣言された変数は先に述べたように,クラスインスタンスで共有されるので,コンストラクタで初期化するとインスタンスを作成するたびに,staticな変数が初期化されてしまうためだ。 これをサウンドで考えてみるとよく分かる。たとえば,次のようなコードを書くとしよう。
class MoguraBody .. { サウンドを共有するためにAudioPresenterとMediaSoundをstaticで宣言したわけだが,上記のようにコンストラクタで初期化すると,生成したモグラの数だけ(サンプルでは9匹だから9回)コンストラクタが実行されてしまい,都合が悪い。かといって,AudioPresenterやMediaSoundは,普通の変数のようには簡単には初期化できない(上記のように,いろいろと行うことが多い)ので,ますます厄介だ。 そんなときに活躍するのがstatic初期化ブロックである。static初期化ブロックは,次のように記述する。
class MoguraBody .. { こう書いておくと,staticで囲んだブロックが1回だけ実行される。staticブロックからはstaticなメンバーしか参照できないので,主にstaticなメンバーの初期化に使うわけである。 ただ,いろいろ制限もある。たとえば,static初期化ブロックはJavaが勝手に実行するブロックであるため,ブロック内で例外をスローすることができない。上記のコードでもMediaSoundのuse()メソッドが例外を返すが,その例外を外部にはスローできないのでエラーの捕捉ができない。 今回は後述する理由でstatic変数ブロックは利用しなかったのだが,覚えておくと便利なJavaの機能であることは確かだろう。 エラーを抑制する今回は単純に,サウンド用のクラス(リスト1)を作成してMoguraBodyの中で次のように宣言,音を出すタイミング(叩かれた,失敗した)でplaySound()というメソッドを呼び出すようにした。
class MoguraBody ... { お分かりだとは思うが,上記のように書いてもMoguraSound()のコンストラクタで発生する例外は捕捉できない。結局のところ,static初期化ブロックを使うのと変わりがないわけだが,サウンドだけ別のクラスにしたほうがMoguraBodyクラスが太り続けるより,後で改造が楽だろうと考えた。 ところで,先に述べたようにサウンドは,いろいろな点でクリティカルな部分があるようだ。たとえば,ほかのサウンドをプレイ中に鳴らすとエラーが起こる場合がある。 モグラクラスの場合,モグラをユーザーがヒットしたときと,モグラをヒットし損ねたときに音を出すようにした。ゲーム中にヒット/ミスヒットが連続して起こると,サウンド再生が重なってしまう。それでも,エミュレータでは問題がないのだが,実機では多少の問題が出ることがあった。そこで,リスト1に示したようにサウンド再生中にフラグを立て,別のサウンドを鳴らさないよう,制御している。 もう1つ,サウンドと同時にキーの連続押下のトラブルが起こりだした。これも実機だけの症状だが,モグラを叩くために同じキーを連打すると,時と場合によってエラーが発生して止まってしまうのである。 必ず停止するのではないため,原因は不明のままだが,メインパネルのkeyPressed()メソッド(押下)でモグラを叩くのではなく,keyReleased()メソッド(押上)でモグラを叩くようにしたところエラーが発生しなくなった。キーイベントの発生の仕方に,やや問題があるのだろう。 今回のサンプルプログラム全体のリストはhttp://gadget.mda.or.jp/iapp/mogura.javaからダウンロードできる。また,実際に動くiアプリはhttp://gadget.mda.or.jp/i/mogu.htmlだ。また,今回はjarアーカイブもhttp://gadget.mda.or.jp/iapp/mogura.jarからダウンロードできるようにしておいた。サウンドファイルの参考にしてほしい。 [米田聡,ITmedia] 関連記事 連載バックナンバー Copyright © ITmedia, Inc. All Rights Reserved. モバイルショップ
最新CPU搭載パソコンはドスパラで!!
最新スペック搭載ゲームパソコン
FEED BACK |