-
Notifications
You must be signed in to change notification settings - Fork 37
1f files
« 1e Functions | index | 1g Global Variables »
On this step we’ll split the code we have into several parts.
The complete source code of this step can be found here:
First, there’s the obvious motivation: we want main.lua
to be as clean as possible. By clean we mean that it should be a hub were the game starts, draws, and ends – but it should not delve on the specifics. Those should be moved to different files.
In order to do that, we can use Lua’s require
function:
-- main.lua
require 'map-functions'
function love.load()
... -- define tileString and quadInfo
loadMap(32,32,'countryside.png',tileString,quadInfo) -- loadMap is now in map-functions.lua
end
function love.draw()
drawMap() -- drawMap is also defined in map-functions.lua
end
Now that we’re starting getting more files, we should also move the images to a subfolder – We’ll call it images
. Our paths will have to be modified so the tileset is now loaded from there.
That is well and good. However, there’s a second problem what we should fix.
Right now our game is only able to load a single Map. Changing the map requires manually modifying the newly-created map-functions.lua
.
We have already paved the way for multiple-mapness. On the previous step, we separated the map-specific data from loadMap
and we put it inside love.load
.
On this section we’ll move each map’s specific data to its own file.
- Map data will be on a file inside the
/maps/
directory. -
loadMap
will take a single parameter: the path to the file that defines a map -
love.load
will look like this:
function love.load() loadMap('/maps/map1.lua')
- A new function, called
newMap
, will do whatloadMap
used to do. It will be called from inside the files inside the/map/
directory.
So the /maps/map1.lua
file, if it existed, should call newMap
with the right parameters at some point.
On this lesson we’ll abandon countriside.png and will use two new tilemaps.
Since we’ll start getting more and more files, I’ve decided to put the images inside an /images/
subfolder.
This will be the resto
tileset (/images/resto.png
)
And this will be the lab
tileset (/images/lab.png
)
I’ve also created a couple sample maps (one per tilemap). The first one is a small tavern, called “Chez Peter”. It will look like this:
The second example is a computer room called “Core Dump”.
On the sourcecode of this example, Chez Peter is loaded by default. This is the complete source of the new main.lua
:
require 'map-functions'
function love.load()
loadMap('maps/chez-peter.lua')
end
function love.draw()
drawMap()
end
Changing so it loads core dump would be as simple as modifying the line that says loadMap('maps/chez-peter.lua')
with loadMap('maps/core-dump.lua')
.
chez-peter.lua
is a lua file that simply invokes newMap
with the correct parameters:
-- file: /maps/chez-peter.lua
local tileString = [[
#########################
# # #
# L[]R L[]R # L[]R #
# L()R L()R # L()R #
# # #
# ### ###
# L[]R L[]R #
# L()R L()R L[]R #
# L()R #
# #
# L[]R L[]R #
# L()R L()R ### ###
# #LL RR#
# #LL RR#
# L[]R L[]R #LL RR#
# L()R L()R #LL RR#
# #LL RR#
#########################
]]
local quadInfo = {
{ ' ', 0, 0 }, -- floor
{ '[', 32, 0 }, -- table top left
{ ']', 64, 0 }, -- table top right
{ '(', 32, 32 }, -- table bottom left
{ ')', 64, 32 }, -- table bottom right
{ 'L', 0, 32 }, -- chair on the left
{ 'R', 96, 32 }, -- chair on the right
{ '#', 96, 0 } -- bricks
}
newMap(32,32,'/images/resto.png', tileString, quadInfo)
core-dump.lua
is very similar so I will not show it here.
The newMap
function is a line-by-line copy of the previous loadMap
function: it accepts some parameters and builds some global variables with them. It is defined inside map-functions.lua
now:
function newMap(tileW, tileH, tilesetPath, tileString, quadInfo)
TileW = tileW
TileH = tileH
Tileset = love.graphics.newImage(tilesetPath)
local tilesetW, tilesetH = Tileset:getWidth(), Tileset:getHeight()
Quads = {}
for _,info in ipairs(quadInfo) do
-- info[1] = the character, info[2] = x, info[3] = y
Quads[info[1]] = love.graphics.newQuad(info[2], info[3], TileW, TileH, tilesetW, tilesetH)
end
TileTable = {}
local width = #(tileString:match("[^\n]+"))
for x = 1,width,1 do TileTable[x] = {} end
local x,y = 1,1
for row in tileString:gmatch("[^\n]+") do
assert(#row == width, 'Map is not aligned: width of row ' .. tostring(y) .. ' should be ' .. tostring(width) .. ', but it is ' .. tostring(#row))
x = 1
for tile in row:gmatch(".") do
TileTable[x][y] = tile
x = x + 1
end
y=y+1
end
end
The loadMap
function has changed. It uses love.filesystem.load.
function loadMap(path)
love.filesystem.load(path)() -- attention! extra parenthesis
end
The only thing worth mentioning about this implementation is those parenthesis at the end.
If you read the love.filesystem.load documentation, it says it very clearly: that function does not “invoke” a lua file. It returns a “chunk”, which is like a function than, when executed, runs the code in the file. In a way, it similar to a function declaration. We could have re-written the code above like this:
function loadMap(path)
local f = love.filesystem.load(path) -- obtain a function
f() -- run a function
end
On this section we started using several folders and files in our project. We also separated map-specific code from code that could be used on any map. Finally, we made an extra function that allowed for super-clean map loading with very little code.
On our next function, we’ll finish cleaning up by removing unnecesary global variables.
- Make sure that you are able to load both maps: Chez Peter and Core Dump, by changing the path of the map loaded inside love.load.
- Experiment by modifying the layout of Chez Peter – move chairs around, remove one table, etc.
- Create your own map! You can use the tilesets on this step (lab.png or resto.png), the one used on previous steps (countryside.png) or a new one created by you.