Reputation: 468
I have been working on a Java game for a while that I started back in my college days. After taking considerable breaks due to my professional career, I'm getting back to it and realizing how awful the code is. I basically had a "monolithic main" with both GUI and game logic in the same class file. What I'm attempting to do, is abstract and "componentize" the GUI into smaller chunks. My executed class extends JFrame which I add and remove panels to/from when buttons are clicked. Ex.
public class GameFrame extends JFrame{
private JPanel[] _panels = {new MainPanel(), new OptionsPanel(), new DifficultyPanel()};
private int _currentPanelIndex = 0;
public GameFrame(){
...
add(_panels[_currentPanelIndex]);
...
}
}
Within each panel class, I have private ActionListeners for the buttons. In MainPanel, I'm getting the singleton GameFrame instance and setting the current panel kind of like:
class SinglePlayerButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
GameFrame instance = GameFrame.getInstance();
JPanel[] panels = instance.getPanels();
int currentPanelIndex = instance.getCurrentPanelIndex();
instance.remove(panels[currentPanelIndex]);
int newPanelIndex;
for(newPanelIndex = 0; newPanelIndex < panels.length; newPanelIndex++){
if(panels[newPanelIndex] instanceof DifficultyPanel){
break;
}
}
instance.add(panels[newPanelIndex]);
}
}
I do not like this deep of coupling in my classes, but I can live with it. However, the real problem is that when I click the last button that takes me into the game, I can't have:
public void actionPerformed(ActionEvent e){
GameFrame.getInstance().startGame();
}
because this will cause my game to run in the Java Event thread, thereby disallowing any other events from being handled. Previously, I had a busy while loop:
...
while(waiting){
//Do nothing
}
remove(_panels[_currentPanelIndex]);
startGame();
...
...
public void actionPerformed(ActionEvent e){
waiting = false;
}
What is the best way to let my GameFrame class know that I've clicked the play button? Can I send an event or message to it from one of its sub-panels telling it to start, and if so, how do I keep the game from running in the Event thread? Should I handle it in the actionPerformed() method and simply spawn a new thread? I would prefer to keep it in the main thread. Thanks.
Upvotes: 2
Views: 6590
Reputation: 14222
Go for Slick 2D (a lightweight OpenGL 2D game development framework with lots of cool stuff) or Nifty-GUI.
Slick has also some examples and tutorials and is easy to learn, for example the StateBasedGame
can easily be used to implement multiple in-game menus (such as main menu, settings menu, in-game options, in-game pause/resume etc.)
Upvotes: 1
Reputation: 38561
You should have the game logic executing on it's own thread of execution, possibly when the user clicks a button. I don't understand your prior approach with the while(wait) - that would still create problems if your game logic did some time consuming calculation that prevented the even thread from doing updates because the even thread does not stop executing when you call startGame().
EDIT:
It's not clear from the code you pasted that the GUI updates and the game logic are happening on seperate threads of execution - you might want to demonstrate that in your code.
Upvotes: 0