Tiled Map Editor
From GiderosMobile
Here you will find various resources to help you create games and apps in Gideros Studio.
note: you may have to provide your own assets (fonts, gfx, …)
Description
On this page you will find various classes to help using Tiled Map Editor in Gideros. Enjoy :-)
Tiled Map Editor Shapes
Here are some 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
RECTANGLES
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
POLYGONS
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
ELLIPSES
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 nil
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, params.h / 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(params.w/2, params.h/2, params.w/2) -- (centerx, centery, radius)
local shape2 = b2.CircleShape.new(params.w - params.w/2, params.h/2, params.w/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