So I have an assignment where I have to create a "game" type application in which there are multiple moving objects (definately over 10) and some are triggered by user KeyEvents.
I seem to understand the concept but I have a question. How do I draw all objects (which animate up and down) and include KeyEvents so they all perform at once, and don't go in a linear sequence. I looked up multi-threading for this but I highly doubt it would be a good idea as I feel this can be done with only 1 thread.
Any feedback or ideas would be greatly appreciated. Thanks! :)
An example of what I mean is:
public void onPaint(Graphics g){
g.draw(apple);
g.draw(character);
moveCharacter(g);
moveApple(g);
}
So here, I have to first move the character, then the apple, how can I do both of them at the same time? Except with multiple objects.
Ideally you will want to separate your actual game logic from the rendering. Do the calculations, moving, etc on a separate thread from the draw thread. There are some subtle complications that may arise from this relating to concurrency, but it's still a good idea.
It's not clear what you mean by "do both at the same time", but the code should execute so fast that it may as well be at the same time. What you want to avoid is having having any sort of blocking in the methods (eg. user input).
Related
I have heard some people advising the separation of logic and rendering into different threads when making games. Apparently, while rendering needs to happen at ~60fps, logic may only need to happen at ~10fps.
I have a few questions about this:
How can the rendering be faster than logic, if logic is what changes the scene? Surely the rendering thread will be repeatedly drawing the exact same image until the logic kicks in to move the entities around the screen, etc?
Won't this create all sorts of nasty concurrency issues, as the logic and rendering may require simultaneous access to the game's objects?
Can I assume that it's perfectly acceptable to keep my logic and rendering in the same thread? I am using the LWJGL, whose tutorials all seem to suggest a common "game loop" which includes both logic and rendering.
If your game logic does not change the scene, your rendering thread could detect this by giving the scene a dirty flag. if the scene is not dirty, the rendering thread may return the old rendered scene again. Sometimes a scene will change even if the game did nothing due to animated objects like grass, trees or flags.
This will happen because two threads do access the same data. But if the game logic thread processes junks of objects locally and updates those chunks kind of atomically, the concurrent access to the same data should be reduced while processing that data. What I try to say is, do not process the concurrently accessed data in a fine grained way but in a coarse grained way to reduce locking.
In my opinion you should never over-complicate a design if not needed. If you have enough time to process the scene 10-times in a second and to draw it, then you should not use more than one thread. All the older games did it one threaded and it worked. As soon as your game gets more and more complex and one thread can't do all the stuff in 1 / 60 seconds, you may want to use more than one thread to take advantage of a multi-core machine. But you should wait until need be, before introducing many threads.
A sprite may be animating through a series of frames, but no game logic (crash detection, movement, etc) may be required.
You will need to use some form of synchronisation or locking.
It depends how much work your rendering and logic code sections are doing.
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 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'm working on shoot 'em up game, that I'm planning on flooding the screen with entities, (Bullets, Mobs, and the like). I've tried a global timer to update everything on the screen, but I've gotten some serious fps drop when I flood the screen like I want.
So, I see myself as having two options. I can either give each individual entity a timer Thread, or I can section off the level into chunks and give each chunk its own timer.
With the first scenario, entities with their own timer threads, I will end up with hundreds of entities, each with their own thread running a timer.
In the section option, I will have multiple sections of the map with a timer updating multiple entities at once, with detections for when an entity leaves from one section to another.
I'm not familiar with Programming with Memory Efficiency in mind, so which method would be better for me to use?
You could try a ScheduledExecutorService.
It's part of the Java higher-level concurrency API. You can decide how many threads should exist (it re-uses threads for different tasks to avoid the overhead of creating new ones every time and is therefore expected to be much more efficient than creating new Threads all the time) or use a cached thread pool (which will create as many threads are necessary, but once a Thread has died it will re-use it to run new tasks).
Another advantage of this API is that not only can you run Runnables, you can also use Callables, which may return a value for you to use in the future (so you can perform calculations in different Threads and then use the result of each Thread for a final result).
I was experimenting with something similar and don't have a definite answer. But maybe some of the feedback I got from Java-Gaming.org will be helpful or of interest.
What I tried was this: each entity has its own thread, and collisions are handled via a very detailed map of the screen (basically a second version of the screen). Then, I have another thread that handles the display of the screen.
An "early" version of this, with over 500 entities being animated, is online:
http://hexara.com/pond.html
Later versions use more elaborate shapes and borders (rather than letting entities die and freeze at the edges) and collision logic such as bouncing off of each other and gravity. I was also playing with sprite aspects like "firefly" blinking. I mention "actors" on the web page, but the code isn't strictly that.
Some folks at java-gaming.org strongly thought having so many threads was not efficient. There was a lot of interesting feedback from them, which you might be interested in exploring. I haven't had time yet.
http://www.java-gaming.org/topics/multi-threading-and-collision-detection/25967/view.html
They were discussing things like hyperthreading and the acca framework for Actors.
I'm writing a little genetic algorithm in Java, as a school assignment. Up until now I've pretty much stuck to doing console applications. However I think a UI would be really helpful for this program, so I'd like to make one. I'm having trouble figuring out how to reconcile a GUI which is event-driven, and a console application which has a beginning and end.
Ideally I'd like to have a bunch of text boxes for settings, and then a Start button. Once you hit Start, the algorithm would start running and the GUI would update on a set interval with the latest program state. How the heck do I accomplish this without the algorithm freezing the GUI or vice-versa? I don't want either one waiting on the other.
How do I get my main loop to not freeze the GUI while the algorithm is running? I assume they need to be in separate threads, but I've never messed with threads before. That seems too complex for this task, which must be commonplace.
You're on to something with threads. GUI programming mandates threads, in most cases -- luckily, Java's threading API isn't too terrible (Python's is modeled on it, so it's doing something right).
Don't be intimidated by threading, though -- it's intermediate, I'd say, but is something that every programmer should understand.
There's a lot of information out there that would predispose you against threads. GUI applications, however, are one area where they are phenomenally useful. Opponents of threading would lead you to believe that an event-programming model would help you in this case, when really, it will not. The solutions that most who say "threading sucks" propose are often worse than threading itself.
You could try to kludge your solution into a single thread, but it would require your CPU-intensive code to yield to the GUI at a predictable interval. That solution sucks. EDIT: Since others are suggesting that approach, let me elaborate on why it sucks: Unbeknownst to you, something is always being updated in a GUI. When you move a window on top and then back off, the entire region under that window is invalidated and code must execute -- in your process -- to redraw that section. Even if you are updating the GUI very quickly, this provides a negative user experience as simple GUI operations block entirely. Buttons highlight when you mouse over, sometimes. A user right clicks. All of these things require CPU time to implement, and if your solitary thread is chewing away on your GA, they will not happen. GUI code being executed is not only your code.
Here's what appears to be a very useful article on the topic.
Two lessons in the trail on the topic are:
Concurrency
Concurrency in Swing
Sorry - it would seem like background tasks would be an easy and obvious sort of thing. Unfortunately, the Java Swing GUI threading model is a bit complicated. There have been some improvements in this area, but one still has to have some knowledge of threading first.
If you have time, I'd suggest reading the chapter on threading in Filthy Rich Clients - Painless Threading through SwingWorker.
If your impatient, just read the JavaDoc on SwingWorker. If you're really impatient, just copy the meaning of life example from the JavaDoc sample usage.
When I was writing a ray-tracer for one of my computer graphics classes in college, I had a long-running task, and I wanted to update the display periodically as the tracer was drawing. I used two separate threads - one thread sleeps, and updates (say every 500 ms); the other thread does the actual raytracing. The key is to synchronize on a common object - in my case, accessing my image buffer was the point of synchronization (one thread can't make changes to the image buffer without first waiting until the other thread is done reading).
For your GA processing, you might have something like this (pseudocode):
Supposing you have some object, generationHistoryObject, which stores the state that you want to display in your GUI, then:
(in Thread #1:)
Generation newGeneration = doMutationAndTestThisGeneration(lastGeneration);
synchronized (generationHistoryObject) {
generationHistoryObject.updateWithNextGeneration(newGeneration);
}
(in Thread #2:)
while (!programIsDone()) {
synchronized (generationHistoryObject) {
drawGuiForCurrentState(generationHistoryObject);
}
Thread.sleep(500);
}
The idea is that you do the time-consuming work for each generation in isolation, then update the part that the GUI has to access in the synchronized block (making the GUI wait to draw until the update is done).
Your problem with Swing is that it is single threaded (which is a good thing) so you want to get your work out of the Swing thread so your application stays responsive.
The thing you need to do is to convert your core algorithm to a Runnable as it can be handled easily by a SwingWorker and with the newer Executors (see Executors for a lot of preconfigured ones). You can also create investigate how to make a PrintStream to a JTextPanel so you can just use standard println statements to output your current status information.
If you want to add a stop button you need to understand the thread model, so you know how to control it. The Java Tutorial has good material on this as well as Swing programming in general. Strongly recommended.
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html
Since your application has to do with genetic algorithms, you could update the GUI every generation or so. You could accomplish this by implementing a next() method in your algorithm code, and calling it from the GUI. This should be simple enough.
However, if you really don't want the GUI to freeze while waiting for the algorithm, you should go for threads.