Difference between revisions of "Tiled Map Editor"

From GiderosMobile
m (Text replacement - "<source" to "<syntaxhighlight")
Line 11: Line 11:
 
'''note:''' '''world''' is used for Box2D ('''LiquidFun''') or '''CBUMP''' but you can remove it and adapt to your needs
 
'''note:''' '''world''' is used for Box2D ('''LiquidFun''') or '''CBUMP''' but you can remove it and adapt to your needs
  
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
LevelX = Core.class(Sprite)
 
LevelX = Core.class(Sprite)
  
Line 31: Line 31:
 
'''note2:''' those are placeholder names ('''bg''' = background layer, '''mg''' = middle ground layer...) adapt to your needs
 
'''note2:''' those are placeholder names ('''bg''' = background layer, '''mg''' = middle ground layer...) adapt to your needs
  
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
Tiled_Levels = Core.class(Sprite)
 
Tiled_Levels = Core.class(Sprite)
  
Line 143: Line 143:
  
 
=== '''RECTANGLES''' ===
 
=== '''RECTANGLES''' ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
Tiled_Shape_Rectangle = Core.class(Sprite)
 
Tiled_Shape_Rectangle = Core.class(Sprite)
  
Line 281: Line 281:
  
 
=== '''POLYGONS''' ===
 
=== '''POLYGONS''' ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
Tiled_Shape_Polygon = Core.class(Sprite)
 
Tiled_Shape_Polygon = Core.class(Sprite)
  
Line 451: Line 451:
  
 
=== '''ELLIPSES''' ===
 
=== '''ELLIPSES''' ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
Tiled_Shape_Ellipse = Core.class(Sprite)
 
Tiled_Shape_Ellipse = Core.class(Sprite)
  
Line 654: Line 654:
  
 
=== '''Our Level''' ===
 
=== '''Our Level''' ===
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
LevelX = Core.class(Sprite)
 
LevelX = Core.class(Sprite)
  
Line 683: Line 683:
 
=== '''IMAGES''' ===
 
=== '''IMAGES''' ===
 
Here is the class to import images from Tiled and draw them in your game.
 
Here is the class to import images from Tiled and draw them in your game.
<source lang="lua">
+
<syntaxhighlight lang="lua">
 
Tiled_Levels = Core.class(Sprite)
 
Tiled_Levels = Core.class(Sprite)
  

Revision as of 15:31, 13 July 2023

Description

On this page you will find various classes to help using Tiled Map Editor in Gideros. Enjoy :-)

note: you may have to provide your own assets (fonts, gfx, …)

Tiled Map Editor

LOAD YOUR MAP

Here is a class to load your Tiled map in Gideros.

note: world is used for Box2D (LiquidFun) or CBUMP but you can remove it and adapt to your needs

<syntaxhighlight lang="lua"> LevelX = Core.class(Sprite)

function LevelX:init() application:setBackgroundColor(0x0) -- the tiled world self.tiled_level = Tiled_Levels.new(self.world, "tiled/levels/level01.lua") self:addChild(self.tiled_level) end </source>

Below is the Tiled_Levels class.

BUILD YOUR MAP

Here is the class to import the levels your created in Tiled and draw them in Gideros using the RECTANGLES, POLYGONS, ELLIPSES classes you will find further below on this page.

note: don't forget to exclude from execution your level lua file (right click -> exclude from execution)

note2: those are placeholder names (bg = background layer, mg = middle ground layer...) adapt to your needs

<syntaxhighlight lang="lua"> Tiled_Levels = Core.class(Sprite)

