If interested I created this video stream where I in 3 sessions create this isometric small techdemo.
First part is more about the normal “isometric” stuff and then I get a little more advanced from there. But it shouldn’t really be hard to convert Tiled-data to isometric.
I did explore an idea I had for an isometric looking RTS, but it wasn’t quite what you are trying to achieve. I would recommend checking out Andreas video above.
Thanks, I’ll watch the video
Hello,
how exactly did you achieve your result? Did you try using the libdefold plugin? The best way to use Defold in conjunction with Defold in order to create an isometric game is to write your own rendering routine, which will load the output generated by Tiled (a lua/json file) and compensate for height difference based on presets of individual tilesets.
For small isometric map there is able to use GO.factory and .lua file from Tiled.
I tried this way here: http://dragosha.com/adventure/
Map Go contains Factory block.go and this script:
Map loader script:
local tiles={}
local WIDTH = tonumber(sys.get_config("display.width"))
local HEIGHT = tonumber(sys.get_config("display.height"))
-- Get info about flipping of tile. Based on object GID in the object layer
-- @param gid GID from .tmx
-- @return realGID (int), flipX (bool), flipY (bool)
local function flippedGID(gid)
local bit31 = 2147483648
local bit30 = 1073741824
local bit29 = 536870912
local flipX = false
local flipY = false
local flipD = false
local realgid = gid
if realgid >= bit31 then
realgid = realgid - bit31
flipX = true
end
if realgid >= bit30 then
realgid = realgid - bit30
flipY = true
end
if realgid >= bit29 then
realgid = realgid - bit29
flipD = not flipD
end
return realgid, flipX, flipY
end
-- @return file name without path and extension
local function pureName(name)
name=string.gsub(name,"%w+/+","")
name=name:gsub("../+","")
name=string.gsub(name,".png","")
return name
end
local isoToScreen = function(ix,iy,tw,th)
local x = (ix-1)*tw/2 - (iy-1)*tw/2
local y = (ix-1)*th/2 + (iy-1)*th/2
return x,y
end
--- Project isometric position to cartesian position
function convert_isometric_to_screen(map, x, y)
local mapH = map.height
local tileW = map.tilewidth
local tileH = map.tileheight
local tileX = x / tileH
local tileY = y / tileH
local offsetX = mapH * tileW / 2
return
(tileX - tileY) * tileW / 2 + offsetX,
mapH*tileH-(tileX + tileY) * tileH / 2
end
--
local function build_board(self, level)
local pos = vmath.vector3()
local layers=#level.layers
local tileset=level.tilesets[1]
local scale = vmath.vector3()
local rot
for i=1,layers do
local layer=level.layers[i]
for j,obj in pairs(layer.objects) do
local gid,flipX,flipY=flippedGID(obj.gid)
local tileInfo=tileset.tiles[gid]
local img=pureName(tileInfo.image)
if level.orientation=="isometric" then
pos.x,pos.y=convert_isometric_to_screen(level, obj.x, obj.y)
--pos.x=200+obj.x+tileInfo.width/2-obj.y/2
--pos.y=(level.height*level.tileheight)-obj.y+tileInfo.height/2
pos.z=0
else
pos.x=obj.x+tileInfo.width/2
pos.y=(level.height*level.tileheight)-obj.y+tileInfo.height/2
pos.z=0
end
if obj.width ~= tileInfo.width then
scale.x= obj.width/tileInfo.width
scale.y= obj.height/tileInfo.height
scale.z= 1
else
scale.x=1 scale.y=1 scale.z=1
end
if obj.rotation ~=0 then
local angle=-obj.rotation * math.pi/180
rot=vmath.quat_rotation_z(angle)
-- print(rot)
else
rot=nil
end
local y=pos.y
if layer.name=="floor" then
pos.y=-obj.height
else
pos.y=HEIGHT+obj.height
end
local id=factory.create("#factory",pos,rot,{img=hash(img),flipX=flipX,flipY=flipY},scale)
local duration=y/HEIGHT
--duration = math.random(duration * 0.9, duration * 1.1)
local delay = j*.01
go.animate(id, "position.y", go.PLAYBACK_ONCE_FORWARD, y, go.EASING_OUTBACK, duration, delay)
table.insert(tiles,{id=id,x=pos.x,y=y,layer=layer.name, height=obj.height})
end
end
end
local function boardAnimation(self)
local pos=vmath.vector3()
for i,t in pairs(tiles) do
local duration=t.y/HEIGHT
local delay = i*.01
local y
if t.layer=="floor" then
y=-t.height
else
y=HEIGHT+t.height
end
go.animate(t.id, "position.y", go.PLAYBACK_ONCE_FORWARD, y, go.EASING_INBACK, duration, delay)
end
end
local function boardAnimation2(self)
local pos=vmath.vector3()
for i,t in pairs(tiles) do
local duration=t.y/HEIGHT
local delay = i*.01
go.animate(t.id, "position.y", go.PLAYBACK_ONCE_FORWARD, t.y, go.EASING_OUTCUBIC, duration, delay)
end
end
function init(self)
build_board(self, require "main/Tiles/map2")
msg.post(".","acquire_input_focus")
end
function final(self)
-- Add finalization code here
-- Remove this function if not needed
msg.post(".","release_input_focus")
end
function update(self, dt)
-- Add update code here
-- Remove this function if not needed
end
function on_message(self, message_id, message, sender)
-- Add message-handling code here
-- Remove this function if not needed
end
function on_input(self, action_id, action)
if action_id==hash("click") and action.pressed then
if self.anim then
boardAnimation2(self)
self.anim=false
else
boardAnimation(self)
self.anim=true
end
end
end
in this implementation method ‘convert_isometric_to_screen’ works not correct, need to fix, i used not isometric map in Tiled in example
Block GO contains “sprite” component and this script:
Block.script:
go.property("img",hash("none"))
go.property("flipX", false)
go.property("flipY", false)
function init(self)
-- Add initialization code here
-- Remove this function if not needed
--go.set_scale(1)
if self.flipX then
sprite.set_hflip("#sprite", true)
end
if self.flipY then
sprite.set_vflip("#sprite", true)
end
if self.img ~= hash("none") then
msg.post("#sprite","play_animation", {id=self.img})
else
msg.post("#sprite","disable")
end
end
Sprite component uses atlas with images that have same names as in Tiled editor.
Wow, nice!
Nice demo, I like it
I’d just like to add that you can use (collection) factories to draw large maps (in Kanji Adventure , the exploration map is 100x100 tiles large), you just have to create a routine that manages creation and deletion of tiles that are on-/offscreen respectively.
Oh, and one (pretty significant) performance optimization that I found out a couple days back - make sure to cut up the data that you are going to use into multiple lua tables. Accessing the following tables:
self.tile_styles = self.tilemap()["layers"][1]["data"]
self.object_styles = self.tilemap()["layers"][3]["data"]
self.large_object_styles = self.tilemap()["layers"][4]["data"]
self.grayscale_mods = self.tilemap()["layers"][5]["data"]
self.tilesets = self.tilemap()["tilesets"]
is much faster than accessing them via
local res = sys.load_resource("/maps/" .. self.map_name .. ".lua")
self.tilemap = assert(loadstring(res))
There is also a helpful list of tips on performance in Lua over at https://www.lua.org/gems/sample.pdf
It’s still impossible to use isometric tile imported from tiled correctly in the editor, any update ? is in the roadmap ?
No, I’m afraid not. Not in the short term at least.
EDIT: Well, you could use a normal 2D grid map and setup your camera so that you get an isometric view. It would require a bit of fiddling with how sprites and other things are rendered though.
Me and my team we currently have an C++ isometric 2D mmorpg that we would like to switch to defold, but suddenly it could be very complicated, we want to use defold for a lot of reasons, but the isometric issue brakes a little bit. All our assets are isometric view already etc.
for exampleYou could quite easily create it using game objects instead. It should be performant enough.
It’s will be painful to move my characters overs this kind of map no ?
No, why would it be difficult? How is your character rendered btw? 2D flipbook animations in four directions? How are your maps described/created? Using Tiled?
My map are created using tiled, my character are 8Direction characters (Dofus-Like).
I can export tiled map into lua files, and then create game object in defold i think
Yes, this would work.
And do you move freely or is it basically tile/grid based movement?
Freely, also i plan to use spine model animation in defold because it’s seem’s really great.
Yes, Fates of Ort is proof that it is possible. And @Tomires used to develop an isometric game as well.
@andreas.strangequest the video you linked sadly doesnt load anymore over the link, do you still have it available somewhere? Im trying to find resources on isometric games in defold, but the forums arent really helpful, was hoping your video is still available
I don’t think Andreas has any videos saved, and it was a long time since he visited the forum.
It would be great to create a sample project using isometric tilemaps imported from Tiled.