0

I'm currently developping a roguelike game, using Swing. I'm using an array of JLabel to display the tiles. When the user input a direction, I redraw the whole tab using the following method (I'm using simplified variable name here) :

for (int i=0 ; i<array.length ; i++){
    for(int j=0 ; j<array[i].length ; j++){
        this.remove(array[i][j]);
        array[i][j] = new JLabel(new ImageIcon(TILEARRAY[i][j]));
        this.add(array[i][j]);
        this.validate();
    }
}

But it's very heavy to deal with, about 0.5s to redraw the whole panel, and when I press the direction, it can't draw fast enough to have a real-time display (it actually does the loop, along the waiting time, and when the whole displacement has been done, draws). I'd like to know if there's a easier and faster way to achieve this, with a " smooth " feeling (let's say like in Stone Soup Dungeon Crawl (tiles version)), using Swing.

Every suggestion on an efficient 2D library for Java is welcome too. I know there is Slick2D, but is there any good other library for this kind of games ?

Thanks

(sorry if my english is bad, I'm not a native speaker of English)

Coulis
  • 196
  • 1
  • 13
  • Some time ago when I wanted to start making games I used this library: http://lwjgl.org/ .Beware though that this is a low level library. Why don't you try using Unity, since they have lots of tutorials – Slimu Mar 27 '14 at 10:53
  • Why don't you use [JLabel#setIcon](http://docs.oracle.com/javase/7/docs/api/javax/swing/JLabel.html#setIcon(javax.swing.Icon)) instead of removing and readding the JLabel? – BackSlash Mar 27 '14 at 10:53
  • You know which titles will change? You could update just the tiles which affect the change – Marco Acierno Mar 27 '14 at 10:54
  • The problem is that it redraws the tiles one after the other, resulting in a weird display. I'd like it to draw the whole array once, instead of tile after tile (I tried to put the `validate()` outside of the loop, still the same result). – Coulis Mar 27 '14 at 10:57
  • maybe use static drawing instead? – Ariel Pinchover Mar 27 '14 at 10:58
  • What do you mean by static drawing ? – Coulis Mar 27 '14 at 11:02
  • Well, i had a chess project and i simply setIcon/Text etc instead of repaint. – Ariel Pinchover Mar 27 '14 at 11:06
  • The problem os still the same ; the display looks weird, one tile at a time (very fast, but I can still a " wave " effect). – Coulis Mar 27 '14 at 11:30
  • Do you see a "wave" effect then you click `New` in [this chess board](http://stackoverflow.com/a/21142687/418556)? – Andrew Thompson Mar 27 '14 at 12:03
  • Just a very little bit, but it's fast enough to be ignored. In my case, you clearly see the display being done on some tiles. – Coulis Mar 27 '14 at 12:11
  • You might consider drawing your 32 x 32 tiles directly to one JPanel acting as a canvas, rather than using JLabels to hold your images. I've drawn line segment images with tens of thousands of points on a JPanel without the "wave" effect you're describing. – Gilbert Le Blanc Mar 27 '14 at 12:11

1 Answers1

2

Call the this.validate(); just once after both loops to avoid layout preferences recalculations

UPDATE. Keep ImageIcons in a Map and reuse them rather than recreating. Key could be i+"_"+j String

StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • That's what I did, but it redraws the tiles one after the other, resulting in a weird display (fast, but not fast enough to be smooth). I'd like it to draw the whole array once. EDIT : it looks like a " wave " effect, if you know what I mean. – Coulis Mar 27 '14 at 11:28
  • Which layout do you use? May be it's better to choose another one (or even implement own faster LayoutManager). Also consider placing them in a JTable and use renderer. Guess you have a lot of similar images. – StanislavL Mar 27 '14 at 11:44
  • I'm using a GridLayout, as it seemed to be the more logical to me. Do you think using another one would increase performances ? – Coulis Mar 27 '14 at 11:45
  • GridLayout is fine. How big is it rows/cols? – StanislavL Mar 27 '14 at 11:54
  • 20*30. What I do is generate a big map (2D int array, 150*150), then generate the display with a 20*30 array of JLabels. Each tile is 32*32 pixels (in case that may have an impact on the performances). – Coulis Mar 27 '14 at 11:56
  • Generate images just once and reuse them. Don't add/remove JLables but instead setIcon() for them – StanislavL Mar 27 '14 at 12:26
  • That worked, along with using repaint() instead of validate() (which is slower). Thank you ! (I'm sorry I can't upvote you, since I still don't have enough reputation) – Coulis Mar 27 '14 at 12:41