73
-- Loads layers from a Lua source file (as generated by Tiled -- http://mapeditor.org).
74
-- Each layer is created as a <Group> and added to preserve its ordering. Tile layers
75
-- are created as <Map> instances; object layers will try to create instances of a class
76
-- named by the object's name property. If no class exists by this name, or the object
77
-- has no name property, a gray fill will be created instead, as a placeholder. If the
78
-- object has a property named _the, then this will set the.[whatever] to it.
81
-- file - filename to load
86
loadLayers = function (self, file)
87
local ok, data = pcall(loadstring(Cached:text(file)))
88
local _, _, directory = string.find(file, '^(.*[/\\])')
89
directory = directory or ''
92
-- store tile properties by gid
96
for _, tileset in pairs(data.tilesets) do
97
for _, tile in pairs(tileset.tiles) do
98
local id = tileset.firstgid + tile.id
100
for key, value in pairs(tile.properties) do
101
tile.properties[key] = tovalue(value)
104
tileProtos[id] = tile
105
tileProtos[id].width = tileset.tilewidth
106
tileProtos[id].height = tileset.tileheight
110
for _, layer in pairs(data.layers) do
111
if View[layer.name] then
112
error('the View class reserves the ' .. layer.name .. ' property for its own use; you cannot load a layer with that name')
115
if STRICT and self[layer.name] then
116
local info = debug.getinfo(2, 'Sl')
117
print('Warning: a property named ' .. layer.name .. ' already exists in the current view (' ..
118
info.short_src .. ', line ' .. info.currentline .. ')')
121
if layer.type == 'tilelayer' then
122
local map = Map:new{ spriteWidth = data.tilewidth, spriteHeight = data.tileheight }
123
map:empty(layer.width, layer.height)
127
for _, tiles in pairs(data.tilesets) do
128
map:loadTiles(directory .. tiles.image, Tile, tiles.firstgid)
130
-- and mix in properties where applicable
132
for id, tile in pairs(tileProtos) do
133
if map.sprites[id] then
134
map.sprites[id]:mixin(tile.properties)
144
for _, val in ipairs(layer.data) do
148
if x > layer.width then
154
self[layer.name] = map
156
elseif layer.type == 'objectgroup' then
157
local group = Group:new()
159
for _, obj in pairs(layer.objects) do
160
-- roll in tile properties if based on a tile
162
if obj.gid and tileProtos[obj.gid] then
163
local tile = tileProtos[obj.gid]
165
obj.name = tile.properties.name
166
obj.width = tile.width
167
obj.height = tile.height
169
for key, value in pairs(tile.properties) do
170
obj.properties[key] = tovalue(value)
173
-- Tiled tile-based objects measure their y
174
-- position at their lower-left corner, instead
175
-- of their upper-left corner as usual
177
obj.y = obj.y - obj.height
180
-- create a new object if the class does exist
185
obj.properties.x = obj.x
186
obj.properties.y = obj.y
187
obj.properties.width = obj.width
188
obj.properties.height = obj.height
190
spr = _G[obj.name]:new(obj.properties)
192
spr = Fill:new{ x = obj.x, y = obj.y, width = obj.width, height = obj.height, fill = { 128, 128, 128 } }
195
if obj.properties._the then
196
the[obj.properties._the] = spr
202
self[layer.name] = group
205
error("don't know how to create a " .. layer.type .. " layer from file data")
209
error('could not load view data from file: ' .. data)
73
213
-- Method: clampTo
74
214
-- Clamps the view so that it never scrolls past a sprite's boundaries.
75
215
-- This only looks at the sprite's position at this instant in time,