2012 年 10 月 のアーカイブ

iPhoneでenchant.jsのサウンド再生

2012 年 10 月 15 日 月曜日 by 山平

Javascript製ゲームエンジンenchant.jsについて、過去にいくつかの記事を書きました。

ここでは触れていないのですが、enchant.jsではiPhone(MobileSafali)ではサウンドの再生に制限があります。

wise9 › enchant.jsのサウンド機能で、ゲームをさらにカッコよく!

特に、iOS上のブラウザ (Mobile Safari) については、「プレイヤーが画面にタップしたとき以外、音声が再生できない!」という大きな制限があるため、暫定的に、デフォルトでは以下のようなコードを実行しフラグを立てない限り再生されないという仕様になっています。・・・が、いまのところバグがあるらしくiOSで正しく再生されません!目下修正中です!

と、いうことで今回はiPhoneでのサウンド再生について調べてみました。
以下のサイトの情報を参考にしています。

D-lagoon ブログ [enchant.js]iPhoneで音を鳴らすのに一苦労 | D-lagoon ブログ

検証のために以下のようなコードを作成しました。

JavaScript:
  1. enchant();
  2. enchant.Sound.enabledInMobileSafari = true;//必須
  3.  
  4. IMAGE_FILE = "chara1.png";
  5. SOUND_FILE = "gameover.wav";
  6. InitBear = function(no){
  7. var game = enchant.Game.instance;
  8. var bear = new Sprite(32, 32);
  9. bear.image = game.assets[IMAGE_FILE];
  10. bear.x = (game.width - bear.width) * (no/5);
  11. bear.y = (game.height - bear.height) * (no/5);
  12. bear.frame = no * 5;
  13. return bear
  14. };
  15.  
  16. window.onload = function(){
  17.  
  18. var game = new Game(320, 320);
  19.  
  20. game.fps = 15;
  21. game.preload(IMAGE_FILE, SOUND_FILE);
  22. game.onload = function(){
  23.  
  24. var no = 1;
  25.  
  26. // 1: 通常、これで再生できる
  27. var bear1 = InitBear(no++);
  28. bear1.addEventListener("touchstart", function(){
  29. game.assets[SOUND_FILE].clone().play();
  30. });
  31. game.rootScene.addChild(bear1);
  32.  
  33. // 2: 参考サイト(D-lagoon ブログ)での回避策
  34. var bear2 = InitBear(no++);
  35. bear2.addEventListener("touchstart", function(){
  36. game.load(SOUND_FILE, function(){
  37. game.assets[SOUND_FILE].play();
  38. });
  39. });
  40. game.rootScene.addChild(bear2);
  41.  
  42. // 3: 上からloadを省略してみる
  43. var bear3 = InitBear(no++);
  44. bear3.addEventListener("touchstart", function(){
  45. game.assets[SOUND_FILE].clone().play();
  46. });
  47. game.rootScene.addChild(bear3);
  48.  
  49. // 4: イベントだけ拾って保持
  50. var bear4 = InitBear(no++);
  51. bear4.flag = false;
  52. bear4.addEventListener("touchstart", function(){
  53. if(this.flag) game.assets[SOUND_FILE].clone().play();
  54. this.flag = false;
  55. });
  56. bear4.addEventListener("enterframe", function(){
  57. this.flag = true;
  58. });
  59. game.rootScene.addChild(bear4);
  60.  
  61. };
  62. game.start();
  63. };

結果は予想通り、2と3でサウンドの再生を確認できました。
しかし、再生までに数秒かかるので、実用的とは言えませんが、Mobile Safaliではこれが限界なようです。

【後日談】
数日後、ふと同じ検証を行なってみました。
するとなぜか1,2,3,4すべてのパターンでサウンドが再生されました。
ソースは触っていないのに何故???
ですが、やっぱり再生までに数秒かかるので、実用的とは言えません。

以上です。