0

Javaでゲームを作っていました。Eclipse では正常に動作しますが、jar にパックすると、マップ内のオブジェクトが決して破棄されないという問題が発生しました。例外を確認するために、コマンドラインから起動したところ、Java は次の例外を示しました。

C:\Users\SriHarshaCH>java -jar C:\Users\SriHarshaCH\Desktop\Treasure.jar

java.io.IOException: mark/reset not supported
        at java.util.zip.InflaterInputStream.reset(Unknown Source)
        at java.io.FilterInputStream.reset(Unknown Source)
        at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
        at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
        at com.gej.sound.WavPlayer.loadSound(WavPlayer.java:39)
        at treasure.Treasure.initResources(Treasure.java:152)
        at com.gej.core.Game.run(Game.java:117)
        at java.lang.Thread.run(Unknown Source)
java.io.IOException: mark/reset not supported
        at java.util.zip.InflaterInputStream.reset(Unknown Source)
        at java.io.FilterInputStream.reset(Unknown Source)
        at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
        at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
        at com.gej.sound.WavPlayer.loadSound(WavPlayer.java:39)
        at treasure.Treasure.initResources(Treasure.java:154)
        at com.gej.core.Game.run(Game.java:117)
        at java.lang.Thread.run(Unknown Source)
java.io.IOException: mark/reset not supported
        at java.util.zip.InflaterInputStream.reset(Unknown Source)
        at java.io.FilterInputStream.reset(Unknown Source)
        at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
        at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
        at com.gej.sound.WavPlayer.loadSound(WavPlayer.java:39)
        at treasure.Treasure.initResources(Treasure.java:156)
        at com.gej.core.Game.run(Game.java:117)
        at java.lang.Thread.run(Unknown Source)
java.io.IOException: mark/reset not supported
        at java.util.zip.InflaterInputStream.reset(Unknown Source)
        at java.io.FilterInputStream.reset(Unknown Source)
        at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
        at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
        at com.gej.sound.WavPlayer.loadSound(WavPlayer.java:39)
        at treasure.Treasure.initResources(Treasure.java:158)
        at com.gej.core.Game.run(Game.java:117)
        at java.lang.Thread.run(Unknown Source)
java.io.IOException: mark/reset not supported
        at java.util.zip.InflaterInputStream.reset(Unknown Source)
        at java.io.FilterInputStream.reset(Unknown Source)
        at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
        at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
        at com.gej.sound.WavPlayer.loadSound(WavPlayer.java:39)
        at treasure.Treasure.initResources(Treasure.java:163)
        at com.gej.core.Game.run(Game.java:117)
        at java.lang.Thread.run(Unknown Source)

しかし、私は zip ファイルを使用しておらず、wav プレーヤーもゲームで正常に動作します。ゲームはまだ起動します。ただし、オブジェクトはマップから削除されません。どうすればこれを解決できますか???

これは、死んだオブジェクトを更新および削除するマップの updateobjects メソッドです。

/**
 * Updates all the objects contained in the map.
 * @param elapsedTime The time elapsed in the current frame.
 */
public static void updateObjects(long elapsedTime){
    for (int i=0; i<objects.size(); i++){
        try {
            GObject obj = objects.get(i);
            if (obj!=null){
                if (obj.isAlive()){
                    obj.superUpdate(elapsedTime);
                    obj.moveHorizontally(elapsedTime);
                    checkCollisions(obj, true, false);
                    obj.moveVertically(elapsedTime);
                    checkCollisions(obj, false, true);
                    checkCollisions(obj, false, false);
                } else {
                    // Remove the dead object
                    objects.remove(i);
                }
            } else {
                objects.remove(i);
            }
        } catch (NullPointerException e){}
    }
}

編集: jar が抽出され、コードで起動されると、ゲームはうまく動作します

java treasure.Treasure

それは何も返さず、うまく機能します。

これがloadSoundメソッドです

/**
 * Loads a sound from a file in the jar file to play them
 * at any time. Supports loading of .wav, .au, .aiff files.
 * Also converts MIDI files on the fly
 * @param s The path of the wav file.
 * @return The sound data loaded into the WavSound object
 */
public static WavSound loadSound(String s){
    // Get an input stream
    InputStream is = WavPlayer.class.getClassLoader().getResourceAsStream(s);
    AudioInputStream audioStream;
    try {
        // Create the audio input stream and audio format
        audioStream = AudioSystem.getAudioInputStream(is);
        AudioFormat format = audioStream.getFormat();
        // The length of the audio file
        int length = (int)(audioStream.getFrameLength() * format.getFrameSize());
        // The array to store the samples in
        byte[] samples = new byte[length];
        // Read the samples into array to reduce disk access (fast-execution)
        DataInputStream dis = new DataInputStream(audioStream);
        dis.readFully(samples);
        // Create a sound container
        WavSound sound = new WavSound(samples, format);
        // Don't start the sound on load
        sound.setState(SoundState.STATE_STOPPED);
        // Create a new player for each sound
        new WavPlayer(sound);
        return sound;
    } catch (Exception e){
        // An error. Mustn't happen
        e.printStackTrace();
    }
    return null;
}

jarファイルを再作成すると、例外の問題が修正されました。しかし、オブジェクトは破壊されていません。

4

1 に答える 1

3

何が起こっているかというと、.wav ファイルを再生するために使用する API がI/O メソッドを使用mark()しているということです。reset()これは、.wav ファイルがファイルシステム上の「実際の」ファイルである場合は正常に機能しますが、jar ファイルにある場合、システムは実行できなくなりmark()reset(). これは、データを jar ファイルに入れる際の落とし穴です。実行時に、jar ファイルがファイルシステムに存在するという保証はありません。ネットワークを介してストリーミングすることもでき、それを実行しているシステム上に物理的に存在することはありません.

プログラムの起動時に .wav リソースをシステム定義の一時ディレクトリにコピーすると、「実際の」ファイルになり、そこから再生できます。

于 2012-06-04T00:34:39.193 に答える