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 使用mark()reset()I/O 方法。当 .wav 文件是文件系统上的“真实”文件时,这可以正常工作,但是当它在 jar 文件中时,系统无法再mark()执行reset(). 这是将数据放入 jar 文件的一个陷阱——在运行时,无法保证 jar 文件驻留在文件系统中。它甚至可以通过网络流式传输,并且在运行它的系统上没有物理存在。

应该发生的是,您在程序启动时将 .wav 资源复制到系统定义的临时目录中,然后可以是“真实”文件,然后从那里播放它们。

于 2012-06-04T00:34:39.193 回答