1

I'm making a scrolling 2D map/tile based game. Each tile (stored as tile[21][11] - 231 tiles total per map) can contain up to 21 values (stored as int[3][7]). While full-screen I see about 8 maps at once.

On average, each map takes about 0.03 seconds to draw (found with System.nanoTime). The problem is that as soon as more than 1 map is on the screen, the Swing event polling noticeably slows down.

Is there any solution to this? I can't draw the map a single time to save it as an image because it has transparency involving moving actors, so it changes too frequently. Also I don't think I can call a thread in paintComponent to draw the maps without it glitching out, but I'm not positive.

Audiocrow
  • 65
  • 5
  • 1
    Background images and tiles should be drawn as BufferedImages. Images off screen should be cached in some way and brought up when needed. You can limit the region of repainting by calling an overload of the method that takes parameters. – Hovercraft Full Of Eels Jun 30 '14 at 01:22
  • 1
    Don't be afraid to use multiple `BufferedImage`s as layers to enhance the effect (back/mid/foreground). Generally, these should only be as large as you need them, splicing in the new content only when it changes – MadProgrammer Jun 30 '14 at 01:38
  • 2
    See also this possible [duplicate](http://stackoverflow.com/q/23145439/230513). – trashgod Jun 30 '14 at 01:47
  • 1
    Flyweight pattern == good. 1+ to @trashgod's answer (but given ages ago). – Hovercraft Full Of Eels Jun 30 '14 at 02:11
  • My Tiles aren't any type of JComponent, it's just data. I call their container the "Map Pane" which draws all of the tiles in its paintComponent. When drawn, all the tiles share a buffered image called the "tileset", and their data tells the code which part to draw. I think that's as flyweight as I can get them. The painting still happens quick, but like I said it's just enough to slowdown the user-input processing. – Audiocrow Jun 30 '14 at 06:17
  • *"..which draws all of the tiles in its paintComponent."* They can be painted instead to a buffered image. For a side scroller, I'd make the image twice as wide as the filed of play. – Andrew Thompson Jul 05 '14 at 02:34

1 Answers1

3

My Tiles aren't any type of JComponent, they're just data. I call their container the MapPane, which draws all of the tiles in its paintComponent.

Likewise, JTable cells are just data rendered inside a JComponent; the flyweight pattern, mentioned here, is still applicable: the goal is to omit any effort to render non-visible cells. Profile and self-time with a view toward optimizing the rendering; some approaches are examined in the KineticModel cited here.

A BufferedImage that needs no scaling is best. If you must scale, experiment with RenderingHints related to interpolation type. If composition is too expensive, construct maps in the background using SwingWorker; publish() them as they become available and process() them on the EDT, as shown here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045