42
43
-- This table's x and y properties shift member sprites' positions when drawn.
43
44
-- To draw sprites at their normal position, set both x and y to 0.
44
45
translate = { x = 0, y = 0 },
46
47
-- Property: translateScale
47
48
-- This table's x and y properties multiply member sprites'
48
49
-- positions, which you can use to simulate parallax scrolling. To draw
49
50
-- sprites at their normal position, set both x and y to 1.
50
51
translateScale = { x = 1, y = 1 },
53
-- an actual love.graphics.translate call
54
realTranslate = { x = 0, y = 0 },
57
-- Zooms in or out all drawing operations in the group, centering them with
58
-- respect to the <origin> property.
62
-- Distorts the group's scale, similar to <Sprite.distort>.
63
distort = { x = 1, y = 1 },
66
-- Sets the center point for all scaling operations.
67
origin = { x = 0, y = 0 },
53
70
-- Adds a sprite to the group.
334
loadLayers = function (self, file, tileClass)
335
local ok, data = pcall(loadstring(Cached:text(file)))
336
local _, _, directory = string.find(file, '^(.*[/\\])')
337
directory = directory or ''
340
-- store tile properties by gid
342
local tileProtos = {}
344
for _, tileset in pairs(data.tilesets) do
345
for _, tile in pairs(tileset.tiles) do
346
local id = tileset.firstgid + tile.id
348
for key, value in pairs(tile.properties) do
349
tile.properties[key] = tovalue(value)
352
tileProtos[id] = tile
353
tileProtos[id].width = tileset.tilewidth
354
tileProtos[id].height = tileset.tileheight
358
for _, layer in pairs(data.layers) do
359
if self.prototype[layer.name] then
360
error('The class you are loading layers into reserves the ' .. layer.name .. ' property for its own use; you cannot load a layer with that name')
363
if STRICT and self[layer.name] then
364
local info = debug.getinfo(2, 'Sl')
365
print('Warning: a property named ' .. layer.name .. ' already exists in this group (' ..
366
info.short_src .. ', line ' .. info.currentline .. ')')
369
if layer.type == 'tilelayer' then
370
local map = Map:new{ spriteWidth = data.tilewidth, spriteHeight = data.tileheight }
371
map:empty(layer.width, layer.height)
375
for _, tiles in pairs(data.tilesets) do
376
map:loadTiles(directory .. tiles.image, tileClass or Tile, tiles.firstgid)
378
-- and mix in properties where applicable
380
for id, tile in pairs(tileProtos) do
381
if map.sprites[id] then
382
map.sprites[id]:mixin(tile.properties)
392
for _, val in ipairs(layer.data) do
396
if x > layer.width then
402
self[layer.name] = map
404
elseif layer.type == 'objectgroup' then
405
local group = Group:new()
407
for _, obj in pairs(layer.objects) do
408
-- roll in tile properties if based on a tile
410
if obj.gid and tileProtos[obj.gid] then
411
local tile = tileProtos[obj.gid]
413
obj.name = tile.properties.name
414
obj.width = tile.width
415
obj.height = tile.height
417
for key, value in pairs(tile.properties) do
418
obj.properties[key] = tovalue(value)
421
-- Tiled tile-based objects measure their y
422
-- position at their lower-left corner, instead
423
-- of their upper-left corner as usual
425
obj.y = obj.y - obj.height
428
-- create a new object if the class does exist
433
obj.properties.x = obj.x
434
obj.properties.y = obj.y
435
obj.properties.width = obj.width
436
obj.properties.height = obj.height
438
spr = _G[obj.name]:new(obj.properties)
440
spr = Fill:new{ x = obj.x, y = obj.y, width = obj.width, height = obj.height, fill = { 128, 128, 128 } }
443
if obj.properties._the then
444
the[obj.properties._the] = spr
450
self[layer.name] = group
453
error("don't know how to create a " .. layer.type .. " layer from file data")
457
error('could not load layers from file: ' .. data)
366
loadLayers = function (self, file, tileClass)
367
local ok, data = pcall(loadstring(Cached:text(file)))
368
local _, _, directory = string.find(file, '^(.*[/\\])')
369
directory = directory or ''
372
-- store tile properties by gid
374
local tileProtos = {}
376
for _, tileset in pairs(data.tilesets) do
377
for _, tile in pairs(tileset.tiles) do
378
local id = tileset.firstgid + tile.id
380
for key, value in pairs(tile.properties) do
381
tile.properties[key] = tovalue(value)
384
tileProtos[id] = tile
385
tileProtos[id].width = tileset.tilewidth
386
tileProtos[id].height = tileset.tileheight
390
for _, layer in pairs(data.layers) do
391
if self.prototype[layer.name] then
392
error('The class you are loading layers into reserves the ' .. layer.name .. ' property for its own use; you cannot load a layer with that name')
395
if STRICT and self[layer.name] then
396
local info = debug.getinfo(2, 'Sl')
397
print('Warning: a property named ' .. layer.name .. ' already exists in this group (' ..
398
info.short_src .. ', line ' .. info.currentline .. ')')
401
if layer.type == 'tilelayer' then
402
local map = Map:new{ spriteWidth = data.tilewidth, spriteHeight = data.tileheight }
403
map:empty(layer.width, layer.height)
407
for _, tiles in pairs(data.tilesets) do
408
map:loadTiles(directory .. tiles.image, tileClass or Tile, tiles.firstgid)
410
-- and mix in properties where applicable
412
for id, tile in pairs(tileProtos) do
413
if map.sprites[id] then
414
map.sprites[id]:mixin(tile.properties)
424
for _, val in ipairs(layer.data) do
428
if x > layer.width then
434
self[layer.name] = map
436
elseif layer.type == 'objectgroup' then
437
local group = Group:new()
439
for _, obj in pairs(layer.objects) do
440
-- roll in tile properties if based on a tile
442
if obj.gid and tileProtos[obj.gid] then
443
local tile = tileProtos[obj.gid]
445
obj.name = tile.properties.name
446
obj.width = tile.width
447
obj.height = tile.height
449
for key, value in pairs(tile.properties) do
450
obj.properties[key] = tovalue(value)
453
-- Tiled tile-based objects measure their y
454
-- position at their lower-left corner, instead
455
-- of their upper-left corner as usual
457
obj.y = obj.y - obj.height
460
-- create a new object if the class does exist
465
obj.properties.x = obj.x
466
obj.properties.y = obj.y
467
obj.properties.width = obj.width
468
obj.properties.height = obj.height
470
spr = _G[obj.name]:new(obj.properties)
472
spr = Fill:new{ x = obj.x, y = obj.y, width = obj.width, height = obj.height, fill = { 128, 128, 128 } }
475
if obj.properties._the then
476
the[obj.properties._the] = spr
482
self[layer.name] = group
485
error("don't know how to create a " .. layer.type .. " layer from file data")
489
error('could not load layers from file: ' .. data)
461
494
-- passes startFrame events to member sprites
463
496
startFrame = function (self, elapsed)
464
497
if not self.active then return end
465
498
elapsed = elapsed * self.timeScale
467
for _, spr in pairs(self.sprites) do
500
for _, spr in self:members() do
468
501
if spr.active then spr:startFrame(elapsed) end