アイコン イチから始める,
iモードJava
プログラミング
 [第19回]

サウンドを鳴らす

サウンドをどうするか?

 本稿のために作成したモグラクラスは,1匹1匹のモグラが独立して動くように作っている。必要な数だけのモグラを生成して,パネルに取り付ければ,あとは勝手にモグラが動く仕掛けだ。

 となれば,サウンドを鳴らす時も1匹1匹のモグラが勝手に鳴いてくれるというのがベストだろう。モグラクラスのコンストラクタでサウンドをロードして,叩かれたりしたときに鳴く,というコードを書けばいいだけの話……だと思うかもしれないが,それではうまくいかない。

 モグラクラスのコンストラクタでサウンドをロードして鳴くようにしたとしよう。たとえば画面に9匹のモグラを出すと,9匹のモグラが,それぞれ独立してサウンドをロード,鳴く形になる。しかしこの方法では非常に無駄が多い上に(携帯の機種にもよると思うが)リソース不足に陥って機能しない可能性がありそうなのだ。

 iアプリのサウンドは,若干だがクリティカルな面があるように見える。サウンドを鳴らしだすと,ちょっとしたことでエラーを発生させて落ちたりするなど,不安定さの原因になってしまうのだ。

 それだけに,できればサウンドは個別のモグラでロードするのではなく,モグラ全体で1つのサウンドを共有して鳴かすようにしたほうが安全だろうと考えた。しかし,モグラ自体の設計は個別に動くように作っている。サウンドだけを1つに統合するには,どうしたらいいのだろうか?

 考えられるのはstaticの利用だ。staticで宣言したメソッドやメンバー変数は,クラスの各インスタンスで共有される。サウンド部分だけstaticで宣言すれば,モグラが何匹になっても1つのサウンドで済ますことができ,リソースの消費を抑えられるだろう。

 やや余談だが,予備知識的に知っておくと便利なJavaの機能の1つに,static初期化ブロックがある。今回は利用しなかったが,参考のために説明を加えておきたい。

 普通,クラスの初期化はコンストラクタで行う。次のような具合だ。

class MoguraBody ... {

  // コンストラクタ
  MoguraBody() {
    いろいろ初期化する
  }
...
}

 しかし,staticで宣言されたメンバー変数は,コンストラクタでは初期化できない。staticで宣言された変数は先に述べたように,クラスインスタンスで共有されるので,コンストラクタで初期化するとインスタンスを作成するたびに,staticな変数が初期化されてしまうためだ。

 これをサウンドで考えてみるとよく分かる。たとえば,次のようなコードを書くとしよう。

class MoguraBody .. {
  static AudioPresenter ap;
  static MediaSound ms;

  // コンストラクタ
  MoguraBody() {
   ms = MediaManager.getSound(...);
   try {
     ms.use();
   }
   catch( Exception e ) {
   }
   ap = AudioPresenter.getAudioPresenter();
   ap.setSound(ms);
  ...
  }
  ...
}

 サウンドを共有するためにAudioPresenterとMediaSoundをstaticで宣言したわけだが,上記のようにコンストラクタで初期化すると,生成したモグラの数だけ(サンプルでは9匹だから9回)コンストラクタが実行されてしまい,都合が悪い。かといって,AudioPresenterやMediaSoundは,普通の変数のようには簡単には初期化できない(上記のように,いろいろと行うことが多い)ので,ますます厄介だ。

 そんなときに活躍するのがstatic初期化ブロックである。static初期化ブロックは,次のように記述する。

class MoguraBody .. {
  static AudioPresenter ap;
  static MediaSound ms;

  // static初期化ブロック
  static {
    try {
    ms = MediaManager.getSound(...);
    ms.use();
    ap = AudioPresenter.getAudioPresenter();
   ...
    }
    catch( Exception e) }
     ...
    }
  }

  // コンストラクタ
  MoguraBody() {
   ..
  }
}

 こう書いておくと,staticで囲んだブロックが1回だけ実行される。staticブロックからはstaticなメンバーしか参照できないので,主にstaticなメンバーの初期化に使うわけである。

 ただ,いろいろ制限もある。たとえば,static初期化ブロックはJavaが勝手に実行するブロックであるため,ブロック内で例外をスローすることができない。上記のコードでもMediaSoundのuse()メソッドが例外を返すが,その例外を外部にはスローできないのでエラーの捕捉ができない。

 今回は後述する理由でstatic変数ブロックは利用しなかったのだが,覚えておくと便利なJavaの機能であることは確かだろう。

エラーを抑制する

 今回は単純に,サウンド用のクラス(リスト1)を作成してMoguraBodyの中で次のように宣言,音を出すタイミング(叩かれた,失敗した)でplaySound()というメソッドを呼び出すようにした。

class MoguraBody ... {

  static MoguraSound ms
   = new MoguraSound();
  ...

}

 お分かりだとは思うが,上記のように書いても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]

関連記事
▼ 携帯コンテンツ市場を狙うISP──BIGLOBEが課金システム提供
▼ 非公式の携帯Javaに課金──ニフティが課金システムを提供
▼ SO503iの“iアプリバグ”の正体は?
▼ 携帯向けJava,3社の違いは?
▼ 一般向け「iアプリ」市場は立ち上がるのか?
▼ iモード対応Javaを作るのに必要なものは?──NTTドコモ,仕様をついに公開


連載バックナンバー

▼ 付録 iモードJava開発関連リンク集

▼ 第1回 プログラム作成への準備

▼ 第2回 iアプリ製作の流れ

▼ 第3回 ファーストiアプリケーション

▼ 第4回 i-JADEを使おう

▼ 第5回 preverifyの環境作り

▼ 第6回 iアプリでミニゲーム〜グラフィックの取り扱い

▼ 第7回 読者からの質問コーナー

▼ 第8回 キーボードに合わせてグラフィックを動かす

▼ 第9回 クラスって何だろう?

▼ 番外編 ドコモ,公式iアプリ作成ツールを公開

▼ 第10回 NTTドコモの開発ツールを使ってみよう

▼ 第11回 サウンドを使ってみる

▼ 第12回 読者からの質問コーナー〜2

▼ 第13回 スクラッチパッドへの書き込み

▼ 第14回 ネットからデータをダウンロードする

▼ 第15回 アニメーションGIFを使ってみる

▼ 番外編2 iアプリのセキュリティは破られていない

▼ 第16回 もぐら叩きを作る〜1

▼ 第17回 モグラクラスの動作検証

▼ 第18回 読者からの質問コーナー〜3

▼ 第19回 サウンドを鳴らす

▼ 第20回 iアプリの割り込み〜再開処理を実装する

▼ 第21回 サーバと通信を行ってみる

▼ 第22回 iアプリプログラマのためのezplus入門

▼ 第23回 J-フォンのJava仕様

▼ 第24回 iアプリの達人になるには?

Copyright © ITmedia, Inc. All Rights Reserved.



Special

おすすめPC情報テキスト

モバイルショップ

最新CPU搭載パソコンはドスパラで!!
第3世代インテルCoreプロセッサー搭載PC ドスパラはスピード出荷でお届けします!!

最新スペック搭載ゲームパソコン
高性能でゲームが快適なのは
ドスパラゲームパソコンガレリア!