Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  [SOLVED] how to draw a huge grid for a map editor?  (Read 2810 times)
0 Members and 1 Guest are viewing this topic.
Offline tacticalPotato37

Senior Newbie





« Posted 2012-07-26 22:50:45 »

I'm making a map editor for my 2d tile based RPG game, and I'm running into a roadblock. The problem is actually how to draw the grid lines efficiently for large maps like, say 300x300 tiles. I mean the actual grid LINES, not the map tiles.

Originally I called redrew the entire grid line by line every time you moved the mouse or clicked(since it allows you to drag and also highlights the tile you are hovering over). This was horrible for large maps and was VERY slow. So my solution was to create a bufferedImage for the grid of a specified size right when a new empty map was created, and redraw that image every time paint was called. This worked well, except that for anything above 200x200ish java would run out of heap space in creating that bufferedImage. I can't really have a preloaded image because the user should be able to specify a new map to be any size. Also, I like the grid to be drawn over the tiles, otherwise the tiles cover up the lines and it looks messier. That means the grid has to be drawn again every time tiles are added right?

Is there another way to draw a very large grid that will repaint each time you move the mouse? The program Tiled can easily create maps of 1000x1000 or more, how is it done?? Thanks
Offline UprightPath
« Reply #1 - Posted 2012-07-26 22:53:46 »

Gridlines are going to have to be redrawn every time you move your mouse or do anything else. It's a fact of life.

The only way you can cut down on the amount of redrawing is to only redraw the lines that will appear on the screen. You can: Figure out the corners of your currently displayed map and only redraw the lines there. This shouldn't be too hard to actually manage to do.

Or, you can: Figure out where your mouse moved through (Where it messed up your art) and attempt to redraw only the damaged section. This is not really trvial though, so...

Offline tacticalPotato37

Senior Newbie





« Reply #2 - Posted 2012-07-26 23:55:05 »

Another thing I should mention is that the whole JPanel is inside a JScrollPane which allows it to fit any map size. I'm not sure but I think it calls repaint() every time you try to scroll, because it lags a lot when scrolling even when I don't make ANY calls to repaint() myself, however if I comment out the grid drawing in paintComponent(), there is no lag in scrolling.

Do you know if there is a feature in JScrollPane that will make it repaint only the visible area? Shouldn't it already do this?

Also it wouldn't be hard to have it so that every time a tile is added the 4 grid lines around it would be redrawn, but every time paintComponent is called it clears the existing picture, so everything has to be redrawn every time either way.

EDIT: JScrollPane calls MY paintComponent() method every time you scroll. I tested with a print statement.
Does that mean I have to manually get the coordinates of the scrolling viewPort and adjust my paint method to that? Angry
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline UprightPath
« Reply #3 - Posted 2012-07-27 00:21:15 »

I wasn't sure how you were doing it.

From what I understand (And I hope someone who knows for sure can back me up/correct me) the paint methods that swing us only actually paint what needs to be repainted (IE- Sent to whatever Graphics module handles the drawing of pixels to the screen). However, everything in the paint method will still get executed.

If you rewrote a paint method, or anything like that, everything there will still get executed (Which if you're telling it to draw 2000 lines every time you scroll on top of telling it to paint all of your images will still be a large amount of repainting.)

Offline loom_weaver

JGO Coder


Medals: 17



« Reply #4 - Posted 2012-07-27 00:23:34 »

If your tiles are slightly smaller than the square they occupy then you can get your grid lines for free.  Use a red background for red gridlines.
Offline tacticalPotato37

Senior Newbie





« Reply #5 - Posted 2012-07-27 00:43:15 »

the paint methods that swing us only actually paint what needs to be repainted (IE- Sent to whatever Graphics module handles the drawing of pixels to the screen)

Is there any way I could take advantage of this in my code though? I think that feature is used mainly for situations like when other windows are covering the one being painted.

I thought the only proper way to paint objects was to override paintComponent()?

@loom_weaver
maybe as a last resort but I like my pretty dotted lines over the tiles  Smiley
Offline UprightPath
« Reply #6 - Posted 2012-07-27 01:03:30 »

Sorry, none that I know of (Beyond what I said before about limiting how many things you tell to get drawn by checking the view port of your scroll pane). Swing isn't really made for things like that, heh.

Offline tacticalPotato37

Senior Newbie





« Reply #7 - Posted 2012-07-27 01:20:24 »

Ok, thanks for the help. I guess I'll go with trying to fit paint the viewport area.
Offline davedes
« Reply #8 - Posted 2012-07-27 01:45:36 »

Drawing several horizontal and vertical lines should be pretty fast... And you shouldn't run out of memory if you're trying to use a single 200x200 image. It sounds like your code is buggy or not optimal.

Offline UprightPath
« Reply #9 - Posted 2012-07-27 01:56:53 »

Well, it sounds like he's trying to draw (1000 / tileX) * (1000 / tileY) images using a Swing Panel to me. >.>

Which is probably buggy and not optimal. Cheesy

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline tacticalPotato37

Senior Newbie





« Reply #10 - Posted 2012-07-27 03:48:19 »

My tiles have 36 width so a 300x300 map is actually a 10800x10800 image. Well the OutOfMemory exception occurs when I try to create a BufferedImage to draw the lines on, not during the use of it, since apparently java can store that much in dynamic memory.

For example if I create a completely empty class and put this code in it, I get the same OutOfMemory exception.
1  
     BufferedImage i = new BufferedImage(36*400, 36*400, BufferedImage.TYPE_INT_ARGB);

BUT...I just discovered...the only reason it's so slow is because I'm using dotted lines. davedes you are right drawing lines is fast and i can make maps of 1000x1000 no problem with normal lines but if I make the lines dotted it lags at 50x50... Cry

right now I'm using this:
1  
2  
3  
4  
   float dash1[] = { 1.5f };
   BasicStroke dashed = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
       BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
   gg.setStroke(dashed);


Anybody know a better way to draw dotted lines??? I really like my dotted lines  Tongue
Offline UprightPath
« Reply #11 - Posted 2012-07-27 03:52:39 »

Question: Is your window size always going to be the same size? As in will the space that you're editing always have the same dimensions (You're not going to allow resizing or anything like that?)

