Issue with flickering in Java 2D Video Game - java

I am writing a Java 2D video game. I am using only the Java 2D api, and all updates are driven off a single update timer. I perform all the drawing in a JPanel utilizing paintComponent(), and I use Volatile Images for all of the graphics images from what I have read should be a performance increase.
In spite of all this, at times my video game starts flickering like crazy. The whole screen starts flashing. The game is written in Java 6, and I am running on Mac OS X 10.10.1.
Any ideas on how to fix this?
Thanks.

According this post you shouldn't call paintComponent() directly. Try calling paint() instead.
Edit: Sorry, I confused paintComponent() and paintComponents(). Maybe you could show some code?

Call setDoubleBuffered(true) on your main window/frame/panel. Or draw to another component and switch when ready.
The flickering occurs because you quickly redraw on the same component. Redrawing in the background, and then quickly switch to the now newly drawn picture gets rid of this. This is called double buffering. Read more here.

Related

Circumvent frequent repaint()-calls for tile-based game

I just started to work on a tile-based simulation game (3D but the graphics will all be 2D pngs/bitmaps). The graphical concept is similar to e.g. gnomoria. I managed to implement the graphical part of the world using a custom subclass from Panel (AWT) that draws the cubes starting at the lowest level left back and works its way up. This way the images of the cubes fit together correctly, but the painting takes too long for a 196*196*100 cubes big world.
Now what I'm asking for are methods to circumvent the repainting of the whole world everytime it changes a little bit.
I think I got a decent idea for the changing process of a single top layer block by just repainting the visible side (either top/left/right) so that it isnt necessary to repaint all the following cubes. But what I'm unable to solve is the repaint whenever I'm moving the screen, i.e. moving the world using a KeyListener. My first idea was to just move the Panel in the Frame but that didn't solve the problem as it still redraws everything if I move the world. Btw I already use hardware acceleration which accelerated :D things a bit, but it is still far away from the goal.
The current result is that the Panel moves, but as soon as something enters the screen that was offscreen before, it repaints this section. The repaint is quite fast but not fast enough to not be visible and disturbing.

How do I run my java program off screen and update the view when I ask it to?

I'm currently learning computer science in high school and using "ReadyToProgram Java". We're trying make a pong game using basic shapes and classes etc. The way my game updates its view is to clear the whole screen and then redraw the paddle and pong in a while loop. It's flashes constantly! When I used Turing in the past grade, we had a command called view.update, where it runs the program off screen and only when you use view.update the program will update the screen. Is there something similar in java? Thanks!
The concept you're looking for is known as double buffering. In general, the concept is that you have an off-screen buffer that you do your graphical operations to, then copy the off-screen buffer to the on-screen display.
I don't know exactly what graphical toolkit you're using for your work. AWT can do this with Graphics.drawImage(). See Double Buffering with awt for one discussion of how to do this. In Swing, this can be handled with JComponent.setDoubleBuffered()
If you are using something else, you may wish to look it up using the exact phrase "double buffering".
Update:
The other answer, of course, is to not clear the entire screen and redraw. Given how the pong objects move, you should be able to clear just the portion of each paddle and ball that has moved.

What is a good approach of to draw graphics with swing?

I am a complete novice when it comes to any kind of graphics. So, I want to create a method in a class Creature that would be able to draw lines on a screen (turtle graphics style). I have no idea what would be a good way of doing this. I mean I could store all lines drawn by user in a container or whatever and every time the repaint() method is called I would redraw all lines but it looks bothersome. Or perhaps it's the best way and I am just being silly? As I said, I don't have any experience with this and everything is starting to look like black magic to me. I would appreciate any help or suggestions. Thanks!
See Custom Painting Approaches for two common ways to do this:
Keep a List of objects to be painted and repaint them every time
Paint to a BufferedImage and just display the image
Updating what to draw and actually drawing it should be separate, because you can't control when repaint() is called. You usually want to control how often the updating is done so it's always a good idea to separate. This also reduces the time it takes to draw so it increases performance as well.

How to delay between drawings in a Java Applet

