- ベストアンサー
Java言語プログラムと音楽の同期について
- Java言語プログラムと音楽の同期についての質問です。音楽ゲームのプログラミングをしていますが、起動する度に微妙な誤差が出てしまいます。同期化や定まったタイミングでの音楽再生は可能でしょうか?
- Java言語プログラムと音楽の同期についてご相談です。音楽ゲームの開発中で、起動の度に微妙な誤差が生じています。同期化させる方法や、定まったタイミングでの音楽再生の実現方法を教えてください。
- Java言語プログラムと音楽の同期化について質問があります。音楽ゲームを作成しているのですが、起動するたびに微妙な誤差が生じてしまいます。同期化させる方法や、定まったタイミングでの音楽再生の実現方法についてアドバイスしていただけると助かります。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#2です。 全く自信ありません。 --- 同期のアイデアですが、 たとえば、 サウンドを再生させたのち、 「音声再生の進行具合」自体を「ゲーム内部時計」にする、 とか・・・。 再生はClip#open()などで。 再生の進行具合はgetFramePosition()などで取得。(これを時計にする) http://java.sun.com/j2se/1.5.0//ja/docs/ja/api/javax/sound/sampled/Clip.html 音声ファイルの各種情報は AudioFormatクラスで。 http://sdc.sun.co.jp/java/docs/j2se/1.5.0/ja/docs/ja/api/javax/sound/sampled/AudioFormat.html JavaのサウンドAPIについては、詳しくはしらないので、 ネットで調べてみてください。 (参考サイト: 「Javaでゲーム作りますが何か」ClipでWAVE再生 http://javagame.main.jp/index.php?Clip%A4%C7WAVE%BA%C6%C0%B8)
その他の回答 (2)
- kacchann
- ベストアンサー率58% (347/594)
「ただ音を流しているだけ」のサンプルコード書いてみました。 同期とかは、させてません。 オーディオファイルは24秒間のauファイルをループ再生して、 再生テンポと表示が一致しているかどうかを確認。 java1.5のappletviewerではOK. java1.4のappletviewerではアウト。(※再生スピードが正確でなく やや遅いし、ノイズがわりと頻繁に入る) 動作確認 OS:WinMe マシン:pentium3 500MHz import java.net.*; import javax.sound.sampled.*; public class Demo extends Applet{ static boolean gameStart;AudioClip ac; public void init(){ setLayout(new BorderLayout()); MyP myP=new MyP();add(myP,"Center"); final GameLoop gameLoop=new GameLoop(myP); gameLoop.start(); Button btn=new Button("1"); btn.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ ac=getAudioClip(getDocumentBase(),"test.au"); gameStart=true;ac.loop();gameLoop.init(); } }); add(btn,"North"); } } class MyP extends Canvas{ boolean mark; void showMark(boolean b){mark=b;} public void paint(Graphics g){ if(!Demo.gameStart){g.drawString("準備中",20,40); }else{ if(mark)g.drawString("打",20,40); else g.drawString("",20,40); } } } class GameLoop extends Thread{ MyP myP;boolean agenda; final long period=1000;final long showPeriod=100; boolean musicStart;long agendaTime;long lastTime; GameLoop(MyP myP){this.myP=myP;} void init(){musicStart=true;} /**ゲームループ*/ public void run(){ while(true){ oneFrame(); try{Thread.sleep(30);}catch(InterruptedException e){} } } void oneFrame(){ if(!Demo.gameStart){return;} if(musicStart){ musicStart=false;agenda=true; lastTime=System.currentTimeMillis(); } long now=System.currentTimeMillis(); if(agenda){ myP.showMark(true);agendaTime=now; }else{ if(now-agendaTime>showPeriod){ myP.showMark(false); } } agenda=false; now=System.currentTimeMillis();long d=now-lastTime; if(d>=period){ long times=d/period;lastTime+=period*times;agenda=true; } myP.repaint(); } }
お礼
ご回答ありがとうございます。 kacchann様のおっしゃる java1.5、java1.4 というのは コンパイル時の -target オプションでの指定、 もしくは実行環境の事だという取り方でよろしいでしょうか? とにかく、わざわざ記述していただいたサンプルプログラム、 是非参考にさせていただきます。ありがとうございます。
- CXI00554
- ベストアンサー率27% (57/205)
「対応するキー」を押した時に毎回何かのオブジェクトをnew()している 場合、オーバーヘッドが気になるかもしれません。そこで、そのオブジェクト をあらかじめ(起動時に)複数プールしておき、キーが押された時に一つ つかうというのはどうでしょうか。 はずしていたらすみません。
補足
早速のご回答ありがとうございます。 ゲームプレイ中に、オブジェクトの生成をするような プログラムの記述はしていないので、その心配はございません。 CXI00554様がおっしゃるように、ゲームで使うオブジェクトに関しては プログラムの初めで全て用意しておく形でプログラムを組んでいます。 試しに、実際のゲームプレイ中にキー操作を 全く行わずに実行してみたりもしましたが、 やはり微妙な誤差が生じます。 System.currentTimeMillis()メソッドで時間を計り、 ゲームのループを回しているのですが、 このSystem.currentTimeMillis()メソッドは しっかりとした値を返さない場合があると言われてるので(笑)、 このメソッドにも問題があるのかと、一人悩んでおります。
お礼
kacchann様、またまたご回答ありがとうございます。 提案してくださった時計システムでどうにかなりそうです。 本当にありがとうございました!