Использование звуковых эффектов в Java-игре - PullRequest
3 голосов
/ 15 марта 2009

В основном я пытаюсь использовать этот класс SoundEffect в простой Java-игре, над которой я работаю для своего задания.

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

/**
 * This enum encapsulates all the sound effects of a game, so as to separate the sound playing
 * codes from the game codes.
 * 1. Define all your sound effect names and the associated wave file.
 * 2. To play a specific sound, simply invoke SoundEffect.SOUND_NAME.play().
 * 3. You might optionally invoke the static method SoundEffect.init() to pre-load all the
 *    sound files, so that the play is not paused while loading the file for the first time.
 * 4. You can use the static variable SoundEffect.volume to mute the sound.
 */
public enum SoundEffect {
   EAT("eat.wav"),   // explosion
   GONG("gong.wav"),         // gong
   SHOOT("shoot.wav");       // bullet

   // Nested class for specifying volume
   public static enum Volume {
      MUTE, LOW, MEDIUM, HIGH
   }

   public static Volume volume = Volume.LOW;

   // Each sound effect has its own clip, loaded with its own sound file.
   private Clip clip;

   // Constructor to construct each element of the enum with its own sound file.
   SoundEffect(String soundFileName) {
      try {
         // Use URL (instead of File) to read from disk and JAR.
         URL url = this.getClass().getClassLoader().getResource(soundFileName);
         // Set up an audio input stream piped from the sound file.
         AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url);
         // Get a clip resource.
         clip = AudioSystem.getClip();
         // Open audio clip and load samples from the audio input stream.
         clip.open(audioInputStream);
      } catch (UnsupportedAudioFileException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (LineUnavailableException e) {
         e.printStackTrace();
      }
   }

   // Play or Re-play the sound effect from the beginning, by rewinding.
   public void play() {
      if (volume != Volume.MUTE) {
         if (clip.isRunning())
            clip.stop();   // Stop the player if it is still running
         clip.setFramePosition(0); // rewind to the beginning
         clip.start();     // Start playing
      }
   }

   // Optional static method to pre-load all the sound files.
   static void init() {
      values(); // calls the constructor for all the elements
   }
}

Вот реализация звука EAT в классе вознаграждений моей игры -

public void react(CollisionEvent e)
    {
        Player player = game.getPlayer();
        if (e.contact.involves(player)) {
            player.changePlayerImageEAT();
            SoundEffect.EAT.play();
            player.addPoint();
            System.out.println("Player now has: "+player.getPoints()+ " points.");
            game.getCurrentLevel().getWorld().remove(this);
        }
    }

Это должно воспроизводить звук EAT, когда игрок соприкасается с наградой в моей игре.

Однако, когда мой игрок сталкивается с вознаграждением, я получаю следующие ошибки в терминале-

javax.sound.sampled.LineUnavailableException: линия с форматом ALAW 8000,0 Гц, 8 бит, стерео, 2 байта / кадр, не поддерживается. в com.sun.media.sound.DirectAudioDevice $ DirectDL.implOpen (DirectAudioDevice.java:494) в com.sun.media.sound.DirectAudioDevice $ DirectClip.implOpen (DirectAudioDevice.java:1280) в com.sun.media.sound.AbstractDataLine.open (AbstractDataLine.java:107) в com.sun.media.sound.DirectAudioDevice $ DirectClip.open (DirectAudioDevice.java:1061) в com.sun.media.sound.DirectAudioDevice $ DirectClip.open (DirectAudioDevice.java:1151) в SoundEffect. (SoundEffect.java:39) в SoundEffect. (SoundEffect.java:15) в Reward.react (Reward.java:41) в city.soi.platform.World.despatchCollisionEvents (World.java:425) в city.soi.platform.World.step (World.java:608) в city.soi.platform.World.access $ 000 (World.java:42) в city.soi.platform.World $ 1.actionPerformed (World.java:756) в javax.swing.Timer.fireActionPerformed (Timer.java:271) в javax.swing.Timer $ DoPostEvent.run (Timer.java:201) в java.awt.event.InvocationEvent.dispatch (InvocationEvent.java:209) в java.awt.EventQueue.dispatchEvent (EventQueue.java:597) в java.awt.EventDispatchThread.pumpOneEventForFilters (EventDispatchThread.java:269) в java.awt.EventDispatchThread.pumpEventsForFilter (EventDispatchThread.java:184) в java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java:174) в java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:169) в java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:161) в java.awt.EventDispatchThread.run (EventDispatchThread.java:122) Исключение в потоке "AWT-EventQueue-0" java.lang.ExceptionInInitializerError в Reward.react (Reward.java:41) в city.soi.platform.World.despatchCollisionEvents (World.java:425) в city.soi.platform.World.step (World.java:608) в city.soi.platform.World.access $ 000 (World.java:42) в city.soi.platform.World $ 1.actionPerformed (World.java:756) в javax.swing.Timer.fireActionPerformed (Timer.java:271) в javax.swing.Timer $ DoPostEvent.run (Timer.java:201) в java.awt.event.InvocationEvent.dispatch (InvocationEvent.java:209) в java.awt.EventQueue.dispatchEvent (EventQueue.java:597) в java.awt.EventDispatchThread.pumpOneEventForFilters (EventDispatchThread.java:269) в java.awt.EventDispatchThread.pumpEventsForFilter (EventDispatchThread.java:184) в java.awt.EventDispatchThread.pumpEventsForHierarchy (EventDispatchThread.java:174) в java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:169) в java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:161) в java.awt.EventDispatchThread.run (EventDispatchThread.java:122) Вызванный: java.lang.NullPointerException в com.sun.media.sound.WaveFileReader.getAudioInputStream (WaveFileReader.java:180) в javax.sound.sampled.AudioSystem.getAudioInputStream (AudioSystem.java:1128) в SoundEffect. (SoundEffect.java:35) в SoundEffect. (SoundEffect.java:16) ... еще 15

Я не могу понять, что не так. Я предполагаю, что это как-то связано с тем, что мои аудио файлы (WAV) не поддерживаются. Однако, независимо от того, сколько способов я их конвертирую, они все равно не работают.

Было бы очень полезно, если бы кто-то любезно объяснил мне, что может быть не так, и как я могу решить эту проблему.

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

Спасибо.

1 Ответ

5 голосов
/ 15 марта 2009

Ваша первопричина Исключение составляет

javax.sound.sampled.LineUnavailableException:
 line with format ALAW 8000.0 Hz, 8 bit, stereo, 2 bytes/frame, not supported

Это происходит из-за того, что не все звуковые драйверы поддерживают все битрейты или кодировки, или из-за того, что на машине просто нет звуковой карты. Звук может быть закодирован в закон или мю закон (или другие, например, MP3) и может быть закодирован с различной скоростью передачи данных и размерами выборки. Java не всегда поддерживает все возможные форматы звука, в зависимости от того, что поддерживается базовой системой.

Вы, вероятно, хотите сделать следующее:

  • Убедитесь, что на компьютере, на котором вы работаете, установлена ​​разумная звуковая карта. Большую часть времени, когда я вижу вышеупомянутое исключение, я работаю на сервере без встроенной звуковой карты или с действительно слабой звуковой картой или без звукового тракта.
  • Если вы используете удаленный терминал или что-то подобное, убедитесь, что для звука настроен способ воспроизведения.
  • Попробуйте перекодировать ваш звуковой образец с другой скоростью или, возможно, в виде файла WAV, а затем попробуйте воспроизвести его.
...