@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.
@@ -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-BEDA_QpG.js"></script>
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 D = Object.defineProperty;
2
- var p = (w, t, i) => t in w ? D(w, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : w[t] = i;
3
- var r = (w, t, i) => p(w, typeof t != "symbol" ? t + "" : t, i);
4
- import a from "phaser";
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 m {
6
+ class D {
7
7
  constructor(t, i) {
8
- r(this, "scene");
9
- r(this, "containers", []);
10
- r(this, "bodies", null);
11
- r(this, "config");
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: h, sills: f } = t, d = this.scene.add.container(0, 0), u = this.scene.add.graphics(), c = this.scene.add.graphics(), x = i.edgeWidth ?? 2;
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 h)
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 f) this.fillRect(d, c, o, i.fill, i.texture);
43
- for (const o of f) c.lineStyle(1, i.edge).lineBetween(o.x, o.y, o.x + o.w, o.y);
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 h) c.lineStyle(1, i.windowFrame).strokeRect(o.x, o.y, o.w, o.h);
46
- return c.lineStyle(x, i.edge), c.strokeRect(e.x, e.y, e.w, e.h), n && c.lineStyle(x, i.edge).strokeRect(n.x, n.y, n.w, n.h), d.add(c), d.setDepth(t.depth), d;
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 P extends a.Plugins.ScenePlugin {
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 m(this.scene, n);
64
+ return new D(this.scene, n);
65
65
  });
66
66
  }
67
67
  }
68
- class W {
68
+ class P {
69
69
  constructor(t, i) {
70
- r(this, "configData");
71
- r(this, "selectedIndex");
72
- r(this, "tool");
73
- r(this, "enabled");
74
- r(this, "camera");
75
- r(this, "gridSize");
76
- r(this, "overlay");
77
- r(this, "callbacks");
78
- r(this, "newWall");
79
- r(this, "drawStart", null);
80
- r(this, "pointerPosition", null);
81
- r(this, "anchorDrag", null);
82
- r(this, "windowDrag", null);
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
- this.drawStart = null, this.pointerPosition = null, this.anchorDrag = null, this.windowDrag = null, this.scene.input.setDefaultCursor("default"), this.refresh();
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.windowDrag && t.isDown) {
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.windowDrag) {
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"), a.Math.Distance.Between(s.x1, s.y1, s.x2, s.y2) >= this.gridSize && this.callbacks.onUpdateWall(n.index, {
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, a.Math.Distance.Between(e.x, e.y, i.x, i.y) >= this.gridSize) {
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.windowDrag) == null ? void 0 : i.wall) ?? ((e = this.anchorDrag) == null ? void 0 : e.wall) ?? (this.selectedIndex === null ? null : this.configData.walls[this.selectedIndex]);
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 s = 8 / this.camera.zoom;
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, s).fillCircle(t.x2, t.y2, s), this.overlay.lineStyle(3 / this.camera.zoom, 2980428, 1).strokeCircle(t.x1, t.y1, s).strokeCircle(t.x2, t.y2, s);
202
- for (const [l, h] of this.getWindowRects(t).entries()) {
203
- const f = ((n = this.windowDrag) == null ? void 0 : n.windowIndex) === l;
204
- this.overlay.fillStyle(f ? 2980428 : 16777215, f ? 0.35 : 0.75).fillRect(h.x, h.y, h.w, h.h), this.overlay.lineStyle(3, 2980428, 1).strokeRect(h.x, h.y, h.w, h.h);
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 - a.Math.Clamp(i, Math.min(s.y1, s.y2), Math.max(s.y1, s.y2))) : Math.hypot(t - a.Math.Clamp(t, Math.min(s.x1, s.x2), Math.max(s.x1, s.x2)), i - s.y1);
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 = a.Math.Distance.Between(t, i, e.x1, e.y1), s = a.Math.Distance.Between(t, i, e.x2, e.y2);
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 h = t.y1 === t.y2, f = h ? Math.sign(t.x2 - t.x1) || 1 : Math.sign(t.y2 - t.y1) || 1, d = h ? (e - t.x1) * f : (n - t.y1) * f, u = Math.abs(t.x2 - t.x1) + Math.abs(t.y2 - t.y1), c = Math.max(0, u - l.width), x = a.Math.Clamp(
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
- c
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 a.Math.Vector2(t.x2, t.y2) : new a.Math.Vector2(t.x1, t.y1), s = this.axisLock(n, e);
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 a.Math.Vector2(
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 a.Math.Vector2(i.x, t.y) : new a.Math.Vector2(t.x, i.y);
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
- W as WallEditor,
267
- m as WallMap,
268
- P as WallMapPlugin,
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.0",
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",