Offline tacticalPotato37

Senior Newbie





« Reply #12 - Posted 2012-07-27 03:54:14 »

The size will change. The user can create a new map of any specified size. I figure whatever the world looks like it will consist of different sized maps.
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #13 - Posted 2012-07-27 09:53:19 »

The size will change. The user can create a new map of any specified size. I figure whatever the world looks like it will consist of different sized maps.
He was asking about the application itself, not your map size.

- Jonas
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #14 - Posted 2012-07-27 10:04:40 »

Anybody know a better way to draw dotted lines??? I really like my dotted lines  Tongue
Well, if you're using plain old g.drawLine, then yes. You can do it manually Smiley
There's an example here. You'll end up drawing a million lines of 1px each, but it'll work. The example is for a dashed line, but you can just make the line length 1 and the gap 1, and there you go.
See how that goes performance-wise.

I don't really see an easy way of doing it. There's no implementation other than the stroke. Stroke might even already be doing the exact same thing as the example does. CBA to look at BasicStroke javadoc, but maybe you should.

- Jonas
Offline tacticalPotato37

Senior Newbie





« Reply #15 - Posted 2012-07-27 19:10:53 »

So, turns out UprightPath is right and it's not that hard to find the visible area in the scroll pane and just paint according to that.  Grin
Here's the code I used:

1  
2  
3  
4  
      int viewX = (int)mScroll.getViewport().getViewPosition().getX()/Tile.width*Tile.width;
      int viewY = (int)mScroll.getViewport().getViewPosition().getY()/Tile.height*Tile.height;
      int viewX2 = (int)mScroll.getViewport().getExtentSize().getWidth()/Tile.width*Tile.width + viewX + tileBuffer * Tile.width;
      int viewY2 = (int)mScroll.getViewport().getExtentSize().getHeight()/Tile.height*Tile.width + viewY + tileBuffer * Tile.height;


Then I took Ultroman's advice and manually painted the dashed lines, which turned out to be faster than using the setStroke() swing method.

1  
2  
3  
4  
5  
6  
 for (int i = viewX; i <= viewX2; i += Tile.width)
   for(int j = viewY; j <= viewY2; j += dSize + dSpace)
     g2d.drawLine(i, j, i, j + dSize);
 for (int i = viewX; i <= viewX2; i += dSize + dSpace)
   for(int j = viewY; j <= viewY2; j += Tile.height)
     g2d.drawLine(i, j, i + dSize, j);


I just tested, and I can create a map of 3000x3000 and even fill it completely with tiles with absolutely no lag!!
Thanks for your help Grin
Offline BoBear2681

JGO Coder


Medals: 19



« Reply #16 - Posted 2012-07-27 21:22:59 »

Why not use Graphics.getClipBounds()?
Offline Ultroman

JGO Knight


Medals: 25
Projects: 1


Snappin' at snizzes since '83


« Reply #17 - Posted 2012-07-28 03:10:12 »

Cool Smiley

Happy to help

- Jonas
Online Riven
« League of Dukes »

JGO Overlord


Medals: 816
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #18 - Posted 2012-08-13 16:20:16 »

Draw your dotted line on a 1024x1 RGBA image, and draw that.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline StumpyStrust
« Reply #19 - Posted 2012-08-13 16:46:11 »

If you are using java2D then I would definitely go with riven on using an image. Java2D slows down the more draw calls you give it so anytime you can reduce the g.draw/fill it is a must.

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (43 views)
2014-10-16 15:22:06

Norakomi (33 views)
2014-10-16 15:20:20

lcass (37 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (66 views)
2014-10-14 00:35:47

TehJavaDev (59 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (86 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!