UNPKG

the-world-engine

Version:

three.js based, unity like game engine for browser

334 lines (330 loc) 9.74 kB
import { Vector2 } from "three/src/Three"; import { EventContainer } from "../../collection/EventContainer"; import { Pathfinder } from "../ai/pathfind/Pathfinder"; import { Directable, Direction } from "../helper/Directable"; export class PlayerGridMovementController extends Directable { disallowMultipleComponent=true; dh=8; gh=1; wh=1; Cr=[]; Ph=.5; Ch=new Vector2; Dh=new Vector2; Mh=new Vector2; Th=new Vector2; Ah=new EventContainer; Vh=new EventContainer; Er=null; Ir=null; Ih=false; bh=null; yh=0; kh=null; Eh=new Vector2; Wh=true; xh=new Vector2; Gh=new Vector2; start() { this.Ir = new Pathfinder(this.Cr, this.wh * this.Ph, this.gh * this.Ph); const t = this.transform; const i = t.position; i.x = this.Ch.x + this.Th.x * this.wh; i.y = this.Ch.y + this.Th.y * this.gh; this.Dh.set(t.localPosition.x, t.localPosition.y); const s = t.parent; if (s) this.Eh.set(s.position.x, s.position.y); } update() { this.kh?.(); if (this.Wh) { this.Hh(); } this.Kh(); this.Lh(); } Hh() { if (this.isMoving) { this.Rh(); return; } const t = this.engine.input.map; const i = this.Dh; if (t.get("w") || t.get("ArrowUp")) { this.direction = Direction.Up; if (this.Sh(i.x, i.y + this.gh)) return; this.Mh.set(i.x, i.y + this.gh); this.Uh(); this.isMoving = true; } else if (t.get("s") || t.get("ArrowDown")) { this.direction = Direction.Down; if (this.Sh(i.x, i.y - this.gh)) return; this.Mh.set(i.x, i.y - this.gh); this.Uh(); this.isMoving = true; } else if (t.get("a") || t.get("ArrowLeft")) { this.direction = Direction.Left; if (this.Sh(i.x - this.wh, i.y)) return; this.Mh.set(i.x - this.wh, i.y); this.Uh(); this.isMoving = true; } else if (t.get("d") || t.get("ArrowRight")) { this.direction = Direction.Right; if (this.Sh(i.x + this.wh, i.y)) return; this.Mh.set(i.x + this.wh, i.y); this.Uh(); this.isMoving = true; } } Fh(t) { const i = this.engine.input.map; if (i.get("w") || i.get("ArrowUp")) { this.direction = Direction.Up; if (this.Sh(t.x, t.y + this.gh)) return false; this.Mh.set(t.x, t.y + this.gh); this.Uh(); return true; } else if (i.get("s") || i.get("ArrowDown")) { this.direction = Direction.Down; if (this.Sh(t.x, t.y - this.gh)) return false; this.Mh.set(t.x, t.y - this.gh); this.Uh(); return true; } else if (i.get("a") || i.get("ArrowLeft")) { this.direction = Direction.Left; if (this.Sh(t.x - this.wh, t.y)) return false; this.Mh.set(t.x - this.wh, t.y); this.Uh(); return true; } else if (i.get("d") || i.get("ArrowRight")) { this.direction = Direction.Right; if (this.Sh(t.x + this.wh, t.y)) return false; this.Mh.set(t.x + this.wh, t.y); this.Uh(); return true; } return false; } Uh() { this.Ah.invoke(Math.floor((this.Mh.x - this.Ch.x) / this.wh), Math.floor((this.Mh.y - this.Ch.y) / this.gh)); } Oh() { this.Vh.invoke(Math.floor((this.Dh.x - this.Ch.x) / this.wh), Math.floor((this.Dh.y - this.Ch.y) / this.gh)); } Rh() { const t = this.engine.input.map; if (t.get("w") || t.get("ArrowUp")) { this.Ih = false; } else if (t.get("s") || t.get("ArrowDown")) { this.Ih = false; } else if (t.get("a") || t.get("ArrowLeft")) { this.Ih = false; } else if (t.get("d") || t.get("ArrowRight")) { this.Ih = false; } } Kh() { if (!this.Ih) return; const t = this.transform; const i = this.xh.set(t.localPosition.x, t.localPosition.y); const s = this.bh[this.yh]; const e = s.distanceTo(i); if (e < this.dh * this.engine.time.deltaTime) { this.yh += 1; if (this.yh >= this.bh.length) { this.Ih = false; return; } else { this.Oh(); } } if (this.Sh(s.x, s.y)) { this.Ih = false; return; } if (this.Mh.equals(this.bh[this.yh])) return; this.Mh.copy(this.bh[this.yh]); this.Uh(); const h = this.bh[this.yh - 1].x; const r = this.bh[this.yh - 1].y; const n = this.bh[this.yh].x; const o = this.bh[this.yh].y; if (r < o) { this.direction = Direction.Up; } else if (r > o) { this.direction = Direction.Down; } else if (h < n) { this.direction = Direction.Right; } else if (h > n) { this.direction = Direction.Left; } this.isMoving = true; } Lh() { if (!this.isMoving) return; const t = this.transform; const i = this.xh.set(t.localPosition.x, t.localPosition.y); let s = i.distanceTo(this.Mh); const e = this.dh * this.engine.time.deltaTime; if (s < e) { if (this.Fh(this.Mh)) { s = i.distanceTo(this.Mh); this.Oh(); } } const h = this.Gh.copy(this.Mh).sub(i).normalize(); if (s < e) { this.isMoving = false; this.Dh.copy(this.Mh); t.localPosition.x = this.Dh.x; t.localPosition.y = this.Dh.y; this.Oh(); } else { h.multiplyScalar(e); this.gameObject.transform.localPosition.x += h.x; this.gameObject.transform.localPosition.y += h.y; } } Sh(t, i) { t += this.Eh.x; i += this.Eh.y; const s = this.Cr; for (let e = 0; e < s.length; ++e) { if (s[e].checkCollision(t, i, this.Ph, this.Ph)) { return true; } } return false; } zh=-1; Bh=new Vector2; jh=.3; Tr=t => { if (t.button !== 0) return; this.Ih = false; const i = this.engine.time.unscaledTime; if (i - this.zh < this.jh) { if (this.Bh.equals(t.gridPosition)) { this.qh(t); this.zh = -1; } } else { this.zh = i; this.Bh.copy(t.gridPosition); } }; qh(t) { if (this.Ih) { this.Ih = false; this.kh = () => { this.tryStartPathfind(t.gridPosition); }; return; } this.kh = () => { this.tryStartPathfind(t.gridPosition); }; } tryStartPathfind(t) { if (this.Ih) return false; this.kh = null; const i = this.bh = this.Ir.findPath(this.positionInGrid, t); if (!i || i.length <= 1) return false; for (let t = 0; t < i.length; ++t) { const s = i[t]; s.x = s.x * this.wh + this.Ch.x; s.y = s.y * this.gh + this.Ch.y; } this.yh = 1; this.isMoving = true; this.Ih = true; return true; } cancelPathfind() { this.Ih = false; } get onMoveToTarget() { return this.Ah; } get onMovedToTarget() { return this.Vh; } teleport(t) { this.isMoving = false; this.Ih = false; this.Dh.copy(t).multiplyScalar(this.wh).add(this.Ch); this.Mh.copy(this.Dh); this.transform.localPosition.x = this.Dh.x; this.transform.localPosition.y = this.Dh.y; this.Uh(); this.Oh(); } get speed() { return this.dh; } set speed(t) { this.dh = t; } get gridCenter() { return this.Ch; } set gridCenter(t) { this.Ch.copy(t); } get gridCellHeight() { return this.gh; } set gridCellHeight(t) { this.gh = t; } get gridCellWidth() { return this.wh; } set gridCellWidth(t) { this.wh = t; } set initPosition(t) { this.Th.copy(t); } set gridPointer(t) { if (this.Er) { this.Er.onPointerDown.removeListener(this.Tr); } this.Er = t; if (this.Er) { this.Er.onPointerDown.addListener(this.Tr); } } get gridPointer() { return this.Er; } addCollideMap(t) { this.Cr.push(t); this.Ir?.addCollideMap(t); } removeCollideMap(t) { const i = this.Cr.indexOf(t); if (i >= 0) { this.Cr.splice(i, 1); this.Ir?.removeCollideMap(t); } } removeAllCollideMaps() { this.Cr.length = 0; this.Ir?.removeAllCollideMaps(); } setGridInfoFromCollideMap(t) { this.wh = t.gridCellWidth; this.gh = t.gridCellHeight; this.Ch.set(t.gridCenterX, t.gridCenterY); } get positionInGrid() { return new Vector2(Math.floor((this.transform.localPosition.x - this.Ch.x) / this.wh), Math.floor((this.transform.localPosition.y - this.Ch.y) / this.gh)); } get receiveKeyboardInput() { return this.Wh; } set receiveKeyboardInput(t) { this.Wh = t; } }