1

開発中のゲームで Java の Clip クラスを使用できません。具体的には、同じクリップを複数回同時に使用することが問題だと思います。グーグルで調べてみたところ、クリップを独自のスレッドで実行することを提案した人もいました。クリップを「リセット」する必要がないように、すべてのスレッドで異なるクリップ オブジェクトを使用するようにクリップ オブジェクトをコピーしたかったのですが、まだ問題が発生しています。実際、問題は、同じクリップが同時に複数回再生されると、ゲームがフリーズしたように見えることです。

Reddit の誰かが、Clip クラスが同期していないことが原因である可能性があり、使用するたびにクリップを開く必要があると示唆しました。サウンドは非常に頻繁に使用されるため、明らかにこれは機能しません。

誰かがクラスの致命的な欠陥を指摘できる場合に備えて、コードは次のとおりです。

/**
    This file is part of Generic Zombie Shooter.

    Generic Zombie Shooter is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Generic Zombie Shooter is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Generic Zombie Shooter.  If not, see <http://www.gnu.org/licenses/>.
 **/
package genericzombieshooter.misc;

import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * Contains all pre-loaded sounds.
 * @author Darin Beaudreau
 */
public enum Sounds {
    // Weapon-Related
    POPGUN("shoot2.wav", false),
    RTPS("shoot1.wav", false),
    BOOMSTICK("shotgun1.wav", false),
    FLAMETHROWER("flamethrower.wav", true),
    THROW("throw2.wav", false),
    EXPLOSION("explosion2.wav", false),
    LANDMINE_ARMED("landmine_armed.wav", false),
    TELEPORT("teleport.wav", false),

    // Zombie-Related
    MOAN1("zombie_moan_01.wav", false),
    MOAN2("zombie_moan_02.wav", false),
    MOAN3("zombie_moan_03.wav", false),
    MOAN4("zombie_moan_04.wav", false),
    MOAN5("zombie_moan_05.wav", false),
    MOAN6("zombie_moan_06.wav", false),
    MOAN7("zombie_moan_07.wav", false),
    MOAN8("zombie_moan_08.wav", false),
    POISONCLOUD("poison_cloud.wav", false),

    // Game Sounds
    POWERUP("powerup.wav", false),
    PURCHASEWEAPON("purchase_weapon.wav", false),
    BUYAMMO("buy_ammo2.wav", false),
    PAUSE("pause.wav", false),
    UNPAUSE("unpause.wav", false);

    private Clip clip;
    private boolean looped;

    Sounds(String filename, boolean loop) {
        openClip(filename, loop);
    }

    private synchronized void openClip(String filename, boolean loop) {
        try {
            URL audioFile = Sounds.class.getResource("/resources/sounds/" + filename);

            AudioInputStream audio = AudioSystem.getAudioInputStream(audioFile);
            AudioFormat format = audio.getFormat();
            DataLine.Info info = new DataLine.Info(Clip.class, format);
            clip = (Clip) AudioSystem.getLine(info);

            clip.open(audio);
        } catch (UnsupportedAudioFileException uae) {
            System.out.println(uae);
        } catch (IOException ioe) {
            System.out.println(ioe);
        } catch (LineUnavailableException lue) {
            System.out.println(lue);
        }
        looped = loop;
    }

    public synchronized void play() {
        play(1.0);
    }

    public synchronized void play(final double gain) {
        Runnable soundPlay = new Runnable() {
            @Override
            public void run() {
                Clip clipCopy = (Clip)clip;
                FloatControl gainControl = (FloatControl)clipCopy.getControl(FloatControl.Type.MASTER_GAIN);
                float dB = (float)(Math.log(gain) / Math.log(10.0) * 20.0);
                gainControl.setValue(dB);
                if(!looped) reset(clipCopy);
                clipCopy.loop((looped)?Clip.LOOP_CONTINUOUSLY:0);

            }
        };
        new Thread(soundPlay).start();
    }

