Is this a good way to draw a grid based map?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
feelixe
Prole
Posts: 36
Joined: Tue Aug 20, 2013 10:29 am

Is this a good way to draw a grid based map?

Post by feelixe »

Hello:) I have a game with gridbased map and I'm wondering if my technique of drawing the map is a decent way of doing it and i have a question if that's the case.

So. I have my grid map and i have coordinations(x,y,x2,y2) of the player + screenwidth + (a border). That kind of creates two rectangles. When you step outside the inner rectangle(player + screenwidth) it resets to the middle of the player.
I use the outer rectangle that i get above and draw the grid map within those coordinats to a canvas. I then draw the canvas.

So is this ok? Or is there a technique that's better for the performance.

If so : I wonder how i would handle map updates, say you change a tile, then i would have to refresh the canvas. Is that heavy work for the computer?

Thanks in advance :cool:
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Is this a good way to draw a grid based map?

Post by Jasoco »

Grids in Lua:

Code: Select all

gridWidth = 50
gridHeight = 30
myGrid = {}
for x = 1, gridWidth do
    myGrid[x] = {}
    for y = 1, gridHeight do
        myGrid[x][y] = {some table or other data, whatever you want each cell to contain}
    end
end
Then in order to access a cell's contents, you'd just ask for myGrid[x][y].whatever or whatever.

That is how you make a grid. Nested tables.
feelixe
Prole
Posts: 36
Joined: Tue Aug 20, 2013 10:29 am

Re: Is this a good way to draw a grid based map?

Post by feelixe »

Jasoco wrote:Grids in Lua:

Code: Select all

gridWidth = 50
gridHeight = 30
myGrid = {}
for x = 1, gridWidth do
    myGrid[x] = {}
    for y = 1, gridHeight do
        myGrid[x][y] = {some table or other data, whatever you want each cell to contain}
    end
end
Then in order to access a cell's contents, you'd just ask for myGrid[x][y].whatever or whatever.

That is how you make a grid. Nested tables.
Yea, that's how I do it. But doesn't the game run slow if i go through the whole grid with a nested for-loop in the .draw function (and the map is bigger than just a few blocks)
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Is this a good way to draw a grid based map?

Post by micha »

feelixe wrote:But doesn't the game run slow if i go through the whole grid with a nested for-loop in the .draw function (and the map is bigger than just a few blocks)
Yes, it will. For drawing a large number of tiles, use a spritebatch.

As a rule of thumb, you should try to minimize the number of love.graphics.draw-calls. With a spritebatch you can draw the whole map by calling draw only once.

Edit: Have a look at the tutorial section in the wiki. Fast drawing of maps is covered in Efficient Tile-based scrolling.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Is this a good way to draw a grid based map?

Post by Jasoco »

You can use a camera system that figures out which tiles are on screen and only loop through those. It's slightly more complicated, but easy if you think about it.

Basically you'd take your camera X/Y divided by your tile size (Also taking any zoom factor into account) and figure out which tiles are on the screen, set the lower X/Y and upper X/Y and only draw/update within those bounds. (Make sure to math.floor any calculations)
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Is this a good way to draw a grid based map?

Post by micha »

Jasoco wrote:You can use a camera system that figures out which tiles are on screen and only loop through those.
I did it this way, too, some time ago. But then I wondered: Is checking the coordinates in Lua really faster than drawing a tile offscreen? I guess at least when all data is at the GPU, it will figure that the tile is offscreen and then not draw it.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Is this a good way to draw a grid based map?

Post by kikito »

micha wrote:Is checking the coordinates in Lua really faster than drawing a tile offscreen?
No, that's probably slower (it would depend on the complexity of drawing an individual cell though - imagine things like animated cells etc).

But that is not what Jasoko is talking about. He's talking about a map system is able to "draw the tiles that touch a rectangular zone, and ignore the rest".

When you have a 2-d tilemap, this is very easy to do. Here's how you draw all the cells in the map:

Code: Select all

function drawMap(map)
  for x=1, #map.columns do
    for y=1, #map.columns[x] do
      drawTile(map, x,y)
    end
  end
end
And here's how you draw just a rectangular zone of that map (in this case specified by the coordinates left, right, top, bottom):

Code: Select all

function drawMapRectangularZone(map, left, right, top, bottom)
  for x=left, right do
    for y=top, bottom do
      drawTile(map, x,y)
    end
  end
end
Notice how the cells outside of the designated rectangular zone are literally ignored; there's not even an "if" for them.

The screen is an axis-aligned rectangle. (Even when it's "rotated and zoomed out" over your map, it's can still be conscripted to an axis-aligned rectangle using its max & min x & y coords). If you use that rectangle with drawMapRectangularZone, that's way faster than drawing the whole map and leaving the card deal with the off-screen things.

If you are interested in seeing this in action, the gamera demo uses this technique (only the rectangles that "touch the screen" - well, the camera's "visible rectangle" are drawn). Here's the relevant function: https://github.com/kikito/gamera/blob/demo/main.lua#L19
When I write def I mean function.
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Is this a good way to draw a grid based map?

Post by micha »

This is indeed a neat trick.

Now I am wondering, could I benefit from this trick, if I draw my map with a spriteBatch? I could empty the batch each frame and refill it, using only the visible tiles. That takes time, too. So that must depend on the size ratio of the whole map to the visible part.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Is this a good way to draw a grid based map?

Post by bartbes »

If you clear and refill your spritebatch for every draw call, you're probably losing any gains from it.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Is this a good way to draw a grid based map?

Post by davisdude »

Just a question about the following code.
kikito wrote:

Code: Select all

function drawMapRectangularZone(map, left, right, top, bottom)
  for x=left, right do
    for y=top, bottom do
      drawTile(map, x,y)
    end
  end
end
Say for instance, you have non-tile-based-movement. How then would it be implemented? I guess you would check if the screen is covering the tile at all, then draw it, right? But then that would require you to loop through the tables, wouldn't it?
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot], whateverest and 4 guests