Enabled switch, text assets, mouse input and the jump-and-run example game
Engine additions that the example game needed: - `enabled` as a shared property of every placeable asset (default on, an override on the scene object). A switched-off object is not drawn, does not collide and its behavior does not run - and neither does anything parented below it. Disabled objects are now hidden in the scene view as well, so the editor shows what the game shows; they stay in the hierarchy panel, which is where they are selected and switched back on. - Asset type `text` (text, fontSize, color, align), rendered in scene and game. - Pointer input in the game view: `On click`, `Mouse position`, `Mouse button`, `Is hovered`, hit-tested against colliders, else sprite/text footprints. - New nodes: Set/Is enabled, Set text, Is asset, Name of, Equals, To text, Join text, Floor/Ceil/Round, Modulo, Random, Time, Restart game. Tooling: shared CDP harness (tools/harness.mjs), central project registry with a guard that keeps destructive scripts off the playground (tools/projects.mjs), plus smoke suites for the demo scene and the jump-and-run game. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4900d7bbf6
commit
76aa441dce
33 files changed
+1905
-301
No files matched your search
@@ -9,10 +9,12 @@ import type { BehaviorAsset } from '../../src/core/model/Asset';
|
||||
import { createEmptyProject } from '../../src/core/model/Project';
|
||||
import { deserializeProject, serializeProject } from '../../src/core/store/serialize';
|
||||
|
||||
function entity(name: string, x = 0): EntityHandle {
|
||||
return { id: name, name, x, y: 0, z: 0, props: {}, parent: null };
|
||||
function entity(name: string, x = 0, assetId = `asset-${name}`): EntityHandle {
|
||||
return { id: name, assetId, name, x, y: 0, z: 0, props: {}, parent: null };
|
||||
}
|
||||
|
||||
const NO_POINTER = { x: 0, y: 0, inside: false, down: false, pressed: false, released: false };
|
||||
|
||||
function context(overrides: Partial<NodeContext> = {}): NodeContext & { logs: string[]; stopped: boolean } {
|
||||
const logs: string[] = [];
|
||||
const ctx = {
|
||||
@@ -25,6 +27,8 @@ function context(overrides: Partial<NodeContext> = {}): NodeContext & { logs: st
|
||||
stopped: false,
|
||||
findByName: () => null,
|
||||
isKeyDown: () => false,
|
||||
pointer: { ...NO_POINTER },
|
||||
hitTest: () => false,
|
||||
isTouching: () => false,
|
||||
moveAndSlide: (target: EntityHandle, dx: number, dy: number) => {
|
||||
target.x += dx;
|
||||
@@ -35,6 +39,7 @@ function context(overrides: Partial<NodeContext> = {}): NodeContext & { logs: st
|
||||
spawn: () => null,
|
||||
destroy: () => {},
|
||||
stop: () => { ctx.stopped = true; },
|
||||
restart: () => {},
|
||||
...overrides,
|
||||
};
|
||||
return ctx;
|
||||
@@ -326,7 +331,7 @@ describe('variables', () => {
|
||||
|
||||
stack.execute(new RenameVariableCommand('mover', 'speed', 'velocity'));
|
||||
expect(behavior.variables[0]!.key).toBe('velocity');
|
||||
expect(behavior.props).toEqual({ velocity: 0 });
|
||||
expect(behavior.props).toEqual({ enabled: true, velocity: 0 });
|
||||
expect(object.overrides).toEqual({ velocity: 5 });
|
||||
expect(behavior.graph.nodes.find((n) => n.id === nodes.speed.node.id)!.params.variable).toBe('velocity');
|
||||
stack.undo();
|
||||
@@ -373,7 +378,7 @@ describe('behavior serialization', () => {
|
||||
const loaded = deserializeProject(serializeProject(project)).assets.find((a) => a.id === 'mover') as BehaviorAsset;
|
||||
expect(loaded.variables).toEqual(behavior.variables);
|
||||
expect(loaded.graph).toEqual(behavior.graph);
|
||||
expect(loaded.props).toEqual({ speed: 0 });
|
||||
expect(loaded.props).toEqual({ enabled: true, speed: 0 });
|
||||
|
||||
const raw = serializeProject(project) as { assets: { graph?: { nodes: unknown[]; edges: unknown[] } }[] };
|
||||
raw.assets[0]!.graph!.nodes.push({ id: 'zzz', type: 'DoesNotExist', x: 0, y: 0, params: {} });
|
||||
|
||||
Reference in new issue
Block a user