function Tiled_Levels:init(xworld, xtiledlevelpath) self.world = xworld self.camera = Sprite.new() self.bg = Sprite.new() -- bg deco self.mg = Sprite.new() -- mg level + sensors self.fg = Sprite.new() -- fg deco self.camera:addChild(self.bg) self.camera:addChild(self.mg) self.camera:addChild(self.fg) self:addChild(self.camera) -- load the tiled level local tiledlevel = loadfile(xtiledlevelpath)() -- the tiled map size local mapwidth, mapheight = tiledlevel.width * tiledlevel.tilewidth, tiledlevel.height * tiledlevel.tileheight print("map size "..mapwidth..", "..mapheight, "app size "..myappwidth..", "..myappheight, "all in pixels.") -- parse the tiled level local layers = tiledlevel.layers local myshape -- shapes from Tiled local mytable -- intermediate table for shapes params for i = 1, #layers do local layer = layers[i] -- ************* -- MG GAME LAYER -- ************* if layer.name == "mg" then -- your Tiled layer name here! local levelsetup = {} local objects = layer.objects for i = 1, #objects do local object = objects[i] local objectName = object.name myshape, mytable = nil, nil -- *************** -- SHAPES -- *************** if objectName == "groundA" then mytable = {color=0x00ff00, isshape=true} else mytable = {color=0xff0000, isshape=true} end levelsetup = {} for k, v in pairs(mytable) do levelsetup[k] = v end self:buildShapes(layer.name, object, levelsetup) -- *************** -- OBJECTS (players, npc, nmes...) -- *************** if objectName == "player1" then self.world.player = LF_Dynamic_Player.new( self.world, "gfx/playable/caverman.png", "player", 6, 7, 1, 1, nil, nil, 0, -5, 1, 0, 1, G_BITPLAYER, playercollisions, G_PLAYER) self.world.player.body:setPosition(object.x, object.y) -- position the body, the bitmap will follow in enterframe self.mg:addChild(self.world.player) end end -- ************* -- WHAT?! -- ************* else print("WHAT?!", layer.name) end end end

function Tiled_Levels:buildShapes(xlayer, xobject, xlevelsetup) local myshape = nil local tablebase = {} if xobject.shape == "ellipse" then tablebase = { x = xobject.x, y = xobject.y, w = xobject.width, h = xobject.height, rotation = xobject.rotation, } for k, v in pairs(xlevelsetup) do tablebase[k] = v end myshape = Tiled_Shape_Ellipse.new(self.world, tablebase) elseif xobject.shape == "polygon" then tablebase = { x = xobject.x, y = xobject.y, coords = xobject.polygon, rotation = xobject.rotation, } for k, v in pairs(xlevelsetup) do tablebase[k] = v end myshape = Tiled_Shape_Polygon.new(self.world, tablebase) elseif xobject.shape == "rectangle" then tablebase = { x = xobject.x, y = xobject.y, w = xobject.width, h = xobject.height, rotation = xobject.rotation, } for k, v in pairs(xlevelsetup) do tablebase[k] = v end myshape = Tiled_Shape_Rectangle.new(self.world, tablebase) else print("*** CANNOT PROCESS THIS SHAPE! ***", xobject.shape, xobject.name) return end myshape:setPosition(xobject.x, xobject.y) if xlayer == "bg" then -- your Tiled layer name here self.bg:addChild(myshape) else -- mg = player layer + sensors layer... self.mg:addChild(myshape) end end </source>

Tiled Map Editor: OBJECT LAYER

Here are the classes to import the shapes your created in Tiled and draw them in Gideros.

note: don't forget to export your Tiled map to a lua file and exclude it from execution (in Gideros Studio)

RECTANGLES

<syntaxhighlight lang="lua"> Tiled_Shape_Rectangle = Core.class(Sprite)

