Edit: This makes alot more sense to me now that i've taken a step away from the code, thanks for the help.
Just found stack overflow the other day through Coding Horror and it looks awesome. Figure that i'd ask the community about a problem i'm currently trying to work out.
I'm developing a roguelike sortof game using j2me for midp 2.0 phones. The project is still in the basic stages of development as I figure out how it's going to work. The part i'm currently stuck on has to do with threading.
The game has a custom HaxCanvas class which extends GameCanvas and Implements runnable. It's run method calls repaint() and then sleeps for 50 ms, resulting in a frame rate of 20 FPS. This allows me to write the rest of the game without having to put repaint everywhere and should make animations and effects easier to do later on. (at least in theory).
The flow of the game is controlled by a GameManager class, which loops through all the NPC's on the map, taking their turns, until it's the player's turn. At this point I need to get input to allow the player to move around and/or attack things. I originally was calling gameManager.runUntilHeroTurn() in the keyPressed method of my HaxCanvas. However after reading up on j2me system threads I realized that putting a method with the potential to run for a while in a callback is a bad idea. However I must used keyPressed to do input handeling, since i need access to the number keys, and getKeyStates() does not support this.
Sofar my attempts to put my gameloop in it's own thread have resulted in disaster. A strange "uncaught ArrayIndexOutOfBoundsException" with no stack trace shows up after the game has run for several turns .
So i suppose my question is this:
For a "turn based" game in j2me, what's the best way to implement the game loop, allowing for input handeling only when it's the player's turn?
Although not j2me specifically you should capture user input, the general strategy is to queue the input it until its time to process the input.
input ---> queue <---> Manager(loop)
This way you can even script input for debug purposes.
So you don't need a new thread. Each time the user presses key you store them in a buffer, and then process the contents of the buffer when necessary. If the player buffer has no input, the manager should skip all gameplay, do animations and then start over (since the game is not an action game).
I would avoid threading for the game logic as J2ME threading, depending on manufacturer of course, does not do a great job of sharing the limited resources. You will often see pauses while a thread does heavy processing. I would only recommend threads for loading or network connectivity features as in this case you will just be giving the user basic "Loading..." feedback.
To handle this, I would not have sub-loops to update each of the AI in one frame. I would do something like following in the run function:
public void run() {
while(true) {
// Update the Game
if(gameManager.isUsersTurn()) {
// Collect User Input
// Process User Input
// Update User's State
}
else {
// Update the active NPC based on their current state
gameManager.updateCurrentNPC();
}
// Do your drawing
}
}
You want to avoid having everything updated in one frame as 1) the updating might be slow, resulting in no immediate visual feedback for the user 2) you can't animate each individual NPC as they make their action. With this setup you could have NPC states, NPC_DECIDE_MOVE and NPC_ANIMATING, that would allow you further control of what the NPC is doing. NPC_ANIMATING would basically put the game in a waiting state for the animation to take place, avoiding any further processing until the animation is complete. Then it could move on to the next NPC's turn.
Also, I would just have a gameManager.update() and gameManager.paint(g) (paint would be called from paint) that would handle everything and keep the run method thin.
Finally, did you look into flushGraphics()? With the GameCanvas you usually create a Graphics object, draw everything to that and then call flushGraphics(), then wait. The method you mention is the way of tackling it for the Canvas class. Just thought I would mention this and post a link:
Game Canvas Basics
Related
What I mean by "tick" is, "each time the program 'updates', or essentially each frame when it runs". Like the Gamemaker Step event for objects. Gamemaker is just bad because these "ticks" or "steps" are directly tied to fps, which can break the game, quite literally.
This is probably a repeated question because I simply don't know what to ask for. If it is, please go ahead and point me in the right direction by giving me the proper terminology for this program. Perhaps there is no "step" in Android Studio, and I just need to have a TimerTask to have my game constantly update and do its actions.
Why do I want to know? Because some actions the AI takes needs to be happening regardless of user input, like in an RTS game. Or for updating your position on a map, that's tied to Google Services' getLastLocation method.
It is the first time I want to write a java game, and I chose to do a Snake Line.
I learnt from a piece of source code from online. It updates the game states and displays in one thread. I changed around that code, and when I changed the FPS (from 60 to 30), animation slows down. More to this, the game behavior changes too. It is duck shooting game, and the space between ducks get narrower.
So I decided to separate the game thread and the display thread to avoid the above problem. But then I realize it brings out the concurrency problem which will be all over the place.
So as the title indicates, is it good to separate game thread and display thread? What is the common practice and why?
From the changes you experience, it sounds like you are using frame as a unit of time measurement. Or, more precisely, you use pixel/frame(or something like that) for velocity and second for time.
This might be OK for a simple game like yours, ones that are light enough on the system resources so that the delay between frames you specify in the code is practically the same as the real delay, meaning you are in complete control over the FPS. When the game get heavier and modern systems can no longer guarantee that property, you have a problem.
The solution is usually not to separate the game and display loops to separate threads, but to not use frames as unit of measurement for game mechanics calculations. Instead, each frame measure the time from the previous frame and use that value for the calculations, eg. multiply it by the speed to know how much to move a game object in this frame.
Not that separating those loops is such a bad idea. You don't get concurrency problems "all over the place", since the interaction between the game logic and the display shouldn't be "all over the place". The interaction should be one-way: the game loop writes data and the display loop reads it. That means you shouldn't have race conditions, but you can still get other multithreading hazards, which you can solve with volatile variables.
I have recently learnt that jMonkey operates on only a single thread which is its openGL render thread. However I'm not able to understand it completely. I can understand that it executes all update and initialize() calls on a single update loop but input should be independent of this update loop, otherwise it will become a polling mechanism.
What exactly happens when the jMonkey application starts. Three tasks that it needs to do is run a update loop, run initialize methods of app states once, do rendering and constantly cater to events? How does it manage all of this via a single thread?
What happens when I add a new app state in the initialize method of another app state?
In input handling input manager notifies the various listeners about events. How are nifty callback events say onClick() are handled on the same render loop?
Lastly in which order this listen- update-render loop runs and where we can find code related to it?
jME uses an approach that's very common in a lot of game engines (and also used in some other user interface libraries such as Swing).
Everything that the game engine does is done in one thread. This can be called the LWJGL thread but as jME can work with alternatives to LWJGL it's more generic to call it the Render Thread or just the jME Thread.
Everything is indeed done on the Render thread, and it does indeed use a polling mechanism. For example if you are holding down the "left" key then each frame the relevant control or app state will be called on the render thread and will move you left by an amount modified by tpf. Tpf is time-per-frame and is very important for keeping smooth movement and letting game systems run at the same speed independently of frame rate.
The only thing within jME3 that commonly uses a separate thread is the Physics Engine. That has a thread that it uses for doing the physics updates and then changes are pushed through to the Render thread using appropriate mechanisms. The system handles this for you though so it is not something you need to worry about.
The thread runs around a game loop. Each time around the loop it checks for things it needs to do (like enqueued tasks, initialize app states, render, etc. It calls update in each active Controller and control, etc). Once it has finished updating everything it then goes on to perform the render. All of this happens every single frame, but computers are so fast that it can still handle all of that and render the game at good frame rates.
That's an implementation detail that you shouldn't need to worry about except to know that it will definitely work. The adding actually gets queued up and handled in the next frame I think.
Everything is handled from the same loop. jME calls through to Nifty to allow Nifty to do its processing. As part of that processing Nifty detects the events and fires off the callback. This means that the callbacks are already coming in on the render thread so you can safely modify the scene graph. jME uses some specially written collections such as SafeArrayList to allow you to modify the scene graph at the same time as iterating over it.
Update, Render, Update, Render, etc. Events firing generally happens as part of the update process when an update is detected. To find the code start by looking in the Application class, you should be able to find the main game loop in there by tracing through from the start() call.
The jME3 Threading Tutorial covers a fair amount of this:
http://hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:multithreading
I am only a beginner in Java and until now I just put the functionality into the addActionListener() method of the buttons, it was enough for little games and stuff.
But now I am trying to make it seriously and I am wondering how to connect those 2.
As an example I am making a Fuchimi game, so I have my classes for the actual game and then a class that builds the frame with everything needed.
But my actual problem right now is, that after the frame is created, it doesn't do the following code since the code pauses at the window, like here:
FuchimiUI ui = new FuchimiUI();
//The following is not executed
Hand playerHand = null;
while (playerHand == null) {
playerHand = ui.getPlayerHand();
}
Hand enemyHand = generateHand();
ui.changeEnemyText("Enemy picked " + enemyHand.toString());
if (enemyHand.beats(playerHand)) {
ui.changeGenText("Computer wins!");
} else
ui.changeGenText("You win!");
The buttons I have just change the hand of the player.
So how can I do that properly, having the game code being compiled while the frame is already open?
I thought about threads, but I have too little knowledge about them, thus I don't know if that would be a good way.
Edit:
The ui.getPlayerHand() method returns the chosen hand(rock, paper or scissors) that the player has chosen through the buttons.
Of course I could have written the whole code in each of the button's addActionListener()methods, but I doubt that's the proper way of doing that.
So in general, all I wanted to do is let the player choose his hand and then let the game generate a random hand, then compare those two and change the text of one of the labels, depending on wether the player won or not.
The problem you are having results from the fact that your while loop is blocking the UI thread. You need to offload it to a different thread and then enqueue the UI updates back on the UI thread. The same situation is encountered here, please have a look.
There are several ways to fix this. One of them is the SwingWorker.
The steps are:
Override doInBackground for your while loop.
In it, call publish to store intermediate results (like the messages you want to display).
Override process to display the intermediate results in your UI.
The third page of above mentioned tutorial covers this.
As much as I agree with Domi's answer, that long-running code should go into a background thread, I strongly suspect that this is not what you need in this situation, that instead you should re-think the structure of your program. Likely what you need instead of that while loop is a modal dialog.
For more and better advice, consider telling us more details of the game logic and your program set up. For instance, tell us exactly what ui.getPlayerHand() does, as a start.
What you want to do is to change the structure of your program so that it is event-driven and state based where its behavior changes depending on its state. For instance if your program is in "choose hand" mode, then those buttons or other user interfaces are all that respond to the user.
I am creating my first game in Java. The game is Monopoly. I am struggling with how I should design the game to model its turn-based structure (managing player turns). I want to allow for both a single human-controlled and one or multiple AI-controlled players to play the game.
My specific issue is that I do not know whether to implement a game loop or not, meaning a loop which can manage the players and the variables directly related to the game of Monopoly, (think of things such as prompting each player for their turn, incrementing the turn to the next player, or getting dice rolls from each player—in turn). I am not referring to the more low-level meaning of the term “game loop” which relates more to drawing frames on the screen, updating physics, or updating AI at a specific rate of time.
My understanding is that my options for trying to implement what I need are either to:
Implement a completely event-driven program which has no such game loop, or
Implement a game loop—something that is long-running in the background and basically never-ending as long as the game is running. This would be the more procedural approach.
When I first started trying to solve this issue, I ran into problems of my UI freezing because my game loop was never-ending and was completely consuming the thread on which it was running (I just made a very simple while loop to illustrate this). So I went to the effort of creating a SwingWorker to encapsulate my game loop. That solved the issue of UI freezes, but still left me wondering if I was going down the wrong path.
As a general rule, I found that most advice on the web generally seems to favor any approach which is event-driven, and thus my current implementation utilizing a SwingWorker could be a step in the wrong direction. But I cannot fully grasp how I would implement a completely event-driven system for this specific task (meaning no game loop present). It seems to me that a loop has to exist somewhere for managing the player turns.
Here are my specific questions:
Are game loops (as I am describing them) appropriate for turn-based games such as Monopoly—specifically for queuing the player turns and prompting the appropriate player for their turn, one player at a time (and queuing the entire procedure of/sequence of steps that comprise a turn)?
If a purely event-driven system were to be created for managing player turns, how do you iterate through each player to prompt them for their turn and keep iterating until the game ends?
If a game loop were to be used to solve the specific problem described above, does it have to be run within its own thread (possibly using SwingWorker) in order to avoid freezing the UI? My situation is Java-specific, but I suppose I would be interested in answers for non-Java-specific situations as well.
Currently, I have my code organized using the MVC pattern. My controller is where my game loop (the actual SwingWorker thread) resides. It is far from complete, but it helps illustrate how I am managing player turns in what I am calling a "game loop".
SwingWorker code from controller:
swingWorker = new SwingWorker<Void, Model>() {
#Override
protected Void doInBackground() throws InterruptedException {
gameLoopRunning = true;
while (gameLoopRunning) {
//to do: use a timer instead of thread.sleep
Thread.sleep(1000);
//user turn prompt
if (model.getActivePlayer().isUserControlled()) {
boolean userRolled = false;
while(!userRolled) {
System.out.println("Roll the dice please...");
Thread.sleep(3000);
}
}
//bot turn prompt
else {
//insert code for bot rolling dice here
model.rollDice();
}
publish(model);
Thread.sleep(1000);
model.incrementPlayerTurn();
publish(model);
}
return null;
}
#Override
protected void process(List<Model> chunks) {
Model gameModel = chunks.get(chunks.size() - 1);
//hard-coded for 6 players
for (int i = 0; i < 6; i++) {
view.getPlayerPanel(i).setTurn(gameModel.getPlayers().get(i).isTurn());
}
view.getGamePanel().getDice().setDie1(model.getDie1());
view.getGamePanel().getDice().setDie2(model.getDie2());
}
};
swingWorker.execute();
The comment from SirDarius is spot on.
Though, for something as simple as advancing player turns, you don't really need to bother implementing a full fledged finite state machine.
In terms of MVC, this is what you should do for human players:
The Model: Provide methods for advancing the active player to the next player and for running through the "turn process" (i.e. rolling the dice, moving the active player's token, etc.). Because much of the turn process is event driven, these method calls will be made from event listeners in the controller.
The View: Raise an event when the active player finishes their turn, as well as raising events on various other input.
The Controller: Whenever a player finishes their turn, tell the model to advance to the next player, and start the "turn process" again. Whenever a player provides input, an event will be fired that tells the model to advance to the next stage of the turn.
For AI players, the majority of the same code can be used, but it does not make sense to have the turn progression be driven by the view. Instead, the model would need to have another "turn process" method which would be specifically for AI players. The only difference being that the code would execute in succession without waiting for input from the view, instead of being a series of event listeners.