Created
February 12, 2019 04:04
-
-
Save teak1/dd31f9f55a7c7b4919b369684bbe0c20 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//tiled render code | |
//by glEnd2 | |
/* | |
to use create a new Tilemap object with the path to your .json file exported from tiled. | |
will do the rest from there. | |
to get renderable canvas use Tilemap.getImage(); | |
rendering is done at creation so that there is less overhead later on. | |
*/ | |
let local = { | |
_(e) { | |
e.style.display = "none"; | |
document.body.appendChild(e); | |
}, | |
createGraphics(w, h) { | |
let c = document.createElement("canvas"); | |
// document.body.appendChild(c); | |
c.setAttribute("width", w); | |
c.setAttribute("height", h); | |
local._(c); | |
return { | |
canvas: c, | |
ctx: c.getContext("2d") | |
}; | |
}, | |
loadJSON(src, cb) { | |
fetch(src).then(res => res.json()).then(cb); | |
}, | |
loadImage(src) { | |
return new Promise((resolve, reject) => { | |
let i = new Image(); | |
i.src = src; | |
local._(i); | |
document.body.appendChild(i); | |
i.addEventListener("load", () => resolve(i)); | |
}); | |
} | |
} | |
class Tilemap { | |
constructor(src) { | |
this.src = src; | |
this.raw = null; | |
local.loadJSON(src, result => { | |
this.raw = result; | |
this.init(); | |
}); | |
this.layers = []; | |
this.rendered = null; | |
this.tilesets = []; | |
this.black = local.createGraphics(100, 100); | |
// this.black.ctx.fillStyle = "black"; | |
// this.black.ctx.fillRect(0, 0, 100, 100); | |
// this.black.background(0); | |
this.graphic = null; | |
this.objects = {}; | |
} | |
async init() { | |
for (var i = 0; i < this.raw.tilesets.length; i++) { | |
this.tilesets[i] = await local.loadImage(this.raw.tilesets[i].image.replace(/\.\./g, "")); | |
} | |
for (var i = 0; i < this.raw.layers.length; i++) { | |
if (this.raw.layers[i].type == "objectgroup") { | |
this.objects[this.raw.layers[i].name] = this.raw.layers[i]; | |
this.layers[i] = null; | |
} else { | |
let w = this.raw.tilewidth * this.raw.layers[i].width; | |
let h = this.raw.tileheight * this.raw.layers[i].height; | |
this.layers[i] = local.createGraphics(w, h); | |
} | |
} | |
this.graphic = local.createGraphics(this.raw.tilewidth * this.raw.width, this.raw.tileheight * this.raw.height); | |
this.render(); | |
console.log("done!"); | |
} | |
renderLayer(index) { | |
let tileset = this.raw.layers[index]; | |
let surface = this.layers[index]; | |
surface.ctx.clearRect(0, 0, Infinity, Infinity); | |
for (var i = 0; i < tileset.data.length; i++) { | |
let tw = this.raw.tilewidth; | |
let th = this.raw.tileheight; | |
let fx = (i % tileset.width) * tw; | |
let fy = ((i - (i % tileset.width)) / tileset.width) * th; | |
let img = this.getImageFromIndex(tileset.data[i]); | |
if (img) surface.ctx.drawImage(img.image, img.x * tw, img.y * th, tw, th, fx, fy, tw, th); | |
} | |
} | |
render() { | |
if (this.graphic) { | |
this.graphic.ctx.clearRect(0, 0, Infinity, Infinity); | |
for (var i = 0; i < this.layers.length; i++) { | |
if (this.layers[i]) { | |
this.renderLayer(i); | |
this.graphic.ctx.drawImage(this.layers[i].canvas, 0, 0, this.graphic.canvas.width, this.graphic.canvas.height); | |
} | |
} | |
} else { | |
return null; | |
} | |
} | |
getImageFromIndex(index) { | |
let data = this.raw.tilesets; | |
let ind = -1; | |
for (var i = 0; i < data.length; i++) { | |
if (index < data[i].firstgid) { | |
ind = i - 1; | |
i = Infinity; | |
continue; | |
} | |
} | |
if (ind == -1) { | |
return { | |
image: this.black.canvas, | |
x: 0, | |
y: 0 | |
}; | |
} else { | |
index -= data[ind].firstgid; | |
let iw = data[ind].columns; | |
let ix = (index % iw); | |
let iy = (index - (index % iw)) / iw; | |
return { | |
image: this.tilesets[ind], | |
x: ix, | |
y: iy | |
} | |
} | |
} | |
getImage() { | |
return this.graphic.canvas; | |
} | |
getObject(path) { | |
path = path.split("/"); | |
return this.objects[path[0]]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
does run asyncish, feel free to change so that it does not block main thread,
image may not be available right away.