首页 文章

libgdx停止用类运行音乐

提问于
浏览
0

我正在使用libGDX开发一款Android游戏 . 结构如下:

Main> Screen:Splashscreen> Screen:MainMenu> Screen:Settings或GameScreen

我对音乐的状态有一个偏好(如果运行“音乐”是真的) . 如果音乐是真的,音乐将在MainMenu中开始 . 现在,用户应该能够在“设置”屏幕中打开和关闭音乐 . 为了管理音乐,我创建了一个名为MusicPlayer的课程 . 代码:

主菜单:

public class StartScreen implements Screen {

   MusicPlayer musicPl;

   Preferences scorepref;
   boolean music;
   (...)

   @Override
   public void show() {

       (...)
       scorepref = Gdx.app.getPreferences("Highscore");

       musicPl = new MusicPlayer();

       music = scorepref.getBoolean("music");

       if(music){
           musicPl.play();
       }
   }
   @Override
   public void dispose() {

       musicPl.dispose();

   }
}

设置:

public class SettingScreen implements Screen {

    Preferences scorepref;

    //Setting Values
    boolean tut = false;
    boolean music = false;
    boolean sounds = false;
    int theme = 0;
    //

    MusicPlayer musicPl;

    int touchX = 0;
    int touchY = 0;
    boolean touchD = false;
    boolean touchU = false;

    @Override
    public void show() {

        (handling Input and setting touchX,touchY,touchD and touchU)
        (...)
        musicPl = new MusicPlayer();
        scorepref = Gdx.app.getPreferences("Highscore");

    }
    @Override
    public void render(float delta) {


        tut = scorepref.getBoolean("tut");
        music = scorepref.getBoolean("music");
        sounds = scorepref.getBoolean("sounds");
        (...)

        //if Touched
        if(touchD == true && touchU == true){
            touchD = false;
            touchU = false;
            //wo?
            Vector3 posn = new Vector3(Gdx.input.getX(),Gdx.input.getY(), 0);
            camera.unproject(posn);

        if(){
            (...)
        } else if (posn.x >= -192 && posn.x <= 192 && posn.y <= 53 && posn.y >= -75) {
            if(music){
                music = false;
                scorepref.putBoolean("music", music);
                scorepref.flush();
                musicPl.stop(); //Error line 206 is here
            } else {
                music = true;
                scorepref.putBoolean("music", music);
                scorepref.flush();
                musicPl.play();
            }
        } (...)
        } else if (posn.x >= -344 && posn.x <= -248 && posn.y <= 543 && posn.y >= 463) {
            ((Game) Gdx.app.getApplicationListener()).setScreen(new StartScreen());
        }

        //var speichern
        scorepref.putBoolean("tut", tut);
        scorepref.putBoolean("music", music);
        scorepref.putBoolean("sounds", sounds);
        scorepref.flush();


   }
   @Override
   public void dispose() {

       musicPl.dispose();

   }
}

音乐播放器:

public class MusicPlayer{

    Music menuMusic;
    boolean isrunning;
    Preferences scorepref;

    public void play (){
        scorepref = Gdx.app.getPreferences("Highscore");

        if(scorepref.getBoolean("running") == true){

        } else {
            menuMusic = Gdx.audio.newMusic(Gdx.files.internal("Theme.mp3"));
            menuMusic.setLooping(true);
            scorepref.putBoolean("running", true);
            scorepref.flush();
            menuMusic.play();

        }

   }

    public void stop(){
        scorepref = Gdx.app.getPreferences("Highscore");
        scorepref.putBoolean("running", false);
        scorepref.flush();
        menuMusic.stop();   //Error line 33 is here

    }

    public void dispose(){
        menuMusic.dispose();
    }



}

我的问题:当我进入设置屏幕时,打开和关闭调谐工作正常 . 当我打开音乐并返回主屏幕时,音乐仍在播放 . 到现在为止还挺好 . 但是当我返回到带有运行音乐的SettingsScreen时,我想把它关掉App崩溃 .

我认为崩溃是由stop方法引起的,因为MusicPlayer不知道要停止什么 . 但我怎么能告诉他或我如何用不同的技术解决这个问题呢?

谢谢你的帮助 .

附:当我在桌面上运行应用程序时,这是我得到的错误:

Exception in thread "LWJGL Application" java.lang.NullPointerException
    at de.hatgames.canone.MusicPlayer.stop(MusicPlayer.java:33)
    at de.hatgames.canone.SettingScreen.render(SettingScreen.java:206)
    at com.badlogic.gdx.Game.render(Game.java:46)
    at de.hatgames.canone.CanoneMain.render(CanoneMain.java:26)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:215)
    at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:120)

CanoneMain.java:26就是这样的:

super.render();

1 回答

  • 0

    当您返回到SettingScreen时,每次都会创建一个新的MusicPlayer实例 .

    musicPl = new MusicPlayer();
    

    只有在调用 play() 时, Music 成员才会被实例化:

    menuMusic = Gdx.audio.newMusic(Gdx.files.internal("Theme.mp3"));
    

    这就是在调用 play() 之前调用 stop() 时menuMusic为null的原因

    有几种解决方案 . 您可以使MusicPlayer静态和全局可访问 .

    或者你可以确保MusicPlayer只是这样一次实例化:

    if(musicPl == null) {
    musicPl = new MusicPlayer();
    }
    

    但这只有在确保SettingsScreen仅实例化一次时才有效 .

    要阅读的好主题可能是单身和工厂模式,因为这种情况经常发生在编程游戏时 .

相关问题