Two really stupid questions..

First of all, let me just say that this is my first forum message…

And without further Blah Blah i’ll get to the questions.

I have recently started developing in Java… which I think is a great language and decided to do some graphic applications (games).
so I began doing something which uses double buffered graphics, the game consists a falling ball which avoids obstacles by pulling itself up whenever space is pressed (a tribute to a friend of mine who did it in VB :)), anyway… the mechanics are all done and i want to replace my ball (filled oval) with an image of a ball, I’ve tried different techniques to load an image and draw it to a Graphics2D object, but no luck… so could anyone explain how to do it?

My second question relates to the double buffering technique, I know it is used to prevent flickering. but my obstacles (which are currently empty 3DRects) are tearing as they move (I switched to draw3DRect from fill3DRect because i wanted to hide the tearing effect,

My technique is as follows - i get the graphics from an Image, render my ball, obstacles etc. to it and then calls repaint(), I have overrided paintCompotent(Graphics g), so it should be ok (It is explained in a book about java games programming).

Help would be greatly appreciated…
Thanks

I haven’t used J2D in a while, but the tearing effect is common to all games that dont sync their frame rate with the monitor’s refresh rate.

The monitor refreshes the screen from the top left working its way down and right, the frequency of the monitor is how many times it can do that in a second. What happens whe you have a frame rate that is higher than that of the monitor’s refresh rate is that when the monitor is refreshing, the data is updated, its draw the last frame, but by the time its gotten to the new row, the data has been updated, the rectangle is in a different position, and thus the lower half of the rectangle is in a different position, hence the tearing. The best way to avoid this is to cap your FPS to that of the monitor’s refresh rate.

Thats the theory part, how its done under J2D, i completely forgot :slight_smile:

I think you can only use vsync in fullscreen exclusive mode with swing, seems like it was enabled when I had the ogl pipeline enabled though… Also, will using a redraw rate less than the monitors refresh rate really solve the problem? Certainly the problem would be less, but you could get tearing at any refresh rate just as long as the screen contents is being changed in the middle of a refresh, right?

The game is not in FSEM, its on a JPanel inside a JFrame.

Anyway… i’ve tried matching the screen’s refresh rate and it didn’y help :-, so it’s not the problem, probably.

Thanks anyway for your help… but do you know of any other method of refreshing without tearing?

oh and what about the image loading, can someone give me any help with that?

Question.

You draw to the image, then call repaint.

Do you then draw the next frame?

If so thats likely causing your tearing.

Repaint is asynchronous. You have no idea when its going to occur. You need to wait for the image to have been painted before you can start drawing the next frame to it.

You could solve this by overriding paint() and using a mutex-wait type logic, but honestly this starts beigna lot of work to do it in a bad way. The better way to do all of this is to use buffer strategy and active rendering. See this article for more details:

http://java.sun.com/docs/books/tutorial/extra/fullscreen/

Are you working on a laptop, tearing can be seen on many games on LCD laptop screens even if there is an attempt at vsync.

Re: Image loader - a tutorial I wrote covers some basic image loading and a bit about accelerated buffer strategy rendering, it might help: www.cokeandcode.com/info/tut2d.html

Kev

Thanks a lot for your help guys… :wink:

actually i have solved the image issue - Image img = ImageIcon((getClass().getResource(“ball.gif”)).getImage();

but about that mutex thing… how do you do it? sounds interesting…

basic pattern is this


boolean painted;
Object mutexObject = new Object();

In your code that calls repaint do this:

...
synchronized(mutexObject){
    painted = false;
    repaint();
    while (!painted){
       try {
           mutexObject.wait();
       } catch (Exception  e) {
           e.printStackTrace();
      }
   }
}
..........

In you paint() routine something like this:

synchronized(MutexObject){
    super(g); // or paint code
   painted = true;
    mutexObject.notify();
}


For more info look at a decent book on multi-threaed java coding (Doug Lea’s is a classic).

Couldn’t you just call repaint(0), which is meant to repaint the screen with 0 milliseconds?

Kev

Nope, cause it doesnt mean “in 0 seconds”. It means in a minimum of 0 seconds. Its stil lasynchronous and happens whenever the GUI thread inside of AWT/Swing actually decides to do it.