function Tiled_Shape_Rectangle:init(xworld, xparams) -- params local params = xparams or {} params.x = xparams.x or nil params.y = xparams.y or nil params.w = xparams.w or 32 params.h = xparams.h or 32 params.color = xparams.color or nil params.alpha = xparams.alpha or 1 params.tex = xparams.tex or nil params.isdeco = xparams.isdeco or nil params.isshape = xparams.isshape or nil params.isbmp = xparams.isbmp or nil params.ispixel = xparams.ispixel or nil params.scalex = xparams.scalex or 1 params.scaley = xparams.scaley or params.scalex params.rotation = xparams.rotation or 0 params.type = xparams.type or nil -- default = b2.STATIC_BODY params.fixedrotation = xparams.fixedrotation or nil params.density = xparams.density or nil params.restitution = xparams.restitution or nil params.friction = xparams.friction or nil params.issensor = xparams.issensor or nil params.gravityscale = xparams.gravityscale or 1 params.BIT = xparams.BIT or nil params.COLBIT = xparams.COLBIT or nil params.NAME = xparams.NAME or nil params.addenterframe = xparams.addenterframe or nil -- image if params.issensor then -- no image for sensors else if params.isshape then self.img = Shape.new() self.img:setLineStyle(4, 0x0000ff, 1) -- change here (width, color, alpha) if params.tex then local tex = Texture.new(params.tex, false, {wrap = Texture.REPEAT}) local matrix = Matrix.new(params.scalex, 0, 0, params.scaley, 0, 0) self.img:setFillStyle(Shape.TEXTURE, tex, matrix) tex = nil else self.img:setFillStyle(Shape.SOLID, params.color) end self.img:beginPath() self.img:moveTo(0, 0) self.img:lineTo(params.w, 0) self.img:lineTo(params.w, params.h) self.img:lineTo(0, params.h) self.img:lineTo(0, 0) self.img:endPath() if params.rotation < 0 then self.img:setAnchorPoint(0, -0.5) end if params.rotation > 0 then self.img:setAnchorPoint(0, 0.5) end self.img:setRotation(params.rotation) self.img:setAlpha(params.alpha) end if params.isbmp then if not params.tex then print("!!!YOU MUST PROVIDE A TEXTURE FOR THE BITMAP!!!") return end local tex = Texture.new(params.tex, false) self.img = Bitmap.new(tex) self.img.isbmp = true self.img.w, self.img.h = params.w, params.h if params.rotation < 0 then self.img:setAnchorPoint(0, 0.5) end -- if params.rotation > 0 then self.img:setAnchorPoint(0, 0.5) end self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) self.img:setAlpha(params.alpha) tex = nil end if params.ispixel then if params.tex then local tex = Texture.new(params.tex, false, {wrap = TextureBase.REPEAT}) self.img = Pixel.new(tex, params.w, params.h) self.img.ispixel = true self.img.w, self.img.h = params.w, params.h self.img:setScale(params.scalex, params.scaley) if params.rotation < 0 then self.img:setAnchorPoint(0, -0.5) end if params.rotation > 0 then self.img:setAnchorPoint(0, 0.5) end self.img:setRotation(params.rotation) self.img:setAlpha(params.alpha) tex = nil else self.img = Pixel.new(params.color, 1, params.w, params.h) self.img.ispixel = true self.img.w, self.img.h = params.w, params.h self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) self.img:setAlpha(params.alpha) end end -- debug if self.img then if xworld.isdebug then self.img:setAlpha(0.5) end self:addChild(self.img) end end -- body self.body = xworld:createBody { type = params.type } -- b2.STATIC_BODY, b2.KINEMATIC_BODY, b2.DYNAMIC_BODY self.body:setGravityScale(params.gravityscale) self.body.name = params.NAME self.body.isdirty = false self.body:setFixedRotation(params.fixedrotation) local shape = b2.PolygonShape.new() shape:setAsBox(params.w/2, params.h/2, params.w/2, params.h/2, ^<params.rotation) -- (half w, half h, centerx, centery, rotation) local fixture = self.body:createFixture { shape = shape, density = params.density, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local filterData = { categoryBits = params.BIT, maskBits = params.COLBIT, groupIndex = 0 } fixture:setFilterData(filterData) -- clean up? filterData = nil fixture = nil shape = nil -- listeners? if params.addenterframe then self.world = xworld self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self) end end

function Tiled_Shape_Rectangle:onEnterFrame() -- your logic here end

function Tiled_Shape_Rectangle:setPosition(xposx, xposy) if self.body then self.body:setPosition(xposx, xposy) if self.img then self.img:setPosition(self.body:getPosition()) end else if self.img then self.img:setPosition(xposx, xposy) end end end </source>

POLYGONS

<syntaxhighlight lang="lua"> Tiled_Shape_Polygon = Core.class(Sprite)

