UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

240 lines (235 loc) 7.91 kB
import { Vector2 } from "three/src/Three"; import { Transform } from "../../hierarchy_object/Transform"; import { CssRenderer } from "./CssRenderer"; import { ImageRenderingMode } from "./CssSpriteRenderer"; export class TileAtlasItem { tl; xa; Ra; constructor(t, i = 1, s = 1) { if (!t.complete) { throw new Error(`Image {${t.src}} is not loaded.`); } this.tl = t; this.Ra = s; this.xa = i; } get htmlImageElement() { return this.tl; } get columnCount() { return this.xa; } get rowCount() { return this.Ra; } } export class CssTilemapRenderer extends CssRenderer { xa=10; Ra=10; tn=1; en=1; sn=16; rn=16; nn=null; cn=ImageRenderingMode.Pixelated; $h=[]; renderInitialize() { this.il(); const t = this.$h; for (let i = 0; i < t.length; ++i) { t[i](); } this.$h.length = 0; } updateCenterOffset(t) { if (!this.css3DObject) return; const i = this.xa * this.tn; const s = this.Ra * this.en; this.css3DObject.position.set(i * this.centerOffset.x, s * this.centerOffset.y, 0); if (t) { Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject); this.transform.enqueueRenderAttachedObject3D(this.css3DObject); } } updateViewScale(t) { if (!this.css3DObject) return; const i = this.viewScale; const s = this.htmlElement; const e = this.xa * this.tn; const h = this.Ra * this.en; s.style.width = e / i + "px"; s.style.height = h / i + "px"; this.css3DObject.scale.set(i, i, i); if (t) { Transform.updateRawObject3DWorldMatrixRecursively(this.css3DObject); this.transform.enqueueRenderAttachedObject3D(this.css3DObject); } } il() { const t = this.xa * this.tn; const i = this.Ra * this.en; const s = this.xa * this.sn; const e = this.Ra * this.rn; this.htmlElement = document.createElement("canvas"); this.htmlElement.width = s; this.htmlElement.height = e; this.htmlElement.style.imageRendering = this.cn; this.htmlElement.style.width = t / this.viewScale + "px"; this.htmlElement.style.height = i / this.viewScale + "px"; const h = this.initializeBaseComponents(false); Transform.updateRawObject3DWorldMatrixRecursively(h); this.transform.enqueueRenderAttachedObject3D(h); } drawTile(t, i, s, e) { if (!this.readyToDraw) { this.$h.push((() => this.drawTile(t, i, s, e))); return; } const h = this.htmlElement.getContext("2d"); const r = this.nn[s]; if (r.rowCount === 1 && r.columnCount === 1) { h.drawImage(r.htmlImageElement, 0, 0, this.sn, this.rn, t * this.sn, i * this.rn, this.sn, this.rn); } else if (e !== undefined) { const s = Math.floor(e / r.columnCount); const n = e % r.columnCount; const o = r.htmlImageElement.width / r.columnCount; const l = r.htmlImageElement.height / r.rowCount; h.drawImage(r.htmlImageElement, n * o, s * l, o, l, t * this.sn, i * this.rn, this.sn, this.rn); } else { throw new Error("Atlas index is required."); } } drawTileFromTwoDimensionalArray(t, i, s) { if (!this.readyToDraw) { this.$h.push((() => this.drawTileFromTwoDimensionalArray(t, i, s))); return; } const e = this.htmlElement.getContext("2d"); for (let h = 0; h < t.length; h++) { const r = t[h]; for (let t = 0; t < r.length; t++) { const n = r[t]; if (n === null) continue; const o = this.nn[n.i]; if (o.rowCount === 1 && o.columnCount === 1) { e.drawImage(o.htmlImageElement, 0, 0, this.sn, this.rn, t * this.sn + i * this.sn, h * this.rn + s * this.rn, this.sn, this.rn); } else if (n.a !== undefined) { const r = n.a % o.columnCount; const l = Math.floor(n.a / o.columnCount); const c = o.htmlImageElement.width / o.columnCount; const u = o.htmlImageElement.height / o.rowCount; e.drawImage(o.htmlImageElement, r * c, l * u, c, u, t * this.sn + i * this.sn, h * this.rn + s * this.rn, this.sn, this.rn); } else { throw new Error("Atlas index is required."); } } } } clearTile(t, i) { if (!this.readyToDraw) { this.$h.push((() => this.clearTile(t, i))); return; } const s = this.htmlElement.getContext("2d"); s.clearRect(t * this.sn, i * this.rn, this.sn, this.rn); } set imageSources(t) { if (!this.readyToDraw) { this.$h.push((() => this.imageSources = t)); return; } this.nn = t; for (let i = 0; i < t.length; ++i) { if (!t[i].htmlImageElement.complete) throw new Error(`Image ${t[i].htmlImageElement.src} is not loaded.`); } } get columnCount() { return this.xa; } set columnCount(t) { this.xa = t; if (this.htmlElement) { const t = this.xa * this.tn; const i = this.xa * this.sn; this.htmlElement.width = i; this.htmlElement.style.width = t / this.viewScale + "px"; this.updateCenterOffset(true); } } get rowCount() { return this.Ra; } set rowCount(t) { this.Ra = t; if (this.htmlElement) { const t = this.Ra * this.en; const i = this.Ra * this.rn; this.htmlElement.height = i; this.htmlElement.style.height = t / this.viewScale + "px"; this.updateCenterOffset(true); } } get gridCellWidth() { return this.tn; } set gridCellWidth(t) { this.tn = t; if (this.htmlElement) { const t = this.xa * this.tn; this.htmlElement.style.width = t / this.viewScale + "px"; this.updateCenterOffset(true); } } get gridCellHeight() { return this.en; } set gridCellHeight(t) { this.en = t; if (this.htmlElement) { const t = this.Ra * this.en; this.htmlElement.style.height = t / this.viewScale + "px"; this.updateCenterOffset(true); } } get tileResolutionX() { return this.sn; } set tileResolutionX(t) { this.sn = t; if (this.htmlElement) { const t = this.xa * this.sn; this.htmlElement.width = t; } } get tileResolutionY() { return this.rn; } set tileResolutionY(t) { this.rn = t; if (this.htmlElement) { const t = this.Ra * this.rn; this.htmlElement.height = t; } } get gridCenter() { const t = this.columnCount % 2 === 1 ? 0 : this.tn / 2; const i = this.rowCount % 2 === 1 ? 0 : this.en / 2; return new Vector2(this.transform.position.x + t, this.transform.position.y + i); } get gridCenterX() { return this.transform.position.x + (this.columnCount % 2 === 1 ? 0 : this.tn / 2); } get gridCenterY() { return this.transform.position.y + (this.rowCount % 2 === 1 ? 0 : this.en / 2); } get imageRenderingMode() { return this.cn; } set imageRenderingMode(t) { this.cn = t; if (this.htmlElement) { this.htmlElement.style.imageRendering = this.cn; } } }