I'm writing a program to input a number and draw that number of circles of random color and location on an applet. I've been up all night trying to figure out how to add a delay between each of the circles appearing. Right now if I have a for-each statement with a delay in it, and say I input 20 circles and have a delay of 1000, it won't do anything for 20 seconds, then all the circles will appear at once, because the screen doesn't get refreshed until the end of the paint() method.
The only other alternative I could think of was to have a for-each statement in the start() method that would add a color and coordinate to an array, and have the paint() method draw all the circles in this array. I could be wrong, but I would imagine that this would use up way too much memory.
Another possibility would be to just add a circle on to the existing frame without clearing it, but I couldn't find a way to do this.
Use a javax.swing.Timer to add a new Circle object to an expandable list such as an ArrayList. Call repaint() after each addition. In paintComponent(Graphics) draw every Circle in the list.
Update
Unfortunately I cannot add comments at the moment (see External JS failed to load for the gory details). For that reason, I'm adding this as an edit.
#mKorbel: No I sure have not tried it on 1.6.0_26! If I'd tried it at all, I'd have posted the code. ;)
#Tycho: I did not notice you added the awt tag and presumed you were working with Swing.
Are you really using AWT? (If so.) Why?
#Tycho: "The only thing I could tell by quickly searching was that Swing is used more for user interfaces, which is not what I'm going for here."
Umm.. both AWT and Swing (using Applet/JApplet or Frame/JFrame) are used for developing Graphical User Interfaces. Or to put that another way, whether using AWT or Swing, or developing an applet or free-floating frame, you are developing a (G)UI.
Either the applet extends java.applet.Applet (AWT) or javax.swing.JApplet (Swing).
If your applet extends Applet, change it to a Swing JApplet. Few GUI developers can even remember AWT well enough to give good advice on it. My advice was all related to JApplet/Swing. It would not work using AWT.
Use a timer. For example, when you start drawing your circles, set a value:
time_press = System.currentTimeMillis();
circles_to_draw = 20;
Then somewhere in your draw method, do the following:
while(circles_to_draw > 0 && System.currentTimeMillis() < time_press + 1000)
{
time_press += 1000;
circles_to_draw --;
//Draw your circle
}

Open webcam and set as background (question)

Best reader,
I'm stuck on one of my concepts.
I'm making a program which classroom children can measure themselves with.
This is what the program includes;
- 1 webcam (only used for a simple webcam view.)
- 2 phidgets (don't mind these.)
So, this was my plan. I'll draw a rectangle on the webcamview and make it repaint itself constantly.
When the repainting is stopped by one of the phidgets, the rectangle's value will be returned in centimeters or meters.
I've already written the code of the rectangle that's repainting itself and this was my result:
(It's a roundRectangle, the lines are kind of hard to see in this image, sorry about that.)
As you can see, the background is now simply black.
I want to set the background of this JFrame as a webcam view (if possible) and then draw the
rectangle over the webcam view instead of the black background.
I've already looked into jmf, fmj and such but am getting errors even after checking my webcam path and adding the needed jar libraries. So I want to try other options.
So;
- I simply want to open my webcam, use it as background (yes live stream, if possible in some way).
And then draw this rectangle over it.
I'm thus wondering if this is possible, or if there's other options for me to achieve this.
Hope you understand my situation, and please ask if anything's unclear.
EDIT:
I got my camera to open now trough java. The running camera is of type "Process".
This is where I got the code for my camera to open: http://www.linglom.com/2007/06/06/how-to-run-command-line-or-execute-external-application-from-java/
I adjusted mine a little so it'll open my camera instead.
But now I'm wondering; is it possible to set a process as background of a JFrame?
Or can I somehow add the process to a JPanel and then add it to a JFrame?
I've tried several things without any succes.
My program as it is now, when I run it, opens the measuring frame and the camera view seperatly.
But the goal is to fuse them and make the repainting-rectangle paint over the camera view.
Help much appreciated!
I don't think it's a matter of setting a webcam stream as the background for your interface. More likely, you need to create a media player component, add it to your GUI, and then overlay your rectangles on top of that component.
As you probably know from searching for Java webcam solutions in Stack Overflow already, it's not easy, but hopefully the JMF Specs and API Guide will help you through it. The API guide is a PDF and has sections on receiving media streams, as well as sample code.

Categories