function Tiled_Shape_Polygon:init(xworld, xparams) -- params local params = xparams or {} params.x = xparams.x or nil params.y = xparams.y or nil params.coords = xparams.coords or nil params.color = xparams.color or nil params.tex = xparams.tex or nil params.isshape = xparams.isshape or nil params.isbmp = xparams.isbmp or nil params.ispixel = xparams.ispixel or nil params.isdeco = xparams.isdeco or nil params.scalex = xparams.scalex or 1 params.scaley = xparams.scaley or params.scalex params.rotation = xparams.rotation or 0 params.type = xparams.type or nil -- default = b2.STATIC_BODY params.fixedrotation = xparams.fixedrotation or true params.density = xparams.density or nil params.restitution = xparams.restitution or nil params.friction = xparams.friction or nil params.gravityscale = xparams.gravityscale or 1 params.issensor = xparams.issensor or false params.BIT = xparams.BIT or nil params.COLBIT = xparams.COLBIT or nil params.NAME = xparams.NAME or nil params.addenterframe = xparams.addenterframe or nil -- image if params.issensor then -- no image for sensors else if params.isshape then self.img = Shape.new() self.img:setLineStyle(4, 0x0000ff, 1) -- change here (width, color, alpha) if params.tex then local tex = Texture.new(params.tex, false, {wrap = TextureBase.REPEAT}) local matrix = Matrix.new(params.scalex, 0, 0, params.scaley, 0, 0) self.img:setFillStyle(Shape.TEXTURE, tex, matrix) tex = nil else self.img:setFillStyle(Shape.SOLID, params.color) end self.img:beginPath() self.img:moveTo(params.coords[1].x, params.coords[1].y) for p = 2, #params.coords do self.img:lineTo(params.coords[p].x, params.coords[p].y) end self.img:closePath() self.img:endPath() self.img:setRotation(params.rotation) self.w, self.h = self.img:getWidth(), self.img:getHeight() end if params.isbmp then if not params.tex then print("!!!YOU MUST PROVIDE A TEXTURE FOR THE BITMAP!!!") return end -- calculate polygon width and height local minx, maxx, miny, maxy = 0, 0, 0, 0 for k, v in pairs(params.coords) do --print("polygon coords", k, v.x, v.y) if v.x < minx then minx = v.x end if v.y < miny then miny = v.y end if v.x > maxx then maxx = v.x end if v.y > maxy then maxy = v.y end end local pw, ph = maxx - minx, maxy - miny -- the polygon dimensions local tex = Texture.new(params.tex, false) self.img = Bitmap.new(tex) self.img.isbmp = true self.img.w, self.img.h = pw, ph self.img:setAnchorPoint(0.5, 0.5) if params.rotation > 0 then self.img:setAnchorPoint(0, 0.5) end if params.rotation < 0 then self.img:setAnchorPoint(0.5, 1) end self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) tex = nil end if params.ispixel then if params.tex then -- calculate polygon width and height local minx, maxx, miny, maxy = 0, 0, 0, 0 for k, v in pairs(params.coords) do --print("polygon coords", k, v.x, v.y) if v.x < minx then minx = v.x end if v.y < miny then miny = v.y end if v.x > maxx then maxx = v.x end if v.y > maxy then maxy = v.y end end local pw, ph = maxx - minx, maxy - miny -- the polygon dimensions local tex = Texture.new(params.tex, false, {wrap = TextureBase.REPEAT}) self.img = Pixel.new(tex, pw, ph) self.img.ispixel = true self.img.w, self.img.h = pw, ph self.img:setAnchorPoint(0, -0.5) -- 0.5, 0.5 if params.rotation > 0 then self.img:setAnchorPoint(0, 0.5) end if params.rotation < 0 then self.img:setAnchorPoint(0.5, 1) end self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) self.img:setTexturePosition(0, 0) tex = nil else -- calculate polygon width and height local minx, maxx, miny, maxy = 0, 0, 0, 0 for k, v in pairs(params.coords) do --print("polygon coords", k, v.x, v.y) if v.x < minx then minx = v.x end if v.y < miny then miny = v.y end if v.x > maxx then maxx = v.x end if v.y > maxy then maxy = v.y end end local pw, ph = maxx - minx, maxy - miny -- the polygon dimensions self.img = Pixel.new(params.color, 1, pw, ph) self.img.ispixel = true self.img.w, self.img.h = pw, ph self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) end end -- debug if self.img then if xworld.isdebug then self.img:setAlpha(0.5) end self:addChild(self.img) end end -- body self.body = xworld:createBody {type = params.type} -- b2.STATIC_BODY, b2.KINEMATIC_BODY, b2.DYNAMIC_BODY self.body:setGravityScale(params.gravityscale) self.body.name = params.NAME self.body.isdirty = false self.body:setFixedRotation(params.fixedrotation) local shape = b2.ChainShape.new() local cs = {} for c = 1, #params.coords do cs[#cs+1] = params.coords[c].x cs[#cs+1] = params.coords[c].y end shape:createLoop(unpack(cs)) -- XXX local fixture = self.body:createFixture { shape = shape, density = params.density, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local filterData = { categoryBits = params.BIT, maskBits = params.COLBIT, groupIndex = 0 } fixture:setFilterData(filterData) -- clean up? filterData = nil fixture = nil cs = nil shape = nil -- listeners? if params.addenterframe then self.world = xworld self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self) end end

