1

我正在为班级编写游戏,但无法添加声音和图像。我们从 Andrew Davison 的 Killer Game Programming 一书中获得了可以使用的框架,我觉得我正在完全复制它,但我无法播放声音文件。

这是 SDLLoader 类:

package zombieCity;


/* SDLLoader  stores a collection of SDLInfo objects
   in a HashMap whose keys are their names. 

   The name and filename for a line is obtained from a sounds
   information file which is loaded when SDLLoader is created.
   The information file is assumed to be in Sounds/.

   SDLLoader allows a specified clip to be played, stopped, 
   resumed, looped. A SoundsWatcher can be attached to a clip.
   All of this functionality is handled in the SDLInfo object; 
   SDLLoader simply redirects the method call to the right SDLInfo.

   It is possible for many lines to play at the same time, since
   each SDLInfo object is responsible for playing its clip.
*/


import java.util.*;
import java.io.*;

import javax.print.DocFlavor.URL;


public class SDLLoader
{
  private final static String SOUND_DIR = "Sounds/";

  private HashMap<String, SDLInfo> sdlMap; 
    /* The key is the clip 'name', the object (value) 
       is a SDLInfo object */


  public SDLLoader(String soundsFnm)
  { sdlMap = new HashMap<String, SDLInfo>();
    loadSoundsFile(soundsFnm);
  }

  public SDLLoader()
  {  sdlMap = new HashMap<String, SDLInfo>();  } 



  private void loadSoundsFile(String soundsFnm)
  /* The file format are lines of:
        <name> <filename>         // a single sound file
     and blank lines and comment lines.
  */
  { 
    String sndsFNm = SOUND_DIR + soundsFnm;
    System.out.println("Reading file: " + sndsFNm);
    try {
        java.net.URL inFile = this.getClass().getResource("/Sounds/SDLInfo.txt");
        System.out.println("url " + inFile);
        InputStreamReader in = new InputStreamReader(inFile.openStream());
      BufferedReader br = new BufferedReader(in);
      StringTokenizer tokens;
      String line, name, fnm;
      while((line = br.readLine()) != null) {
        if (line.length() == 0)  // blank line
          continue;
        if (line.startsWith("//"))   // comment
          continue;

        tokens = new StringTokenizer(line);
        if (tokens.countTokens() != 2)
          System.out.println("Wrong no. of arguments for " + line);
        else {
          name = tokens.nextToken();
          fnm = tokens.nextToken();
          load(name, fnm);
        }
      }
      br.close();
    } 
    catch (IOException e) 
    { System.out.println("Error reading file: " + sndsFNm);
      System.exit(1);
    }
  }  // end of loadSoundsFile()



  // ----------- manipulate a particular clip --------


  public void load(String name, String fnm)
  // create a SDLInfo object for name and store it
  {
    if (sdlMap.containsKey(name))
      System.out.println( "Error: " + name + "already stored");
    else {
      sdlMap.put(name, new SDLInfo(name, fnm) );
      System.out.println("-- " + name + "/" + fnm);
    }
  }  // end of load()


  public void close(String name)
  // close the specified clip
  {  SDLInfo si = (SDLInfo) sdlMap.get(name);
     if (si == null)
       System.out.println( "Error: " + name + "not stored");
     else
      si.close();
  } // end of close()



  public void play(String name, boolean toLoop)
  // play (perhaps loop) the specified clip
  {  SDLInfo si = (SDLInfo) sdlMap.get(name);
     if (si == null)
       System.out.println( "Error: " + name + "not stored");
     else
      si.beginPlayback(toLoop);
  } // end of play()


  public void stop(String name)
  // stop the clip, resetting it to the beginning
  { SDLInfo si = (SDLInfo) sdlMap.get(name);
    if (si == null)
      System.out.println( "Error: " + name + "not stored");
    else
      si.stop();
  } // end of stop()

  // -------------------------------------------------------


  public void setWatcher(String name, SoundsWatcher sw)
  /* Set up a watcher for the clip. It will be notified when
     the clip loops or stops. */
  { SDLInfo si = (SDLInfo) sdlMap.get(name);
    if (si == null)
      System.out.println( "Error: " + name + "not stored");
    else
      si.setWatcher(sw);
  } // end of setWatcher()

}  // end of ClipsLoader class

堆栈跟踪

    fps: 100; period: 10 ms
Reading file: Sounds/SDLInfo.txt
url file:/C:/Documents%20and%20Settings/MyName/Desktop/java%20programs/Zombie%20City/bin/Sounds/SDLInfo.txt
Exception in thread "main" java.lang.NullPointerException
    at com.sun.media.sound.StandardMidiFileReader.getSequence(Unknown Source)
    at javax.sound.midi.MidiSystem.getSequence(Unknown Source)
    at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at zombieCity.SDLInfo.loadLine(SDLInfo.java:35)
    at zombieCity.SDLInfo.<init>(SDLInfo.java:27)
    at zombieCity.SDLLoader.load(SDLLoader.java:95)
    at zombieCity.SDLLoader.loadSoundsFile(SDLLoader.java:73)
    at zombieCity.SDLLoader.<init>(SDLLoader.java:38)
    at zombieCity.FlyingHero.simpleInitialize(FlyingHero.java:144)
    at zombieCity.Frame.<init>(Frame.java:68)
    at zombieCity.FlyingHero.<init>(FlyingHero.java:80)
    at zombieCity.FlyingHero.main(FlyingHero.java:376)

