@unboxy/phaser-sdk 0.2.24 → 0.2.26

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.
@@ -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.toLowerCase();
43
- if (k === 'z') {
44
- e.preventDefault();
45
- this.postShortcut(e.shiftKey ? 'redo' : 'undo');
46
- }
47
- else if (k === 'y') {
48
- e.preventDefault();
49
- this.postShortcut('redo');
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
- else if (k === 's') {
57
+ if (k === 'Backspace' || k === 'Delete') {
58
+ // Suppress default (Backspace = browser back-nav inside iframe).
52
59
  e.preventDefault();
53
- this.postShortcut('save');
60
+ this.postShortcut('delete');
54
61
  }
55
62
  };
56
63
  }
@@ -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';
@@ -185,29 +185,36 @@ function createTilemapStub(ctx, entity) {
185
185
  const g = ctx.scene.add.graphics();
186
186
  const w = entity.size.width * entity.tileSize.width;
187
187
  const h = entity.size.height * entity.tileSize.height;
188
+ // Draw centered around (0, 0) so the entity's transform.x/y anchors at the
189
+ // tilemap's center — matches sprite / primitive / code-rendered convention.
190
+ // Slice 6's real tilemap renderer can revisit anchor semantics.
191
+ const left = -w / 2;
192
+ const top = -h / 2;
188
193
  g.fillStyle(0xffffff, 0.04);
189
- g.fillRect(0, 0, w, h);
190
- // Outer border
194
+ g.fillRect(left, top, w, h);
191
195
  g.lineStyle(2, 0xaaaaaa, 0.6);
192
- g.strokeRect(0, 0, w, h);
193
- // Cell grid — only draw if cells aren't too tiny (perf cap).
196
+ g.strokeRect(left, top, w, h);
194
197
  if (entity.tileSize.width >= 8 && entity.size.width * entity.size.height < 4000) {
195
198
  g.lineStyle(1, 0xaaaaaa, 0.15);
196
199
  for (let i = 1; i < entity.size.width; i++) {
197
- const x = i * entity.tileSize.width;
200
+ const x = left + i * entity.tileSize.width;
198
201
  g.beginPath();
199
- g.moveTo(x, 0);
200
- g.lineTo(x, h);
202
+ g.moveTo(x, top);
203
+ g.lineTo(x, top + h);
201
204
  g.strokePath();
202
205
  }
203
206
  for (let i = 1; i < entity.size.height; i++) {
204
- const y = i * entity.tileSize.height;
207
+ const y = top + i * entity.tileSize.height;
205
208
  g.beginPath();
206
- g.moveTo(0, y);
207
- g.lineTo(w, y);
209
+ g.moveTo(left, y);
210
+ g.lineTo(left + w, y);
208
211
  g.strokePath();
209
212
  }
210
213
  }
214
+ // Same hit-test stash as code-rendered — Phaser Graphics has no intrinsic
215
+ // bounds, so the editor reads these from data. Slice 6's real tilemap will
216
+ // use Phaser.Tilemap which has its own bounds and won't need this.
217
+ sizeForHitTest(g, w, h);
211
218
  return g;
212
219
  }
213
220
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unboxy/phaser-sdk",
3
- "version": "0.2.24",
3
+ "version": "0.2.26",
4
4
  "description": "Unboxy Phaser 3 SDK — game infrastructure for the Unboxy platform",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",