EventMapper/assets/scripts/KaplayMap/gameobj.js

231 lines
6.2 KiB
JavaScript
Raw Normal View History

2024-06-02 05:39:23 +00:00
export class GameObjManager {
map;
2024-06-08 16:36:42 +00:00
opts = {
2024-06-11 04:16:13 +00:00
textColor: "FFFFFF",
2024-06-08 16:36:42 +00:00
bgColor: "303030",
bgFocusColor: "505030",
bgHoverColor: "505050",
bgFocusHoverColor: "707050",
bgClickColor: "202020",
bgFocusClickColor: "404020",
borderColor: "000000",
borderFocusColor: "808000",
font: "monospace",
fontSize: 24,
maxFontWidth: 16,
2024-06-09 12:23:14 +00:00
floorOpacity: 0.75,
roomOpacity: 0.75,
2024-06-08 16:36:42 +00:00
};
2024-06-02 05:39:23 +00:00
2024-06-05 07:30:05 +00:00
mainmanager;
2024-06-02 05:39:23 +00:00
floorObject;
roomObjects = new Map([]);
2024-06-08 16:36:42 +00:00
constructor(map, opts = {}) {
2024-06-02 05:39:23 +00:00
this.map = map;
2024-06-08 16:36:42 +00:00
this.opts = {
...this.opts,
...opts,
};
2024-06-05 07:30:05 +00:00
}
generateFloor() {
2024-06-02 05:39:23 +00:00
if (this.floorObject) this.floorObject.destroy();
2024-06-05 07:30:05 +00:00
const currentFloor = this.mainmanager.getCurrentFocusObject("floor");
2024-06-02 05:39:23 +00:00
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),
2024-06-11 04:16:13 +00:00
this.map.kp.color(this.map.kp.Color.fromHex(this.opts.bgColor)),
2024-06-09 12:23:14 +00:00
this.map.kp.opacity(this.opts.floorOpacity),
2024-06-02 05:39:23 +00:00
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;
2024-06-09 12:23:14 +00:00
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,
},
});
2024-06-02 05:39:23 +00:00
this.map.kp.drawText({
text: currentFloor.name,
size: 24 * camScale,
pos: this.map.kp.vec2(-4 * camScale, -8 * camScale),
2024-06-11 04:16:13 +00:00
color: this.map.kp.Color.fromHex(this.opts.textColor),
2024-06-02 05:39:23 +00:00
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
2024-06-08 16:36:42 +00:00
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);
2024-06-03 03:54:02 +00:00
this.map.zoomToAbs(
Math.log2(scale), // log scale
boundingBox.center()
);
2024-06-03 03:54:02 +00:00
}
zoomToFloor() {
const objectBounds = this.floorObject.renderArea().bbox();
this.zoomToBounds(objectBounds);
}
2024-06-03 03:54:02 +00:00
zoomToRoom(id) {
const selectedObject = this.roomObjects.get(id);
if (selectedObject == null) return;
const objectBounds = selectedObject.renderArea().bbox();
this.zoomToBounds(objectBounds);
2024-06-03 03:54:02 +00:00
}
2024-06-02 05:39:23 +00:00
generateRooms() {
if (this.roomObjects.size > 0) {
this.roomObjects.forEach((x) => x.destroy());
this.roomObjects.clear();
}
2024-06-05 07:30:05 +00:00
const currentRooms = this.mainmanager.getAllFocusObject("room");
2024-06-02 05:39:23 +00:00
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),
2024-06-08 16:36:42 +00:00
this.map.kp.color(this.map.kp.Color.fromHex(this.opts.bgColor)),
2024-06-09 12:23:14 +00:00
this.map.kp.opacity(this.opts.roomOpacity),
2024-06-02 05:39:23 +00:00
this.map.kp.area(),
this.map.kp.pos(),
this.map.kp.z(6),
{
2024-06-03 03:54:02 +00:00
clickForgiveness: 5,
2024-06-02 05:39:23 +00:00
startClickPosition: null,
},
]);
this.roomObjects.set(room.id, obj);
obj.onUpdate(() => {
2024-06-08 16:36:42 +00:00
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);
}
2024-06-02 05:39:23 +00:00
if (this.map.kp.isMousePressed() && obj.isHovering()) {
obj.startClickPosition = this.map.kp.mousePos();
2024-06-08 16:36:42 +00:00
}
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);
2024-06-02 05:39:23 +00:00
}
if (this.map.kp.isMouseReleased() && obj.isHovering()) {
const endClickPosition = this.map.kp.mousePos();
if (
obj.startClickPosition &&
obj.startClickPosition.dist(endClickPosition) < obj.clickForgiveness
) {
2024-06-05 07:30:05 +00:00
window.location.hash = room.id;
2024-06-02 05:39:23 +00:00
}
2024-06-08 16:36:42 +00:00
if (roomFocused)
obj.color = this.map.kp.Color.fromHex(this.opts.bgFocusHoverColor);
2024-06-02 05:39:23 +00:00
this.map.clearMouseMode();
}
});
obj.onDraw(() => {
const camScale = 1 / this.map.kp.camScale().y;
2024-06-08 16:36:42 +00:00
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,
},
2024-06-02 05:39:23 +00:00
});
2024-06-08 16:36:42 +00:00
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(),
2024-06-11 04:16:13 +00:00
color: this.map.kp.Color.fromHex(this.opts.textColor),
2024-06-08 16:36:42 +00:00
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(),
2024-06-11 04:16:13 +00:00
color: this.map.kp.Color.fromHex(this.opts.textColor),
2024-06-08 16:36:42 +00:00
align: "center",
anchor: "center",
});
2024-06-02 05:39:23 +00:00
});
this.floorObject.add(obj);
});
}
}