Tile-based tutorials

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Tile-based tutorials

Post by kikito »

Ryne wrote:Started recreating my game with the tutorial today. I'll put it to the test and let you know If I have trouble with anything!
Sure, go ahead. Let me know about any rough spots, I'll be glad to help.

Part 1 is nearly done (I've to change some code, and finish up the docs of the last two sections). I'm planning to start with the second part ("entities") pretty soon.
When I write def I mean function.
User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

Re: Tile-based tutorials

Post by Ryne »

kikito wrote:
Ryne wrote:Started recreating my game with the tutorial today. I'll put it to the test and let you know If I have trouble with anything!
Sure, go ahead. Let me know about any rough spots, I'll be glad to help.

Part 1 is nearly done (I've to change some code, and finish up the docs of the last two sections). I'm planning to start with the second part ("entities") pretty soon.
Everything is going great so far but I wish this one part was explained more. Even though you explain nested loops (which is perfect), this, to me, seems like a complicated nested loop.

Code: Select all

function love.draw()
  for y=1, #TileTable do
    local row = TileTable[y]
    for x=1, #row do
      local number = row[x]
      love.graphics.drawq(Tileset, Quads[number], (x-1)*TileW, (y-1)*TileH)
    end
  end
end
You go into "some" explanation though not as in-depth as the rest of the tutorial.

Are you using x/y here for a specific reason? When I think of x/y, I think of coordinates, so this kind of confuses me and makes me think that it's not the same as the previously explained loop code. Also, why are local row and local number there? What purpose do they serve?
@rynesaur
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Tile-based tutorials

Post by Robin »

Ryne wrote:Are you using x/y here for a specific reason? When I think of x/y, I think of coordinates, so this kind of confuses me and makes me think that it's not the same as the previously explained loop code.
They are coordinates, or at least screen coordinates are derived from them:

Code: Select all

love.graphics.drawq(Tileset, Quads[number], (x-1)*TileW, (y-1)*TileH)
That draws a tile from the tileset at ((x-1)*TileW, (y-1)*TileH)
Ryne wrote:Also, why are local row and local number there? What purpose do they serve?
row is a convenience variable that just holds the current row. number has a lousy name, but it is the cell in row y at column x. To be specific, is specifies which tile to use.

This should probably all be explained there.
Help us help you: attach a .love.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Tile-based tutorials

Post by kikito »

You are right. I should have explained that loop a bit better.

And probably modify a bit the variable names.

Let me see.

The easiest way to understand the double loops there is by having a look at TileTable

Code: Select all

TileTable = {
  { 1,1,1 },
  { 1,2,1 },
  { 1,1,1 }
}
Let's say that the 1s represent grass and the 2s represent a box. Then we need something that eventually tells us "here goes grass" and "here goes a box".
The easiest way is by making two loops, one inside the other.

The first loop (or "external" loop) is used to set up a variable called "row". It will contain different rows of TileTable. For example, with a TileTable like the one above, row will have the value {1,1,1} on the first iteration, {1,2,1} on the second and {1,1,1} again on the third (and last). That is the same as doing TileTable[1], TileTable[2], and TileTable[3]. That [1],[2],[3] is currently managed by the "y" variable - I should have named it rowIndex or something similar.

But we still don't have something that tells us "grass goes here". What we have with "row" is a "list" of several horizontal tiles. We need individual ones. So, we need to do more stuff with row.

Row will be {1,1,1}, then {1,2,1} and then {1,1,1}. We can do stuff with it before it changes its value.

Code: Select all

{1,1,1} do stuff here {1,2,1} do stuff here {1,1,1} do stuff here
The "stuff" we do is using an internal loop to go over it. This way, we for example, when row is {1,2,1}, we want something that is 1 on a first iteration, 2 on the second and 1 on the third. That's the "number" variable. At this point, we finally have something that, iteratively, tells us "this is grass" or "this is a box". It's called "number" because it holds "the number that represents a tile in a row". I can't think of a better name for it - I'm open to suggestions.

The 1,2,1 values of number can be obtained by doing row[1], row[2] and row[3]. That "1,2,3" is controlled by the "x" variable. I should rename it to something else, so people don't get confused with "coordinates". But I don't know what.

So, we have something that tells us "grass", "grass", "box", etc. The only thing missing is the "here" of "grass goes here". That is a simple calculation that can be done with "x" and "y" (names will be changed).

Let me know if this explanation is good enough.
When I write def I mean function.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Tile-based tutorials

Post by Robin »

kikito wrote:That "1,2,3" is controlled by the "x" variable. I should rename it to something else, so people don't get confused with "coordinates". But I don't know what.
Perhaps naming y and x row_index and column_index respectively?
Help us help you: attach a .love.
User avatar
Ryne
Party member
Posts: 444
Joined: Fri Jan 29, 2010 11:10 am

Re: Tile-based tutorials

Post by Ryne »

Alright, That makes a lot more sense now. :), thanks for the explanation!
@rynesaur
User avatar
Raylin
Prole
Posts: 30
Joined: Thu Dec 30, 2010 8:48 am
Location: Chicago
Contact:

Re: Tile-based tutorials

Post by Raylin »

I was playing around with your tutorial and I found that my game redraws the map every cycle.
Major slowdowns ensued.

Any way to make it draw when a change occurs or something?
User avatar
tentus
Inner party member
Posts: 1060
Joined: Sun Oct 31, 2010 7:56 pm
Location: Appalachia
Contact:

Re: Tile-based tutorials

Post by tentus »

love.draw() happens every frame, yes. That's just how rendering works: every frame gets rendered. Trying to cache the map would be a tremendous amount of code for negligible (or possibly negative) benefit.
Kurosuke needs beta testers
User avatar
TechnoCat
Inner party member
Posts: 1611
Joined: Thu Jul 30, 2009 12:31 am
Location: Milwaukee, WI
Contact:

Re: Tile-based tutorials

Post by TechnoCat »

You can modify love.run to stop it from clearing and drawing every frame (love.graphics.clear and love.graphics.present). But, this is not what you want to do most likely.

http://love2d.org/wiki/love.run
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: Tile-based tutorials

Post by kikito »

Update!
  • I've updated step 1b with an explanation of the loop used for drawing, similar to the one above.
  • I've renamed some variables - from x,y to columnIndex, rowIndex, mostly
  • I've updated the code on steps 1a to 1f, as well as added the documentation on 1f.
The only thing missing regarding tile loading and drawing is step 1e, which consists on removing some unnecessary global variables. I'm pretty confident I'll able to have its code reviewed and documented tomorrow.
Raylin wrote:I was playing around with your tutorial and I found that my game redraws the map every cycle.
Major slowdowns ensued.

Any way to make it draw when a change occurs or something?
If major slowdowns ensued, it is possible that you are doing something wrong. A common mistake, for example, is loading up stuff (images or quads) again and again on the love.draw function, instead of loading them just once inside love.load. Another common one is using love.setFont with a number parameter. This creates one new font object on each frame, which rapidly eats up all available memory.

If you still need help, please open a new thread on the support forum, including your current code. I'll be glad to give it a look.
When I write def I mean function.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest