我在使用不同对象的实例时遇到问题,这就是:
我一直在用Java(Swing& AWT)开发一款小游戏,我有以下几个类:
其中:
App扩展了JFrame并且是一个具有应用程序主要功能的框架(main),这个类创建了游戏窗口,并且只存在这个JFrame
MenuScene和GameScene类是应用程序的场景,例如当您看到菜单并且您想要看到最高分时,它是一个场景,游戏的级别是一个场景等,但是在这种情况下,我只有两个场景,我在JPanels中表示了它们:MenuScene扩展了JPanel并创建了游戏菜单(按钮,图像等),同样适用于GameScene类,这也扩展了JPanel并创建了游戏。
其他类(Play,Event,Timer)是简单的类,它们具有游戏"逻辑,键盘控制,计时器,游戏操作,并在三个全局变量中实例化GameScene课程。
一切都从App开始,创建它的一个实例,并在其构造函数中调用一个方法来创建"创建"菜单(MenuScene.java)。现在,菜单中有一个JButton,当按下"创建"游戏(GameScene.java)和这个类有一个JButton随时返回菜单...这里我有问题,因为如果我正在玩,我回到菜单游戏仍然存在,我可以输,这没有任何意义,就好像你玩,但不是看到游戏,你看到菜单,有趣的是图形部分工作得很好,即如果我按下一个按钮,它删除我拥有的东西,并快速绘制我想要的场景。这是因为Play,Timer和Event被实例化或者#34;存在"如果我没有记错的话。所以,如果我再次按下"创建游戏" JButton我会重新创建GameScene的第二个实例吗?而且对于MenuScene和GameScene来说是无限的。这个问题有方法解决吗?您认为我应该如何构建应用程序?
我给你一个最重要的课程大纲:
App.java
public class App extends JFrame {
private JPanel rootPanel;
public App() {
//Define frame
...
runScene(new MenuScene(this));
}
public void runScene(JPanel scene) {
destroyScene();
rootPanel.setBackground(scene.getBackground());
rootPanel.add(scene);
rootPane.validate();
rootPanel.repaint();
}
private void destroyScene() {
rootPanel.removeAll();
rootPanel.revalidate();
rootPanel.repaint();
}
public static void main(String[] args) { //Main
new App();
}
}
MenuScene.java
public class MenuScene extends JPanel {
private App app;
public MenuScene(App app) {
this.app = app;
//Define JPanel
...
buttonStart.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
app.runScene(new GameScene(app));
}
});
}
}
GameScene.java
public class GameScene extends JPanel {
private App;
private Play;
private Timer;
private Event; //Define controls (keyboard)
public GameScene(App app) {
this.app = app;
//Define JPanel, Play, Timer and Event
...
buttonBackMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
app.runScene(new MenuScene(app));
}
});
}
}
Play.java
public class Play {
private JLabel[][] x;
public Play(JLabel[][] x) { //This matrix is important (is an reference), is instanced in GameScene, this is an problem?
this.x = x;
//Define others variables
}
}
我感谢任何帮助。
答案 0 :(得分:0)
我找到了一个有点特殊的解决方案,但我不知道它是否是最好的:
最好的方法是,由于GC不选择活动计时器,因此最好停止它们并将其他对象与null匹配。使用Singleton模式我有一个Frame的单个实例,同一个实例将在任何想要运行另一个场景的类(Scene)中使用,这里是一个实现:
<强> App.java 强>
public class App extends JFrame {
private JPanel rootPanel;
private static App app;
private App() {
super("x");
createApp();
}
public static App getInstance() {
if (app == null) {
app = new App();
}
return app;
}
private void createApp() {
//Define JFrame, rootPanel, buttons, etc ...
}
public void runScene(JPanel scene) {
rootPanel.removeAll();
rootPanel.add(scene);
rootPanel.revalidate();
rootPanel.repaint();
}
public static void main(String[] args) { //Main
getInstance().runScene(new MenuScene());
}
}
<强> GameScene.java 强>
public class GameScene extends JPanel {
private Play p;
private Timer t;
private Event e; //Define controls (keyboard)
private JLabel[][] mat;
public GameScene() {
//Define JPanel, Matrix, Play, Timer and Event
...
buttonBackMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent x) {
This method is useful to create another scene for example from another instance other than this (GameScene)
changeScene(new MenuScene());
}
});
}
public void changeScene(JPanel scene) {
e.removeKeyDispatcher(); //You must create a method that allows you to move the event key dispatcher
t.stopAllTimers(); //You must create a method to stop all timers, or any object that is active.
t = null;
e = null;
p = null;
//If you have more active objects and work with other instances of other classes they should be "broken" or "stopped" and then match their instance to null
App.getInstance().runScene(scene);
}
//Optional...
public JLabel[][] getMat() {
return mat;
}
}
Play.java,Event.java,Timer.java(X)
public class X {
private GameScene g;
private JLabel[][] mat;
public X(GameScene g) {
this.g = g;
//I would use the instance of the class I need to access the variables I'm going to use, for example:
this.mat = g.getMat();
}
}