@zylem/behaviors 0.3.1 → 0.4.1
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.
- package/dist/behavior-system-y8SGrGWy.d.ts +580 -0
- package/dist/{chunk-ARJWUNRE.js → chunk-27UPCP5B.js} +10 -10
- package/dist/{chunk-ARJWUNRE.js.map → chunk-27UPCP5B.js.map} +1 -1
- package/dist/{chunk-YUO6SKJD.js → chunk-4L36OPY2.js} +33 -23
- package/dist/chunk-4L36OPY2.js.map +1 -0
- package/dist/{chunk-DYLH6K7B.js → chunk-4WH2ZN7P.js} +1 -1
- package/dist/{chunk-DYLH6K7B.js.map → chunk-4WH2ZN7P.js.map} +1 -1
- package/dist/{chunk-ZPSAXX73.js → chunk-5SM5SH5O.js} +26 -26
- package/dist/chunk-5SM5SH5O.js.map +1 -0
- package/dist/{chunk-STCCNLPC.js → chunk-5XZWTFGF.js} +5 -3
- package/dist/chunk-5XZWTFGF.js.map +1 -0
- package/dist/{chunk-JAN34G6S.js → chunk-67XLJ26X.js} +152 -168
- package/dist/chunk-67XLJ26X.js.map +1 -0
- package/dist/{chunk-2CLT36VB.js → chunk-75FJIUIG.js} +22 -23
- package/dist/chunk-75FJIUIG.js.map +1 -0
- package/dist/{chunk-OYWFPIHF.js → chunk-A4CA35DQ.js} +20 -17
- package/dist/chunk-A4CA35DQ.js.map +1 -0
- package/dist/{chunk-SS7ELMJ7.js → chunk-F72WX4MH.js} +49 -33
- package/dist/chunk-F72WX4MH.js.map +1 -0
- package/dist/{chunk-RTRVBEIB.js → chunk-FTDZAKZW.js} +5 -18
- package/dist/chunk-FTDZAKZW.js.map +1 -0
- package/dist/{chunk-XIJNE67Y.js → chunk-GFARAJV2.js} +3 -5
- package/dist/{chunk-XIJNE67Y.js.map → chunk-GFARAJV2.js.map} +1 -1
- package/dist/{chunk-VAN4WW3F.js → chunk-H4TJ7X4O.js} +4 -7
- package/dist/chunk-H4TJ7X4O.js.map +1 -0
- package/dist/{chunk-KS72RZHX.js → chunk-IZJFUAXB.js} +1 -1
- package/dist/{chunk-KS72RZHX.js.map → chunk-IZJFUAXB.js.map} +1 -1
- package/dist/{chunk-SVLNF434.js → chunk-JXMF4NUI.js} +51 -3
- package/dist/chunk-JXMF4NUI.js.map +1 -0
- package/dist/chunk-KFFETUAL.js +40 -0
- package/dist/chunk-KFFETUAL.js.map +1 -0
- package/dist/chunk-LL4FLHIY.js +12 -0
- package/dist/chunk-LL4FLHIY.js.map +1 -0
- package/dist/{chunk-RTVRUNYR.js → chunk-OTLSUYQQ.js} +2 -2
- package/dist/chunk-OTLSUYQQ.js.map +1 -0
- package/dist/{chunk-Y6UJOUE5.js → chunk-Q75LKHDF.js} +14 -2
- package/dist/chunk-Q75LKHDF.js.map +1 -0
- package/dist/{chunk-KOZUNIIE.js → chunk-QDCJLJUV.js} +10 -10
- package/dist/{chunk-KOZUNIIE.js.map → chunk-QDCJLJUV.js.map} +1 -1
- package/dist/{chunk-LD5SMIB3.js → chunk-QVCMJ4Q2.js} +1 -1
- package/dist/{chunk-LD5SMIB3.js.map → chunk-QVCMJ4Q2.js.map} +1 -1
- package/dist/{chunk-F3KRX2V4.js → chunk-RDHSHEZM.js} +46 -24
- package/dist/chunk-RDHSHEZM.js.map +1 -0
- package/dist/chunk-UIG7MWS2.js +518 -0
- package/dist/chunk-UIG7MWS2.js.map +1 -0
- package/dist/{chunk-6C6NXNEW.js → chunk-UL6Q5HDP.js} +25 -3
- package/dist/chunk-UL6Q5HDP.js.map +1 -0
- package/dist/{chunk-XG2YMCJW.js → chunk-VMQHNJJI.js} +6 -8
- package/dist/{chunk-XG2YMCJW.js.map → chunk-VMQHNJJI.js.map} +1 -1
- package/dist/{chunk-GCNRXAKH.js → chunk-XP3ASVGJ.js} +13 -10
- package/dist/chunk-XP3ASVGJ.js.map +1 -0
- package/dist/{chunk-ID5QJYF5.js → chunk-Y7YIAWPW.js} +11 -1
- package/dist/chunk-Y7YIAWPW.js.map +1 -0
- package/dist/{chunk-4I6E6DGV.js → chunk-Z72F2ENM.js} +6 -8
- package/dist/{chunk-4I6E6DGV.js.map → chunk-Z72F2ENM.js.map} +1 -1
- package/dist/{chunk-FPTWVCPN.js → chunk-ZA43LPRM.js} +4 -24
- package/dist/chunk-ZA43LPRM.js.map +1 -0
- package/dist/{chunk-K3UNLQ7W.js → chunk-ZRQWSURL.js} +2 -2
- package/dist/chunk-ZRQWSURL.js.map +1 -0
- package/dist/cooldown.d.ts +2 -1
- package/dist/cooldown.js +1 -1
- package/dist/coordinators/boundary-ricochet-3d.d.ts +12 -5
- package/dist/coordinators/boundary-ricochet-3d.js +2 -1
- package/dist/coordinators/boundary-ricochet.d.ts +9 -7
- package/dist/coordinators/boundary-ricochet.js +2 -1
- package/dist/coordinators/first-person-shooter.d.ts +9 -8
- package/dist/coordinators/first-person-shooter.js +3 -3
- package/dist/coordinators/multidirectional-space-shooter.d.ts +12 -9
- package/dist/coordinators/multidirectional-space-shooter.js +4 -4
- package/dist/coordinators/top-down-shooter.d.ts +9 -8
- package/dist/coordinators/top-down-shooter.js +3 -3
- package/dist/core.d.ts +4 -4
- package/dist/core.js +17 -39
- package/dist/core.js.map +1 -1
- package/dist/destructible-3d.d.ts +2 -1
- package/dist/first-person.d.ts +12 -12
- package/dist/first-person.js +9 -8
- package/dist/index.d.ts +37 -14
- package/dist/index.js +73 -44
- package/dist/jumper-2d.d.ts +7 -6
- package/dist/jumper-2d.js +6 -5
- package/dist/jumper-3d.d.ts +12 -11
- package/dist/jumper-3d.js +7 -6
- package/dist/{moveable-BCRpjAQb.d.ts → moveable-Cl9h-_w7.d.ts} +2 -78
- package/dist/particle-emitter.d.ts +1 -1
- package/dist/particle-emitter.js +1 -1
- package/dist/platformer-2d.d.ts +306 -0
- package/dist/platformer-2d.js +24 -0
- package/dist/platformer-3d.d.ts +74 -87
- package/dist/platformer-3d.js +5 -4
- package/dist/ricochet-2d.d.ts +1 -1
- package/dist/ricochet-2d.js +2 -2
- package/dist/ricochet-3d.d.ts +1 -1
- package/dist/ricochet-3d.js +2 -2
- package/dist/runtime-2d.d.ts +93 -2
- package/dist/runtime-2d.js +145 -22
- package/dist/runtime-2d.js.map +1 -1
- package/dist/screen-visibility.d.ts +2 -1
- package/dist/screen-wrap.d.ts +2 -1
- package/dist/screen-wrap.js +1 -1
- package/dist/shooter-2d.d.ts +5 -3
- package/dist/shooter-2d.js +2 -2
- package/dist/shooter-fire-DGripl0z.d.ts +55 -0
- package/dist/thruster.d.ts +8 -18
- package/dist/thruster.js +6 -6
- package/dist/top-down-movement.d.ts +7 -4
- package/dist/top-down-movement.js +5 -5
- package/dist/{use-behavior-D_82jAL3.d.ts → use-behavior-B85d5u7-.d.ts} +1 -1
- package/dist/world-boundary-2d.d.ts +2 -1
- package/dist/world-boundary-2d.js +2 -2
- package/dist/world-boundary-3d.d.ts +2 -1
- package/dist/world-boundary-3d.js +2 -2
- package/package.json +7 -5
- package/dist/behavior-system-DYbx-x_-.d.ts +0 -307
- package/dist/chunk-2C3Z5GE7.js +0 -176
- package/dist/chunk-2C3Z5GE7.js.map +0 -1
- package/dist/chunk-2CLT36VB.js.map +0 -1
- package/dist/chunk-3PYGRHAL.js +0 -35
- package/dist/chunk-3PYGRHAL.js.map +0 -1
- package/dist/chunk-6C6NXNEW.js.map +0 -1
- package/dist/chunk-F3KRX2V4.js.map +0 -1
- package/dist/chunk-FPTWVCPN.js.map +0 -1
- package/dist/chunk-GCNRXAKH.js.map +0 -1
- package/dist/chunk-ID5QJYF5.js.map +0 -1
- package/dist/chunk-JAN34G6S.js.map +0 -1
- package/dist/chunk-K3UNLQ7W.js.map +0 -1
- package/dist/chunk-OYWFPIHF.js.map +0 -1
- package/dist/chunk-RTRVBEIB.js.map +0 -1
- package/dist/chunk-RTVRUNYR.js.map +0 -1
- package/dist/chunk-SS7ELMJ7.js.map +0 -1
- package/dist/chunk-STCCNLPC.js.map +0 -1
- package/dist/chunk-SVLNF434.js.map +0 -1
- package/dist/chunk-VAN4WW3F.js.map +0 -1
- package/dist/chunk-Y6UJOUE5.js.map +0 -1
- package/dist/chunk-YUO6SKJD.js.map +0 -1
- package/dist/chunk-ZPSAXX73.js.map +0 -1
- package/dist/runtime-pong.d.ts +0 -92
- package/dist/runtime-pong.js +0 -38
- /package/dist/{runtime-pong.js.map → platformer-2d.js.map} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createThrusterInputComponent,
|
|
3
3
|
createThrusterMovementComponent
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IZJFUAXB.js";
|
|
5
5
|
import {
|
|
6
6
|
getRotationAngle2D,
|
|
7
|
-
|
|
8
|
-
} from "./chunk-
|
|
7
|
+
normalizeDirection2DInto
|
|
8
|
+
} from "./chunk-Y7YIAWPW.js";
|
|
9
9
|
import {
|
|
10
10
|
SyncStateMachine,
|
|
11
11
|
t
|
|
@@ -88,8 +88,9 @@ var ThrusterFSM = class {
|
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
// src/lib/behaviors/thruster/thruster
|
|
92
|
-
var
|
|
91
|
+
// src/lib/behaviors/thruster/thruster.system.ts
|
|
92
|
+
var _thrustDirection = { x: 0, y: 0 };
|
|
93
|
+
var ThrusterSystem = class {
|
|
93
94
|
constructor(world) {
|
|
94
95
|
this.world = world;
|
|
95
96
|
}
|
|
@@ -114,13 +115,13 @@ var ThrusterMovementBehavior = class {
|
|
|
114
115
|
}
|
|
115
116
|
const rotationZ = getRotationAngle2D(body.rotation());
|
|
116
117
|
const currentVel = body.linvel();
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
118
|
+
const hasVectorThrust = normalizeDirection2DInto(input.thrustX, input.thrustY, _thrustDirection);
|
|
119
|
+
if (hasVectorThrust) {
|
|
119
120
|
const thrustScale = Math.min(1, Math.hypot(input.thrustX, input.thrustY));
|
|
120
121
|
const thrustAmount = thruster.linearThrust * thrustScale * 0.1;
|
|
121
122
|
body.setLinvel({
|
|
122
|
-
x: currentVel.x +
|
|
123
|
-
y: currentVel.y +
|
|
123
|
+
x: currentVel.x + _thrustDirection.x * thrustAmount,
|
|
124
|
+
y: currentVel.y + _thrustDirection.y * thrustAmount,
|
|
124
125
|
z: currentVel.z
|
|
125
126
|
}, true);
|
|
126
127
|
} else if (input.thrust !== 0) {
|
|
@@ -157,12 +158,10 @@ var defaultOptions = {
|
|
|
157
158
|
var THRUSTER_BEHAVIOR_KEY = /* @__PURE__ */ Symbol.for("zylem:behavior:thruster");
|
|
158
159
|
var ThrusterBehaviorSystem = class {
|
|
159
160
|
constructor(world, wasmStage, getBehaviorLinks) {
|
|
160
|
-
this.world = world;
|
|
161
161
|
this.wasmStage = wasmStage;
|
|
162
162
|
this.getBehaviorLinks = getBehaviorLinks;
|
|
163
|
-
this.movementBehavior = new
|
|
163
|
+
this.movementBehavior = new ThrusterSystem(world);
|
|
164
164
|
}
|
|
165
|
-
world;
|
|
166
165
|
wasmStage;
|
|
167
166
|
getBehaviorLinks;
|
|
168
167
|
movementBehavior;
|
|
@@ -184,6 +183,15 @@ var ThrusterBehaviorSystem = class {
|
|
|
184
183
|
if (!gameEntity.$thruster) {
|
|
185
184
|
gameEntity.$thruster = createThrusterInputComponent();
|
|
186
185
|
}
|
|
186
|
+
const handle = gameEntity.runtimeHandle ?? -1;
|
|
187
|
+
if (this.wasmStage && handle >= 0) {
|
|
188
|
+
this.ensureWasmAttached(handle, options);
|
|
189
|
+
const input = gameEntity.$thruster;
|
|
190
|
+
if (input) {
|
|
191
|
+
this.wasmStage.writeInputAxes(handle, input.thrust, input.rotate);
|
|
192
|
+
}
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
187
195
|
if (!thrusterRef.fsm && gameEntity.$thruster) {
|
|
188
196
|
thrusterRef.fsm = new ThrusterFSM({ input: gameEntity.$thruster });
|
|
189
197
|
}
|
|
@@ -195,15 +203,6 @@ var ThrusterBehaviorSystem = class {
|
|
|
195
203
|
thrustY: gameEntity.$thruster.thrustY
|
|
196
204
|
});
|
|
197
205
|
}
|
|
198
|
-
const handle = gameEntity.runtimeHandle ?? -1;
|
|
199
|
-
if (this.wasmStage && handle >= 0) {
|
|
200
|
-
this.ensureWasmAttached(handle, options);
|
|
201
|
-
const input = gameEntity.$thruster;
|
|
202
|
-
if (input) {
|
|
203
|
-
this.wasmStage.setThrusterInput(handle, input.thrust, input.rotate);
|
|
204
|
-
}
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
206
|
if (!gameEntity.body) continue;
|
|
208
207
|
if (!gameEntity.physics) {
|
|
209
208
|
gameEntity.physics = { body: gameEntity.body };
|
|
@@ -235,7 +234,7 @@ export {
|
|
|
235
234
|
ThrusterState,
|
|
236
235
|
ThrusterEvent,
|
|
237
236
|
ThrusterFSM,
|
|
238
|
-
|
|
237
|
+
ThrusterSystem,
|
|
239
238
|
ThrusterBehavior
|
|
240
239
|
};
|
|
241
|
-
//# sourceMappingURL=chunk-
|
|
240
|
+
//# sourceMappingURL=chunk-75FJIUIG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/behaviors/thruster/thruster-fsm.ts","../src/lib/behaviors/thruster/thruster.system.ts","../src/lib/behaviors/thruster/thruster.descriptor.ts"],"sourcesContent":["/**\n * ThrusterFSM\n * \n * State machine controller for thruster behavior.\n * FSM does NOT touch physics or ThrusterSystem - it only writes ThrusterInputComponent.\n */\n\nimport { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { ThrusterInputComponent } from './components';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM State Model\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ThrusterState {\n\tIdle = 'idle',\n\tActive = 'active',\n\tBoosting = 'boosting',\n\tDisabled = 'disabled',\n\tDocked = 'docked',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Events\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport enum ThrusterEvent {\n\tActivate = 'activate',\n\tDeactivate = 'deactivate',\n\tBoost = 'boost',\n\tEndBoost = 'endBoost',\n\tDisable = 'disable',\n\tEnable = 'enable',\n\tDock = 'dock',\n\tUndock = 'undock',\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FSM Context Object\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface ThrusterFSMContext {\n\tinput: ThrusterInputComponent;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Player Input (raw input from controller/keyboard)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface PlayerInput {\n\tthrust: number;\n\trotate: number;\n\tthrustX?: number;\n\tthrustY?: number;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ThrusterFSM Controller\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport class ThrusterFSM {\n\tmachine: SyncStateMachine<ThrusterState, ThrusterEvent, never>;\n\n\tconstructor(private ctx: ThrusterFSMContext) {\n\t\tthis.machine = new SyncStateMachine<ThrusterState, ThrusterEvent, never>(\n\t\t\tThrusterState.Idle,\n\t\t\t[\n\t\t\t\t// Core transitions\n\t\t\t\tt(ThrusterState.Idle, ThrusterEvent.Activate, ThrusterState.Active),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Deactivate, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Boost, ThrusterState.Boosting),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Disable, ThrusterState.Disabled),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Dock, ThrusterState.Docked),\n\t\t\t\tt(ThrusterState.Boosting, ThrusterEvent.EndBoost, ThrusterState.Active),\n\t\t\t\tt(ThrusterState.Boosting, ThrusterEvent.Disable, ThrusterState.Disabled),\n\t\t\t\tt(ThrusterState.Disabled, ThrusterEvent.Enable, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Docked, ThrusterEvent.Undock, ThrusterState.Idle),\n\t\t\t\t// Self-transitions (no-ops for redundant events)\n\t\t\t\tt(ThrusterState.Idle, ThrusterEvent.Deactivate, ThrusterState.Idle),\n\t\t\t\tt(ThrusterState.Active, ThrusterEvent.Activate, ThrusterState.Active),\n\t\t\t]\n\t\t);\n\t}\n\n\t/**\n\t * Get current state\n\t */\n\tgetState(): ThrusterState {\n\t\treturn this.machine.getState();\n\t}\n\n\t/**\n\t * Dispatch an event to transition state\n\t */\n\tdispatch(event: ThrusterEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\t/**\n\t * Update FSM state based on player input.\n\t * Auto-transitions between Idle/Active to report current state.\n\t * Does NOT modify input - just observes and reports.\n\t */\n\tupdate(playerInput: PlayerInput): void {\n\t\tconst state = this.machine.getState();\n\t\tconst hasInput =\n\t\t\tMath.abs(playerInput.thrust) > 0.01\n\t\t\t|| Math.abs(playerInput.rotate) > 0.01\n\t\t\t|| Math.abs(playerInput.thrustX ?? 0) > 0.01\n\t\t\t|| Math.abs(playerInput.thrustY ?? 0) > 0.01;\n\n\t\t// Auto-transition to report state based on input\n\t\tif (hasInput && state === ThrusterState.Idle) {\n\t\t\tthis.dispatch(ThrusterEvent.Activate);\n\t\t} else if (!hasInput && state === ThrusterState.Active) {\n\t\t\tthis.dispatch(ThrusterEvent.Deactivate);\n\t\t}\n\t}\n}\n","/**\n * ThrusterSystem\n * \n * This is the heart of the thruster movement system - a pure, stateless force generator.\n * Works identically for player, AI, and replay.\n */\n\nimport type { ZylemWorld } from '../../collision/world';\nimport type { PhysicsBodyComponent } from '../components';\nimport type { ThrusterMovementComponent, ThrusterInputComponent } from './components';\nimport {\n\tgetRotationAngle2D,\n\tnormalizeDirection2DInto,\n\ttype Direction2D,\n} from '../shared/direction-2d';\n\n// Per-frame scratch; normalizeDirection2DInto writes here instead of\n// allocating a fresh direction object per entity per frame.\nconst _thrustDirection: Direction2D = { x: 0, y: 0 };\n\n/**\n * Entity with thruster components\n */\nexport interface ThrusterEntity {\n\tphysics: PhysicsBodyComponent;\n\tthruster: ThrusterMovementComponent;\n\t$thruster: ThrusterInputComponent;\n}\n\n/**\n * ThrusterSystem - Force generator for thruster-equipped entities\n * \n * Responsibilities:\n * - Query entities with PhysicsBody, ThrusterMovement, and ThrusterInput components\n * - Apply velocities based on thrust input (2D mode)\n * - Apply angular velocity based on rotation input\n */\nexport class ThrusterSystem {\n\tconstructor(private world: ZylemWorld | null) {}\n\n\t/**\n\t * Update a single thruster-enabled entity.\n\t */\n\tupdateEntity(gameEntity: any, _dt: number): void {\n\t\tif (!gameEntity.physics?.body || !gameEntity.thruster || !gameEntity.$thruster) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst e: ThrusterEntity = {\n\t\t\tphysics: gameEntity.physics,\n\t\t\tthruster: gameEntity.thruster,\n\t\t\t$thruster: gameEntity.$thruster,\n\t\t};\n\n\t\tconst body = e.physics.body;\n\t\tconst thruster = e.thruster;\n\t\tconst input = e.$thruster;\n\n\t\tif (thruster.linearDamping != null && typeof body.setLinearDamping === 'function') {\n\t\t\tbody.setLinearDamping(thruster.linearDamping);\n\t\t}\n\n\t\t// Get Z rotation from quaternion (for 2D sprites)\n\t\tconst rotationZ = getRotationAngle2D(body.rotation());\n\t\tconst currentVel = body.linvel();\n\t\tconst hasVectorThrust = normalizeDirection2DInto(input.thrustX, input.thrustY, _thrustDirection);\n\n\t\t// --- Linear thrust ---\n\t\tif (hasVectorThrust) {\n\t\t\tconst thrustScale = Math.min(1, Math.hypot(input.thrustX, input.thrustY));\n\t\t\tconst thrustAmount = thruster.linearThrust * thrustScale * 0.1;\n\t\t\tbody.setLinvel({\n\t\t\t\tx: currentVel.x + _thrustDirection.x * thrustAmount,\n\t\t\t\ty: currentVel.y + _thrustDirection.y * thrustAmount,\n\t\t\t\tz: currentVel.z,\n\t\t\t}, true);\n\t\t} else if (input.thrust !== 0) {\n\t\t\tconst forwardX = Math.sin(-rotationZ);\n\t\t\tconst forwardY = Math.cos(-rotationZ);\n\t\t\tconst thrustAmount = thruster.linearThrust * input.thrust * 0.1;\n\t\t\tbody.setLinvel({\n\t\t\t\tx: currentVel.x + forwardX * thrustAmount,\n\t\t\t\ty: currentVel.y + forwardY * thrustAmount,\n\t\t\t\tz: currentVel.z\n\t\t\t}, true);\n\t\t}\n\n\t\t// --- Angular thrust (Z-axis for 2D) ---\n\t\tif (input.rotate !== 0) {\n\t\t\tbody.setAngvel({ x: 0, y: 0, z: -thruster.angularThrust * input.rotate }, true);\n\t\t} else {\n\t\t\t// Stop rotation when no input\n\t\t\tconst angVel = body.angvel();\n\t\t\tbody.setAngvel({ x: angVel.x, y: angVel.y, z: 0 }, true);\n\t\t}\n\t}\n\n\tupdate(dt: number): void {\n\t\tif (!this.world?.collisionMap) return;\n\t\tfor (const [, entity] of this.world.collisionMap) {\n\t\t\tthis.updateEntity(entity, dt);\n\t\t}\n\t}\n}\n","/**\n * Thruster Behavior Descriptor\n * \n * Type-safe descriptor for the thruster behavior system using the new entity.use() API.\n * This wraps the existing ThrusterSystem and components.\n */\n\nimport { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { ThrusterSystem, ThrusterEntity } from './thruster.system';\nimport { ThrusterFSM } from './thruster-fsm';\nimport {\n\tcreateThrusterInputComponent,\n\tcreateThrusterMovementComponent,\n\ttype ThrusterMovementComponent,\n\ttype ThrusterInputComponent,\n} from './components';\nimport type { WasmStageRuntime } from '../../runtime/wasm-stage-runtime';\n\n/**\n * Thruster behavior options (typed for entity.use() autocomplete)\n */\nexport interface ThrusterBehaviorOptions {\n\t/** Forward thrust force (default: 10) */\n\tlinearThrust: number;\n\t/** Rotation torque (default: 5) */\n\tangularThrust: number;\n\t/** Optional linear damping override */\n\tlinearDamping?: number;\n}\n\nconst defaultOptions: ThrusterBehaviorOptions = {\n\tlinearThrust: 10,\n\tangularThrust: 5,\n\tlinearDamping: undefined,\n};\n\nconst THRUSTER_BEHAVIOR_KEY = Symbol.for('zylem:behavior:thruster');\n\n/**\n * Adapter that wraps ThrusterSystem as a BehaviorSystem.\n * \n * This bridges the entity.use() pattern with the ECS component-based approach:\n * - Reads options from entity behaviorRefs\n * - Initializes ThrusterMovementComponent and ThrusterInputComponent on entities\n * - Creates FSM lazily and attaches to BehaviorRef for access via handle.getFSM()\n * - Delegates physics to ThrusterSystem\n * \n * NOTE: Input is controlled by the user via entity.onUpdate() - set entity.input.thrust/rotate\n */\nclass ThrusterBehaviorSystem implements BehaviorSystem {\n\tprivate movementBehavior: ThrusterSystem;\n\tprivate attachedRuntimeSlots = new Set<number>();\n\n\tconstructor(\n\t\tworld: import('../../collision/world').ZylemWorld | null,\n\t\tprivate wasmStage: WasmStageRuntime | null,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.movementBehavior = new ThrusterSystem(world);\n\t}\n\n\tupdate(_ecs: unknown, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(THRUSTER_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst thrusterRef = link.ref as any;\n\n\t\t\tconst options = thrusterRef.options as ThrusterBehaviorOptions;\n\n\t\t\tif (!gameEntity.thruster) {\n\t\t\t\tgameEntity.thruster = createThrusterMovementComponent(\n\t\t\t\t\toptions.linearThrust,\n\t\t\t\t\toptions.angularThrust,\n\t\t\t\t\t{ linearDamping: options.linearDamping },\n\t\t\t\t) as ThrusterMovementComponent;\n\t\t\t}\n\n\t\t\tif (!gameEntity.$thruster) {\n\t\t\t\tgameEntity.$thruster = createThrusterInputComponent() as ThrusterInputComponent;\n\t\t\t}\n\n\t\t\t// Wasm fast path: the Rust runtime owns the thruster simulation;\n\t\t\t// skip the (input-mirroring) TS FSM entirely.\n\t\t\tconst handle = (gameEntity.runtimeHandle ?? -1) as number;\n\t\t\tif (this.wasmStage && handle >= 0) {\n\t\t\t\tthis.ensureWasmAttached(handle, options);\n\t\t\t\tconst input = gameEntity.$thruster as ThrusterInputComponent | undefined;\n\t\t\t\tif (input) {\n\t\t\t\t\tthis.wasmStage.writeInputAxes(handle, input.thrust, input.rotate);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!thrusterRef.fsm && gameEntity.$thruster) {\n\t\t\t\tthrusterRef.fsm = new ThrusterFSM({ input: gameEntity.$thruster });\n\t\t\t}\n\n\t\t\tif (thrusterRef.fsm && gameEntity.$thruster) {\n\t\t\t\tthrusterRef.fsm.update({\n\t\t\t\t\tthrust: gameEntity.$thruster.thrust,\n\t\t\t\t\trotate: gameEntity.$thruster.rotate,\n\t\t\t\t\tthrustX: gameEntity.$thruster.thrustX,\n\t\t\t\t\tthrustY: gameEntity.$thruster.thrustY,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (!gameEntity.body) continue;\n\t\t\tif (!gameEntity.physics) {\n\t\t\t\tgameEntity.physics = { body: gameEntity.body };\n\t\t\t}\n\t\t\tthis.movementBehavior.updateEntity(gameEntity, delta);\n\t\t}\n\t}\n\n\tprivate ensureWasmAttached(handle: number, options: ThrusterBehaviorOptions): void {\n\t\tif (!this.wasmStage || this.attachedRuntimeSlots.has(handle)) return;\n\t\tthis.wasmStage.attachThruster(handle, {\n\t\t\tmaxSpeed: 50,\n\t\t\tacceleration: options.linearThrust,\n\t\t\tturnRateRadPerSec: options.angularThrust,\n\t\t\tlinearDamping: options.linearDamping ?? 0,\n\t\t});\n\t\tthis.attachedRuntimeSlots.add(handle);\n\t}\n\n\tdestroy(_ecs: unknown): void {\n\t\tthis.attachedRuntimeSlots.clear();\n\t}\n}\n\n/**\n * ThrusterBehavior - typed descriptor for thruster movement.\n * \n * Uses the existing ThrusterSystem under the hood.\n * \n * @example\n * ```typescript\n * import { ThrusterBehavior } from \"@zylem/game-lib/behavior\";\n * \n * const ship = createSprite({ ... });\n * ship.use(ThrusterBehavior, { linearThrust: 15, angularThrust: 8 });\n * ```\n */\nexport const ThrusterBehavior = defineBehavior<ThrusterBehaviorOptions, Record<string, never>, ThrusterEntity>({\n\tname: 'thruster',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew ThrusterBehaviorSystem(ctx.world, ctx.wasmStage ?? null, ctx.getBehaviorLinks),\n});\n"],"mappings":"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","names":["ThrusterState","ThrusterEvent"]}
|
|
@@ -5,17 +5,19 @@ import {
|
|
|
5
5
|
} from "./chunk-EIWQM6U3.js";
|
|
6
6
|
import {
|
|
7
7
|
angleFromDirection2D,
|
|
8
|
-
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
normalizeDirection2DInto
|
|
9
|
+
} from "./chunk-Y7YIAWPW.js";
|
|
10
10
|
import {
|
|
11
11
|
StageTopDownPlane
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-Q75LKHDF.js";
|
|
13
13
|
import {
|
|
14
14
|
defineBehavior
|
|
15
15
|
} from "./chunk-EZNCCO4L.js";
|
|
16
16
|
|
|
17
|
-
// src/lib/behaviors/top-down-movement/top-down-movement.
|
|
18
|
-
var
|
|
17
|
+
// src/lib/behaviors/top-down-movement/top-down-movement.system.ts
|
|
18
|
+
var _moveDirection = { x: 0, y: 0 };
|
|
19
|
+
var _facingDirection = { x: 0, y: 0 };
|
|
20
|
+
var TopDownMovementSystem = class {
|
|
19
21
|
updateEntity(entity, _delta) {
|
|
20
22
|
if (!entity.body || !entity.transformStore || !entity.topDownMovement || !entity.$topDownMovement || !entity.topDownMovementState) {
|
|
21
23
|
return;
|
|
@@ -23,16 +25,17 @@ var TopDownMovementRuntimeBehavior = class {
|
|
|
23
25
|
const movement = entity.topDownMovement;
|
|
24
26
|
const input = entity.$topDownMovement;
|
|
25
27
|
const state = entity.topDownMovementState;
|
|
26
|
-
const
|
|
28
|
+
const isMoving = normalizeDirection2DInto(input.moveX, input.moveY, _moveDirection);
|
|
27
29
|
const velocity = entity.body.linvel();
|
|
28
|
-
state.moving =
|
|
29
|
-
entity.transformStore.velocity.x =
|
|
30
|
-
entity.transformStore.velocity.y =
|
|
30
|
+
state.moving = isMoving;
|
|
31
|
+
entity.transformStore.velocity.x = isMoving ? _moveDirection.x * movement.moveSpeed : 0;
|
|
32
|
+
entity.transformStore.velocity.y = isMoving ? _moveDirection.y * movement.moveSpeed : 0;
|
|
31
33
|
entity.transformStore.velocity.z = velocity.z;
|
|
32
|
-
entity.transformStore.dirty.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
entity.transformStore.dirty.velocityX = true;
|
|
35
|
+
entity.transformStore.dirty.velocityY = true;
|
|
36
|
+
entity.transformStore.dirty.velocityZ = true;
|
|
37
|
+
if (normalizeDirection2DInto(input.faceX, input.faceY, _facingDirection)) {
|
|
38
|
+
state.facingAngle = angleFromDirection2D(_facingDirection);
|
|
36
39
|
}
|
|
37
40
|
entity.setRotationZ?.(state.facingAngle);
|
|
38
41
|
}
|
|
@@ -57,7 +60,7 @@ var TopDownMovementBehaviorSystem = class {
|
|
|
57
60
|
}
|
|
58
61
|
wasmStage;
|
|
59
62
|
getBehaviorLinks;
|
|
60
|
-
behavior = new
|
|
63
|
+
behavior = new TopDownMovementSystem();
|
|
61
64
|
attachedRuntimeSlots = /* @__PURE__ */ new Set();
|
|
62
65
|
update(_ecs, delta) {
|
|
63
66
|
const links = this.getBehaviorLinks?.(TOP_DOWN_MOVEMENT_BEHAVIOR_KEY);
|
|
@@ -80,7 +83,7 @@ var TopDownMovementBehaviorSystem = class {
|
|
|
80
83
|
this.ensureWasmAttached(handle, ref.options);
|
|
81
84
|
const input = entity.$topDownMovement;
|
|
82
85
|
if (input) {
|
|
83
|
-
this.wasmStage.
|
|
86
|
+
this.wasmStage.writeInputAxes(handle, input.moveX ?? 0, input.moveY ?? input.moveZ ?? 0);
|
|
84
87
|
}
|
|
85
88
|
continue;
|
|
86
89
|
}
|
|
@@ -109,7 +112,7 @@ var TopDownMovementBehavior = defineBehavior({
|
|
|
109
112
|
});
|
|
110
113
|
|
|
111
114
|
export {
|
|
112
|
-
|
|
115
|
+
TopDownMovementSystem,
|
|
113
116
|
TopDownMovementBehavior
|
|
114
117
|
};
|
|
115
|
-
//# sourceMappingURL=chunk-
|
|
118
|
+
//# sourceMappingURL=chunk-A4CA35DQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/behaviors/top-down-movement/top-down-movement.system.ts","../src/lib/behaviors/top-down-movement/top-down-movement.descriptor.ts"],"sourcesContent":["import {\n\tangleFromDirection2D,\n\tnormalizeDirection2DInto,\n\ttype Direction2D,\n} from '../shared/direction-2d';\nimport type {\n\tTopDownMovementComponent,\n\tTopDownMovementInputComponent,\n\tTopDownMovementStateComponent,\n} from './components';\n\n// Per-frame scratch objects; normalizeDirection2DInto writes here instead of\n// allocating fresh direction objects per entity per frame.\nconst _moveDirection: Direction2D = { x: 0, y: 0 };\nconst _facingDirection: Direction2D = { x: 0, y: 0 };\n\nexport interface TopDownMovementEntity {\n\tbody: {\n\t\tlinvel(): { x: number; y: number; z: number };\n\t};\n\ttransformStore?: {\n\t\tvelocity: { x: number; y: number; z: number };\n\t\tdirty: { velocityX: boolean; velocityY: boolean; velocityZ: boolean };\n\t};\n\tsetRotationZ?: (angle: number) => void;\n\ttopDownMovement: TopDownMovementComponent;\n\t$topDownMovement: TopDownMovementInputComponent;\n\ttopDownMovementState: TopDownMovementStateComponent;\n}\n\nexport class TopDownMovementSystem {\n\tupdateEntity(entity: TopDownMovementEntity, _delta: number): void {\n\t\tif (\n\t\t\t!entity.body\n\t\t\t|| !entity.transformStore\n\t\t\t|| !entity.topDownMovement\n\t\t\t|| !entity.$topDownMovement\n\t\t\t|| !entity.topDownMovementState\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst movement = entity.topDownMovement;\n\t\tconst input = entity.$topDownMovement;\n\t\tconst state = entity.topDownMovementState;\n\t\tconst isMoving = normalizeDirection2DInto(input.moveX, input.moveY, _moveDirection);\n\t\tconst velocity = entity.body.linvel();\n\n\t\tstate.moving = isMoving;\n\t\tentity.transformStore.velocity.x = isMoving ? _moveDirection.x * movement.moveSpeed : 0;\n\t\tentity.transformStore.velocity.y = isMoving ? _moveDirection.y * movement.moveSpeed : 0;\n\t\tentity.transformStore.velocity.z = velocity.z;\n\t\tentity.transformStore.dirty.velocityX = true;\n\t\tentity.transformStore.dirty.velocityY = true;\n\t\tentity.transformStore.dirty.velocityZ = true;\n\n\t\tif (normalizeDirection2DInto(input.faceX, input.faceY, _facingDirection)) {\n\t\t\tstate.facingAngle = angleFromDirection2D(_facingDirection);\n\t\t}\n\n\t\tentity.setRotationZ?.(state.facingAngle);\n\t}\n}\n","import { defineBehavior, type BehaviorRef } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport {\n\tcreateTopDownMovementComponent,\n\tcreateTopDownMovementInputComponent,\n\tcreateTopDownMovementStateComponent,\n} from './components';\nimport {\n\tTopDownMovementSystem,\n\ttype TopDownMovementEntity,\n} from './top-down-movement.system';\nimport {\n\tStageTopDownPlane,\n\ttype WasmStageRuntime,\n} from '../../runtime/wasm-stage-runtime';\n\nexport interface TopDownMovementBehaviorOptions {\n\tmoveSpeed?: number;\n}\n\nexport interface TopDownMovementHandle {\n\tgetFacingAngle(): number;\n}\n\nconst defaultOptions: TopDownMovementBehaviorOptions = {\n\tmoveSpeed: 8,\n};\n\nconst TOP_DOWN_MOVEMENT_BEHAVIOR_KEY = Symbol.for(\n\t'zylem:behavior:top-down-movement',\n);\n\nfunction createTopDownMovementHandle(\n\tref: BehaviorRef<TopDownMovementBehaviorOptions>,\n): TopDownMovementHandle {\n\treturn {\n\t\tgetFacingAngle: () =>\n\t\t\t(ref as any).__entity?.topDownMovementState?.facingAngle ?? 0,\n\t};\n}\n\nclass TopDownMovementBehaviorSystem implements BehaviorSystem {\n\tprivate behavior = new TopDownMovementSystem();\n\tprivate attachedRuntimeSlots = new Set<number>();\n\n\tconstructor(\n\t\tprivate wasmStage: WasmStageRuntime | null,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {}\n\n\tupdate(_ecs: unknown, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(TOP_DOWN_MOVEMENT_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst entity = link.entity as any;\n\t\t\tconst ref = link.ref as any;\n\n\t\t\tif (!entity.topDownMovement) {\n\t\t\t\tentity.topDownMovement = createTopDownMovementComponent(ref.options);\n\t\t\t}\n\t\t\tif (!entity.$topDownMovement) {\n\t\t\t\tentity.$topDownMovement = createTopDownMovementInputComponent();\n\t\t\t}\n\t\t\tif (!entity.topDownMovementState) {\n\t\t\t\tentity.topDownMovementState = createTopDownMovementStateComponent();\n\t\t\t}\n\n\t\t\tref.__entity = entity;\n\n\t\t\tconst handle = (entity.runtimeHandle ?? -1) as number;\n\t\t\tif (this.wasmStage && handle >= 0) {\n\t\t\t\tthis.ensureWasmAttached(handle, ref.options as TopDownMovementBehaviorOptions);\n\t\t\t\tconst input = entity.$topDownMovement;\n\t\t\t\tif (input) {\n\t\t\t\t\tthis.wasmStage.writeInputAxes(handle, input.moveX ?? 0, input.moveY ?? input.moveZ ?? 0);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!entity.body || !entity.transformStore) continue;\n\t\t\tthis.behavior.updateEntity(entity, delta);\n\t\t}\n\t}\n\n\tprivate ensureWasmAttached(handle: number, options: TopDownMovementBehaviorOptions): void {\n\t\tif (!this.wasmStage || this.attachedRuntimeSlots.has(handle)) return;\n\t\tthis.wasmStage.attachTopDown(handle, {\n\t\t\tplane: StageTopDownPlane.Xy,\n\t\t\tspeed: options.moveSpeed ?? defaultOptions.moveSpeed!,\n\t\t\tfaceMovement: true,\n\t\t});\n\t\tthis.attachedRuntimeSlots.add(handle);\n\t}\n\n\tdestroy(_ecs: unknown): void {\n\t\tthis.attachedRuntimeSlots.clear();\n\t}\n}\n\nexport const TopDownMovementBehavior = defineBehavior<\n\tTopDownMovementBehaviorOptions,\n\tTopDownMovementHandle,\n\tTopDownMovementEntity\n>({\n\tname: 'top-down-movement',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew TopDownMovementBehaviorSystem(ctx.wasmStage ?? null, ctx.getBehaviorLinks),\n\tcreateHandle: createTopDownMovementHandle,\n});\n"],"mappings":"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","names":[]}
|
|
@@ -2,14 +2,18 @@ import {
|
|
|
2
2
|
GroundProbe3D,
|
|
3
3
|
getGroundAnchorOffsetY,
|
|
4
4
|
getGroundSnapTargetY
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-JXMF4NUI.js";
|
|
6
6
|
import {
|
|
7
7
|
setVelocityIntent
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-OTLSUYQQ.js";
|
|
9
9
|
import {
|
|
10
10
|
SyncStateMachine,
|
|
11
11
|
t
|
|
12
12
|
} from "./chunk-4URF65BR.js";
|
|
13
|
+
import {
|
|
14
|
+
STAGE_INPUT_BUTTON_JUMP,
|
|
15
|
+
readBehaviorSnapshot
|
|
16
|
+
} from "./chunk-Q75LKHDF.js";
|
|
13
17
|
import {
|
|
14
18
|
defineBehavior
|
|
15
19
|
} from "./chunk-EZNCCO4L.js";
|
|
@@ -48,7 +52,7 @@ function createJumpState2D() {
|
|
|
48
52
|
};
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
// src/lib/behaviors/jumper-2d/jumper-2d.
|
|
55
|
+
// src/lib/behaviors/jumper-2d/jumper-2d.system.ts
|
|
52
56
|
function jumpVelocityFromHeight(gravity, height) {
|
|
53
57
|
return Math.sqrt(2 * gravity * height);
|
|
54
58
|
}
|
|
@@ -59,7 +63,7 @@ var Jumper2DTickEvent = /* @__PURE__ */ ((Jumper2DTickEvent3) => {
|
|
|
59
63
|
Jumper2DTickEvent3["Land"] = "land";
|
|
60
64
|
return Jumper2DTickEvent3;
|
|
61
65
|
})(Jumper2DTickEvent || {});
|
|
62
|
-
var
|
|
66
|
+
var Jumper2DSystem = class {
|
|
63
67
|
tick(config, input, ctx, state) {
|
|
64
68
|
const dtMs = ctx.dt * 1e3;
|
|
65
69
|
const now = performance.now();
|
|
@@ -218,11 +222,6 @@ var defaultOptions = {
|
|
|
218
222
|
debugGroundProbe: false
|
|
219
223
|
};
|
|
220
224
|
var JUMPER_2D_BEHAVIOR_KEY = /* @__PURE__ */ Symbol.for("zylem:behavior:jumper-2d");
|
|
221
|
-
var JUMPER_2D_OFFSETS = [
|
|
222
|
-
{ x: 0, z: 0 },
|
|
223
|
-
{ x: 0.35, z: 0 },
|
|
224
|
-
{ x: -0.35, z: 0 }
|
|
225
|
-
];
|
|
226
225
|
function isJumper2DGrounded(params) {
|
|
227
226
|
if (params.velocityY > 0) {
|
|
228
227
|
return false;
|
|
@@ -237,22 +236,22 @@ function shouldSnapJumper2DToGround(support, options, velocityY) {
|
|
|
237
236
|
}
|
|
238
237
|
var Jumper2DBehaviorSystem = class {
|
|
239
238
|
constructor(world, scene, wasmStage, getBehaviorLinks) {
|
|
240
|
-
this.world = world;
|
|
241
239
|
this.scene = scene;
|
|
242
240
|
this.wasmStage = wasmStage;
|
|
243
241
|
this.getBehaviorLinks = getBehaviorLinks;
|
|
244
242
|
this.groundProbe = new GroundProbe3D(world);
|
|
245
243
|
}
|
|
246
|
-
world;
|
|
247
244
|
scene;
|
|
248
245
|
wasmStage;
|
|
249
246
|
getBehaviorLinks;
|
|
250
|
-
behavior = new
|
|
247
|
+
behavior = new Jumper2DSystem();
|
|
251
248
|
groundProbe;
|
|
252
249
|
initializedEntities = /* @__PURE__ */ new Set();
|
|
253
250
|
timeSinceGroundedMs = /* @__PURE__ */ new Map();
|
|
254
251
|
wasJumpHeld = /* @__PURE__ */ new Map();
|
|
255
252
|
attachedRuntimeSlots = /* @__PURE__ */ new Set();
|
|
253
|
+
/** Reused per-entity per-frame instead of spreading a fresh input object. */
|
|
254
|
+
effectiveInput = createJumpInput2D();
|
|
256
255
|
update(_ecs, delta) {
|
|
257
256
|
const links = this.getBehaviorLinks?.(JUMPER_2D_BEHAVIOR_KEY);
|
|
258
257
|
if (!links) return;
|
|
@@ -263,9 +262,11 @@ var Jumper2DBehaviorSystem = class {
|
|
|
263
262
|
const handle = gameEntity.runtimeHandle ?? -1;
|
|
264
263
|
if (this.wasmStage && handle >= 0) {
|
|
265
264
|
this.ensureWasmAttached(handle, options);
|
|
265
|
+
jumperRef.__wasmStage = this.wasmStage;
|
|
266
|
+
jumperRef.__entity = gameEntity;
|
|
266
267
|
const input2 = gameEntity.$jumper2d;
|
|
267
268
|
const jumpPressed = !!(input2?.jumpPressed || input2?.jumpHeld);
|
|
268
|
-
this.wasmStage.
|
|
269
|
+
this.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_JUMP, jumpPressed);
|
|
269
270
|
continue;
|
|
270
271
|
}
|
|
271
272
|
if (!gameEntity.body) continue;
|
|
@@ -292,7 +293,6 @@ var Jumper2DBehaviorSystem = class {
|
|
|
292
293
|
const probeOriginYOffset = 0.05 - getGroundAnchorOffsetY(gameEntity);
|
|
293
294
|
const support = this.groundProbe.probeSupport(gameEntity, {
|
|
294
295
|
rayLength,
|
|
295
|
-
offsets: JUMPER_2D_OFFSETS,
|
|
296
296
|
mode: "any",
|
|
297
297
|
debug: options.debugGroundProbe ?? false,
|
|
298
298
|
scene: this.scene,
|
|
@@ -328,11 +328,11 @@ var Jumper2DBehaviorSystem = class {
|
|
|
328
328
|
const state = gameEntity.jumper2dState;
|
|
329
329
|
const previousHeld = this.wasJumpHeld.get(gameEntity.uuid) ?? false;
|
|
330
330
|
const held = input.jumpHeld === true;
|
|
331
|
-
const effectiveInput =
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
331
|
+
const effectiveInput = this.effectiveInput;
|
|
332
|
+
effectiveInput.jumpPressed = input.jumpPressed || held && !previousHeld;
|
|
333
|
+
effectiveInput.jumpHeld = held;
|
|
334
|
+
effectiveInput.jumpReleased = input.jumpReleased || !held && previousHeld;
|
|
335
|
+
effectiveInput.fastFall = input.fastFall;
|
|
336
336
|
const store = gameEntity.transformStore;
|
|
337
337
|
const ctx = {
|
|
338
338
|
dt: delta,
|
|
@@ -376,20 +376,36 @@ var Jumper2DBehaviorSystem = class {
|
|
|
376
376
|
this.attachedRuntimeSlots.clear();
|
|
377
377
|
}
|
|
378
378
|
};
|
|
379
|
-
var
|
|
379
|
+
var Jumper2DBehavior = defineBehavior({
|
|
380
380
|
name: "jumper-2d",
|
|
381
381
|
defaultOptions,
|
|
382
382
|
systemFactory: (ctx) => new Jumper2DBehaviorSystem(ctx.world, ctx.scene, ctx.wasmStage ?? null, ctx.getBehaviorLinks),
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
383
|
+
// On the wasm fast path the handle reads the runtime snapshot buffer
|
|
384
|
+
// (previous-step values); the TS FSM only backs the no-wasm fallback.
|
|
385
|
+
createHandle: (ref) => {
|
|
386
|
+
const jumpsUsed = () => {
|
|
387
|
+
const snapshot = readBehaviorSnapshot(ref);
|
|
388
|
+
if (snapshot) return snapshot.jumpCount;
|
|
389
|
+
return ref.fsm?.getJumpsUsed() ?? 0;
|
|
390
|
+
};
|
|
391
|
+
return {
|
|
392
|
+
getState: () => {
|
|
393
|
+
const snapshot = readBehaviorSnapshot(ref);
|
|
394
|
+
if (snapshot) {
|
|
395
|
+
if (snapshot.grounded) return "grounded" /* Grounded */;
|
|
396
|
+
return snapshot.verticalVelocity > 0 ? "jumping" /* Jumping */ : "falling" /* Falling */;
|
|
397
|
+
}
|
|
398
|
+
return ref.fsm?.getState() ?? "grounded" /* Grounded */;
|
|
399
|
+
},
|
|
400
|
+
isJumping: () => {
|
|
401
|
+
const snapshot = readBehaviorSnapshot(ref);
|
|
402
|
+
if (snapshot) return !snapshot.grounded && snapshot.verticalVelocity > 0;
|
|
403
|
+
return ref.fsm?.isJumping() ?? false;
|
|
404
|
+
},
|
|
405
|
+
getJumpsUsed: jumpsUsed,
|
|
406
|
+
getJumpsRemaining: () => (ref.options.maxJumps ?? 1) - jumpsUsed()
|
|
407
|
+
};
|
|
408
|
+
}
|
|
393
409
|
});
|
|
394
410
|
|
|
395
411
|
export {
|
|
@@ -397,10 +413,10 @@ export {
|
|
|
397
413
|
createJumpInput2D,
|
|
398
414
|
createJumpState2D,
|
|
399
415
|
Jumper2DTickEvent,
|
|
400
|
-
|
|
416
|
+
Jumper2DSystem,
|
|
401
417
|
Jumper2DState,
|
|
402
418
|
Jumper2DEvent,
|
|
403
419
|
Jumper2DFSM,
|
|
404
|
-
|
|
420
|
+
Jumper2DBehavior
|
|
405
421
|
};
|
|
406
|
-
//# sourceMappingURL=chunk-
|
|
422
|
+
//# sourceMappingURL=chunk-F72WX4MH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/behaviors/jumper-2d/components.ts","../src/lib/behaviors/jumper-2d/jumper-2d.system.ts","../src/lib/behaviors/jumper-2d/jumper-2d-fsm.ts","../src/lib/behaviors/jumper-2d/jumper-2d.descriptor.ts"],"sourcesContent":["export interface JumpConfig2D {\n\tjumpHeight: number;\n\tgravity: number;\n\tmaxFallSpeed?: number;\n\tmaxJumps: number;\n\tresetJumpsOnGround: boolean;\n\tcoyoteTimeMs: number;\n\tjumpBufferMs: number;\n\tminTimeBetweenJumpsMs?: number;\n\tvariableJump?: {\n\t\tenabled: boolean;\n\t\tcutGravityMultiplier: number;\n\t\tmaxHoldMs?: number;\n\t};\n}\n\nexport function createJumpConfig2D(\n\toptions: Partial<JumpConfig2D> = {},\n): JumpConfig2D {\n\treturn {\n\t\tjumpHeight: options.jumpHeight ?? 2.5,\n\t\tgravity: options.gravity ?? 20,\n\t\tmaxFallSpeed: options.maxFallSpeed,\n\t\tmaxJumps: options.maxJumps ?? 1,\n\t\tresetJumpsOnGround: options.resetJumpsOnGround ?? true,\n\t\tcoyoteTimeMs: options.coyoteTimeMs ?? 100,\n\t\tjumpBufferMs: options.jumpBufferMs ?? 80,\n\t\tminTimeBetweenJumpsMs: options.minTimeBetweenJumpsMs,\n\t\tvariableJump: options.variableJump,\n\t};\n}\n\nexport interface JumpInput2D {\n\tjumpPressed: boolean;\n\tjumpHeld: boolean;\n\tjumpReleased: boolean;\n\tfastFall?: boolean;\n}\n\nexport function createJumpInput2D(): JumpInput2D {\n\treturn {\n\t\tjumpPressed: false,\n\t\tjumpHeld: false,\n\t\tjumpReleased: false,\n\t\tfastFall: false,\n\t};\n}\n\nexport interface JumpContext2D {\n\tdt: number;\n\tvelocityY: number;\n\tisGrounded: boolean;\n\ttimeSinceGroundedMs: number;\n\tsetVerticalVelocity(y: number): void;\n}\n\nexport interface JumpState2D {\n\tjumpsUsed: number;\n\tlastJumpTimeMs: number;\n\tbufferedJumpMs: number;\n\tcoyoteMs: number;\n\tisJumping: boolean;\n\tjumpHoldMs: number;\n\tjumpCutApplied: boolean;\n}\n\nexport function createJumpState2D(): JumpState2D {\n\treturn {\n\t\tjumpsUsed: 0,\n\t\tlastJumpTimeMs: 0,\n\t\tbufferedJumpMs: 0,\n\t\tcoyoteMs: 0,\n\t\tisJumping: false,\n\t\tjumpHoldMs: 0,\n\t\tjumpCutApplied: false,\n\t};\n}\n","import type {\n\tJumpConfig2D,\n\tJumpContext2D,\n\tJumpInput2D,\n\tJumpState2D,\n} from './components';\n\nfunction jumpVelocityFromHeight(gravity: number, height: number): number {\n\treturn Math.sqrt(2 * gravity * height);\n}\n\nexport enum Jumper2DTickEvent {\n\tNone = 'none',\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n}\n\nexport interface Jumper2DTickResult {\n\tevent: Jumper2DTickEvent;\n}\n\nexport class Jumper2DSystem {\n\ttick(\n\t\tconfig: JumpConfig2D,\n\t\tinput: JumpInput2D,\n\t\tctx: JumpContext2D,\n\t\tstate: JumpState2D,\n\t): Jumper2DTickResult {\n\t\tconst dtMs = ctx.dt * 1000;\n\t\tconst now = performance.now();\n\t\tlet event = Jumper2DTickEvent.None;\n\t\tlet jumpedThisFrame = false;\n\n\t\tif (ctx.isGrounded) {\n\t\t\tstate.coyoteMs = config.coyoteTimeMs;\n\t\t\tif (config.resetJumpsOnGround) {\n\t\t\t\tstate.jumpsUsed = 0;\n\t\t\t}\n\t\t\tif (state.isJumping) {\n\t\t\t\tstate.isJumping = false;\n\t\t\t\tstate.jumpCutApplied = false;\n\t\t\t\tevent = Jumper2DTickEvent.Land;\n\t\t\t}\n\t\t} else {\n\t\t\tstate.coyoteMs = Math.max(0, state.coyoteMs - dtMs);\n\t\t}\n\n\t\tif (input.jumpPressed) {\n\t\t\tstate.bufferedJumpMs = config.jumpBufferMs;\n\t\t} else {\n\t\t\tstate.bufferedJumpMs = Math.max(0, state.bufferedJumpMs - dtMs);\n\t\t}\n\n\t\tif (state.isJumping && input.jumpHeld) {\n\t\t\tstate.jumpHoldMs += dtMs;\n\t\t}\n\n\t\tconst wantsJump = state.bufferedJumpMs > 0;\n\t\tconst isFirstJump =\n\t\t\tctx.isGrounded || (state.coyoteMs > 0 && state.jumpsUsed === 0);\n\t\tconst hasAirJumps = state.jumpsUsed > 0 && state.jumpsUsed < config.maxJumps;\n\t\tconst canJump = isFirstJump || hasAirJumps;\n\t\tconst cooldownOk =\n\t\t\tconfig.minTimeBetweenJumpsMs == null ||\n\t\t\tnow - state.lastJumpTimeMs >= config.minTimeBetweenJumpsMs;\n\n\t\tif (wantsJump && canJump && cooldownOk) {\n\t\t\tctx.setVerticalVelocity(jumpVelocityFromHeight(config.gravity, config.jumpHeight));\n\t\t\tjumpedThisFrame = true;\n\t\t\tstate.jumpsUsed++;\n\t\t\tstate.lastJumpTimeMs = now;\n\t\t\tstate.bufferedJumpMs = 0;\n\t\t\tstate.coyoteMs = 0;\n\t\t\tstate.isJumping = true;\n\t\t\tstate.jumpHoldMs = 0;\n\t\t\tstate.jumpCutApplied = false;\n\t\t\tevent = Jumper2DTickEvent.Jump;\n\t\t}\n\n\t\tif (!ctx.isGrounded || jumpedThisFrame) {\n\t\t\tlet gravityMul = 1;\n\t\t\tconst isFalling = ctx.velocityY < 0;\n\n\t\t\tif (isFalling) {\n\t\t\t\tgravityMul = input.fastFall ? 1.75 : 1;\n\t\t\t\tif (event !== Jumper2DTickEvent.Land) {\n\t\t\t\t\tevent = Jumper2DTickEvent.Fall;\n\t\t\t\t}\n\t\t\t} else if (state.isJumping) {\n\t\t\t\tconst variableJump = config.variableJump;\n\t\t\t\tif (variableJump?.enabled && !state.jumpCutApplied) {\n\t\t\t\t\tconst holdExpired =\n\t\t\t\t\t\tvariableJump.maxHoldMs != null &&\n\t\t\t\t\t\tstate.jumpHoldMs >= variableJump.maxHoldMs;\n\t\t\t\t\tif (!input.jumpHeld || holdExpired) {\n\t\t\t\t\t\tgravityMul = variableJump.cutGravityMultiplier;\n\t\t\t\t\t\tstate.jumpCutApplied = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlet newVelocityY = ctx.velocityY - config.gravity * gravityMul * ctx.dt;\n\t\t\tif (config.maxFallSpeed != null) {\n\t\t\t\tnewVelocityY = Math.max(-config.maxFallSpeed, newVelocityY);\n\t\t\t}\n\t\t\tctx.setVerticalVelocity(newVelocityY);\n\t\t} else {\n\t\t\tctx.setVerticalVelocity(0);\n\t\t}\n\n\t\treturn { event };\n\t}\n}\n","import { SyncStateMachine, t } from '../../core/utility/sync-state-machine';\nimport type { JumpState2D } from './components';\n\nexport enum Jumper2DState {\n\tGrounded = 'grounded',\n\tJumping = 'jumping',\n\tFalling = 'falling',\n}\n\nexport enum Jumper2DEvent {\n\tJump = 'jump',\n\tFall = 'fall',\n\tLand = 'land',\n}\n\nexport interface Jumper2DFSMContext {\n\tstate: JumpState2D;\n}\n\nexport class Jumper2DFSM {\n\tmachine: SyncStateMachine<Jumper2DState, Jumper2DEvent, never>;\n\n\tconstructor(private ctx: Jumper2DFSMContext) {\n\t\tthis.machine = new SyncStateMachine<Jumper2DState, Jumper2DEvent, never>(\n\t\t\tJumper2DState.Grounded,\n\t\t\t[\n\t\t\t\tt(Jumper2DState.Grounded, Jumper2DEvent.Jump, Jumper2DState.Jumping),\n\t\t\t\tt(Jumper2DState.Grounded, Jumper2DEvent.Fall, Jumper2DState.Falling),\n\t\t\t\tt(Jumper2DState.Grounded, Jumper2DEvent.Land, Jumper2DState.Grounded),\n\t\t\t\tt(Jumper2DState.Jumping, Jumper2DEvent.Fall, Jumper2DState.Falling),\n\t\t\t\tt(Jumper2DState.Jumping, Jumper2DEvent.Land, Jumper2DState.Grounded),\n\t\t\t\tt(Jumper2DState.Jumping, Jumper2DEvent.Jump, Jumper2DState.Jumping),\n\t\t\t\tt(Jumper2DState.Falling, Jumper2DEvent.Land, Jumper2DState.Grounded),\n\t\t\t\tt(Jumper2DState.Falling, Jumper2DEvent.Jump, Jumper2DState.Jumping),\n\t\t\t\tt(Jumper2DState.Falling, Jumper2DEvent.Fall, Jumper2DState.Falling),\n\t\t\t],\n\t\t);\n\t}\n\n\tgetState(): Jumper2DState {\n\t\treturn this.machine.getState();\n\t}\n\n\tdispatch(event: Jumper2DEvent): void {\n\t\tif (this.machine.can(event)) {\n\t\t\tthis.machine.syncDispatch(event);\n\t\t}\n\t}\n\n\tisJumping(): boolean {\n\t\treturn this.getState() === Jumper2DState.Jumping;\n\t}\n\n\tisGrounded(): boolean {\n\t\treturn this.getState() === Jumper2DState.Grounded;\n\t}\n\n\tgetJumpsUsed(): number {\n\t\treturn this.ctx.state.jumpsUsed;\n\t}\n\n\tapplyTickEvent(tickEvent: string, isGrounded: boolean): void {\n\t\tswitch (tickEvent) {\n\t\t\tcase 'jump':\n\t\t\t\tthis.dispatch(Jumper2DEvent.Jump);\n\t\t\t\tbreak;\n\t\t\tcase 'fall':\n\t\t\t\tthis.dispatch(Jumper2DEvent.Fall);\n\t\t\t\tbreak;\n\t\t\tcase 'land':\n\t\t\t\tthis.dispatch(Jumper2DEvent.Land);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (!isGrounded && this.getState() === Jumper2DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper2DEvent.Fall);\n\t\t\t\t}\n\t\t\t\tif (isGrounded && this.getState() !== Jumper2DState.Grounded) {\n\t\t\t\t\tthis.dispatch(Jumper2DEvent.Land);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n","import { defineBehavior } from '../behavior-descriptor';\nimport type { BehaviorEntityLink, BehaviorSystem } from '../behavior-system';\nimport { setVelocityIntent } from '../../capabilities/velocity-intents';\nimport {\n\tGroundProbe3D,\n\tgetGroundAnchorOffsetY,\n\tgetGroundSnapTargetY,\n\ttype GroundProbeSupportHit,\n} from '../shared/ground-probe-3d';\nimport {\n\tcreateJumpConfig2D,\n\tcreateJumpInput2D,\n\tcreateJumpState2D,\n\ttype JumpConfig2D,\n\ttype JumpContext2D,\n\ttype JumpInput2D,\n\ttype JumpState2D,\n} from './components';\nimport {\n\tJumper2DSystem,\n\tJumper2DTickEvent,\n} from './jumper-2d.system';\nimport { Jumper2DFSM, Jumper2DState } from './jumper-2d-fsm';\nimport {\n\tSTAGE_INPUT_BUTTON_JUMP,\n\treadBehaviorSnapshot,\n\ttype WasmStageRuntime,\n} from '../../runtime/wasm-stage-runtime';\n\nexport interface Jumper2DBehaviorOptions {\n\tjumpHeight?: number;\n\tgravity?: number;\n\tmaxFallSpeed?: number;\n\tmaxJumps?: number;\n\tresetJumpsOnGround?: boolean;\n\tcoyoteTimeMs?: number;\n\tjumpBufferMs?: number;\n\tminTimeBetweenJumpsMs?: number;\n\tvariableJump?: JumpConfig2D['variableJump'];\n\tgroundRayLength?: number;\n\tsnapToGroundDistance?: number;\n\tdebugGroundProbe?: boolean;\n}\n\nconst defaultOptions: Jumper2DBehaviorOptions = {\n\tjumpHeight: 2.5,\n\tgravity: 20,\n\tmaxJumps: 1,\n\tresetJumpsOnGround: true,\n\tcoyoteTimeMs: 100,\n\tjumpBufferMs: 80,\n\tgroundRayLength: 1,\n\tdebugGroundProbe: false,\n};\n\nconst JUMPER_2D_BEHAVIOR_KEY = Symbol.for('zylem:behavior:jumper-2d');\n\nexport function isJumper2DGrounded(params: {\n\tnearGround?: boolean;\n\tvelocityY: number;\n\tsupportToi?: number | null;\n\tsnapToGroundDistance?: number;\n}): boolean {\n\tif (params.velocityY > 0) {\n\t\treturn false;\n\t}\n\n\tif (params.snapToGroundDistance != null) {\n\t\treturn (\n\t\t\tparams.supportToi != null &&\n\t\t\tparams.supportToi <= params.snapToGroundDistance\n\t\t);\n\t}\n\n\treturn params.nearGround === true;\n}\n\nfunction shouldSnapJumper2DToGround(\n\tsupport: GroundProbeSupportHit | null,\n\toptions: Jumper2DBehaviorOptions,\n\tvelocityY: number,\n): support is GroundProbeSupportHit {\n\treturn (\n\t\tsupport != null &&\n\t\toptions.snapToGroundDistance != null &&\n\t\tvelocityY <= 0 &&\n\t\tsupport.toi <= options.snapToGroundDistance\n\t);\n}\n\nexport interface Jumper2DEntity {\n\tuuid: string;\n\tbody: import('@dimforge/rapier3d-compat').RigidBody | null;\n\ttransformStore: import('../../capabilities/transform-store').TransformState;\n\tjumper2d: JumpConfig2D;\n\t$jumper2d: JumpInput2D;\n\tjumper2dState: JumpState2D;\n}\n\nclass Jumper2DBehaviorSystem implements BehaviorSystem {\n\tprivate behavior = new Jumper2DSystem();\n\tprivate groundProbe: GroundProbe3D;\n\tprivate initializedEntities = new Set<string>();\n\tprivate timeSinceGroundedMs = new Map<string, number>();\n\tprivate wasJumpHeld = new Map<string, boolean>();\n\tprivate attachedRuntimeSlots = new Set<number>();\n\t/** Reused per-entity per-frame instead of spreading a fresh input object. */\n\tprivate effectiveInput: JumpInput2D = createJumpInput2D();\n\n\tconstructor(\n\t\tworld: import('../../collision/world').ZylemWorld | null,\n\t\tprivate scene: any,\n\t\tprivate wasmStage: WasmStageRuntime | null,\n\t\tprivate getBehaviorLinks?: (key: symbol) => Iterable<BehaviorEntityLink>,\n\t) {\n\t\tthis.groundProbe = new GroundProbe3D(world);\n\t}\n\n\tupdate(_ecs: unknown, delta: number): void {\n\t\tconst links = this.getBehaviorLinks?.(JUMPER_2D_BEHAVIOR_KEY);\n\t\tif (!links) return;\n\n\t\tfor (const link of links) {\n\t\t\tconst gameEntity = link.entity as any;\n\t\t\tconst jumperRef = link.ref as any;\n\n\t\t\tconst options = jumperRef.options as Jumper2DBehaviorOptions;\n\t\t\tconst handle = (gameEntity.runtimeHandle ?? -1) as number;\n\t\t\tif (this.wasmStage && handle >= 0) {\n\t\t\t\tthis.ensureWasmAttached(handle, options);\n\t\t\t\tjumperRef.__wasmStage = this.wasmStage;\n\t\t\t\tjumperRef.__entity = gameEntity;\n\t\t\t\tconst input = gameEntity.$jumper2d as JumpInput2D | undefined;\n\t\t\t\tconst jumpPressed = !!(input?.jumpPressed || input?.jumpHeld);\n\t\t\t\tthis.wasmStage.writeInputButton(handle, STAGE_INPUT_BUTTON_JUMP, jumpPressed);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!gameEntity.body) continue;\n\n\t\t\tif (!gameEntity.jumper2d) {\n\t\t\t\tgameEntity.jumper2d = createJumpConfig2D(options);\n\t\t\t}\n\t\t\tif (!gameEntity.$jumper2d) {\n\t\t\t\tgameEntity.$jumper2d = createJumpInput2D();\n\t\t\t}\n\t\t\tif (!gameEntity.jumper2dState) {\n\t\t\t\tgameEntity.jumper2dState = createJumpState2D();\n\t\t\t}\n\t\t\tif (!this.initializedEntities.has(gameEntity.uuid)) {\n\t\t\t\tthis.initializedEntities.add(gameEntity.uuid);\n\t\t\t\tgameEntity.body.setGravityScale(0, true);\n\t\t\t}\n\t\t\tif (!jumperRef.fsm && gameEntity.jumper2dState) {\n\t\t\t\tjumperRef.fsm = new Jumper2DFSM({\n\t\t\t\t\tstate: gameEntity.jumper2dState,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst rayLength = options.groundRayLength ?? 1;\n\t\t\tconst bodyVelocity = gameEntity.body.linvel();\n\t\t\tconst probeOriginYOffset = 0.05 - getGroundAnchorOffsetY(gameEntity);\n\t\t\tconst support = this.groundProbe.probeSupport(gameEntity, {\n\t\t\t\trayLength,\n\t\t\t\tmode: 'any',\n\t\t\t\tdebug: options.debugGroundProbe ?? false,\n\t\t\t\tscene: this.scene,\n\t\t\t\toriginYOffset: probeOriginYOffset,\n\t\t\t});\n\t\t\tconst nearGround = support != null;\n\t\t\tconst isGrounded = isJumper2DGrounded({\n\t\t\t\tnearGround,\n\t\t\t\tvelocityY: bodyVelocity.y,\n\t\t\t\tsupportToi: support?.toi ?? null,\n\t\t\t\tsnapToGroundDistance: options.snapToGroundDistance,\n\t\t\t});\n\t\t\tif (shouldSnapJumper2DToGround(support, options, bodyVelocity.y)) {\n\t\t\t\tconst currentPosition = gameEntity.body.translation();\n\t\t\t\tgameEntity.body.setTranslation(\n\t\t\t\t\t{\n\t\t\t\t\t\tx: currentPosition.x,\n\t\t\t\t\t\ty: getGroundSnapTargetY(gameEntity, support),\n\t\t\t\t\t\tz: currentPosition.z,\n\t\t\t\t\t},\n\t\t\t\t\ttrue,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tlet timeSinceGroundedMs = this.timeSinceGroundedMs.get(gameEntity.uuid) ?? 0;\n\t\t\tif (isGrounded) {\n\t\t\t\ttimeSinceGroundedMs = 0;\n\t\t\t} else {\n\t\t\t\ttimeSinceGroundedMs += delta * 1000;\n\t\t\t}\n\t\t\tthis.timeSinceGroundedMs.set(gameEntity.uuid, timeSinceGroundedMs);\n\n\t\t\tconst config: JumpConfig2D = gameEntity.jumper2d;\n\t\t\tconst input: JumpInput2D = gameEntity.$jumper2d;\n\t\t\tconst state: JumpState2D = gameEntity.jumper2dState;\n\t\t\tconst previousHeld = this.wasJumpHeld.get(gameEntity.uuid) ?? false;\n\t\t\tconst held = input.jumpHeld === true;\n\t\t\tconst effectiveInput = this.effectiveInput;\n\t\t\teffectiveInput.jumpPressed = input.jumpPressed || (held && !previousHeld);\n\t\t\teffectiveInput.jumpHeld = held;\n\t\t\teffectiveInput.jumpReleased = input.jumpReleased || (!held && previousHeld);\n\t\t\teffectiveInput.fastFall = input.fastFall;\n\n\t\t\tconst store = gameEntity.transformStore;\n\t\t\tconst ctx: JumpContext2D = {\n\t\t\t\tdt: delta,\n\t\t\t\tvelocityY: bodyVelocity.y,\n\t\t\t\tisGrounded,\n\t\t\t\ttimeSinceGroundedMs,\n\t\t\t\tsetVerticalVelocity: (y: number) => {\n\t\t\t\t\tsetVelocityIntent(\n\t\t\t\t\t\tstore,\n\t\t\t\t\t\t'jumper-2d',\n\t\t\t\t\t\t{ y },\n\t\t\t\t\t\t{ mode: 'replace', priority: 20 },\n\t\t\t\t\t);\n\t\t\t\t\tctx.velocityY = y;\n\t\t\t\t},\n\t\t\t};\n\n\t\t\tconst result = this.behavior.tick(config, effectiveInput, ctx, state);\n\t\t\tthis.wasJumpHeld.set(gameEntity.uuid, held);\n\n\t\t\tif (jumperRef.fsm) {\n\t\t\t\t(jumperRef.fsm as Jumper2DFSM).applyTickEvent(result.event, isGrounded);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate ensureWasmAttached(handle: number, options: Jumper2DBehaviorOptions): void {\n\t\tif (!this.wasmStage || this.attachedRuntimeSlots.has(handle)) return;\n\t\tconst jumpForce = Math.sqrt(2 * (options.gravity ?? 20) * (options.jumpHeight ?? 2.5));\n\t\tthis.wasmStage.attachJumper2D(handle, {\n\t\t\tjumpForce,\n\t\t\tmaxJumps: options.maxJumps ?? 1,\n\t\t\tjumpBufferTime: (options.jumpBufferMs ?? 80) / 1000,\n\t\t\tcoyoteTime: (options.coyoteTimeMs ?? 100) / 1000,\n\t\t\tgravity: options.gravity ?? 20,\n\t\t});\n\t\tthis.attachedRuntimeSlots.add(handle);\n\t}\n\n\tdestroy(_ecs: unknown): void {\n\t\tthis.groundProbe.destroy();\n\t\tthis.initializedEntities.clear();\n\t\tthis.timeSinceGroundedMs.clear();\n\t\tthis.wasJumpHeld.clear();\n\t\tthis.attachedRuntimeSlots.clear();\n\t}\n}\n\nexport const Jumper2DBehavior = defineBehavior<\n\tJumper2DBehaviorOptions,\n\t{\n\t\tgetState: () => Jumper2DState;\n\t\tisJumping: () => boolean;\n\t\tgetJumpsUsed: () => number;\n\t\tgetJumpsRemaining: () => number;\n\t},\n\tJumper2DEntity\n>({\n\tname: 'jumper-2d',\n\tdefaultOptions,\n\tsystemFactory: (ctx) =>\n\t\tnew Jumper2DBehaviorSystem(ctx.world, ctx.scene, ctx.wasmStage ?? null, ctx.getBehaviorLinks),\n\t// On the wasm fast path the handle reads the runtime snapshot buffer\n\t// (previous-step values); the TS FSM only backs the no-wasm fallback.\n\tcreateHandle: (ref) => {\n\t\tconst jumpsUsed = () => {\n\t\t\tconst snapshot = readBehaviorSnapshot(ref);\n\t\t\tif (snapshot) return snapshot.jumpCount;\n\t\t\treturn (ref.fsm as Jumper2DFSM | undefined)?.getJumpsUsed() ?? 0;\n\t\t};\n\t\treturn {\n\t\t\tgetState: () => {\n\t\t\t\tconst snapshot = readBehaviorSnapshot(ref);\n\t\t\t\tif (snapshot) {\n\t\t\t\t\tif (snapshot.grounded) return Jumper2DState.Grounded;\n\t\t\t\t\treturn snapshot.verticalVelocity > 0\n\t\t\t\t\t\t? Jumper2DState.Jumping\n\t\t\t\t\t\t: Jumper2DState.Falling;\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t(ref.fsm as Jumper2DFSM | undefined)?.getState() ??\n\t\t\t\t\tJumper2DState.Grounded\n\t\t\t\t);\n\t\t\t},\n\t\t\tisJumping: () => {\n\t\t\t\tconst snapshot = readBehaviorSnapshot(ref);\n\t\t\t\tif (snapshot) return !snapshot.grounded && snapshot.verticalVelocity > 0;\n\t\t\t\treturn (ref.fsm as Jumper2DFSM | undefined)?.isJumping() ?? false;\n\t\t\t},\n\t\t\tgetJumpsUsed: jumpsUsed,\n\t\t\tgetJumpsRemaining: () => (ref.options.maxJumps ?? 1) - jumpsUsed(),\n\t\t};\n\t},\n});\n"],"mappings":"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","names":["Jumper2DTickEvent","Jumper2DState","Jumper2DEvent","input"]}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
+
fireShooter2DIfRequested,
|
|
2
3
|
getEntityFacingAngle2D,
|
|
3
4
|
resolveAim2D
|
|
4
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UL6Q5HDP.js";
|
|
5
6
|
import {
|
|
6
7
|
createThrusterInputComponent
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-IZJFUAXB.js";
|
|
8
9
|
|
|
9
10
|
// src/lib/coordinators/multidirectional-space-shooter.coordinator.ts
|
|
10
11
|
var MultidirectionalSpaceShooterCoordinator = class {
|
|
@@ -32,25 +33,11 @@ var MultidirectionalSpaceShooterCoordinator = class {
|
|
|
32
33
|
if (aim.hasAimInput) {
|
|
33
34
|
this.entity.setRotationZ(aim.angle);
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const sourcePosition = this.entity.body?.translation();
|
|
39
|
-
if (!sourcePosition) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
void this.shooter.fire({
|
|
43
|
-
source: this.entity,
|
|
44
|
-
stage: this.stage,
|
|
45
|
-
target: {
|
|
46
|
-
x: sourcePosition.x + aim.direction.x,
|
|
47
|
-
y: sourcePosition.y + aim.direction.y
|
|
48
|
-
}
|
|
49
|
-
});
|
|
36
|
+
fireShooter2DIfRequested(this.entity, this.shooter, this.stage, input, aim);
|
|
50
37
|
}
|
|
51
38
|
};
|
|
52
39
|
|
|
53
40
|
export {
|
|
54
41
|
MultidirectionalSpaceShooterCoordinator
|
|
55
42
|
};
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
43
|
+
//# sourceMappingURL=chunk-FTDZAKZW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/coordinators/multidirectional-space-shooter.coordinator.ts"],"sourcesContent":["import {\n\tcreateThrusterInputComponent,\n\ttype ThrusterInputComponent,\n} from '../behaviors/thruster/components';\nimport type {\n\tShooter2DHandle,\n\tShooter2DSourceEntity,\n\tShooter2DStageLike,\n} from '../behaviors/shooter-2d/shooter-2d.descriptor';\nimport { getEntityFacingAngle2D, resolveAim2D } from './shared/top-down-aim';\nimport {\n\tfireShooter2DIfRequested,\n\ttype Shooter2DAimFireInput,\n} from './shared/shooter-fire';\n\nexport interface MultidirectionalSpaceShooterInput extends Shooter2DAimFireInput {\n\tmoveX: number;\n\tmoveY: number;\n}\n\nexport type MultidirectionalSpaceShooterEntity = Shooter2DSourceEntity & {\n\t$thruster?: ThrusterInputComponent;\n\tsetRotationZ(angle: number): void;\n};\n\n/**\n * Coordinator that fans a single input snapshot out to the thruster behavior\n * (vector thrust), entity rotation (aim), and the Shooter2D behavior (fire\n * requests).\n */\nexport class MultidirectionalSpaceShooterCoordinator {\n\tconstructor(\n\t\tprivate entity: MultidirectionalSpaceShooterEntity,\n\t\tprivate shooter: Shooter2DHandle,\n\t\tprivate stage: Shooter2DStageLike,\n\t) {}\n\n\tpublic update(input: MultidirectionalSpaceShooterInput): void {\n\t\tif (!this.entity.$thruster) {\n\t\t\tthis.entity.$thruster = createThrusterInputComponent();\n\t\t}\n\n\t\tthis.entity.$thruster.thrustX = input.moveX;\n\t\tthis.entity.$thruster.thrustY = input.moveY;\n\t\tthis.entity.$thruster.thrust = 0;\n\t\tthis.entity.$thruster.rotate = 0;\n\n\t\tconst aim = resolveAim2D(\n\t\t\tinput.aimX,\n\t\t\tinput.aimY,\n\t\t\tgetEntityFacingAngle2D(this.entity),\n\t\t);\n\t\tif (aim.hasAimInput) {\n\t\t\tthis.entity.setRotationZ(aim.angle);\n\t\t}\n\n\t\tfireShooter2DIfRequested(this.entity, this.shooter, this.stage, input, aim);\n\t}\n}\n"],"mappings":";;;;;;;;;;AA8BO,IAAM,0CAAN,MAA8C;AAAA,EACpD,YACS,QACA,SACA,OACP;AAHO;AACA;AACA;AAAA,EACN;AAAA,EAHM;AAAA,EACA;AAAA,EACA;AAAA,EAGF,OAAO,OAAgD;AAC7D,QAAI,CAAC,KAAK,OAAO,WAAW;AAC3B,WAAK,OAAO,YAAY,6BAA6B;AAAA,IACtD;AAEA,SAAK,OAAO,UAAU,UAAU,MAAM;AACtC,SAAK,OAAO,UAAU,UAAU,MAAM;AACtC,SAAK,OAAO,UAAU,SAAS;AAC/B,SAAK,OAAO,UAAU,SAAS;AAE/B,UAAM,MAAM;AAAA,MACX,MAAM;AAAA,MACN,MAAM;AAAA,MACN,uBAAuB,KAAK,MAAM;AAAA,IACnC;AACA,QAAI,IAAI,aAAa;AACpB,WAAK,OAAO,aAAa,IAAI,KAAK;AAAA,IACnC;AAEA,6BAAyB,KAAK,QAAQ,KAAK,SAAS,KAAK,OAAO,OAAO,GAAG;AAAA,EAC3E;AACD;","names":[]}
|
|
@@ -112,12 +112,10 @@ var defaultOptions = {
|
|
|
112
112
|
};
|
|
113
113
|
var SCREEN_WRAP_BEHAVIOR_KEY = /* @__PURE__ */ Symbol.for("zylem:behavior:screen-wrap");
|
|
114
114
|
var ScreenWrapSystem = class {
|
|
115
|
-
constructor(
|
|
116
|
-
this.world = world;
|
|
115
|
+
constructor(wasmStage, getBehaviorLinks) {
|
|
117
116
|
this.wasmStage = wasmStage;
|
|
118
117
|
this.getBehaviorLinks = getBehaviorLinks;
|
|
119
118
|
}
|
|
120
|
-
world;
|
|
121
119
|
wasmStage;
|
|
122
120
|
getBehaviorLinks;
|
|
123
121
|
attachedRuntimeSlots = /* @__PURE__ */ new Set();
|
|
@@ -198,7 +196,7 @@ var ScreenWrapSystem = class {
|
|
|
198
196
|
var ScreenWrapBehavior = defineBehavior({
|
|
199
197
|
name: "screen-wrap",
|
|
200
198
|
defaultOptions,
|
|
201
|
-
systemFactory: (ctx) => new ScreenWrapSystem(ctx.
|
|
199
|
+
systemFactory: (ctx) => new ScreenWrapSystem(ctx.wasmStage ?? null, ctx.getBehaviorLinks)
|
|
202
200
|
});
|
|
203
201
|
|
|
204
202
|
export {
|
|
@@ -207,4 +205,4 @@ export {
|
|
|
207
205
|
ScreenWrapFSM,
|
|
208
206
|
ScreenWrapBehavior
|
|
209
207
|
};
|
|
210
|
-
//# sourceMappingURL=chunk-
|
|
208
|
+
//# sourceMappingURL=chunk-GFARAJV2.js.map
|