我正在使用libGDX开发一款Android游戏。 结构如下:
主要>屏幕:Splashscreen>屏幕:MainMenu>屏幕:设置或GameScreen
我对音乐状态有偏好(如果运行“音乐”是真的)。 如果音乐是真的,音乐将从MainMenu开始。 现在,用户应该能够在“设置”屏幕中打开和关闭音乐。 为了管理音乐,我创建了一个名为MusicPlayer的课程。 守则:
的MainMenu:
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();
}
}
MusicPlayer:
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不知道要停止什么。但我怎么能告诉他或我如何用不同的技术解决这个问题呢?
感谢您的帮助。
P.S。 当我在桌面上运行应用程序时,这是我得到的错误:
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();
答案 0 :(得分:0)
当您返回到SettingScreen时,每次都会创建一个新的MusicPlayer实例。
musicPl = new MusicPlayer();
Music
成员仅在调用play()
时实例化:
menuMusic = Gdx.audio.newMusic(Gdx.files.internal("Theme.mp3"));
这就是为什么在调用stop()
之前调用play()
时,menuMusic为空
有几种解决方案。您可以使MusicPlayer静态和全局访问。
或者你可以确保MusicPlayer只会像这样实例化一次:
if(musicPl == null) {
musicPl = new MusicPlayer();
}
但这只有在确保SettingsScreen仅实例化一次时才有效。
要阅读的好主题可能是单身和工厂模式,因为这种情况经常发生在编程游戏时。
答案 1 :(得分:0)
另外将Singleton用作音乐播放器作为全局对象的一部分将很有帮助。