0

インターネットで wav ファイルを再生する方法を調べましたが、それらは別のスレッドで再生されないため、曲が完了するまでプログラムが停止することがわかりました。これはゲームでは機能しません。ただし、別のスレッドですべてを再生しようとすると、遅れます。誰でもこれを修正できますか?

注:背景にも継続的にペイントしています:

public class DrawThread extends Thread {

    JFrame j;

    public DrawThread(JFrame frame) {
        j = frame;
    }

    public void run() {
        while (!(isInterrupted())) {
            if (j.isDisplayable() && j.isActive() && j.isEnabled())
            j.update(j.getGraphics());
        }
    }

}

そして update は次のペイントを呼び出すだけです:

public void paint(Graphics g) {
            Graphics2D bg = (Graphics2D) g;
    bg.setBackground(Color.black);
    int w = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    int h = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
    if (time < 500) {
        x[time] = r.nextInt(w) + 150;
        y[time] = h;
        z[time] = r.nextInt(w) + 150;
        time++;
    }
    for (int i = 0; i < time; i++) {
        y[i] -= forward;
        x[i] -= right;
        if (y[i] < 1) {
            x[i] = r.nextInt(400) - 200;
            y[i] = 300;
            z[i] = r.nextInt(400) - 200;
        } else if (y[i] > 300) {
            x[i] = r.nextInt(400) - 200;
            y[i] = 1;
            z[i] = r.nextInt(400) - 200;
        }
        if (x[i] > 200)
            x[i] = -200;
        else if (x[i] < -200)
            x[i] = 200;
        bg.setColor(color);
        bg.drawLine(
                getWidth() / 2 + (int) Math.round(x[i] * 200 / y[i]),
                getHeight() / 2 + (int) Math.round(z[i] * 200 / y[i]),
                getWidth()
                        / 2
                        + (int) Math.round((x[i] + right) * 200
                                / Math.abs(y[i] + forward)),
                getHeight()
                        / 2
                        + (int) Math.round((z[i]) * 200
                                / Math.abs(y[i] + forward)));
    }
}

編集:私が使用している音楽プレーヤー クラスを追加します (私は BigClip に切り替えました):

import java.io.File;
import java.util.Collection;
import java.util.HashMap;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;

import org.crystalix.util.SoundListener;

public class MSHandler {
public static boolean pause = false;
public static boolean stop = false;
private static HashMap<String, BigClip> clips = new HashMap<String, BigClip>();

public static void stopAll() {
    Collection<BigClip> c = clips.values();
    for (BigClip b : c) {
        System.out.println("Stopping "+b.toString());
        b.stop();
        System.out.println("Stopped "+b.toString());
    }
}

public static void playMusic(File file) {
    try {
        AudioInputStream audioIn = AudioSystem.getAudioInputStream(file);
        BigClip clip = new BigClip();
        clip.open(audioIn);
        clip.addLineListener(new SoundListener());
        clip.loop(1);
        clip.start();
        clips.put(file.getName(), clip);
    } catch (Exception e) {
        System.err.println("Sound could not be started!");
        e.printStackTrace(System.err);
    }
}
}
4

1 に答える 1

0

wavファイルの再生に使用しているコードを表示していません。そのため、何が問題になっているのかを診断するのが少し難しくなります。

1)wavは、単に独自のスレッド上にある必要があります。正しく行うと、他のものをブロックすることはありません。Javaサウンドチュートリアルは、これを指摘するのに特に良い仕事をしていません。つまり、wav再生を呼び出すコードを独自のランナブルに配置すれば大丈夫です。

2)再生したい時間の前にwavを「開く」ことができます。その後、最終的に移動するように指示すると、すぐに「開始」する必要があります。

別の注意:wavファイルがすでにメモリにある場合、wavファイルを再生するコードはより高速に実行されます。そのため、最初のwav再生は、少しためらった後にのみ開始される場合があります。ただし、ゼロボリュームで別のサウンドを再生してサウンド再生コードをメモリに取り込むことで、これに対処することは可能です。私はよく、音のあるプログラムの開始時にこれを行います。

バックグラウンドでの継続的なペイントは、JVMがサウンドを処理する時間がないほど多くのCPUを使用している場合にのみ問題になります。それが問題だったら、私は本当に驚きます。もしそうなら、おそらく聞こえるのは、クリック数が多いサウンドの再生です。

于 2012-11-25T08:44:06.893 に答える