Difference between revisions of "Tiled Map Editor"

From GiderosMobile
(Created page with "__TOC__ Here you will find various resources to help you create games and apps in Gideros Studio.<br/> '''note:''' you may have to provide your own assets (fonts, gfx, …) =...")
 
Line 6: Line 6:
 
On this page you will find various classes to help using Tiled Map Editor in Gideros. Enjoy ''':-)'''
 
On this page you will find various classes to help using Tiled Map Editor in Gideros. Enjoy ''':-)'''
  
== Tiled Map Editor Shapes ==
+
== Tiled Map Editor: OBJECT LAYER ==
 
Here are some classes to import the shapes your created in Tiled and draw them in Gideros.<br/>
 
Here are some classes to import the shapes your created in Tiled and draw them in Gideros.<br/>
 
'''note:''' don't forget to export your Tiled map to a lua file
 
'''note:''' don't forget to export your Tiled map to a lua file
  
=== RECTANGLES ===
+
=== '''RECTANGLES''' ===
 
<source lang="lua">
 
<source lang="lua">
 
Tiled_Shape_Rectangle = Core.class(Sprite)
 
Tiled_Shape_Rectangle = Core.class(Sprite)
Line 148: Line 148:
 
</source>
 
</source>
  
=== POLYGONS ===
+
=== '''POLYGONS''' ===
 
<source lang="lua">
 
<source lang="lua">
 
Tiled_Shape_Polygon = Core.class(Sprite)
 
Tiled_Shape_Polygon = Core.class(Sprite)
Line 318: Line 318:
 
</source>
 
</source>
  
=== ELLIPSES ===
+
=== '''ELLIPSES''' ===
 
<source lang="lua">
 
<source lang="lua">
 
Tiled_Shape_Ellipse = Core.class(Sprite)
 
Tiled_Shape_Ellipse = Core.class(Sprite)

Revision as of 22:19, 25 November 2020

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: OBJECT LAYER

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