简体   繁体   中英

Background music thread dying at game over rather than pausing

I'm working on a snake clone project and am having trouble implementing a feature where the background music stops only during my game over screen.

My music plays during the first round of gameplay but won't start up again after I press the reset key for the game. I've debugged as far as to see that the thread I created to loop the music dies at game-over, and I'm not sure how to fix this.

SoundFX backgroundSongLoop = new SoundFX(backgroundSong, true);

public Gameplay() {
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);


    //the speed of the snake
    timer = new Timer(clockSpeed, this);
    
    backgroundSongLoop.start();
    timer.start();
}

public void paint(Graphics g){

    //region Snake-Snake Collision
    for (int b=1; b<lengthOfSnake; b++){
        if(snakeXLength[b]==snakeXLength[0] && snakeYLength[b]==snakeYLength[0]){
            backgroundSongLoop.setOn(false);
            failedSoundFX.playSound(failSound);
            failed=true;
            timer.stop(); }

//region restart function
    if (failed){
        if (e.getKeyCode()==KeyEvent.VK_SPACE) {
            backgroundSongLoop.setOn(true);
            score = 0;
            lengthOfSnake = 3;
            moves = 0;
            repaint();
            timer.start();
        }
    }
    //endregion




public class SoundFX extends Thread{

private final String soundName;
public boolean isOn;

public SoundFX(String soundName) {
    this.soundName = soundName;
}
public SoundFX(String soundName, boolean isOn) {
    this.soundName = soundName;
    this.isOn = isOn;
}

public void setOn(boolean on) {
    isOn = on;
}

public void playSound(String soundName){
    File soundFile = new File(soundName);
    try{
        Clip clip = AudioSystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(soundFile));
        clip.start();
    } catch (Exception e){
        e.printStackTrace();
    }
}

@Override
public void run() {
    //public void loopSong(String soundName, boolean playing){
        File soundFile = new File(soundName);
        try{
            Clip clip = AudioSystem.getClip();
            clip.open(AudioSystem.getAudioInputStream(soundFile));
                while (isOn){
                    clip.loop(Clip.LOOP_CONTINUOUSLY);
                }
                while (!isOn){
                    clip.stop();
                }
        } catch (Exception e){
            e.printStackTrace();
        }
}

}

Two things:

  1. Use clip.setFramePosition(0) to position the clip for restarting at the beginning.

  2. Put the clip.open() method in a constructor and make clip an instance variable. That way, when you wish to restart it, only the following is needed:

     public void play() { clip.setFramePosition(0); clip.loop(); }

By doing this, you avoid reloading from the file location every time you wish to play the cue. The cue won't even start until all the file operations are done, so this method gives you a much quicker start.

I think if you do this, you can also write a method that calls clip.stop() and just call all of these methods directly on your SoundFX class without needing to extend Thread .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM