tags:

views:

315

answers:

10

I was programming a simple game and wanted to display it via the Java Graphics + Swing API. It felt a little slow, of course, so I measured how long it took to repaint, which was around 32ms. Then I read about accelerated Java graphics and used the method described here: Space Invaders

However, somehow this is even slower. It now takes around 98ms to redraw. Why is that?

Note that I am aware of libraries like LWGL and JOGL, but I don't want to use a full-blown OpenGL wrapper for such a graphically simple game.

+2  A: 

You may look at processing.

+6  A: 

Swing will be slow for a game. Your best bet is probably an SDL wrapper, such as jsdl or sdljava. SDL is quite lightweight and supported on many platforms.

The nice thing is, well-implemented 2d graphics library wrappers implement the Graphics interface, so you should be able to try several and see which one performs best for your app without modifying your code.

Claudiu
+1  A: 

I agree with Nicolas, for graphics / interactivity processing is great

just_a_dude
+1  A: 

Try JGame. It's a simple engine for 2D games which uses GL when its available and can produce games that run on anything from a mobile phone to a desktop system.

Aaron Digulla
+4  A: 
  1. Read this about timers
  2. Use an always sleeping thread in the background to lower the system interrupt rate to get much more precise timers!
  3. You can take a look at my code in here
  4. A small game I've created can be found here

    long renderStart = System.nanoTime() // render stuff here long renderTime = (System.nanoTime() - renderStart) / 1000000;

Ivo Wetzel
I downloaded your library (Bonsai). But I've one question: You made a class `GameEngine`. What is the purpose here (Google translation)?
Martijn Courteaux
Actually I had a problem with my Eclipse SVN Plugin, so it did not delete the file remotely. Just today I deleted the file via another SVN Client... which crashed the whole eclipse Project, so I had to rebuild it which then again somehow destroyed the repository :D So the file is just a left over from development, at sometime I wanted to factor out the actual engine from the applet/gui.
Ivo Wetzel
thanks (15 chars)
Martijn Courteaux
+1  A: 

First of all, you should check and see how much time is spent in your own code vs. how much time is spent actually drawing the frame. You may have some bug or glitch that makes it run more slowly.

You should be able to get much better performance then 98ms to draw your screen. Those game libraries will probably be using the same graphics calls as you would. But which containers you use can have a big impact on how fast things draw. I remember a couple months ago working on some double buffered graphics code, and how the back buffer was created made a huge difference in performance.

In particular, make sure you only create background image once or at least, only when your canvas resizes. In my draw code I do this:

        //create a graphics backplane
    if(backplane == null || !backplaneSize.equals(this.getSize())){
        backplane = this.createImage((int)this.getSize().getWidth(), (int)this.getSize().getHeight());
        backplaneSize = this.getSize();
    }

So the back plane only gets created if it's new, or if the component is resized. This has a huge impact on speed.

I've been doing graphics programming in java since JDK 1.0. Actually I'd never heard of this BufferStrategy thing. Heh.

I've never had any trouble getting good frame rates with basic java graphics calls. Another thing to look out for is making sure that Swing isn't trying to clear the background of your component for you. That can be another source of slowdown.

Chad Okere
+2  A: 

I am not an expert, but Java2D supports different rendering pipelines. On my machine, switching to the OpenGL one by setting the system property

sun.java2d.opengl=true

yielded a substantial increase in rendering speed.

meriton
+4  A: 

A few hints to improve performance:

  1. Clip and just draw the area that has changed
  2. Don't scale anything when drawing
  3. Use the correct buffer strategy
  4. Use full screen exclusive mode if appropriate.

Swing isn't inherently slow. Most of the confusion about Swing comes from people who don't know or understand about the Event Dispatch Thread (and yes, it's a lot of effort to get it right).

Regarding your times, are you just calling g.drawImage between the time settings? If so, what size are you repainting, and are you doing any scaling on this call?

EDIT: Forgot to mention Pulp Core - a very nice gaming framework for Java.

Pool
+1  A: 

Java2D performance is a bit of a dark art. It can vary between platforms, but it possible to get it to perform well.

Sometimes doing seemingly innocuous things can result in much slower performance. You want to make sure that you are using accelerated images as much as possible.

The type of the image can also be significant. I don't know the full details, but I do know that my programs were much faster using type 1 images (INT RGB) than other types such as type 5 (3BYTE BGR) because of conversion issues.

Dan Dyer
+1  A: 

I can't tell exactly what you are doing. Your question is about Swing but you mention a Canvas and Bufferstrategy. Well in Swing you would use a JPanel which is automatically double buffered so you don't have to worry about that.

I tested a simple animation with 1000 moving balls. The Timer was set to fire every 100ms. When the Timer fired, the 1000 ball where randomly moved to a new position and a new BufferedImage was created and the panel displaying the image was repainted. The difference in time between the repainting was 110ms implying it only took 10ms to create an new BufferedImage and do the painting. The painting was done a a full screen so no clipping was done.

This posting show the example code I tested.

camickr
If you want to measure the time for something quick, the best way is to use System.nanoTime() (added in JDK 1.5), which measures in nanoseconds. It's not as accurate over long periods as System.currentTimeMillis, but for short periods it's obviously more efficient.
Chad Okere