Horrendous Performance in a Simple Java2D App

Hi all,

I’ve just finished my entry for the 14th Ludum Dare 48-hours game making competition yesterday, and decided to do it in java using java2d for the graphics.

I’m not that familiar with the API and haven’t done a lot of graphics programming, but my game is quite small (only a dozen or so very small moving object) so I assumed I could program it naively and still encounter no performance problems.

Needless to say, I was wrong. The game performs alright most of the time but once there are a bit too many ‘enemies’ moving around on the screen or the resolution is cranked up too high it start getting visibly slower.

I’ve determined the performance bottleneck to be the screen drawing functions, when those are commented out the game is very fast.

Could someone give me a heads up on what I might be doing wrong here? The (very short) source code is located here with most of it the Main class, with the usual suspects being the draw() function that is called in the inner game loop.

Thanks in advance,
Ido.

it looks like you are trying to redraw the Jframe each game tick… you probably want to use a bufferstrategy and draw to the back buffer and then flip it to the front.

But if you look at line 337 you see that I already use the strategy to update the screen.

Did I understand you wrong?

Could it also be because I reuse the same graphics instead of disposing it and getting a new graphics context every time?

In general, there’s no point in using swing if you use your own buffer strategy.

In drawPolygonBody you seem to be creating new polygons on each frame. Is that necessary? Did you check the rate of garbage being generated (-verbose:gc or use VisualVM/VisualGC)?


    graphics.drawLine((int) v1.x, (int) v1.y, (int) v2.x, (int) v2.y);
    graphics.drawLine((int) v2.x, (int) v2.y, (int) v3.x, (int) v3.y);
    graphics.drawLine((int) v3.x, (int) v3.y, (int) v4.x, (int) v4.y);
    graphics.drawLine((int) v4.x, (int) v4.y, (int) v1.x, (int) v1.y);

So you transform the points yourself and then draw the rectangle? Have you tried just setting a transform and doing a drawRect? With latest java versions that should be much faster.

Dmitri

Thanks for the answers!

I’m sorry if that’s a dumb question, but where did I use swing? Do you mean defining it as extending JFrame? What should I use instead?

OK, I’ll wrap the bodies in a class that also saves the polygons created upon instantiation.

I actually did but I ran into some problems & just reverted back to doing it this way. I’ll check it out again.

Thanks again Dimitri.

2 more questions:

  1. do you have any idea why it would sometimes be sluggish on key input?
    I.e. it would wait a noticeable fraction of a second between key press and the action.

  2. sound playing is also sometimes delayed by a small but evident amount of time.

-Ido.

Hi,

What about this line which is in your game loop:

Thread.sleep(25);

With such a big sleep you can only get 40fps maximum without drawing anything. Make it sleep for just 1ms and everything will probably be fine.

Once you do that, if there’s still performance problems you should profile using this VM option: -Xprof

Good luck,
Keith

If you’re running on linux with intel graphics and don’t have ‘UseFBDev’ set to ‘true’ in xorg.conf this may help:

-Dsun.java2d.pmoffscreen=false

(add it as an addition argument on the commandline, or as VM argument in your IDE).

Also have a look at this : http://java.sun.com/products/java-media/2D/perf_graphics.html.