    public synchronized void reset() {
        reset(clip);
    }

    public synchronized void reset(Clip clipCopy) {
        synchronized(clipCopy) { clipCopy.stop(); }
        clipCopy.setFramePosition(0);
    }

    public static void init() {
        values();
    }
}

列挙型と静的な play() メソッドを使用して、私がやろうとしていることは、私が達成しようとしていることに対して可能ですか? それとも、別の方法を見つける必要がありますか? 別のクラスを使用しても問題ありませんが、必要に応じてライブラリを使用することもできますが、コア Java 内に留まりたいと考えています。

誰かが私がやりたいことをする方法を考えることができますか?

4

1 に答える 1

1

クリップは同時実行をサポートしません。クリップはいつでも再開でき、何度でも再生できます。ただし、一度に再生できる特定のクリップのインスタンスは常に 1 つだけです。

TinySound は優れたライブラリですが、彼の Clips で同時再生が可能かどうかは思い出せません。このライブラリについては、Java-gaming.org にかなりのスレッドがあります。

Net Beans についてはわかりませんが、Eclipse で Git Hub ソースを使用するには、Git Hub が提供するアカウントのセットアップ方法とクローンの作成方法に関する指示に従い、クローンをデスクトップにダウンロードします (Bash を使用)。 . 手順は簡単ではありませんが、これは製品 (GitHub) の非常に基本的な使用法であり、サポートを見つけることができるはずです。

プロジェクトがデスクトップに配置されたら、場所として指定されたデスクトップ クローンのルート ディレクトリを使用して、Eclipse で新しいプロジェクトを作成します。Eclipse には、外部ライブラリをプロジェクトにリンクするための追加設定があります。Net Beans に同様のものがない場合、私は本当に驚きます。

Eclipse では、プロジェクトを作成したり、zip ファイルからライブラリをリンクしたりすることもできます。Zip は、Jar ファイルとまったく同じ形式です。Net Beans には、プロジェクトの zip または jar にリンクする方法が必要です。Eclipse では、zip に保存されたプロジェクトに対して「アーカイブ」という用語を使用します。しかし、あなたが持っているzipが、外部プロジェクトとしてロードするために必要なすべてのものであるかどうかはわかりません. GitHub での私の経験は最小限です。

銃声などを再利用したい場合は、サポートしたい同時コピーごとに 1 つのクリップを作成する必要があります。

最終的には、独自のクリップ オブジェクトをコーディングし、それに複数のカーソルを提供し、同時カーソルからのデータを混合するためのインターフェイスを提供しました。それはかなりうまくいきます!お試し用にコピーを送らせていただきます。継続的に動作するオーディオ ミキサーを使用するように設定されています (TinySound と同じだと思います)。でも、コードを送ってくれれば、Clip 部分をスタンドアロンに書き換えることができるかもしれません。また、「PFClip」では、パンニングや音量設定、再生スピードを変えられるので、銃声の速さを変えることができます。そうすることで、別の銃のように聞こえます (または、非常に遅くすると爆発します)。

このライブラリには、いくつかのクールな追加機能があります。クリップをループするための PFLoop (端をスムーズにオーバーラップさせることができます) と、フランジャー、ステレオ コーラス、およびピッチ可変エコーを作成しました。TinySound とは異なり、44100fps および 16 ビットのステレオ wav 形式以外はサポートしていません。私が取り組んでいるゲームのためにこれを書きました。ブラウザ経由でプレイできます: http://hexara.com/game.html風鈴効果は、同時クリップを使用するものです。

忘れた!以前のミキサーの別のデモがあり、同時にさまざまな方法で単一の銃声を使用しています: ここにリンクの説明を入力してください JGO にリストされているコードは古くなっていますが、スレッドの下のページには、独自の同時クリップを作成するために使用されます。

連絡先情報は、2 番目のリンク サイトに記載されています。

于 2013-10-04T23:53:41.857 に答える