@unboxy/phaser-sdk 0.2.23 → 0.2.25
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.
|
@@ -2,6 +2,7 @@ import Phaser from 'phaser';
|
|
|
2
2
|
import { getEntityRegistry } from '../scene/EntityRegistry.js';
|
|
3
3
|
import { parseColor, spawnEntity } from '../scene/spawnEntity.js';
|
|
4
4
|
import { resolveRenderScript } from '../scene/renderScripts.js';
|
|
5
|
+
import { getManifest } from '../scene/SceneLoader.js';
|
|
5
6
|
import { EditorOverlayScene, EDITOR_OVERLAY_KEY } from './EditorOverlayScene.js';
|
|
6
7
|
import { getEditorState, setEditorActive, setSelection, } from './EditorState.js';
|
|
7
8
|
/**
|
|
@@ -384,23 +385,49 @@ async function createEntity(game, entity, manifestAsset) {
|
|
|
384
385
|
console.warn('[unboxy/editor] createEntity: world scene has no entity registry');
|
|
385
386
|
return;
|
|
386
387
|
}
|
|
388
|
+
// Resolve which AssetRecord to use for the lazy-load probe. Three paths:
|
|
389
|
+
// 1. Host passed `manifestAsset` (asset is brand-new) — use that.
|
|
390
|
+
// 2. Already in manifest but not provided (re-drag of existing asset)
|
|
391
|
+
// — look it up via the cached manifest.
|
|
392
|
+
// 3. Non-sprite entity (no asset needed) — leave undefined.
|
|
393
|
+
let assetForLoad = manifestAsset;
|
|
394
|
+
if (!assetForLoad && entity.kind === 'sprite') {
|
|
395
|
+
const visual = entity.visual;
|
|
396
|
+
const assetId = visual?.assetId;
|
|
397
|
+
if (assetId) {
|
|
398
|
+
try {
|
|
399
|
+
const manifest = getManifest(scene);
|
|
400
|
+
assetForLoad = manifest.assets.find((a) => a.id === assetId);
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
/* manifest not in cache — should not happen in edit mode */
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
387
407
|
// Lazy-load texture if needed (sprite + asset not yet in cache).
|
|
388
|
-
if (
|
|
408
|
+
if (assetForLoad &&
|
|
389
409
|
entity.kind === 'sprite' &&
|
|
390
|
-
!scene.textures.exists(
|
|
391
|
-
await loadAssetIntoScene(scene,
|
|
410
|
+
!scene.textures.exists(assetForLoad.textureKey)) {
|
|
411
|
+
await loadAssetIntoScene(scene, assetForLoad);
|
|
392
412
|
}
|
|
393
413
|
const ctx = {
|
|
394
414
|
scene,
|
|
395
415
|
registry,
|
|
396
416
|
resolveAsset: (id) => {
|
|
397
|
-
// For ad-hoc creation we may not have full manifest access. Rely on
|
|
398
|
-
// the host to have stamped the right textureKey/path into the asset
|
|
399
|
-
// we received via manifestAsset; fallback to a synthetic record so
|
|
400
|
-
// spawnEntity can still find a textureKey.
|
|
401
417
|
if (manifestAsset && manifestAsset.id === id)
|
|
402
418
|
return manifestAsset;
|
|
403
|
-
|
|
419
|
+
// Fallback: look up in the manifest cache. Covers re-drag of an
|
|
420
|
+
// already-in-manifest asset where the host omitted manifestAsset.
|
|
421
|
+
try {
|
|
422
|
+
const manifest = getManifest(scene);
|
|
423
|
+
const found = manifest.assets.find((a) => a.id === id);
|
|
424
|
+
if (found)
|
|
425
|
+
return found;
|
|
426
|
+
}
|
|
427
|
+
catch {
|
|
428
|
+
/* fall through to throw */
|
|
429
|
+
}
|
|
430
|
+
throw new Error(`[unboxy/editor] createEntity: asset '${id}' not found in manifest`);
|
|
404
431
|
},
|
|
405
432
|
resolveRenderScript: undefined,
|
|
406
433
|
};
|
|
@@ -46,9 +46,9 @@ interface EditorOverlayInitData {
|
|
|
46
46
|
/**
|
|
47
47
|
* Forward an editor keyboard shortcut to the host. Set when the iframe has
|
|
48
48
|
* focus (which is always after the user clicks the canvas to select);
|
|
49
|
-
* native Cmd+Z otherwise can't reach the host.
|
|
49
|
+
* native Cmd+Z / Backspace otherwise can't reach the host.
|
|
50
50
|
*/
|
|
51
|
-
postShortcut: (action: 'undo' | 'redo' | 'save') => void;
|
|
51
|
+
postShortcut: (action: 'undo' | 'redo' | 'save' | 'delete') => void;
|
|
52
52
|
}
|
|
53
53
|
export declare class EditorOverlayScene extends Phaser.Scene {
|
|
54
54
|
private graphics;
|
|
@@ -27,8 +27,6 @@ export class EditorOverlayScene extends Phaser.Scene {
|
|
|
27
27
|
constructor() {
|
|
28
28
|
super({ key: EDITOR_OVERLAY_KEY });
|
|
29
29
|
this.handleShortcut = (e) => {
|
|
30
|
-
if (!(e.metaKey || e.ctrlKey))
|
|
31
|
-
return;
|
|
32
30
|
// Don't swallow keys when the user is typing in a real form control —
|
|
33
31
|
// shouldn't happen inside the iframe, but be defensive.
|
|
34
32
|
const target = e.target;
|
|
@@ -39,18 +37,27 @@ export class EditorOverlayScene extends Phaser.Scene {
|
|
|
39
37
|
if (target.isContentEditable)
|
|
40
38
|
return;
|
|
41
39
|
}
|
|
42
|
-
const k = e.key
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
const k = e.key;
|
|
41
|
+
if (e.metaKey || e.ctrlKey) {
|
|
42
|
+
const lower = k.toLowerCase();
|
|
43
|
+
if (lower === 'z') {
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
this.postShortcut(e.shiftKey ? 'redo' : 'undo');
|
|
46
|
+
}
|
|
47
|
+
else if (lower === 'y') {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
this.postShortcut('redo');
|
|
50
|
+
}
|
|
51
|
+
else if (lower === 's') {
|
|
52
|
+
e.preventDefault();
|
|
53
|
+
this.postShortcut('save');
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
50
56
|
}
|
|
51
|
-
|
|
57
|
+
if (k === 'Backspace' || k === 'Delete') {
|
|
58
|
+
// Suppress default (Backspace = browser back-nav inside iframe).
|
|
52
59
|
e.preventDefault();
|
|
53
|
-
this.postShortcut('
|
|
60
|
+
this.postShortcut('delete');
|
|
54
61
|
}
|
|
55
62
|
};
|
|
56
63
|
}
|
package/dist/protocol.d.ts
CHANGED
|
@@ -177,7 +177,7 @@ export interface EditorDragEndMessage {
|
|
|
177
177
|
*/
|
|
178
178
|
export interface EditorShortcutMessage {
|
|
179
179
|
type: 'unboxy:editor:shortcut';
|
|
180
|
-
action: 'undo' | 'redo' | 'save';
|
|
180
|
+
action: 'undo' | 'redo' | 'save' | 'delete';
|
|
181
181
|
}
|
|
182
182
|
export type EditorSdkToHostMessage = EditorSceneLoadedMessage | EditorSelectionPickedMessage | EditorDragEndMessage | EditorShortcutMessage;
|
|
183
183
|
export type RpcMethod = 'saves.get' | 'saves.set' | 'saves.delete' | 'saves.list' | 'gameData.get' | 'gameData.set' | 'gameData.delete' | 'gameData.list' | 'realtime.getToken';
|