SurfaceView : As I know, SurfaceView is drawing on different thread ( using SurfaceHolder.Callback()).
In one Android Game Project, I see in SurfaceView class : they process Physics (location,...) in same class, but when process Graphics (drawing to screen), they use another thread to process. And Android Example Landern has used this model too.
Please tell me which advantages of this model ? (means, using another thread to draw to screen rather than drawing on same thread of SurfaceView).
Thanks :)
From my limited expierience:
If you draw in a seperate thread, you can keep up "background animations" (moving water, gras, burning fires) while you are doing more complex calculations etc. in the "main" thread.
If you do it all in one thread, you basically block all movement while you are drawing and vice versa, every movement/calculation blocks drawing.
Advantages depend on whtt game you want to make. if you make a boardgame without any special animations and effects, you are good to go with one thread I guess.
Related
I'm developing a plugin for an old application that uses the Swing UI toolkit. As far as I know, Swing's philosophy is that everything executes on the Event Dispatch Thread. I need to integrate a JPanel where it repaint()s itself every 16ms.
I think this will cause the EDT to be flooded with redrawing that JPanel and making other events wait longer, (mentioned in the Javadocs) which could slow down the app. I'm already seeing slowdowns in a test instance of the application.
The way I see it now there are 2 solutions:
Render everything to an image, then render that to the screen, this way, long computations can be rendered by a background thread and the EDT takes care of drawing a simple image, reducing latency.
Make repaint calls only when the user is actually doing something.
What is a performant way to draw dynamic, frequently-updated content inside a Swing UI without blocking the EDT and the rest of the UI?
The animation, processing changes painting complex modelling objects on a Graphics/Graphics2D can indeed be separated. Whether SwingWorker, SwingTimer, event driven.
You can use a BuffferedImage with getGraphics and at the end of Graphics2D drawing do a disposeGraphics. Take a compatible image type as the Graphics of the screen.
Then the actual painting will just do a drawImage in the paintComponent update event handling.
Log processing times, and repaints - for optimization. This profiling is crucial to knowing performance bottlenecks.
Often costly things can be improved. Like using affine transformations, preloaded images of course, and so on. Like doing light-weight drawing instead of tiny JComponent hierarchies. Like pruning invisible parts.
Just a forewarning: I'm new to java - I normally use UnrealScript and C# but I'm branching out, so there is likely one or two things I've done incorrectly or against the normal java convection (that would be more in align with convictions of those other two languages)
Feel free to point them out, and I'll mold myself to them accordingly
I'm making a JRPGish style game in java using BlueJ. I'm not aiming massively high, and am more doing it as a proof-of-concept rather than a full blown game.
So far its going ok. I'm got a sprite animation working using a sprite sheet and the player can walk around with the sprite changing to the correct animation depending on the direction.
However I'm having an issue when the player stops moving - there sometimes is a afterimage of the previous frame - In fairness, this may be happening all the time except you cant see it if the player stops moving on the first and last frame of the walking animations, as those take up the same pixel space and thus are hidden (if that makes sense)
Here is an image of the issue in action:
This is after the player has moved, and then stopped, leaving the last frame of the "moveRight" sprite behind.
I have created a small version of my project that has just the character animation playing when you press a key, and stopping when you release, in which the issue appears
The Skeleton class
The Character class
The GameManager class
The KeyManager class
To start the game run the Main method in GameManager
You'll need to save this image with the filename of "James.png" and place it in the same folder of the java project for it to work
Thanks in advance for any help given.
paintComponent() passes Graphics to drawCharactor(). drawCharactor() should not disposes that Graphics object unless you made a copy, this Graphics is shared.
Also, do not call repaint() from drawCharactor(). repaint() schedules another paint cycle. You already do call repaint() from a timer.
Do not use java.util.Timer use javax.swing.Timer for Swing painting. See How to Use Swing Timers
For more information and examples Performing Custom Painting and Painting in AWT and Swing.
Consider posting a minimal example.
I am currently writing a Fractal Explorer program, and I am encountering a really weird issue with it: I am drawing the fractal on a BufferedImage, and I get random black areas in that image. Screenshots: http://imgur.com/a/WalM7
The image is calculated multi-threaded: The big image is split into four (because I have a four-core processor) sub-images that are calculated individually. The black areas appear at the beginning of each of the sub-images. They are always rectangular, not necessarily following the order in which the pixels are calculated (left-to-right, but the area does not always stretch to the far side of the sub-image).
I have verified that immediately after the pixel is drawn (with Graphics.drawLine), BufferedImage.getRGB returns the right color for the pixel, but after the calculation is finished, it can return black instead, as the pixel is drawn on the screen.
The problem seems to vanish if I disable multi-threaded calculating (by assigning only one core to javaw.exe via the task manager) but I really don't want to have to abandon multi-core calculation. Has anyone else encountered this problem (I have not found anything via Google and stackoverflow), and do you know how to fix it?
The Graphics.drawLine call is synchronized on the Graphics object; if I additionally synchronized it on the BufferedImage, nothing changes.
If you want to see the bug for yourself, you can download the program at http://code.lucaswerkmeister.de/jfractalizer/. It is also available on GitHub (https://github.com/lucaswerkmeister/JFractalizer), but I only switched to GitHub recently, and in the first GitHub commit the problem is already apparent.
I think the problem is that neither BufferedImage nor Graphics is thread safe and that you see stale values in the thread that reads the BufferedImage after the computation.
Synchronizing on the BufferedImage like you said should actually help. But note that you must synchronize all accesses from all threads, including the read-only accesses. So my guess is that the thread that draws the BufferedImage on some component (which should be the AWT thread) does so without synchronization and therefore sees stale values.
However, I would suggest that instead of sharing a BufferedImage among multiple threads, you give each thread a separate image on which it can draw. Then, after all threads are finished, combine their work on a new image in the AWT thread.
Also, I suggest you use an ExecutorService for that if you don't do so already. It has the advantage that the visibility issues of the return values of the Callable tasks (in your case the image parts of the worker threads) are handled by the library classes.
If you combine these two approaches, you will not need to do any manual synchronization, which is always a good thing (as it's easy to get wrong).
Buffered images may not be thread safe because their data may live on the graphics card. However, this can be overridden. By using the ((DataBufferInt) image.getRaster().getDataBuffer()).getData() secret technique for high speed full image drawing (data buffer type depends on the image type you chose), you will get an unaccelerated image. As long as you never write to the same pixel twice, this should be theoretically completely safe. But remember to join() your threads somehow before reading pixels out of the image. join() method from thread not actually recommended as this requires thread death.
Related note:
The flicker you are witnessing is probably an artifact of the way awt renders to the screen. It runs in immediate mode, meaning every draw action you take immediately updates the screen. This slows down rendering of multiple objects directly to the window. You can get around the flicker by implementing a double buffering strategy. I like to draw to an intermediate image and then draw only that image to the screen.
Here is my problem:
I currently have on Canvas in my main game activity that is constantly being drawn with OnDraw(). This is a board game with two players. When a player's turn begins, there are many options that the player can do, and I would like all of this to be put in a different class.
Also, this new class must draw NEW animations on top of the current canvas. These animations will came from attacks (I haven't even looked into animations yet). So basically I would like another canvas on top of the main one.
Furthermore, the OnDraw function in the main activity must PAUSE and wait for the other class with the canvas on top to complete.
Let me try and summarize this: I have a main game class with one canvas. This class handles the players' turns and setting up the game. It also draws the playing field. I need another class, when it is a player's turn, to draw animations and other things on top of the current canvas.
Can anybody help me with this?
NOTE : I looked into Fragments and FragmentManager, but it seems I can only use XML Views with that and not RenderViews.
Thank you!
You might want to consider using multiple bitmaps as buffers and then just add them on top of each other before rendering to the canvas.
There is a nice example in the "samples" pack that comes with the sdk that shows of how you can merge bitmaps on top of each other.
Let me know if you want to try this out and need some more pointers on how to do it :)
I'm trying to animate a chess piece in a board. First I created a java.util.Timer object that "scheduleAtFixedRate" a TimerTask implemented as a proxy function. So I kept a record of the piece to move (piece-moving-record) and when it's apropriate (when the user move the piece using the mouse) the TimerTask proxy function should be test if the record is not nil and execute the piece-moving function. The piece-moving function just updates the x and y coordinates of the piece, according to a vector pre-calculated. I put a add-watch on the piece-moving-record so when it changes it should repaint the board (canvas). The paint method tests if this piece-moving-record is not nil to paint it.
The problem is that the animation doesn't appear. The piece just jump to the destiny, without the movement between. There is some problem with the animation scheme ou there is a better way to do it?
Updates to Swing components should be done on the Event Dispatch Thread (EDT). So you should be usig a Swing Timer since any code executed when the Timer fires will be executed on the EDT.
All you should have to do is set the location of the chess piece and it will repaint itself automatiocally.
Read the section from the Swing tutorial on How to Use Timers for more information.
Swing doesn't do animation automagically it does not matter if you have a timer or not. If you want to animate movement you need to move the piece some distance at a time and repaint the canvas with every move so it gives the illusion so to speak of movement.
you can use Trident library : Here
There's a Animator demo in the JDK. It uses awt but it should give you some ideas.
jdk1.6.0_20\demo\applets\Animator
Another idea might be to look at the Processing visualisation framework from processing.org. It's a simple but powerful and well-documented programming language for animation and visualisation. The API is very straightforward , and has a very transparent Clojure wrapper named Rosado.