Sun Microsystems, are you listening?

I've been going through many of these posts on this message board only to notice that so many Java and would be Java programmers are having the same problem with animation as I am. Many of the problems seem to stem from the Graphics.drawImage() method. Simply put, we are asking the JVM to draw an image on a buffer. We are NOT asking the JVM to schedule a time to draw nor are we wanting a thread to be spawned. What we need is the image to be drawn to the buffer and a return value of true or false when the function is complete. Most importantly, we want the process of drawing an image to begin the moment drawImage() is called without delay!

If in your wisdom you feel that us lowly programmers need your help with timing issues, feel free to wait for the next horizontal refresh. But only do so if you can accomplish that feat with skipping a refresh. Otherwise, I would prefer to handle my own timing.

drawImage() is a command to be carried out immediately, not a leisurely request.

Ron_W

[1022 byte] By [Ronald_Wa] at [2007-10-1 10:47:36]
# 1

To do this use BufferedImages. Use ImageIO.read(url) to read images and g.drawImage(img,x,y,null) to display them. The way I get urls is Class.getResource(relative path).

IIRC, the weird setup is so that images loaded over a slow connection can be displayed when only partly downloaded, and so that these images don't stop the whole app from loading. One would do this by calling repaint() whenever the ImageObserver says that more has been recieved. Here drawImage() returns as soon as all of the Image that it has has been drawn.

BTW, what would the true/false return value be?

ben77@aol.coma at 2007-7-10 3:15:30 > top of Java-index,Other Topics,Java Game Development...
# 2

I'm testing this app on several different workstations to find some very disturbing differences. First of all, on a Windows box, it's running at about 32 FPS but smooth as glass. On a Linux box it runs at about 52 FPS but very jerky. However, on the Linux box, if you keep the mouse in motion (and on the applet), the graphics become much smoother (tolerable) until the mouse stops.

What seems to be happening here is that the paint() function is getting scheduled and then performed whenever. Therefore, several of the frames, get "dropped". Keeping the mouse moving might be giving the paint() function a higher priority, and therefore painting is happening immediately. My gripe is that there is no way for me to code this desired effect, despite the fact that the JVM can handle the command. (As demonstrated by moving the mouse around the screen)

Thanks for the advice, but I don't believe that is the answer. I am using a doubled buffered technique. You can see that for yourself if you like by viewing this code.

http://astrodust.com/games/somegame/CptWydner.java

If you follow the code you will see that the function act() renders graphics to the back buffer and the function paint() simply paints the buffer to the applet. If you have 2 machines, one running Linux and one running windows, you will also the aforementioned difference in performance by running this applet. You can see what your FPS is by opening the Java console.

http://astrodust.com/games/somegame/applet.htm

If anyone has an OS other than Linux or Windows (especially Mac OS X) I would really like to know what your experience is in reference to this applet.

To answer your question about the true/false return, I was thinking a true on success and a false on failure at the time I wrote that statement. However, since then I've considered the fact that a try/catch block or an integer return might be of more value. An example integer return might be 0 for no errors or an integer code for the reason of failure. More of a C mindset I guess. The "Java" way would obviously be the try/catch method. Either is preferred to not knowing when the painting is done.

Ron_W

Ronald_Wa at 2007-7-10 3:15:30 > top of Java-index,Other Topics,Java Game Development...
# 3
Are you using active or passive rendering?
paulcwa at 2007-7-10 3:15:31 > top of Java-index,Other Topics,Java Game Development...
# 4

Runs at ~50 FPS and smoothly for me under Linux.

> What seems to be happening here is that the paint() function is getting scheduled and then performed whenever.

No. If you were calling repaint() then this could (and probably would) happen. Calling paint(getGraphics()) makes it run now, assuming no other threads/processes preempt it.

One problem I saw was that paint doesn't check if g is null, giving a NullPointerException it the Graphics isn't ready yet.

Also, what errors would drawImage have, other than the Image being null?

ben77@aol.coma at 2007-7-10 3:15:31 > top of Java-index,Other Topics,Java Game Development...
# 5

When I first read your post that said that you were getting a smooth 50 FPS my first instinct was to ask about your hardware or to doubt that my opinion of smooth is the same as yours. However, I decided to check my xorg.conf file to ensure that I was in fact using the right driver for my video card. (Which I was) But while poking around in there I noticed that my default depth was set to 16bit. Surprised, I set the default depth (back?) up to 24bit where I thought I had it in the first place. I re-ran my test applet and noticed a dramatic improvement in animation.

This new twist has lead me to more questions and new problems. For example, why does moving the mouse improve animation when the video depth is set to 16bit? Given your statement about paint() not running in its own thread, that question is even more perplexing. At the higher depth, keyboard IO is now quite unresponsive. So, I'll need to explore options there. Finally, what measures do I need to take to ensure that the end users OS / Graphics configuration has minimal effects on my application?

Thanks for your advice on checking for a valid Graphics object before executing paint(). You are right, and I'll make those changes. As for your question about what kind of error messages should be returned from a failed paint() call, I'm not sure.When I thought the paint() was running on it's own thread, I had contemplated an interrupted error and of course the null graphics object. But if paint() doesn't run in its own thread, that seems like extra baggage that need not be in the language but rather left to the programmer to handle.

Intel 2.7g

512 meg ram

i852 video

Linux Kernel 2.6.7

Gnome 2.8.3

Mozilla 1.7.5

Java 1.4.2_06-b03

Ron_W

Ronald_Wa at 2007-7-10 3:15:31 > top of Java-index,Other Topics,Java Game Development...
# 6
I'm using a double buffered active rendering technique.Ron_W
Ronald_Wa at 2007-7-10 3:15:31 > top of Java-index,Other Topics,Java Game Development...
# 7

Note to anyone reading this who might still be using JVM-1.4.2:

On the Linux platform, there is a HUGE difference between Java 1.4.2 and 1.5.1 in the graphics rendering abilities of the JVM's. Java 1.5.1 is far superior and well worth the download. Any complaints I have had with Java 2D has now be rectified in Java 1.5.1 and all the preceeding posts on this thread are now meaningless. (Except for the one that reminds me to check for a valid graphics object).

Great Job Sun! Apparently... you were listening. :)

Ron_W

Ronald_Wa at 2007-7-10 3:15:31 > top of Java-index,Other Topics,Java Game Development...