@unboxy/phaser-sdk 0.2.22 → 0.2.23
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.
|
@@ -209,15 +209,15 @@ function hitTest(game, worldX, worldY) {
|
|
|
209
209
|
let topmost = null;
|
|
210
210
|
let topmostDepth = -Infinity;
|
|
211
211
|
for (const go of registry.all()) {
|
|
212
|
-
const
|
|
213
|
-
if (
|
|
212
|
+
const r = entityHitRect(go);
|
|
213
|
+
if (!r)
|
|
214
214
|
continue;
|
|
215
|
-
const r = withBounds.getBounds();
|
|
216
215
|
if (worldX < r.x || worldX > r.x + r.width)
|
|
217
216
|
continue;
|
|
218
217
|
if (worldY < r.y || worldY > r.y + r.height)
|
|
219
218
|
continue;
|
|
220
|
-
const
|
|
219
|
+
const withDepth = go;
|
|
220
|
+
const depth = typeof withDepth.depth === 'number' ? withDepth.depth : 0;
|
|
221
221
|
if (depth >= topmostDepth) {
|
|
222
222
|
topmostDepth = depth;
|
|
223
223
|
topmost = go;
|
|
@@ -225,6 +225,37 @@ function hitTest(game, worldX, worldY) {
|
|
|
225
225
|
}
|
|
226
226
|
return topmost;
|
|
227
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Compute a hit-test rectangle for a spawned entity in world coords.
|
|
230
|
+
*
|
|
231
|
+
* 1. If the entity has `editorHitWidth` / `editorHitHeight` set in data
|
|
232
|
+
* (code-rendered entities — Graphics has no intrinsic bounds), use
|
|
233
|
+
* those centered on the entity's x/y.
|
|
234
|
+
* 2. Otherwise fall back to Phaser's `getBounds()` (works for Sprite,
|
|
235
|
+
* Rectangle, Arc, Container — anything with a Size component).
|
|
236
|
+
*
|
|
237
|
+
* Returns null if neither path yields a usable rect.
|
|
238
|
+
*/
|
|
239
|
+
function entityHitRect(go) {
|
|
240
|
+
const hitW = go.getData('editorHitWidth');
|
|
241
|
+
const hitH = go.getData('editorHitHeight');
|
|
242
|
+
if (typeof hitW === 'number' && typeof hitH === 'number') {
|
|
243
|
+
const positioned = go;
|
|
244
|
+
return {
|
|
245
|
+
x: positioned.x - hitW / 2,
|
|
246
|
+
y: positioned.y - hitH / 2,
|
|
247
|
+
width: hitW,
|
|
248
|
+
height: hitH,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
const withBounds = go;
|
|
252
|
+
if (typeof withBounds.getBounds !== 'function')
|
|
253
|
+
return null;
|
|
254
|
+
const r = withBounds.getBounds();
|
|
255
|
+
if (r.width === 0 && r.height === 0)
|
|
256
|
+
return null;
|
|
257
|
+
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
258
|
+
}
|
|
228
259
|
function findRegistry(game) {
|
|
229
260
|
for (const scene of game.scene.getScenes(false)) {
|
|
230
261
|
const reg = getEntityRegistry(scene);
|
|
@@ -190,10 +190,24 @@ export class EditorOverlayScene extends Phaser.Scene {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
function computeBounds(go) {
|
|
193
|
-
//
|
|
193
|
+
// Code-rendered entities stash hit dimensions on data because Phaser
|
|
194
|
+
// Graphics has no intrinsic bounds. Use those when present.
|
|
195
|
+
const hitW = go.getData('editorHitWidth');
|
|
196
|
+
const hitH = go.getData('editorHitHeight');
|
|
197
|
+
if (typeof hitW === 'number' && typeof hitH === 'number') {
|
|
198
|
+
const positioned = go;
|
|
199
|
+
return {
|
|
200
|
+
x: positioned.x - hitW / 2,
|
|
201
|
+
y: positioned.y - hitH / 2,
|
|
202
|
+
width: hitW,
|
|
203
|
+
height: hitH,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
194
206
|
const withBounds = go;
|
|
195
207
|
if (typeof withBounds.getBounds !== 'function')
|
|
196
208
|
return null;
|
|
197
209
|
const r = withBounds.getBounds();
|
|
210
|
+
if (r.width === 0 && r.height === 0)
|
|
211
|
+
return null;
|
|
198
212
|
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
199
213
|
}
|
|
@@ -94,6 +94,8 @@ function createGroup(ctx, entity) {
|
|
|
94
94
|
return container;
|
|
95
95
|
}
|
|
96
96
|
function createCodeRendered(ctx, entity) {
|
|
97
|
+
const w = entity.visual.width ?? 64;
|
|
98
|
+
const h = entity.visual.height ?? 64;
|
|
97
99
|
const render = ctx.resolveRenderScript?.(entity.visual.script);
|
|
98
100
|
if (!render) {
|
|
99
101
|
// Slice 3.5: render scripts have a registry now, but a missing entry
|
|
@@ -102,21 +104,35 @@ function createCodeRendered(ctx, entity) {
|
|
|
102
104
|
// the user sees the entity exists but the visual is unresolved.
|
|
103
105
|
const ph = ctx.scene.add.graphics();
|
|
104
106
|
ph.fillStyle(0x666666, 0.4);
|
|
105
|
-
ph.fillRect(-
|
|
107
|
+
ph.fillRect(-w / 2, -h / 2, w, h);
|
|
106
108
|
ph.lineStyle(2, 0xff8800, 0.9);
|
|
107
|
-
ph.strokeRect(-
|
|
108
|
-
|
|
109
|
+
ph.strokeRect(-w / 2, -h / 2, w, h);
|
|
110
|
+
sizeForHitTest(ph, w, h);
|
|
109
111
|
ph.setData('renderScriptMissing', entity.visual.script);
|
|
110
112
|
return ph;
|
|
111
113
|
}
|
|
112
114
|
const g = ctx.scene.add.graphics();
|
|
113
115
|
const params = entity.visual.params ?? {};
|
|
114
116
|
render(g, params);
|
|
117
|
+
sizeForHitTest(g, w, h);
|
|
115
118
|
// Stash data needed for live re-render from EditorBridge.applyEdit.
|
|
116
119
|
g.setData('renderScriptPath', entity.visual.script);
|
|
117
120
|
g.setData('renderScriptParams', params);
|
|
118
121
|
return g;
|
|
119
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Phaser Graphics doesn't track its drawn area — `getBounds()` returns
|
|
125
|
+
* a 0×0 rect because the Graphics class doesn't include the Size/Origin
|
|
126
|
+
* mixins. Rather than fight Phaser's class hierarchy with method casts,
|
|
127
|
+
* stash the editor hit area on the GameObject's data manager. The editor
|
|
128
|
+
* overlay reads these before falling back to `getBounds()`. The implicit
|
|
129
|
+
* convention: hit area is centered on the GameObject's x/y, matching how
|
|
130
|
+
* render scripts conventionally draw around (0, 0).
|
|
131
|
+
*/
|
|
132
|
+
function sizeForHitTest(g, width, height) {
|
|
133
|
+
g.setData('editorHitWidth', width);
|
|
134
|
+
g.setData('editorHitHeight', height);
|
|
135
|
+
}
|
|
120
136
|
function applyTransform(go, t) {
|
|
121
137
|
// Most game objects implement Transform; Container does too. Cast through
|
|
122
138
|
// a permissive shape so this works for sprite/rect/circle/container alike.
|
package/dist/scene/types.d.ts
CHANGED
|
@@ -116,6 +116,14 @@ export interface CodeRenderedVisual {
|
|
|
116
116
|
/** Path to render script, e.g. `"src/visuals/boss-renderer.ts"`. */
|
|
117
117
|
script: string;
|
|
118
118
|
params?: Record<string, unknown>;
|
|
119
|
+
/**
|
|
120
|
+
* Optional bounds used for editor hit-testing (click + drag) and the
|
|
121
|
+
* selection rectangle. Phaser Graphics has no intrinsic size, so we set
|
|
122
|
+
* it explicitly. Defaults to 64×64 centered on the entity. The agent can
|
|
123
|
+
* override per-entity when the script draws something larger or smaller.
|
|
124
|
+
*/
|
|
125
|
+
width?: number;
|
|
126
|
+
height?: number;
|
|
119
127
|
}
|
|
120
128
|
export type WorldVisual = SpriteVisual | PrimitiveVisual | CodeRenderedVisual;
|
|
121
129
|
export type WorldEntityKind = 'sprite' | 'primitive' | 'code-rendered' | 'group' | 'tilemap' | 'trigger';
|