export class GameObjManager { map; opts = { bgColor: "303030", bgFocusColor: "505030", bgHoverColor: "505050", bgFocusHoverColor: "707050", bgClickColor: "202020", bgFocusClickColor: "404020", borderColor: "000000", borderFocusColor: "808000", font: "monospace", fontSize: 24, maxFontWidth: 16, floorOpacity: 0.75, roomOpacity: 0.75, }; mainmanager; floorObject; roomObjects = new Map([]); constructor(map, opts = {}) { this.map = map; this.opts = { ...this.opts, ...opts, }; } generateFloor() { if (this.floorObject) this.floorObject.destroy(); const currentFloor = this.mainmanager.getCurrentFocusObject("floor"); const polygon = new this.map.kp.Polygon( currentFloor.poly.map(([x, y]) => this.map.kp.vec2(x, y)) ); this.floorObject = this.map.kp.make([ this.map.kp.polygon(polygon.pts), this.map.kp.color(this.map.kp.Color.fromHex("303030")), this.map.kp.opacity(this.opts.floorOpacity), this.map.kp.pos(), this.map.kp.z(5), ]); const bounds = polygon.bbox(); this.map.camBounds = bounds; this.floorObject.onDraw(() => { const camScale = 1 / this.map.kp.camScale().y; this.map.kp.drawPolygon({ pts: polygon.pts, pos: this.map.kp.vec2(0), fill: false, outline: { color: this.map.kp.Color.fromHex(this.opts.borderColor), width: 8 * camScale, }, }); this.map.kp.drawText({ text: currentFloor.name, size: 24 * camScale, pos: this.map.kp.vec2(-4 * camScale, -8 * camScale), color: this.map.kp.WHITE, anchor: "botleft", }); }); this.map.kp.add(this.floorObject); } zoomToBounds(boundingBox) { // Get screen size const width = this.map.kp.width(); const height = this.map.kp.height(); // Get bbox size const bBoxWidth = boundingBox.width * 2; const bBoxHeight = boundingBox.height * 2; // Compare bounds const scaledWidth = width / bBoxWidth; const scaledHeight = height / bBoxHeight; // Whichever one is biggest const scale = Math.min(scaledWidth, scaledHeight); this.map.zoomToAbs( Math.log2(scale), // log scale boundingBox.center() ); } zoomToFloor() { const objectBounds = this.floorObject.renderArea().bbox(); this.zoomToBounds(objectBounds); } zoomToRoom(id) { const selectedObject = this.roomObjects.get(id); if (selectedObject == null) return; const objectBounds = selectedObject.renderArea().bbox(); this.zoomToBounds(objectBounds); } generateRooms() { if (this.roomObjects.size > 0) { this.roomObjects.forEach((x) => x.destroy()); this.roomObjects.clear(); } const currentRooms = this.mainmanager.getAllFocusObject("room"); currentRooms.forEach((room) => { const polygon = new this.map.kp.Polygon( room.poly.map(([x, y]) => this.map.kp.vec2(x, y)) ); const obj = this.map.kp.make([ this.map.kp.polygon(polygon.pts), this.map.kp.color(this.map.kp.Color.fromHex(this.opts.bgColor)), this.map.kp.opacity(this.opts.roomOpacity), this.map.kp.area(), this.map.kp.pos(), this.map.kp.z(6), { clickForgiveness: 5, startClickPosition: null, }, ]); this.roomObjects.set(room.id, obj); obj.onUpdate(() => { const roomFocused = this.mainmanager.getCurrentFocus("room") == room.id; if (roomFocused) { obj.z = 7; } else { obj.z = 6; } if (obj.isHovering()) { if (roomFocused) obj.color = this.map.kp.Color.fromHex(this.opts.bgFocusHoverColor); else obj.color = this.map.kp.Color.fromHex(this.opts.bgHoverColor); } else { if (roomFocused) obj.color = this.map.kp.Color.fromHex(this.opts.bgFocusColor); else obj.color = this.map.kp.Color.fromHex(this.opts.bgColor); } if (this.map.kp.isMousePressed() && obj.isHovering()) { obj.startClickPosition = this.map.kp.mousePos(); } if (this.map.kp.isMouseDown() && obj.isHovering()) { if (roomFocused) obj.color = this.map.kp.Color.fromHex(this.opts.bgFocusClickColor); else obj.color = this.map.kp.Color.fromHex(this.opts.bgClickColor); } if (this.map.kp.isMouseReleased() && obj.isHovering()) { const endClickPosition = this.map.kp.mousePos(); if ( obj.startClickPosition && obj.startClickPosition.dist(endClickPosition) < obj.clickForgiveness ) { window.location.hash = room.id; } if (roomFocused) obj.color = this.map.kp.Color.fromHex(this.opts.bgFocusHoverColor); this.map.clearMouseMode(); } }); obj.onDraw(() => { const camScale = 1 / this.map.kp.camScale().y; const roomFocused = this.mainmanager.getCurrentFocus("room") == room.id; this.map.kp.drawPolygon({ pts: polygon.pts, pos: this.map.kp.vec2(0), fill: false, outline: { color: this.map.kp.Color.fromHex( roomFocused ? this.opts.borderFocusColor : this.opts.borderColor ), width: 8 * camScale, }, }); if ( this.opts.maxFontWidth * camScale * room.name.length > polygon.bbox().width ) this.map.kp.drawText({ text: room.shortName + "…", size: this.opts.fontSize * camScale, pos: polygon.bbox().center(), color: this.map.kp.WHITE, align: "center", anchor: "center", }); else this.map.kp.drawText({ text: room.name, width: polygon.bbox().width, size: this.opts.fontSize * camScale, pos: polygon.bbox().center(), color: this.map.kp.WHITE, align: "center", anchor: "center", }); }); this.floorObject.add(obj); }); } }