【发布时间】:2017-01-18 18:49:52
【问题描述】:
我在处理不同对象的实例时遇到问题,会发生这种情况:
我一直在用 Java(Swing 和 AWT)开发一个小游戏,我有以下类:
- App.java
- Play.java
- Event.java
- GameScene.java
- MenuScene.java
- Timer.java
地点:
App扩展了JFrame,是一个带有应用程序主功能的框架(main),这个类创建游戏窗口,只存在这个JFrame
MenuScene 和 GameScene 类是应用程序的场景,例如当你看到菜单,你想看最高分时,它是一个场景,游戏的关卡是一个场景等,但是在这种情况下,我只有两个场景,我在 JPanel 中表示它们: MenuScene 扩展 JPanel 并创建游戏菜单(按钮、图像等),同样适用于 GameScene 类,这也扩展 JPanel 并创建游戏。
其他类(Play、Event、Timer)是简单类,它们具有“游戏逻辑”、键盘控制、定时器、游戏操作,并在 GameScene 类的三个全局变量中实例化。
一切都从 App 开始,创建它的一个实例,并在其构造函数中调用一个方法来“创建”菜单 (MenuScene.java)。现在菜单有一个 JButton 按下时“创建”游戏(GameScene.java)并且这个类有一个 JButton 可以随时返回菜单......这是我遇到问题的地方,因为如果我正在玩并且我返回菜单 游戏仍然存在,我可能会输,这没有任何意义,就好像你在玩但没有看到游戏,而是看到了菜单,有趣的是,图形部分效果很好,即如果我按下一个按钮,它就会删除我有什么并快速绘制我想要的场景。这是因为如果我没记错的话,Play、Timer 和 Event 是在内存中实例化或“存在”的。因此,如果我再次按下“创建游戏”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
}
}
感谢您的帮助。
【问题讨论】:
-
当您从游戏中按下返回时,您应该拆除/销毁游戏控件,尤其是计时器,您还应该取消引用 app 变量以防止任何循环引用
-
1) “我给你一个最重要的类的大纲:” 为了尽快获得更好的帮助,请发布minimal reproducible example 或Short, Self Contained, Correct Example。 2)
rootPanel.removeAll(); rootPanel.revalidate(); rootPanel.repaint();使用CardLayout,如this answer 所示。
标签: java swing design-patterns awt instances