I'm still working on moving my android app over to OpenGL and i'm once again having an issue.
I have gotten to the point where everything FUNCTIONS, the only problem is that the animation seems a little juddery.
I'm monitoring the frame rates and seeing that the drawing thread isn't slowing down, but every once in a while, the main loop slows a bit and I suspect I'm having a problem I was worried about.
The way the app works is that as new objects (say for instance, enemies) are created, 2 objects are actually created. The first one is created and mapped in the main thread, and then in it's constructor, it creates a mesh object which is then added to a group to be drawn continuously by the renderer.
Every time an attribute for the object is changed, (such as its coordinates) The object relays the necessary command to its mesh counterpart (in this example to translate the mesh.)
It was suggested that this was thread safe communication, but i'm having my doubts. I also notice a greater amount of frame skip when new objects are created, I can fix this somewhat by reusing the same mesh object for identical Game objects, but I don't believe this will fix everything by itself.
Can you think of a way to make this more efficient and thread-safe?
Another possible solution: The game logic does not HAVE to go at full speed (realtime) I have it actually set up so that no updates are made untill 33 millis pass. So obviously, I should have plenty of time between frames to draw, can I set it up so that draw is only called on command in the thread (after the game logic has been updated)?
It looks like you need something like a ScheduledThreadPoolExecutor.
With one of these you could put your renderer on a schedule so it executes at 30fps leaving your main/control thread to do whatever it needs to do to the object map between frames.
I don't think you need any wait/notify interlocking as all you really need is to block access to the map while the renderer is walking it. To do this you just need to make the map synchronized. As this will only happen once every 1/30th of a second you are certainly not introducing a significant overhead.
Your main aim should be to put as little unnecessary load on the CPU as possible, this is the key to smooth multithread work. Try to spend as much time as possible either sleeping or blocked.
Added
I subtract the time it took to loop from 33ms, and use the result to specify the length of sleep().
I wonder if that may be part of your issue. On a Windows machine you often get a 15ms resolution on the currentTimeMillis so your sleeps may end up hardly sleeping at all. It may be worth experimenting with a ScheduledThreadPoolExecutor just to see if it improves your timing. ... oops ... this is Android isn't it. Still ... it may be worth a try.
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'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.
How would one go about implementing a mouselistener (or some other way, doesn't matter) that will handle a mouse click event at ANY part of the program? Preferably returning to the line it left off at when the click event handler method completes.
I am using swing. The 'context' is a GUI that constantly updates, but must respond to a mouse click from the user at any time with no delay. Indeed I do have experience with events, using and overwriting their handlers etc., not too in-depth I suppose but what i do know has been sufficient in anything until now.
I could not understand your first para, so my answer goes for your second para, if I understood that correctly. ;)
Swing follows single thread model. So, you should be updating the UI from Event Dispatch Thread (EDT). This thread is responsible for delivering the events to your code too, hence the name. If you are continuously updating an UI in a loop then that is going to keep the EDT busy and blocked. The end effect will be an UI which does not respond to user events. This because the events are getting queued and EDT can pick them and deliver them to your code when it becomes free.
Games typically encounter this kind of scenario. You might have noticed that games typically have one fixed rate of refresh which they call FPS (Frames Per Second). Typically maintaining 60 FPS is good enough. That is, you need to draw your UI 50 times per second, but right now it seems that your render loop (which updates the UI) is running continuously.
You need to have separate thread continuously running which is responsible for drawing the UI. This should draw into a buffer (Image). And then invoke repaint() on the UI element to be updated. That UI element's paintComponent() needs to overridden, so that it can copy the image in Image buffer and paint that on the graphics context.
Now comes the real trick. The loop which calls repaint() must do some arithmetic to make sure it does not go beyond drawing 60 times, i.e. looping 60 times, per second. If and when it does then it must call Thread.sleep(sleepTime), where sleepTime is the number of milliseconds left in a second after looping 60 times. It might happen sometime that your loop may take more than a second to complete 60 iterations, then don't just go ahead for next iteration, but call Thread.yield(). This will give other threads a chance to use the CPU, e.g. maybe your EDT. To make the matter more complicated, do not keep yielding always, so might want to put some logic to make sure that yield for only x consecutive times. This last scenario should be very rare, if at all. This scenario means the system is under heavy load.
Remember, repaint() is thread safe and allowed to be called from any thread. It schedules a paint() call on EDT. So, calling repaint() does not guarantee a paint. So, you may want to experiment with different values of FPS to find the one which suites you.
By the way, the trick of rendering to an in-memory Image is technically called Double buffer. This gives us the ability to render nice smooth animations.
Further reading:-
LANSim - Wrote this code a long time back. You can use this code as an example.
http://java.sun.com/docs/books/performance/1st_edition/html/JPSwingThreads.fm.html
Killer Game Programming in Java - This book is on this subject.
Have you looked at SwingWorker? It's a simple framework that lets you run computations in the background and periodically publish updates to the GUI thread.
I decided to convert my spritesbased 2d game for android to use opengl-es to help with some render-related framerate issues. Currently the setup is as follows:
Rendering tkaes place in its own thread, with rendermode set to continuous. Game logic updating takes place in a seperate threaad. Both threads interact with a synchronized drawlock class which ensures that they are never touching the game information simultaneously.
So basically, the render thread waits for any current update to finish before drawing and the update thread waits for the current render to end before starting an update. Everything looks great except or some choppiness I've noticed in the picture when moving around the screen.
I believe this is likely due to a lack of consistency in the number of updates that happen in between each render, on average twice as many updates happen because as of right now not a whole lot is happening in the update. But this lacks consistency so sometimes 1 gets through, sometimes 2, 3 etc so the delta in positions of items being drawn is also not consistent thus creating the choppiness.
Anyone have an idea how I might rectify this? The update thread is regulated to 60 times per second with sleeps...maybe something similar needs to happen under render? I'm just not sure at this point.
Depending on how voluminous your game data is, you might try replicating it. While the game engine is updating one copy, the rendering engine is working off the other. When an update is finished, the rendering engine switches to reading the updated copy while the game engine waits until the updates are transferred to the older copy (which the engine will then update on the next cycle). It's kind of a double-buffering approach, but applied to the game data instead of to the display buffer.