function Tiled_Shape_Polygon:onEnterFrame() -- your logic here end

function Tiled_Shape_Polygon:setPosition(xposx, xposy) if self.body then self.body:setPosition(xposx, xposy) if self.img then self.img:setPosition(self.body:getPosition()) end else if self.img then self.img:setPosition(xposx, xposy) end end end </source>

ELLIPSES

<syntaxhighlight lang="lua"> Tiled_Shape_Ellipse = Core.class(Sprite)

function Tiled_Shape_Ellipse:init(xworld, xparams) -- params local params = xparams or {} params.x = xparams.x or nil params.y = xparams.y or nil params.w = xparams.w or 32 params.h = xparams.h or 32 params.steps = xparams.steps or 16 -- 24 params.color = xparams.color or nil params.tex = xparams.tex or nil params.isdeco = xparams.isdeco or nil params.isshape = xparams.isshape or nil params.isbmp = xparams.isbmp or nil params.ispixel = xparams.ispixel or nil params.scalex = xparams.scalex or 1 params.scaley = xparams.scaley or params.scalex params.rotation = xparams.rotation or 0 params.type = xparams.type or nil -- default = b2.STATIC_BODY params.fixedrotation = xparams.fixedrotation or nil params.density = xparams.density or 0 params.restitution = xparams.restitution or nil params.friction = xparams.friction or nil params.gravityscale = xparams.gravityscale or 1 params.issensor = xparams.issensor or nil params.BIT = xparams.BIT or nil params.COLBIT = xparams.COLBIT or nil params.NAME = xparams.NAME or nil params.addenterframe = xparams.addenterframe or nil -- image if params.issensor then -- no image for sensors else local sin, cos, d2r = math.sin, math.cos, math.pi / 180 if params.isshape then self.img = Shape.new() self.img:setLineStyle(4, 0x0000ff, 1) -- change here (width, color, alpha) if params.tex then local tex = Texture.new(params.tex, false, {wrap = Texture.REPEAT}) local matrix = Matrix.new(params.scalex, 0, 0, params.scaley, 0, 0) self.img:setFillStyle(Shape.TEXTURE, tex, matrix) tex = nil else self.img:setFillStyle(Shape.SOLID, params.color) end self.img:beginPath() for i = 0, 360, 360 / params.steps do self.img:lineTo((params.w / 2) + params.w / 2 * sin(i * d2r), (params.h / 2) + params.h / 2 * cos(i * d2r)) end self.img:endPath() self.img:setRotation(params.rotation) end if params.isbmp then if not params.tex then print("!!!YOU MUST PROVIDE A TEXTURE FOR THE BITMAP!!!") return end local tex = Texture.new(params.tex, false) self.img = Bitmap.new(tex) self.img.w, self.img.h = params.w, params.h if params.rotation > 0 then self.img:setAnchorPoint(0, 0.5) end if params.rotation < 0 then self.img:setAnchorPoint(0.5, 1) end self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) -- print("bmp", params.w, params.h) tex = nil end if params.ispixel then if params.tex then local tex = Texture.new(params.tex, false, {wrap = TextureBase.REPEAT}) self.img = Pixel.new(tex, params.w, params.h) self.img.ispixel = true self.img.w, self.img.h = params.w, params.h self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) -- print("pixel", params.w, params.h, params.rotation) tex = nil else self.img = Pixel.new(0xff0000, 1, params.w, params.h) self.img.ispixel = true self.img.w, self.img.h = params.w, params.h self.img:setScale(params.scalex, params.scaley) self.img:setRotation(params.rotation) -- print("pixel", params.w, params.h, params.rotation) end end -- debug if self.img then if xworld.isdebug then self.img:setAlpha(0.5) end self:addChild(self.img) end end -- body self.body = xworld:createBody { type = params.type } -- b2.STATIC_BODY, b2.KINEMATIC_BODY, b2.DYNAMIC_BODY self.body:setGravityScale(params.gravityscale) self.body.name = params.NAME self.body.isdirty = false self.body:setFixedRotation(params.fixedrotation) if params.w < params.h then -- capsule up -- print("capsule up") local shape = b2.CircleShape.new(params.w / 2, 0 + params.w / 2, params.w / 2) -- (centerx, centery, radius) local shape2 = b2.CircleShape.new(params.w / 2, params.h - params.w / 2, params.w / 2) -- (centerx, centery, radius) local shape3 = b2.EdgeShape.new(0, params.w / 2, 0, params.h - (params.w / 2)) -- (x1,y1,x2,y2) local shape4 = b2.EdgeShape.new(params.w, params.w / 2, params.w, params.h - (params.w / 2)) -- (x1,y1,x2,y2) local fixture = self.body:createFixture { shape = shape, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local fixture2 = self.body:createFixture { shape = shape2, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local fixture3 = self.body:createFixture { shape = shape3, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local fixture4 = self.body:createFixture { shape = shape4, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local filterData = { categoryBits = params.BIT, maskBits = params.COLBIT, groupIndex = 0 } fixture:setFilterData(filterData) fixture2:setFilterData(filterData) fixture3:setFilterData(filterData) fixture4:setFilterData(filterData) -- clean up? filterData = nil fixture, fixture2, fixture3, fixture4 = nil, nil,nil, nil shape, shape2, shape3, shape4 = nil, nil, nil, nil elseif params.w > params.h then -- capsule laid -- print("capsule laid") local shape = b2.CircleShape.new(0 + params.h / 2, params.h/2, params.h/2) -- (centerx, centery, radius) local shape2 = b2.CircleShape.new(params.w - params.h / 2, params.h/2, params.h/2) -- (centerx, centery, radius) local shape3 = b2.EdgeShape.new(params.h / 2, 0, params.w - (params.h / 2), 0) -- (x1,y1,x2,y2) local shape4 = b2.EdgeShape.new(params.h / 2, params.h, params.w - (params.h / 2), params.h) -- (x1,y1,x2,y2) local fixture = self.body:createFixture { shape = shape, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local fixture2 = self.body:createFixture { shape = shape2, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local fixture3 = self.body:createFixture { shape = shape3, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local fixture4 = self.body:createFixture { shape = shape4, density = params.density * 0.25, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local filterData = { categoryBits = params.BIT, maskBits = params.COLBIT, groupIndex = 0 } fixture:setFilterData(filterData) fixture2:setFilterData(filterData) fixture3:setFilterData(filterData) fixture4:setFilterData(filterData) -- clean up? filterData = nil fixture, fixture2, fixture3, fixture4 = nil, nil,nil, nil shape, shape2, shape3, shape4 = nil, nil, nil, nil else -- circle -- print("circle") local shape = b2.CircleShape.new(params.w / 2, params.h / 2, params.w / 2) -- (centerx, centery, radius) local fixture = self.body:createFixture { shape = shape, density = params.density, restitution = params.restitution, friction = params.friction, isSensor = params.issensor } local filterData = { categoryBits = params.BIT, maskBits = params.COLBIT, groupIndex = 0 } fixture:setFilterData(filterData) -- clean up? filterData = nil fixture = nil shape = nil end -- rotation local rot = math.rad(params.rotation) self.body:setAngle(rot) -- listeners? if params.addenterframe then self.world = xworld self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self) end end

function Tiled_Shape_Ellipse:onEnterFrame() -- your logic here end

function Tiled_Shape_Ellipse:setPosition(xposx, xposy) if self.body then self.body:setPosition(xposx, xposy) if self.img then self.img:setPosition(self.body:getPosition()) end else if self.img then self.img:setPosition(xposx, xposy) end end end </source>

Tiled Map Editor: IMAGE LAYER

It is the same as above:

  • we load the Tiled level in the scene (our level)
  • we have a class which will load our images from Tiled to our level

Our Level

<syntaxhighlight lang="lua"> LevelX = Core.class(Sprite)

function LevelX:init() -- b2d world if g_currentlevel == 1 then self.world = b2.World.new(0, 20, true) -- XXX elseif g_currentlevel == 2 then self.world = b2.World.new(0, 20, true) -- XXX else self.world = b2.World.new(0, 20, true) -- XXX end -- lists self.world.grounds = {} self.world.groundnmes = {} self.world.airnmes = {} -- ... -- the tiled level tiled_levels = {} tiled_levels[1] = loadfile("tiled/levels/forest01.lua")() tiled_levels[2] = loadfile("tiled/levels/mountain_village.lua")() -- ... g_currentlevel = 1 self.tiled_level = Tiled_Levels.new(self.world, tiled_levels[g_currentlevel]) -- ... -- order self:addChild(self.tiled_level ) end </source>

IMAGES

Here is the class to import images from Tiled and draw them in your game. <syntaxhighlight lang="lua"> Tiled_Levels = Core.class(Sprite)

function Tiled_Levels:init(xworld, xtiledlevel) self.world = xworld -- the Tiled map size, I need the Tiled map dimensions for the parallax self.mapwidth, self.mapheight = xtiledlevel.width * xtiledlevel.tilewidth, xtiledlevel.height * xtiledlevel.tileheight print("map size "..self.mapwidth..", "..self.mapheight, "app size "..myappwidth..", "..myappheight, "all in pixels.") -- camera self.camera = Sprite.new() -- game layers self.bg2_backB = Sprite.new() -- game bg: nmes, deco, ... self.bg2_backA = Sprite.new() -- game bg: nmes, deco, ... self.bg2_base = Sprite.new() -- game bg: nmes, deco, ... self.bg2_frontA = Sprite.new() -- game bg: nmes, deco, ... -- ... -- order self.camera:addChild(self.bg2_backB) self.camera:addChild(self.bg2_backA) self.camera:addChild(self.bg2_base) self.camera:addChild(self.bg2_frontA) self.camera:addChild(self.bg2_frontB) -- ... -- final self:addChild(self.camera)

-- put all the Tiled Tileset images in a table local tilesetimages = {} local tilesets = xtiledlevel.tilesets for i = 1, #tilesets do local tileset = tilesets[i] -- TILESETS -- ******** if tileset.name == "images" then -- your Tiled Tileset! name here local tiles = tileset.tiles for i = 1, #tiles do tilesetimages[tiles[i].id+1] = { path=tiles[i].image, width=tiles[i].width, height=tiles[i].height, } end end end

-- parse the Tiled level local layers = xtiledlevel.layers local myshape -- shapes from Tiled local mytable -- intermediate table for shapes params for i = 1, #layers do local layer = layers[i]

-- PLAYABLE -- ******** -- ...

-- GROUPED IMAGES -- ************** local path = "tiled/levels/" if layer.name == "IMAGES" then -- group local layers2 = layer.layers for i = 1, #layers2 do local layer2 = layers2[i] if layer2.name == "bg_images_deco" then local objects = layer2.objects for i = 1, #objects do local object = objects[i] local tex = Texture.new(path..tilesetimages[object.gid].path, false) local bitmap = Bitmap.new(tex) bitmap:setAnchorPoint(0, 1) -- because I always forget to set Tiled object alignment local scalex, scaley = object.width / tex:getWidth(), object.height / tex:getHeight() bitmap:setScale(scalex, scaley) bitmap:setPosition(object.x, object.y) bitmap:setRotation(object.rotation) self.bg2_base:addChild(bitmap) end elseif layer2.name == "fg_images_deco" then local objects = layer2.objects for i = 1, #objects do local object = objects[i] local tex = Texture.new(path..tilesetimages[object.gid].path, false) local bitmap = Bitmap.new(tex) bitmap:setAnchorPoint(0, 1) -- because I always forget to set Tiled object alignment local scalex, scaley = object.width / tex:getWidth(), object.height / tex:getHeight() bitmap:setScale(scalex, scaley) bitmap:setPosition(object.x, object.y) bitmap:setRotation(object.rotation) self.fg2_base:addChild(bitmap) end elseif layer2.name == "static_images" then -- ... end end end end end </source>