Horrible performance in a simple Java2D application

I just finished my record for the 14th Ludum Dare tournament in 48 hours, and decided to do it in java using java2d for graphics.

I am not familiar with the API and havenโ€™t done a lot of graphical programming, but my game is quite small (only about a dozen or a very small moving object), so I assumed that I could program it naively and still have no performance issues.

Needless to say, I was wrong. The game works well, but since there are too many โ€œenemiesโ€ moving around the screen or the resolution has worked too high, it starts to noticeably slow down.

I defined a performance bottleneck as a screen drawing function, when they are commented on, the game is very fast.

Can someone let me know what I can do wrong here? The (very short) source code is here with most of Main , with the usual suspects being draw () , which gets called into the internal game loop .

I already use BufferStrategy to update the screen, so this should not be a problem if I am not mistaken.

Thanks in advance, Ido.

+4
source share
4 answers

A few observations, although I do not think that any of them will help much.

The main thing is that you draw the AWT stream. Override paintComponent () and call repaint () on the object instead. This may cause other problems.

You recreate colors in every frame. This may or may not be one of the things you want to cache. I donโ€™t think that being consistent for your colors is likely to ruin GCing and make it easier when you want to reuse colors later.

You redraw all the windows in each frame. You just need to redraw the changed sections.

You do not need to draw a background. Set the background color and let the parent take care of everything.

As a design element, bodies should be responsible for drawing. Their owner must notify them that they need to be drawn, not drawn.

Organs recreate their condition every time. Consider storing them between times and mutating them as needed. You can spend a lot of time doing trigger calculations in drawCircleBody ()

Something to consider is setting up a timer instead of using sleep during a cycle. This will provide you with a more consistent frame rate, but you need to make sure that you can actually fulfill your obligations (or combine several frames into one if you miss a deadline), or you will create too many threads.

Consider using SwingWorker to do the calculations, then update the state in the done () method, ending with a repaint () call.

These are just a few things. You have to experiment to see what works and what doesn't. It has been some time since I made a Java graphic drawing.

+7
source

Your code does not comply with the single-threaded rule:

http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html

I'm not sure if this will cause certain performance problems that you see, but it stands out as a big potential problem, imo.

+6
source

Well, just from a brief look at your draw () function, it seems like you are declaring several new objects (especially in drawPolygonBody). Try reusing objects instead of declaring new ones every time.

EDIT: instanceof has overhead. It would be a better idea to extend Body to use the draw (Graphics g) function, which draws itself. eg:

public class Circle extends Body { // override public void draw(Graphics g) { ... } } ... void drawBody(Body body) { body.draw(); } 
+6
source

Have you tried profiling it to see where the nodal node device is?

It's hard to say a lot just by looking at it, but I wonder why you both draw and fill the polygon in drawPolygonBody.
In addition, in drawBoxBody you draw four lines separately, rather than just calling drawRect ().

+4
source

All Articles