在此类中捕获了错误:

package zombieCity;
/* Load a line, which can be played, stopped, resumed, looped. 

   An object implementing the SoundsWatcher interface 
   can be notified when the line loops or stops.
*/

import java.io.*;
import javax.sound.sampled.*;


public class SDLInfo implements LineListener, Runnable
{
  private final static String SOUND_DIR = "Sounds/";

  private String name, filename;
  private SourceDataLine line = null;
  private boolean isLooping = false;
  private SoundsWatcher watcher = null;
  private Thread soundPlayer;


  public SDLInfo(String nm, String fnm)
  { name = nm;
    filename = SOUND_DIR + fnm;

    loadLine(filename);
  } // end of SDLInfo()


  private void loadLine(String fnm)
  {
    try {
      // link an audio stream to the sound line's file
      AudioInputStream stream = AudioSystem.getAudioInputStream(
                          getClass().getResource(fnm) );

      AudioFormat format = stream.getFormat();

      // convert ULAW/ALAW formats to PCM format
      if ( (format.getEncoding() == AudioFormat.Encoding.ULAW) ||
           (format.getEncoding() == AudioFormat.Encoding.ALAW) ) {
        AudioFormat newFormat = 
           new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                                format.getSampleRate(),
                                format.getSampleSizeInBits()*2,
                                format.getChannels(),
                                format.getFrameSize()*2,
                                format.getFrameRate(), true);  // big endian
        // update stream and format details
        stream = AudioSystem.getAudioInputStream(newFormat, stream);
        System.out.println("Converted Audio format: " + newFormat);
        format = newFormat;
      }

      DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

      // make sure sound system supports data line
      if (!AudioSystem.isLineSupported(info)) {
        System.out.println("Unsupported Line File: " + fnm);
        return;
      }

      // get clip line resource
      line = (SourceDataLine) AudioSystem.getLine(info);

      // listen to line for events
      line.addLineListener(this);

      line.open(format);    // open the sound file as a line
      stream.close(); // we're done with the input stream

    } // end of try block

    catch (UnsupportedAudioFileException audioException) {
      System.out.println("Unsupported audio file: " + fnm);
    }
    catch (LineUnavailableException noLineException) {
      System.out.println("No audio line available for : " + fnm + " " + noLineException);
    }
    catch (IOException ioException) {
      System.out.println("Could not read: " + fnm);
    }
 //   catch (Exception e) {
  //    System.out.println("Problem with " + fnm);
  //  }
  } // end of loadLine()


  public void update(LineEvent lineEvent){}
  // update() not used


  public void close()
  { if (line != null) {
      line.stop();
      line.close();
    }
  }

  public void beginPlayback(boolean toLoop)
  {
      if (line != null){
          isLooping = toLoop;
          if (soundPlayer == null) {
              soundPlayer = new Thread(this);
              soundPlayer.start();
          }
      }
  }

  public void play()
  {
    try{
      if (line != null) {
          int numRead = 0;
          byte[] buffer = new byte[line.getBufferSize()];
          AudioInputStream stream = AudioSystem.getAudioInputStream(getClass().getResource(filename) );
          line.start();
          // read and play chunks of the audio
          int offset;
          while ((numRead = stream.read(buffer,0,buffer.length)) >= 0) {
              offset = 0;
              while (offset < numRead)
                  offset += line.write(buffer, offset, numRead-offset);
          }
          // wait until all data is played, then stop the line
          stream.close();
          line.drain();
          line.stop();
      }
    }
    catch (IOException ioException) {
      System.out.println("Could not read: " + filename);
    }
    catch (UnsupportedAudioFileException audioException) {
        System.out.println("Unsupported audio file: " + filename);
      }

  } //end of play()

  public void run()
  {
     do{ play();}while(isLooping);
  }

  public void stop()
  // stop and reset line to its start
  { if (line != null) {
      isLooping = false;
      line.drain();
      line.stop();
    }
  }

  public void setWatcher(SoundsWatcher sw)
  {  watcher = sw;  }


  // -------------- other access methods -------------------

  public String getName()
  {  return name;  }

}  // end of ClipInfo class
4

2 回答 2

2

您是否尝试过使用 .wav 文件

如果您需要在

在这里转换

于 2013-03-09T18:57:15.057 回答
0

尝试在以下位置添加完整的声音文件目录

private final static String SOUND_DIR = "Sounds/";

示例目录

"C:/Stuff/Sounds/soundfile.wav

这可能会帮助你

这里

于 2013-03-09T19:22:38.077 回答