Класс OggStreamer-Thread (для воспроизведения музыки в моей игре) работает только в 1/3 времени - PullRequest
2 голосов
/ 24 марта 2012

Прежде всего, я люблю вас, ребята!Это лучший сайт для поиска ответов на странные и сложные вопросы программирования.Это первая проблема, для которой я не смог найти решения на этом сайте, поэтому спасибо за это.

Итак, у меня есть запускаемый Game.class и запускаемый OggStreamer.class, чтобы позволить музыкеработать в своем отдельном потоке, который я посылаю в качестве параметра для использования Game-class.Когда я запускаю игру из моей IDE, OggStreamer всегда работает, но когда я экспортирую его в .jar-файл, он работает только в 1/3 случаев, когда я запускаю его.И это не значит, что первый музыкальный фрагмент не запускается, а затем будет воспроизводиться следующий музыкальный фрагмент… он вообще не работает, пока я не запустил игру несколько раз.

У кого-нибудь из вас, хороших людей, была подобная проблема?Я мог бы понять это, если бы это вообще не работало, что могло указывать на то, что что-то не так с ссылками на файл в музыке внутри jar-файла ... но он работает, но не всегда.

ПРИМЕЧАНИЕ: это моя первая попытка в программировании игр, и я знаю, что это не очень красиво и что я новичок :) Я бы многое изменил в общем дизайне, но я использую это какпроект, который поможет мне понять проблемы, с которыми я столкнусь, когда сяду за разработку реальной платформы для моей следующей игры.

Start.class

public static void main(String[] args) throws InterruptedException{
ExecutorService threadExecutor = Executors.newCachedThreadPool();
Game game = new Game(musicStreamer);
game.init(); // loads stuff
threadExecutor.execute( musicStreamer ); // start task1
threadExecutor.execute( game ); // start task2
threadExecutor.shutdown();
}

OggStreamer.class

public class OggStreamer implements Runnable{

private URL url;
private AudioInputStream stream;
private AudioInputStream decodedStream;
private AudioFormat format;
private AudioFormat decodedFormat;
private boolean stop, running;
String filename = "";
SourceDataLine line = null;

public OggStreamer() {
    this.stop = true;
    this.running = true;
    this.url = null;
}

public void run() {
    while(running){
            while (!this.stop) {
                System.out.println("Playing Loop");
                try {
                    // Get AudioInputStream from given file.
                    this.stream = AudioSystem.getAudioInputStream(this.url);
                    this.decodedStream = null;
                    if (this.stream != null) {
                        this.format = this.stream.getFormat();
                        this.decodedFormat = new AudioFormat(
                                AudioFormat.Encoding.PCM_SIGNED,
                                this.format.getSampleRate(), 16,
                                this.format.getChannels(),
                                this.format.getChannels() * 2,
                                this.format.getSampleRate(), false);
                        // Get AudioInputStream that will be decoded by underlying
                        // VorbisSPI
                        this.decodedStream = AudioSystem.getAudioInputStream(
                                this.decodedFormat, this.stream);
                    }else{
                        JOptionPane.showMessageDialog(null, "Stream = null!");
                    }
                } catch (Exception e) {
                    // Do nothing
                    System.out.println("Could not get or decode audiostream");
                }
                line = null;
                try {
                    line = this.getSourceDataLine(this.decodedFormat);
                    FloatControl volume = (FloatControl)line.getControl(FloatControl.Type.MASTER_GAIN);
                    volume.setValue(1);
                } catch (LineUnavailableException lue) {
                    // Do nothing
                    JOptionPane.showMessageDialog(null, "Line is unavailable!");
                }
                if (line != null) {
                    try {
                        byte[] data = new byte[4096];
                        // Start
                        line.start();
                        int nBytesRead = 0;

                        while (nBytesRead != -1) {
                            nBytesRead = this.decodedStream.read(data, 0,
                                    data.length);
                            if (nBytesRead != -1) {
                                line.write(data, 0, nBytesRead);
                            }
                            if (this.stop) {
                                break;
                            }
                        }

                        // Stop
                        line.drain();
                        line.stop();
                        line.close();
                    } catch (IOException io) {
                        // Do nothing
                        JOptionPane.showMessageDialog(null, "Line cannot start!");
                    }
                }
            }
    }
}

private SourceDataLine getSourceDataLine(AudioFormat audioFormat)
        throws LineUnavailableException {
    SourceDataLine res = null;
    DataLine.Info info = new DataLine.Info(SourceDataLine.class,
            audioFormat);
    res = (SourceDataLine) AudioSystem.getLine(info);
    res.open(audioFormat);
    return res;
}


public void startLoop(String filenameString) {
    this.filename = filenameString;
    System.out.println("Starting loop with: "+filenameString);
    this.url = this.getClass().getResource(filenameString);
    this.stop = false;
}

public void stopLoop() {
    System.out.println("Stopping loop");
    try {
        if(this.decodedStream!=null)this.decodedStream.close();
        if(this.stream!=null)this.stream.close();
    } catch (IOException e) {
    }
    this.stop = true;
    this.url = null;
}

public boolean isStop() {
    return stop;
}

public void setStop(boolean stop) {
    this.stop = stop;
}

public URL getUrl() {
    return url;
}

public void setUrl(String string) {
    this.filename = string;
    this.url = this.getClass().getResource(string);
}

public String getFilename() {
    return filename;
}
}

Game.class использует класс OggStreamer следующим образом:

if(musicStreamer!=null && !musicStreamer.getFilename().equals("/snm/sound/oggs/Prelude.ogg")){
            if(!musicStreamer.isStop())musicStreamer.stopLoop();
            musicStreamer.startLoop("/snm/sound/oggs/Prelude.ogg");
}
...