Z-order via position.z and reset-to-default for asset properties
- Position is now { x, y, z }; higher z draws on top, ties keep hierarchy order
- Viewport sorts the objects layer deterministically (syncDrawOrder)
- Inspector shows a Z field; asset properties that differ from the schema
default are marked bold with a reset button (ResetAssetPropertyCommand)
- isModified() helper, unit tests, E2E checks and seed updated
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
aaa8154adf
commit
d4b1ffa051
18 files changed
+232
-63
No files matched your search
@@ -284,6 +284,52 @@ try {
|
||||
check('camera symbol is drawn in the overlay layer above sprites', layers === '["overlay","objects","objects"]', layers);
|
||||
await shot('13-symbol-on-top');
|
||||
|
||||
// 11. Z-order: put both crates on the origin. With equal z the hierarchy order wins
|
||||
// (o1 before o2 → o2 on top); raising o1's z draws it above o2; undo restores it.
|
||||
await evaluate(`(() => {
|
||||
const o2 = __gm.state.activeScene.objects.find(o => o.id === 'o2');
|
||||
o2.position.x = 0; o2.position.y = 0;
|
||||
__gm.state.preview();
|
||||
})()`);
|
||||
await sleep(200);
|
||||
const orderBefore = await evaluate(`JSON.stringify(__gm.drawOrder().filter(id => id === 'o1' || id === 'o2'))`);
|
||||
check('equal z keeps hierarchy order', orderBefore === '["o1","o2"]', orderBefore);
|
||||
await evaluate(`__gm.state.select({ kind: 'object', sceneId: __gm.state.activeScene.id, objectId: 'o1' })`);
|
||||
await sleep(200);
|
||||
const zLabel = await locate('Z');
|
||||
await click(zLabel.x + 160, zLabel.y); // plain click → text editing with everything selected
|
||||
await typeText('5');
|
||||
await keyPress('Enter', 'Enter', { windowsVirtualKeyCode: 13 });
|
||||
await sleep(200);
|
||||
const zNow = await evaluate(`__gm.state.activeScene.objects.find(o => o.id === 'o1').position.z`);
|
||||
check('Z field sets position.z', zNow === 5, `z=${zNow}`);
|
||||
const orderAfter = await evaluate(`JSON.stringify(__gm.drawOrder().filter(id => id === 'o1' || id === 'o2'))`);
|
||||
check('higher z is drawn on top', orderAfter === '["o2","o1"]', orderAfter);
|
||||
await shot('14-z-order');
|
||||
await keyPress('z', 'KeyZ', { modifiers: 2, windowsVirtualKeyCode: 90 });
|
||||
await sleep(200);
|
||||
const zUndone = await evaluate(`__gm.state.activeScene.objects.find(o => o.id === 'o1').position.z`);
|
||||
check('undo restores z', zUndone === 0, `z=${zUndone}`);
|
||||
|
||||
// 12. Asset defaults: the Crate asset has height 60 (schema default 100), width and
|
||||
// color at their defaults → exactly one reset button is visible. Clicking it puts
|
||||
// height back to 100 and hides the button; undo brings 60 back.
|
||||
await evaluate(`__gm.state.select({ kind: 'asset', assetId: 'crate' })`);
|
||||
await sleep(200);
|
||||
const resetButton = await evaluate(`__gm.locate('↺')`);
|
||||
check('asset inspector shows a reset for the non-default height', Boolean(resetButton));
|
||||
await click(resetButton.x, resetButton.y);
|
||||
await sleep(200);
|
||||
const heightReset = await evaluate(`__gm.state.project.assets.find(a => a.id === 'crate').props.height`);
|
||||
check('reset puts the asset property back to its default', heightReset === 100, `height=${heightReset}`);
|
||||
check('reset button hidden once the value is at default', !(await evaluate(`__gm.locate('↺')`)));
|
||||
await shot('15-asset-reset');
|
||||
await keyPress('z', 'KeyZ', { modifiers: 2, windowsVirtualKeyCode: 90 });
|
||||
await sleep(200);
|
||||
const heightUndone = await evaluate(`__gm.state.project.assets.find(a => a.id === 'crate').props.height`);
|
||||
check('undo restores the asset value', heightUndone === 60, `height=${heightUndone}`);
|
||||
check('reset button visible again after undo', Boolean(await evaluate(`__gm.locate('↺')`)));
|
||||
|
||||
check('no exceptions during run', !consoleLog.some((l) => l.startsWith('EXCEPTION')), consoleLog.filter((l) => l.startsWith('EXCEPTION')).slice(0, 3).join(' | '));
|
||||
ws.close();
|
||||
} catch (error) {
|
||||
|
||||
+3
-3
@@ -22,9 +22,9 @@ const project = {
|
||||
name: 'Level 1',
|
||||
props: { backgroundColor: 0x22252c },
|
||||
objects: [
|
||||
{ id: 'o1', assetId: 'crate', name: '', position: { x: -150, y: 0 }, overrides: {} },
|
||||
{ id: 'o2', assetId: 'crate', name: 'Blue crate', position: { x: 120, y: -80 }, overrides: { width: 140, color: 0x4488ff } },
|
||||
{ id: 'o3', assetId: 'cam', name: '', position: { x: 0, y: 0 }, overrides: {} },
|
||||
{ id: 'o1', assetId: 'crate', name: '', position: { x: -150, y: 0, z: 0 }, overrides: {} },
|
||||
{ id: 'o2', assetId: 'crate', name: 'Blue crate', position: { x: 120, y: -80, z: 0 }, overrides: { width: 140, color: 0x4488ff } },
|
||||
{ id: 'o3', assetId: 'cam', name: '', position: { x: 0, y: 0, z: 0 }, overrides: {} },
|
||||
],
|
||||
},
|
||||
{ id: 'crate', type: 'sprite', name: 'Crate', props: { width: 100, height: 60, color: 0xe0553f } },
|
||||
|
||||
Reference in new issue
Block a user