Page 1 of 1

Load map from required LUA file.

Posted: Mon Jan 21, 2013 10:27 pm
by AveryRE
So I've been following the grid-locked player tutorial, and it teaches how to create a map within main.lua, like so:

Code: Select all

	
function love.load()

-- Define the map used.
    map = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    }
end
However, to keep it clean I would like to have the maps stored in other, required lua files. So for example I have:

Code: Select all


require("maps/dungeon1");

function love.load()
      map = level_map
end
Where "level_map" would be the table within the dungeon1.lua file. But when I pass that along to the draw stage:

Code: Select all

function love.draw()

	-- Render the map.
	for y=1, #map do
        for x=1, #map[y] do
		-- Check space and render suitable tile.
            if map[y][x] == 1 then
                love.graphics.draw(tile_brick, x * 32, y * 32)
            end
            if map[y][x] == 0 then
                love.graphics.draw(tile_cobble, x * 32, y * 32)
            end
        end
    end

end
I get that the value is nil, how would I go about doing this?

Thanks!
Avery

Re: Load map from required LUA file.

Posted: Mon Jan 21, 2013 11:33 pm
by rexjericho
Here's one way that you can do this:

in file maps.lua:

Code: Select all

  -- this function is for loading all your maps into accessible variables
  function load_maps()
      level1_map = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    }
    
    level2_map = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    }
    
    level3_map = {
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    }
end
And you can access these maps in your main.lua like this:

Code: Select all

require 'maps'

function love.load()
  load_maps()
  map = level1_map
end

function love.draw()

   -- Render the map.
   for y=1, #map do
        for x=1, #map[y] do
      -- Check space and render suitable tile.
            if map[y][x] == 1 then
                love.graphics.setColor(255,255,255,255)
                love.graphics.rectangle('fill', x * 32, y * 32, 32, 32)
            end
            if map[y][x] == 0 then
                love.graphics.setColor(255,255,255,170)
                love.graphics.rectangle('fill', x * 32, y * 32, 32, 32)
            end
        end
    end

end
Attached is a .love of the above code.

Re: Load map from required LUA file.

Posted: Mon Jan 21, 2013 11:55 pm
by AveryRE
Thanks! Works perfectly!

Re: Load map from required LUA file.

Posted: Tue Jan 22, 2013 12:02 am
by xXxMoNkEyMaNxXx
You could also do:

Code: Select all

--Maps.lua
map1={
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
}
map2={
{0,1,0,11,1,1,1,01,01,0,1,0010,}
}

Code: Select all

maps=require'Maps'
maps.map1
maps.map2

Re: Load map from required LUA file.

Posted: Tue Jan 22, 2013 4:59 am
by Jasoco
I don't like to require maps. Since maps can change from time to time. It's better to do this:

Code: Select all

--Level file
return {
    name = "The name of this level if you need it",
    map = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    },
    other_data = {
        --Miscellaneous Stuff
    }
}
To load a level file's contents into a temporary blueprint table:

Code: Select all

local tmpLevel = love.filesystem.load(levelFile)()
NOTE: The extra () at the end

This will place all the level files table data into the local tmpLevel table. You then deal with it piece by piece building the level from this "blueprint". For instance, turn the map grid into a global game map grid. Take the other_data you might have like item placements, enemy placements, etc and create those items and enemies. Since all the data gets dumped right onto the tmpLevel variable. So for instance, tmpLevel.name will be what was returned as name from the file. In this case it was the string "The name of this level if you need it". So you'll want to dump this tmpLevel.name into a more permanent place since tmpLevel will be deleted when you leave the loadLevel function.

The benefit to this is that you won't be loading all the levels into memory at once. Instead only loading one at a time and replacing the previous one in memory.

Re: Load map from required LUA file.

Posted: Thu Jan 24, 2013 5:11 pm
by I~=Spam
Jasoco wrote:I don't like to require maps. Since maps can change from time to time. It's better to do this:

Code: Select all

--Level file
return {
    name = "The name of this level if you need it",
    map = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
    },
    other_data = {
        --Miscellaneous Stuff
    }
}
To load a level file's contents into a temporary blueprint table:

Code: Select all

local tmpLevel = love.filesystem.load(levelFile)()
NOTE: The extra () at the end

This will place all the level files table data into the local tmpLevel table. You then deal with it piece by piece building the level from this "blueprint". For instance, turn the map grid into a global game map grid. Take the other_data you might have like item placements, enemy placements, etc and create those items and enemies. Since all the data gets dumped right onto the tmpLevel variable. So for instance, tmpLevel.name will be what was returned as name from the file. In this case it was the string "The name of this level if you need it". So you'll want to dump this tmpLevel.name into a more permanent place since tmpLevel will be deleted when you leave the loadLevel function.

The benefit to this is that you won't be loading all the levels into memory at once. Instead only loading one at a time and replacing the previous one in memory.
That's exactly how I do it! :awesome:

Re: Load map from required LUA file.

Posted: Thu Jan 24, 2013 7:07 pm
by Jasoco
I~=Spam wrote:That's exactly how I do it! :awesome:
I've seen a lot of peoples projects where they require every map one at a time into memory right from the start. Not a good idea. Much better to only load things when they're needed. Keeps memory usage lower and free for more stuff.

If you use love.filesystem.load you can just "return" all the required level data as a table which will then delete itself from memory only leaving you with the copied data which you can then do with as you wish. Or you can set globals in the file as well but it's better to do it the other way. Tables are awesome.