@mertdogar/phaser-procedural-walls 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/WallEditor.d.ts +4 -0
- package/dist/editor/assets/{index-BEDA_QpG.js → index-BIMJ5usj.js} +1299 -1299
- package/dist/editor/index.html +1 -1
- package/dist/index.js +87 -56
- package/package.json +1 -1
package/dist/editor/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>Wallcraft Prototype</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-BIMJ5usj.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-BVmRKDUb.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import
|
|
1
|
+
var m = Object.defineProperty;
|
|
2
|
+
var S = (f, t, i) => t in f ? m(f, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : f[t] = i;
|
|
3
|
+
var a = (f, t, i) => S(f, typeof t != "symbol" ? t + "" : t, i);
|
|
4
|
+
import h from "phaser";
|
|
5
5
|
import { resolveWalls as g } from "./geometry.js";
|
|
6
|
-
class
|
|
6
|
+
class D {
|
|
7
7
|
constructor(t, i) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
a(this, "scene");
|
|
9
|
+
a(this, "containers", []);
|
|
10
|
+
a(this, "bodies", null);
|
|
11
|
+
a(this, "config");
|
|
12
12
|
this.scene = t, this.config = i, this.build();
|
|
13
13
|
}
|
|
14
14
|
setWalls(t) {
|
|
@@ -32,18 +32,18 @@ class m {
|
|
|
32
32
|
this.containers.push(this.drawWall(s, t[s.spec.preset])), this.bodies && this.addBody(s);
|
|
33
33
|
}
|
|
34
34
|
drawWall(t, i) {
|
|
35
|
-
const { body: e, lip: n, bodyPieces: s, lipPieces: l, windows:
|
|
35
|
+
const { body: e, lip: n, bodyPieces: s, lipPieces: l, windows: c, sills: r } = t, d = this.scene.add.container(0, 0), u = this.scene.add.graphics(), w = this.scene.add.graphics(), x = i.edgeWidth ?? 2;
|
|
36
36
|
for (const o of s) this.fillRect(d, u, o, i.fill, i.texture);
|
|
37
37
|
for (const o of l) this.fillRect(d, u, o, i.lipFill ?? i.fill, i.lipTexture);
|
|
38
38
|
const y = i.windowFill ?? 4030344;
|
|
39
|
-
for (const o of
|
|
39
|
+
for (const o of c)
|
|
40
40
|
u.fillStyle(y, i.windowAlpha ?? 0.5), u.fillRect(o.x, o.y, o.w, o.h);
|
|
41
41
|
d.add(u);
|
|
42
|
-
for (const o of
|
|
43
|
-
for (const o of
|
|
42
|
+
for (const o of r) this.fillRect(d, w, o, i.fill, i.texture);
|
|
43
|
+
for (const o of r) w.lineStyle(1, i.edge).lineBetween(o.x, o.y, o.x + o.w, o.y);
|
|
44
44
|
if (i.windowFrame !== void 0)
|
|
45
|
-
for (const o of
|
|
46
|
-
return
|
|
45
|
+
for (const o of c) w.lineStyle(1, i.windowFrame).strokeRect(o.x, o.y, o.w, o.h);
|
|
46
|
+
return w.lineStyle(x, i.edge), w.strokeRect(e.x, e.y, e.w, e.h), n && w.lineStyle(x, i.edge).strokeRect(n.x, n.y, n.w, n.h), d.add(w), d.setDepth(t.depth), d;
|
|
47
47
|
}
|
|
48
48
|
fillRect(t, i, e, n, s) {
|
|
49
49
|
if (!s) {
|
|
@@ -58,28 +58,30 @@ class m {
|
|
|
58
58
|
this.scene.physics.add.existing(e, !0), this.bodies.add(e);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
class
|
|
61
|
+
class M extends h.Plugins.ScenePlugin {
|
|
62
62
|
constructor(t, i, e) {
|
|
63
63
|
super(t, i, e), typeof t.add.wallMap != "function" && i.registerGameObject("wallMap", function(n) {
|
|
64
|
-
return new
|
|
64
|
+
return new D(this.scene, n);
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
class
|
|
68
|
+
class P {
|
|
69
69
|
constructor(t, i) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
a(this, "configData");
|
|
71
|
+
a(this, "selectedIndex");
|
|
72
|
+
a(this, "tool");
|
|
73
|
+
a(this, "enabled");
|
|
74
|
+
a(this, "camera");
|
|
75
|
+
a(this, "gridSize");
|
|
76
|
+
a(this, "overlay");
|
|
77
|
+
a(this, "callbacks");
|
|
78
|
+
a(this, "newWall");
|
|
79
|
+
a(this, "drawStart", null);
|
|
80
|
+
a(this, "pointerPosition", null);
|
|
81
|
+
a(this, "anchorDrag", null);
|
|
82
|
+
a(this, "windowDrag", null);
|
|
83
|
+
a(this, "wallDrag", null);
|
|
84
|
+
a(this, "wallPreview", null);
|
|
83
85
|
var e;
|
|
84
86
|
if (this.scene = t, this.gridSize = i.gridSize ?? 32, !Number.isFinite(this.gridSize) || this.gridSize <= 0) throw new Error("gridSize must be positive and finite");
|
|
85
87
|
this.camera = i.camera ?? t.cameras.main, this.configData = i.config, this.selectedIndex = i.selectedIndex, this.tool = i.tool, this.enabled = i.enabled ?? !0, this.callbacks = i, this.newWall = { ...i.newWall, thickness: ((e = i.newWall) == null ? void 0 : e.thickness) ?? 16 }, this.overlay = t.add.graphics().setDepth(i.overlayDepth ?? 1e4), t.input.on("pointerdown", this.handlePointerDown, this), t.input.on("pointermove", this.handlePointerMove, this), t.input.on("pointerup", this.handlePointerUp, this), t.input.on("pointerupoutside", this.handlePointerUp, this), t.events.once("shutdown", this.destroy, this), this.refresh();
|
|
@@ -91,13 +93,14 @@ class W {
|
|
|
91
93
|
this.newWall = { ...t, thickness: t.thickness ?? 16 };
|
|
92
94
|
}
|
|
93
95
|
get dragging() {
|
|
94
|
-
return !!(this.drawStart || this.anchorDrag || this.windowDrag);
|
|
96
|
+
return !!(this.drawStart || this.anchorDrag || this.windowDrag || this.wallDrag);
|
|
95
97
|
}
|
|
96
98
|
cancel() {
|
|
97
|
-
|
|
99
|
+
var t;
|
|
100
|
+
this.drawStart = null, this.pointerPosition = null, this.anchorDrag = null, this.windowDrag = null, this.wallDrag = null, (t = this.wallPreview) == null || t.destroy(), this.wallPreview = null, this.scene.input.setDefaultCursor("default"), this.refresh();
|
|
98
101
|
}
|
|
99
102
|
destroy() {
|
|
100
|
-
this.scene.input.off("pointerdown", this.handlePointerDown, this), this.scene.input.off("pointermove", this.handlePointerMove, this), this.scene.input.off("pointerup", this.handlePointerUp, this), this.scene.input.off("pointerupoutside", this.handlePointerUp, this), this.scene.events.off("shutdown", this.destroy, this), this.scene.input.setDefaultCursor("default"), this.overlay.destroy();
|
|
103
|
+
this.cancel(), this.scene.input.off("pointerdown", this.handlePointerDown, this), this.scene.input.off("pointermove", this.handlePointerMove, this), this.scene.input.off("pointerup", this.handlePointerUp, this), this.scene.input.off("pointerupoutside", this.handlePointerUp, this), this.scene.events.off("shutdown", this.destroy, this), this.scene.input.setDefaultCursor("default"), this.overlay.destroy();
|
|
101
104
|
}
|
|
102
105
|
handlePointerDown(t) {
|
|
103
106
|
if (!this.enabled || !t.leftButtonDown()) return;
|
|
@@ -122,6 +125,11 @@ class W {
|
|
|
122
125
|
}, this.scene.input.setDefaultCursor("grabbing");
|
|
123
126
|
return;
|
|
124
127
|
}
|
|
128
|
+
if (this.selectedIndex !== null && this.onSelectedLine(t.worldX, t.worldY)) {
|
|
129
|
+
const s = this.configData.walls[this.selectedIndex];
|
|
130
|
+
this.wallDrag = { index: this.selectedIndex, wall: s, start: new h.Math.Vector2(t.worldX, t.worldY), preview: s }, this.scene.input.setDefaultCursor("grabbing");
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
125
133
|
this.callbacks.onSelectWall(this.findWall(t.worldX, t.worldY));
|
|
126
134
|
return;
|
|
127
135
|
}
|
|
@@ -129,7 +137,15 @@ class W {
|
|
|
129
137
|
}
|
|
130
138
|
handlePointerMove(t) {
|
|
131
139
|
if (this.enabled) {
|
|
132
|
-
if (t.updateWorldPoint(this.camera), this.
|
|
140
|
+
if (t.updateWorldPoint(this.camera), this.wallDrag && t.isDown) {
|
|
141
|
+
const i = this.wallDrag;
|
|
142
|
+
i.preview = this.moveWall(i, t.worldX, t.worldY), this.wallPreview ?? (this.wallPreview = new D(this.scene, { presets: this.configData.presets, walls: [i.wall] }));
|
|
143
|
+
for (const e of this.wallPreview.containers)
|
|
144
|
+
e.setPosition(i.preview.x1 - i.wall.x1, i.preview.y1 - i.wall.y1).setAlpha(0.65).setDepth(this.overlay.depth - 1);
|
|
145
|
+
this.refresh();
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
if (this.windowDrag && t.isDown) {
|
|
133
149
|
this.windowDrag.wall = this.moveWindow(
|
|
134
150
|
this.windowDrag.wall,
|
|
135
151
|
this.windowDrag.windowIndex,
|
|
@@ -151,13 +167,18 @@ class W {
|
|
|
151
167
|
const e = this.configData.walls[this.selectedIndex];
|
|
152
168
|
this.scene.input.setDefaultCursor(e.y1 === e.y2 ? "ew-resize" : "ns-resize");
|
|
153
169
|
} else
|
|
154
|
-
this.scene.input.setDefaultCursor(this.findAnchor(t.worldX, t.worldY) ? "grab" : "default");
|
|
170
|
+
this.scene.input.setDefaultCursor(this.findAnchor(t.worldX, t.worldY) || this.onSelectedLine(t.worldX, t.worldY) ? "grab" : "default");
|
|
155
171
|
!this.drawStart || !t.isDown || (this.pointerPosition = this.axisLock(this.drawStart, this.snapPoint(t.worldX, t.worldY)), this.refresh());
|
|
156
172
|
}
|
|
157
173
|
}
|
|
158
174
|
handlePointerUp(t) {
|
|
159
175
|
if (!this.enabled) return;
|
|
160
|
-
if (t.updateWorldPoint(this.camera), this.
|
|
176
|
+
if (t.updateWorldPoint(this.camera), this.wallDrag) {
|
|
177
|
+
const n = this.wallDrag, s = this.moveWall(n, t.worldX, t.worldY);
|
|
178
|
+
this.cancel(), (s.x1 !== n.wall.x1 || s.y1 !== n.wall.y1) && this.callbacks.onUpdateWall(n.index, { x1: s.x1, y1: s.y1, x2: s.x2, y2: s.y2 });
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (this.windowDrag) {
|
|
161
182
|
const n = this.windowDrag, s = this.moveWindow(n.wall, n.windowIndex, t.worldX, t.worldY);
|
|
162
183
|
this.windowDrag = null, this.scene.input.setDefaultCursor("default"), this.callbacks.onUpdateWall(n.index, { windows: s.windows }), this.refresh();
|
|
163
184
|
return;
|
|
@@ -168,7 +189,7 @@ class W {
|
|
|
168
189
|
n.endpoint,
|
|
169
190
|
this.snapPoint(t.worldX, t.worldY)
|
|
170
191
|
);
|
|
171
|
-
this.anchorDrag = null, this.scene.input.setDefaultCursor("default"),
|
|
192
|
+
this.anchorDrag = null, this.scene.input.setDefaultCursor("default"), h.Math.Distance.Between(s.x1, s.y1, s.x2, s.y2) >= this.gridSize && this.callbacks.onUpdateWall(n.index, {
|
|
172
193
|
x1: s.x1,
|
|
173
194
|
y1: s.y1,
|
|
174
195
|
x2: s.x2,
|
|
@@ -178,7 +199,7 @@ class W {
|
|
|
178
199
|
}
|
|
179
200
|
if (!this.drawStart) return;
|
|
180
201
|
const i = this.axisLock(this.drawStart, this.snapPoint(t.worldX, t.worldY)), e = this.drawStart;
|
|
181
|
-
if (this.drawStart = null, this.pointerPosition = null,
|
|
202
|
+
if (this.drawStart = null, this.pointerPosition = null, h.Math.Distance.Between(e.x, e.y, i.x, i.y) >= this.gridSize) {
|
|
182
203
|
const n = this.newWall.preset ?? (Object.hasOwn(this.configData.presets, "interior") ? "interior" : Object.keys(this.configData.presets)[0]);
|
|
183
204
|
if (!n || !Object.hasOwn(this.configData.presets, n)) throw new Error("Choose an existing wall preset before drawing");
|
|
184
205
|
this.callbacks.onAddWall({
|
|
@@ -193,15 +214,15 @@ class W {
|
|
|
193
214
|
this.refresh();
|
|
194
215
|
}
|
|
195
216
|
refresh() {
|
|
196
|
-
var i, e, n;
|
|
217
|
+
var i, e, n, s;
|
|
197
218
|
if (!this.overlay || (this.overlay.clear(), !this.enabled)) return;
|
|
198
|
-
const t = ((i = this.
|
|
219
|
+
const t = ((i = this.wallDrag) == null ? void 0 : i.preview) ?? ((e = this.windowDrag) == null ? void 0 : e.wall) ?? ((n = this.anchorDrag) == null ? void 0 : n.wall) ?? (this.selectedIndex === null ? null : this.configData.walls[this.selectedIndex]);
|
|
199
220
|
if (t) {
|
|
200
|
-
const
|
|
201
|
-
this.overlay.lineStyle(4, 2980428, 1).lineBetween(t.x1, t.y1, t.x2, t.y2), this.overlay.fillStyle(16777215, 1).fillCircle(t.x1, t.y1,
|
|
202
|
-
for (const [
|
|
203
|
-
const
|
|
204
|
-
this.overlay.fillStyle(
|
|
221
|
+
const l = 8 / this.camera.zoom;
|
|
222
|
+
this.overlay.lineStyle(4, 2980428, 1).lineBetween(t.x1, t.y1, t.x2, t.y2), this.overlay.fillStyle(16777215, 1).fillCircle(t.x1, t.y1, l).fillCircle(t.x2, t.y2, l), this.overlay.lineStyle(3 / this.camera.zoom, 2980428, 1).strokeCircle(t.x1, t.y1, l).strokeCircle(t.x2, t.y2, l);
|
|
223
|
+
for (const [c, r] of this.getWindowRects(t).entries()) {
|
|
224
|
+
const d = ((s = this.windowDrag) == null ? void 0 : s.windowIndex) === c;
|
|
225
|
+
this.overlay.fillStyle(d ? 2980428 : 16777215, d ? 0.35 : 0.75).fillRect(r.x, r.y, r.w, r.h), this.overlay.lineStyle(3, 2980428, 1).strokeRect(r.x, r.y, r.w, r.h);
|
|
205
226
|
}
|
|
206
227
|
}
|
|
207
228
|
this.drawStart && this.pointerPosition && (this.overlay.lineStyle(4, 14916150, 0.95).lineBetween(
|
|
@@ -214,16 +235,26 @@ class W {
|
|
|
214
235
|
findWall(t, i) {
|
|
215
236
|
let e = null;
|
|
216
237
|
for (const [n, s] of this.configData.walls.entries()) {
|
|
217
|
-
const l = s.x1 === s.x2 ? Math.hypot(t - s.x1, i -
|
|
238
|
+
const l = s.x1 === s.x2 ? Math.hypot(t - s.x1, i - h.Math.Clamp(i, Math.min(s.y1, s.y2), Math.max(s.y1, s.y2))) : Math.hypot(t - h.Math.Clamp(t, Math.min(s.x1, s.x2), Math.max(s.x1, s.x2)), i - s.y1);
|
|
218
239
|
l <= s.thickness / 2 + 10 / this.camera.zoom && (!e || l < e.distance) && (e = { index: n, distance: l });
|
|
219
240
|
}
|
|
220
241
|
return (e == null ? void 0 : e.index) ?? null;
|
|
221
242
|
}
|
|
243
|
+
onSelectedLine(t, i) {
|
|
244
|
+
const e = this.selectedIndex === null ? void 0 : this.configData.walls[this.selectedIndex];
|
|
245
|
+
if (!e) return !1;
|
|
246
|
+
const n = e.y1 === e.y2, s = n ? t : i, l = n ? e.x1 : e.y1, c = n ? e.x2 : e.y2;
|
|
247
|
+
return s >= Math.min(l, c) && s <= Math.max(l, c) && Math.abs(n ? i - e.y1 : t - e.x1) <= 6 / this.camera.zoom;
|
|
248
|
+
}
|
|
249
|
+
moveWall(t, i, e) {
|
|
250
|
+
const n = Math.round((i - t.start.x) / this.gridSize) * this.gridSize, s = Math.round((e - t.start.y) / this.gridSize) * this.gridSize, l = t.wall;
|
|
251
|
+
return { ...l, x1: l.x1 + n, y1: l.y1 + s, x2: l.x2 + n, y2: l.y2 + s };
|
|
252
|
+
}
|
|
222
253
|
findAnchor(t, i) {
|
|
223
254
|
if (this.selectedIndex === null) return null;
|
|
224
255
|
const e = this.configData.walls[this.selectedIndex];
|
|
225
256
|
if (!e) return null;
|
|
226
|
-
const n =
|
|
257
|
+
const n = h.Math.Distance.Between(t, i, e.x1, e.y1), s = h.Math.Distance.Between(t, i, e.x2, e.y2);
|
|
227
258
|
return Math.min(n, s) > 16 / this.camera.zoom ? null : n <= s ? "start" : "end";
|
|
228
259
|
}
|
|
229
260
|
findWindow(t, i) {
|
|
@@ -241,30 +272,30 @@ class W {
|
|
|
241
272
|
var y;
|
|
242
273
|
const s = ((y = t.windows) == null ? void 0 : y.map((o) => ({ ...o }))) ?? [], l = s[i];
|
|
243
274
|
if (!l) return t;
|
|
244
|
-
const
|
|
275
|
+
const c = t.y1 === t.y2, r = c ? Math.sign(t.x2 - t.x1) || 1 : Math.sign(t.y2 - t.y1) || 1, d = c ? (e - t.x1) * r : (n - t.y1) * r, u = Math.abs(t.x2 - t.x1) + Math.abs(t.y2 - t.y1), w = Math.max(0, u - l.width), x = h.Math.Clamp(
|
|
245
276
|
Math.round((d - l.width / 2) / this.gridSize) * this.gridSize,
|
|
246
277
|
0,
|
|
247
|
-
|
|
278
|
+
w
|
|
248
279
|
);
|
|
249
280
|
return s[i] = { ...l, offset: x }, { ...t, windows: s };
|
|
250
281
|
}
|
|
251
282
|
moveEndpoint(t, i, e) {
|
|
252
|
-
const n = i === "start" ? new
|
|
283
|
+
const n = i === "start" ? new h.Math.Vector2(t.x2, t.y2) : new h.Math.Vector2(t.x1, t.y1), s = this.axisLock(n, e);
|
|
253
284
|
return i === "start" ? { ...t, x1: s.x, y1: s.y } : { ...t, x2: s.x, y2: s.y };
|
|
254
285
|
}
|
|
255
286
|
snapPoint(t, i) {
|
|
256
|
-
return new
|
|
287
|
+
return new h.Math.Vector2(
|
|
257
288
|
Math.round(t / this.gridSize) * this.gridSize,
|
|
258
289
|
Math.round(i / this.gridSize) * this.gridSize
|
|
259
290
|
);
|
|
260
291
|
}
|
|
261
292
|
axisLock(t, i) {
|
|
262
|
-
return Math.abs(i.x - t.x) >= Math.abs(i.y - t.y) ? new
|
|
293
|
+
return Math.abs(i.x - t.x) >= Math.abs(i.y - t.y) ? new h.Math.Vector2(i.x, t.y) : new h.Math.Vector2(t.x, i.y);
|
|
263
294
|
}
|
|
264
295
|
}
|
|
265
296
|
export {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
297
|
+
P as WallEditor,
|
|
298
|
+
D as WallMap,
|
|
299
|
+
M as WallMapPlugin,
|
|
269
300
|
g as resolveWalls
|
|
270
301
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mertdogar/phaser-procedural-walls",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Phaser 4 scene plugin that renders procedural top-down walls with faces, see-through windows, depth sorting and Arcade colliders from wall centerline data.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"phaser",
|