cubeforge 0.1.8 → 0.2.0
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/index.d.mts +315 -190
- package/dist/index.js +2382 -565
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import React__default, { CSSProperties, ReactNode } from 'react';
|
|
4
|
-
import { Plugin, EntityId, System, ECSWorld, ScriptUpdateFn,
|
|
5
|
-
export { Component, ECSWorld, Ease, EntityId, Plugin, ScriptUpdateFn, TransformComponent, TweenHandle, WorldSnapshot, createTag, createTransform, definePlugin, findByTag, tween } from '@cubeforge/core';
|
|
6
|
-
import { InputManager, ActionBindings } from '@cubeforge/input';
|
|
7
|
-
export { ActionBindings, InputManager, InputMap, createInputMap } from '@cubeforge/input';
|
|
8
|
-
import {
|
|
9
|
-
export {
|
|
10
|
-
|
|
11
|
-
export {
|
|
4
|
+
import { Plugin, EntityId, System, ECSWorld, ScriptUpdateFn, NavGrid, WorldSnapshot, EventBus } from '@cubeforge/core';
|
|
5
|
+
export { AssetProgress, Component, ECSWorld, Ease, EntityId, GameTimer, NavGrid, Plugin, PreloadManifest, ScriptUpdateFn, TransformComponent, TweenHandle, Vec2Like, WorldSnapshot, arrive, createTag, createTimer, createTransform, definePlugin, findByTag, flee, patrol, preloadManifest, seek, tween, wander } from '@cubeforge/core';
|
|
6
|
+
import { InputManager, ActionBindings, InputContextName, PlayerInput, InputRecorderControls } from '@cubeforge/input';
|
|
7
|
+
export { ActionBindings, AxisBinding, InputContextName, InputManager, InputMap, InputRecorderControls, InputRecording, InputRecording as InputRecordingData, PlayerInput, createInputMap, createInputRecorder, createPlayerInput, globalInputContext } from '@cubeforge/input';
|
|
8
|
+
import { EngineState } from '@cubeforge/context';
|
|
9
|
+
export { EngineState, useCircleEnter, useCircleExit, useCircleStay, useCollisionEnter, useCollisionExit, useCollisionStay, useTriggerEnter, useTriggerExit, useTriggerStay } from '@cubeforge/context';
|
|
10
|
+
export { AISteering, AnimationClip, AnimationControllerResult, BindingControls, GameState as GameStateDefinition, GameStateMachineResult, HealthControls, HealthOptions, KinematicBodyControls, LevelTransitionControls, PathfindingControls, PlatformerControllerOptions, RestartControls, SaveControls, SaveOptions, TopDownMovementOptions, TransitionOptions, TransitionType, useAISteering, useAnimationController, useDamageZone, useDropThrough, useGameStateMachine, useHealth, useKinematicBody, useLevelTransition, usePathfinding, usePersistedBindings, usePlatformerController, useRestart, useSave, useTopDownMovement } from '@cubeforge/gameplay';
|
|
11
|
+
export { AudioGroup, SoundControls, duck, getGroupVolume, setGroupMute, setGroupVolume, setMasterVolume, stopGroup, useSound } from '@cubeforge/audio';
|
|
12
|
+
export { DevToolsHandle } from '@cubeforge/devtools';
|
|
13
|
+
export { BoxColliderComponent, CapsuleColliderComponent, CircleColliderComponent, RaycastHit, RigidBodyComponent, overlapBox, overlapCircle, raycast, raycastAll, sweepBox } from '@cubeforge/physics';
|
|
14
|
+
export { AnimationStateComponent, ParallaxLayerComponent, Particle, ParticlePoolComponent, SpriteComponent, SquashStretchComponent, TextComponent, TrailComponent, createSprite } from '@cubeforge/renderer';
|
|
12
15
|
|
|
13
16
|
interface GameControls {
|
|
14
17
|
pause(): void;
|
|
@@ -177,6 +180,17 @@ interface CircleColliderProps {
|
|
|
177
180
|
}
|
|
178
181
|
declare function CircleCollider({ radius, offsetX, offsetY, isTrigger, layer, mask, }: CircleColliderProps): null;
|
|
179
182
|
|
|
183
|
+
interface CapsuleColliderProps {
|
|
184
|
+
width: number;
|
|
185
|
+
height: number;
|
|
186
|
+
offsetX?: number;
|
|
187
|
+
offsetY?: number;
|
|
188
|
+
isTrigger?: boolean;
|
|
189
|
+
layer?: string;
|
|
190
|
+
mask?: string | string[];
|
|
191
|
+
}
|
|
192
|
+
declare function CapsuleCollider({ width, height, offsetX, offsetY, isTrigger, layer, mask, }: CapsuleColliderProps): null;
|
|
193
|
+
|
|
180
194
|
interface ScriptProps {
|
|
181
195
|
/** Called once when the entity is mounted — use to attach extra components */
|
|
182
196
|
init?: (entityId: EntityId, world: ECSWorld) => void;
|
|
@@ -223,8 +237,16 @@ interface AnimationProps {
|
|
|
223
237
|
playing?: boolean;
|
|
224
238
|
/** Called once when a non-looping animation finishes playing */
|
|
225
239
|
onComplete?: () => void;
|
|
240
|
+
/**
|
|
241
|
+
* Callbacks fired when the animation advances to specific frame indices.
|
|
242
|
+
* Key = 0-based position in the `frames` array.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* frameEvents={{ 2: () => playFootstep(), 5: () => playFootstep() }}
|
|
246
|
+
*/
|
|
247
|
+
frameEvents?: Record<number, () => void>;
|
|
226
248
|
}
|
|
227
|
-
declare function Animation({ frames, fps, loop, playing, onComplete }: AnimationProps): null;
|
|
249
|
+
declare function Animation({ frames, fps, loop, playing, onComplete, frameEvents }: AnimationProps): null;
|
|
228
250
|
|
|
229
251
|
interface SquashStretchProps {
|
|
230
252
|
/** How much to squash/stretch (default 0.2) */
|
|
@@ -261,6 +283,40 @@ interface ParticleEmitterProps {
|
|
|
261
283
|
}
|
|
262
284
|
declare function ParticleEmitter({ active, preset, rate, speed, spread, angle, particleLife, particleSize, color, gravity, maxParticles, }: ParticleEmitterProps): null;
|
|
263
285
|
|
|
286
|
+
interface VirtualJoystickProps {
|
|
287
|
+
/** Diameter of the joystick base in pixels (default 120) */
|
|
288
|
+
size?: number;
|
|
289
|
+
/** Screen corner to anchor to (default 'left') */
|
|
290
|
+
position?: 'left' | 'right';
|
|
291
|
+
/** Extra CSS applied to the outer container */
|
|
292
|
+
style?: React__default.CSSProperties;
|
|
293
|
+
/** Show an action button (e.g. jump) alongside the joystick (default false) */
|
|
294
|
+
actionButton?: boolean;
|
|
295
|
+
/** Label shown on the action button (default 'A') */
|
|
296
|
+
actionLabel?: string;
|
|
297
|
+
/** Name of the virtual button to set (default 'action') */
|
|
298
|
+
actionName?: string;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* On-screen virtual joystick for touch / mobile. Place it as a sibling of the
|
|
302
|
+
* `<Game>` canvas (inside a `position: relative` container).
|
|
303
|
+
*
|
|
304
|
+
* Read the joystick state with `useVirtualInput()`.
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* <div style={{ position: 'relative' }}>
|
|
308
|
+
* <Game ...>...</Game>
|
|
309
|
+
* <VirtualJoystick position="left" actionButton />
|
|
310
|
+
* </div>
|
|
311
|
+
*
|
|
312
|
+
* // Inside an entity:
|
|
313
|
+
* function MobilePlayer() {
|
|
314
|
+
* const virt = useVirtualInput()
|
|
315
|
+
* // virt.axisX, virt.axisY, virt.button('action')
|
|
316
|
+
* }
|
|
317
|
+
*/
|
|
318
|
+
declare function VirtualJoystick({ size, position, style, actionButton, actionLabel, actionName, }: VirtualJoystickProps): react_jsx_runtime.JSX.Element;
|
|
319
|
+
|
|
264
320
|
interface MovingPlatformProps {
|
|
265
321
|
/** Start position */
|
|
266
322
|
x1: number;
|
|
@@ -353,8 +409,21 @@ interface TilemapProps {
|
|
|
353
409
|
* Receives the global tile ID, the property map, and the tile's world position.
|
|
354
410
|
*/
|
|
355
411
|
onTileProperty?: (tileId: number, properties: Record<string, unknown>, x: number, y: number) => void;
|
|
412
|
+
/**
|
|
413
|
+
* If provided, collision-layer tiles automatically mark the corresponding
|
|
414
|
+
* NavGrid cells as non-walkable. The grid must already be created with the
|
|
415
|
+
* correct dimensions (map.width × map.height) and cellSize (map.tilewidth).
|
|
416
|
+
*/
|
|
417
|
+
navGrid?: NavGrid;
|
|
418
|
+
/**
|
|
419
|
+
* Name of the object layer that contains spawn markers.
|
|
420
|
+
* Objects in this layer are forwarded to `onSpawnObject` just like any
|
|
421
|
+
* other object layer, but they are also identified as spawn points so you
|
|
422
|
+
* can filter them by `layer.name === spawnLayer` inside the callback.
|
|
423
|
+
*/
|
|
424
|
+
spawnLayer?: string;
|
|
356
425
|
}
|
|
357
|
-
declare function Tilemap({ src, onSpawnObject, layerFilter, zIndex, collisionLayer, triggerLayer: triggerLayerName, onTileProperty, }: TilemapProps): React__default.ReactElement | null;
|
|
426
|
+
declare function Tilemap({ src, onSpawnObject, layerFilter, zIndex, collisionLayer, triggerLayer: triggerLayerName, onTileProperty, navGrid, }: TilemapProps): React__default.ReactElement | null;
|
|
358
427
|
|
|
359
428
|
interface ParallaxLayerProps {
|
|
360
429
|
/** Image URL to use as the background layer */
|
|
@@ -388,21 +457,94 @@ interface ScreenFlashHandle {
|
|
|
388
457
|
}
|
|
389
458
|
declare const ScreenFlash: React.ForwardRefExoticComponent<React.RefAttributes<ScreenFlashHandle>>;
|
|
390
459
|
|
|
391
|
-
interface
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
460
|
+
interface CameraZoneProps {
|
|
461
|
+
/** World-space center X of the trigger zone */
|
|
462
|
+
x: number;
|
|
463
|
+
/** World-space center Y of the trigger zone */
|
|
464
|
+
y: number;
|
|
465
|
+
/** Half-width of the trigger zone */
|
|
466
|
+
width: number;
|
|
467
|
+
/** Half-height of the trigger zone */
|
|
468
|
+
height: number;
|
|
469
|
+
/**
|
|
470
|
+
* When an entity with this tag enters the zone, the camera stops following
|
|
471
|
+
* its entity and locks to the fixed position (targetX, targetY).
|
|
472
|
+
*/
|
|
473
|
+
watchTag?: string;
|
|
474
|
+
/** Fixed world-space X the camera moves to when activated (defaults to zone center) */
|
|
475
|
+
targetX?: number;
|
|
476
|
+
/** Fixed world-space Y the camera moves to when activated (defaults to zone center) */
|
|
477
|
+
targetY?: number;
|
|
478
|
+
children?: React__default.ReactNode;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Invisible trigger area. When the player (or another tagged entity) enters
|
|
482
|
+
* the zone, the camera follow entity is cleared and the camera locks to the
|
|
483
|
+
* zone's center (or a custom target). On exit, the camera resumes following.
|
|
484
|
+
*
|
|
485
|
+
* Zone detection runs inside the ScriptSystem tick — it respects pause and
|
|
486
|
+
* deterministic stepping.
|
|
487
|
+
*
|
|
488
|
+
* @example
|
|
489
|
+
* ```tsx
|
|
490
|
+
* <CameraZone x={500} y={300} width={200} height={150} watchTag="player" />
|
|
491
|
+
* ```
|
|
492
|
+
*/
|
|
493
|
+
declare function CameraZone({ x, y, width, height, watchTag, targetX, targetY, children, }: CameraZoneProps): react_jsx_runtime.JSX.Element;
|
|
494
|
+
|
|
495
|
+
interface TrailProps {
|
|
496
|
+
/** Maximum number of trail points (default 20) */
|
|
497
|
+
length?: number;
|
|
498
|
+
/** CSS color string (default '#ffffff') */
|
|
499
|
+
color?: string;
|
|
500
|
+
/** Trail width in pixels (default 3) */
|
|
501
|
+
width?: number;
|
|
405
502
|
}
|
|
503
|
+
/**
|
|
504
|
+
* Renders a fading polyline that follows the entity's position.
|
|
505
|
+
*
|
|
506
|
+
* The trail is drawn in the render pass — it uses the entity's Transform
|
|
507
|
+
* history collected each frame.
|
|
508
|
+
*
|
|
509
|
+
* Must be used inside an `<Entity>` with a `<Transform>`.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```tsx
|
|
513
|
+
* <Entity id="bullet">
|
|
514
|
+
* <Transform x={x} y={y} />
|
|
515
|
+
* <Sprite width={6} height={6} color="#ff0" />
|
|
516
|
+
* <Trail length={15} color="#ff0" width={2} />
|
|
517
|
+
* </Entity>
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
declare function Trail({ length, color, width }: TrailProps): null;
|
|
521
|
+
|
|
522
|
+
interface AssetLoaderProps {
|
|
523
|
+
/** List of asset URLs to preload */
|
|
524
|
+
assets: string[];
|
|
525
|
+
/** Shown while assets are loading */
|
|
526
|
+
fallback?: React__default.ReactNode;
|
|
527
|
+
/** Called if any asset fails to load */
|
|
528
|
+
onError?: (err: Error) => void;
|
|
529
|
+
children: React__default.ReactNode;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Suspense-style asset loading boundary.
|
|
533
|
+
*
|
|
534
|
+
* Shows `fallback` until all assets in the list are loaded (or errored).
|
|
535
|
+
* Once loaded, renders `children`.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```tsx
|
|
539
|
+
* <AssetLoader
|
|
540
|
+
* assets={['/hero.png', '/tiles.png', '/jump.wav']}
|
|
541
|
+
* fallback={<div>Loading…</div>}
|
|
542
|
+
* >
|
|
543
|
+
* <GameScene />
|
|
544
|
+
* </AssetLoader>
|
|
545
|
+
* ```
|
|
546
|
+
*/
|
|
547
|
+
declare function AssetLoader({ assets, fallback, onError, children }: AssetLoaderProps): react_jsx_runtime.JSX.Element;
|
|
406
548
|
|
|
407
549
|
declare function useGame(): EngineState;
|
|
408
550
|
|
|
@@ -507,6 +649,35 @@ declare function useEntity(): EntityId;
|
|
|
507
649
|
*/
|
|
508
650
|
declare function useDestroyEntity(): () => void;
|
|
509
651
|
|
|
652
|
+
interface VirtualInputState {
|
|
653
|
+
/** Left–right axis in [−1, 1]. Positive = right. */
|
|
654
|
+
readonly axisX: number;
|
|
655
|
+
/** Up–down axis in [−1, 1]. Positive = down. */
|
|
656
|
+
readonly axisY: number;
|
|
657
|
+
/** Whether a named virtual button is currently pressed. */
|
|
658
|
+
button(name: string): boolean;
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Returns the current state of the on-screen virtual joystick and buttons.
|
|
662
|
+
* Reads synchronously from the module-level store — safe to call in a Script
|
|
663
|
+
* update function every frame without triggering React re-renders.
|
|
664
|
+
*
|
|
665
|
+
* Combine with keyboard or gamepad input for multi-input support:
|
|
666
|
+
*
|
|
667
|
+
* @example
|
|
668
|
+
* function MobilePlayer() {
|
|
669
|
+
* const input = useInput()
|
|
670
|
+
* const virt = useVirtualInput()
|
|
671
|
+
*
|
|
672
|
+
* // Script update:
|
|
673
|
+
* const moveX = input.isHeld('ArrowRight') ? 1
|
|
674
|
+
* : input.isHeld('ArrowLeft') ? -1
|
|
675
|
+
* : virt.axisX
|
|
676
|
+
* const jump = input.isPressed('Space') || virt.button('action')
|
|
677
|
+
* }
|
|
678
|
+
*/
|
|
679
|
+
declare function useVirtualInput(): VirtualInputState;
|
|
680
|
+
|
|
510
681
|
declare function useInput(): InputManager;
|
|
511
682
|
|
|
512
683
|
interface BoundInputMap {
|
|
@@ -516,6 +687,16 @@ interface BoundInputMap {
|
|
|
516
687
|
isActionPressed(action: string): boolean;
|
|
517
688
|
/** True only on the frame any bound key was released. */
|
|
518
689
|
isActionReleased(action: string): boolean;
|
|
690
|
+
/**
|
|
691
|
+
* Returns -1..1 for axis bindings. For key bindings, 1 if down, 0 otherwise.
|
|
692
|
+
* @see {@link AxisBinding}
|
|
693
|
+
*/
|
|
694
|
+
getAxis(action: string): number;
|
|
695
|
+
/**
|
|
696
|
+
* Alias for `getAxis`. Matches the `PlayerInput` naming convention — use this
|
|
697
|
+
* when writing code that needs to work with both `useInputMap` and `usePlayerInput`.
|
|
698
|
+
*/
|
|
699
|
+
getActionAxis(action: string): number;
|
|
519
700
|
}
|
|
520
701
|
/**
|
|
521
702
|
* React hook that returns a pre-bound action map for use inside `<Game>`.
|
|
@@ -537,141 +718,146 @@ declare function useInputMap(bindings: ActionBindings): BoundInputMap;
|
|
|
537
718
|
declare function useEvents(): EventBus;
|
|
538
719
|
declare function useEvent<T>(event: string, handler: (data: T) => void): void;
|
|
539
720
|
|
|
540
|
-
interface
|
|
541
|
-
/** Horizontal move speed in px/s (default 200) */
|
|
542
|
-
speed?: number;
|
|
543
|
-
/** Upward impulse on jump (default -500) */
|
|
544
|
-
jumpForce?: number;
|
|
545
|
-
/** Max consecutive jumps, e.g. 2 for double jump (default 1) */
|
|
546
|
-
maxJumps?: number;
|
|
547
|
-
/** Seconds after leaving ground the player can still jump (default 0.08) */
|
|
548
|
-
coyoteTime?: number;
|
|
549
|
-
/** Seconds to buffer a jump input before landing (default 0.08) */
|
|
550
|
-
jumpBuffer?: number;
|
|
721
|
+
interface CoordinateHelpers {
|
|
551
722
|
/**
|
|
552
|
-
*
|
|
553
|
-
*
|
|
723
|
+
* Convert a world-space position to canvas pixel coordinates.
|
|
724
|
+
* Takes current camera position and zoom into account.
|
|
554
725
|
*/
|
|
555
|
-
|
|
726
|
+
worldToScreen(wx: number, wy: number): {
|
|
727
|
+
x: number;
|
|
728
|
+
y: number;
|
|
729
|
+
};
|
|
556
730
|
/**
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
* Defaults:
|
|
561
|
-
* left: ['ArrowLeft', 'KeyA', 'a']
|
|
562
|
-
* right: ['ArrowRight', 'KeyD', 'd']
|
|
563
|
-
* jump: ['Space', 'ArrowUp', 'KeyW', 'w']
|
|
731
|
+
* Convert canvas pixel coordinates to world-space position.
|
|
732
|
+
* Takes current camera position and zoom into account.
|
|
564
733
|
*/
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
jump?: string | string[];
|
|
734
|
+
screenToWorld(sx: number, sy: number): {
|
|
735
|
+
x: number;
|
|
736
|
+
y: number;
|
|
569
737
|
};
|
|
570
738
|
}
|
|
571
739
|
/**
|
|
572
|
-
*
|
|
573
|
-
* The entity must already have a RigidBody component.
|
|
740
|
+
* Returns helpers for converting between world-space and screen (canvas pixel) coordinates.
|
|
574
741
|
*
|
|
575
742
|
* @example
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
* <Entity id="player">
|
|
581
|
-
* <Transform x={100} y={300} />
|
|
582
|
-
* <Sprite width={28} height={40} color="#4fc3f7" />
|
|
583
|
-
* <RigidBody />
|
|
584
|
-
* <BoxCollider width={26} height={40} />
|
|
585
|
-
* </Entity>
|
|
586
|
-
* )
|
|
743
|
+
* ```tsx
|
|
744
|
+
* function Minimap() {
|
|
745
|
+
* const { worldToScreen, screenToWorld } = useCoordinates()
|
|
746
|
+
* // worldToScreen(player.x, player.y) → canvas pixel position of player
|
|
587
747
|
* }
|
|
748
|
+
* ```
|
|
588
749
|
*/
|
|
589
|
-
declare function
|
|
750
|
+
declare function useCoordinates(): CoordinateHelpers;
|
|
590
751
|
|
|
591
|
-
interface
|
|
592
|
-
/**
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
|
|
752
|
+
interface PreloadState {
|
|
753
|
+
/** 0–1 loading progress */
|
|
754
|
+
progress: number;
|
|
755
|
+
/** True when all assets have finished loading (or errored) */
|
|
756
|
+
loaded: boolean;
|
|
757
|
+
/** First error encountered, if any */
|
|
758
|
+
error: Error | null;
|
|
596
759
|
}
|
|
597
760
|
/**
|
|
598
|
-
*
|
|
599
|
-
*
|
|
761
|
+
* Preloads a list of asset URLs using the engine's AssetManager.
|
|
762
|
+
* Returns loading progress and a `loaded` flag.
|
|
763
|
+
*
|
|
764
|
+
* Works with images (any extension) — audio goes through the engine's audio API.
|
|
600
765
|
*
|
|
601
766
|
* @example
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
* <
|
|
606
|
-
* <
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
* useTopDownMovement(playerId, { speed: 180 })
|
|
767
|
+
* ```tsx
|
|
768
|
+
* function Level() {
|
|
769
|
+
* const { progress, loaded } = usePreload(['/hero.png', '/tiles.png'])
|
|
770
|
+
* if (!loaded) return <LoadingBar progress={progress} />
|
|
771
|
+
* return <GameScene />
|
|
772
|
+
* }
|
|
773
|
+
* ```
|
|
610
774
|
*/
|
|
611
|
-
declare function
|
|
775
|
+
declare function usePreload(assets: string[]): PreloadState;
|
|
612
776
|
|
|
613
|
-
interface
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
stop(): void;
|
|
618
|
-
/** Change the volume (0–1). */
|
|
619
|
-
setVolume(v: number): void;
|
|
777
|
+
interface InputContextControls {
|
|
778
|
+
push(ctx: InputContextName): void;
|
|
779
|
+
pop(ctx: InputContextName): void;
|
|
780
|
+
readonly active: InputContextName;
|
|
620
781
|
}
|
|
621
782
|
/**
|
|
622
|
-
*
|
|
783
|
+
* Access and manipulate the global input context stack.
|
|
784
|
+
*
|
|
785
|
+
* If you pass a `ctx` argument, that context is automatically pushed on mount
|
|
786
|
+
* and popped on unmount — ideal for pause menus, cutscenes, etc.
|
|
787
|
+
*
|
|
788
|
+
* @example
|
|
789
|
+
* ```tsx
|
|
790
|
+
* function PauseMenu() {
|
|
791
|
+
* useInputContext('pause') // auto-push/pop
|
|
792
|
+
* return <div>Paused</div>
|
|
793
|
+
* }
|
|
794
|
+
* ```
|
|
795
|
+
*/
|
|
796
|
+
declare function useInputContext(ctx?: InputContextName): InputContextControls;
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Returns a `PlayerInput` bound to the shared InputManager for the given player ID.
|
|
623
800
|
*
|
|
624
|
-
*
|
|
625
|
-
*
|
|
801
|
+
* @param playerId - Player number (1-based).
|
|
802
|
+
* @param bindings - Action bindings for this player.
|
|
626
803
|
*
|
|
627
804
|
* @example
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
805
|
+
* ```tsx
|
|
806
|
+
* function P1({ x, y }: Props) {
|
|
807
|
+
* const p1 = usePlayerInput(1, { jump: 'Space', left: 'ArrowLeft', right: 'ArrowRight' })
|
|
808
|
+
* return (
|
|
809
|
+
* <Entity id="p1">
|
|
810
|
+
* <Script update={(id, world, input, dt) => {
|
|
811
|
+
* if (p1.isActionPressed('jump')) rb.vy = -400
|
|
812
|
+
* }} />
|
|
813
|
+
* </Entity>
|
|
814
|
+
* )
|
|
631
815
|
* }
|
|
816
|
+
* ```
|
|
632
817
|
*/
|
|
633
|
-
declare function
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
818
|
+
declare function usePlayerInput(playerId: number, bindings: ActionBindings): PlayerInput;
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* Returns an array of `PlayerInput` objects for local multiplayer.
|
|
822
|
+
* Each player gets their own action bindings.
|
|
823
|
+
*
|
|
824
|
+
* @param bindingsPerPlayer - Array of binding objects, one per player.
|
|
825
|
+
*
|
|
826
|
+
* @example
|
|
827
|
+
* ```tsx
|
|
828
|
+
* const [p1, p2] = useLocalMultiplayer([
|
|
829
|
+
* { jump: 'Space', left: 'ArrowLeft', right: 'ArrowRight' },
|
|
830
|
+
* { jump: 'KeyW', left: 'KeyA', right: 'KeyD' },
|
|
831
|
+
* ])
|
|
832
|
+
* ```
|
|
833
|
+
*/
|
|
834
|
+
declare function useLocalMultiplayer(bindingsPerPlayer: ActionBindings[]): PlayerInput[];
|
|
637
835
|
|
|
638
836
|
/**
|
|
639
|
-
*
|
|
837
|
+
* Returns an `InputRecorderControls` instance that persists across renders.
|
|
838
|
+
*
|
|
839
|
+
* Use inside a `<Script update>` to drive recording/playback:
|
|
640
840
|
*
|
|
641
841
|
* @example
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
*
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
842
|
+
* ```tsx
|
|
843
|
+
* function DemoPlayer() {
|
|
844
|
+
* const recorder = useInputRecorder()
|
|
845
|
+
*
|
|
846
|
+
* return (
|
|
847
|
+
* <Script update={(id, world, input, dt) => {
|
|
848
|
+
* if (recorder.isRecording) {
|
|
849
|
+
* recorder.captureFrame([...downKeys])
|
|
850
|
+
* }
|
|
851
|
+
* if (recorder.isPlaying) {
|
|
852
|
+
* const frame = recorder.advancePlayback()
|
|
853
|
+
* // apply frame.pressedKeys to player controller
|
|
854
|
+
* }
|
|
855
|
+
* }} />
|
|
856
|
+
* )
|
|
652
857
|
* }
|
|
858
|
+
* ```
|
|
653
859
|
*/
|
|
654
|
-
|
|
655
|
-
/** Advance the timer by dt seconds. Calls onComplete when it reaches zero. */
|
|
656
|
-
update(dt: number): void;
|
|
657
|
-
/** Start (or resume) counting down. */
|
|
658
|
-
start(): void;
|
|
659
|
-
/** Pause counting without resetting. */
|
|
660
|
-
stop(): void;
|
|
661
|
-
/** Reset elapsed time to 0 and stop. Optionally change the duration. */
|
|
662
|
-
reset(newDuration?: number): void;
|
|
663
|
-
/** Reset elapsed time to 0 and immediately start. */
|
|
664
|
-
restart(): void;
|
|
665
|
-
/** Whether the timer is currently counting. */
|
|
666
|
-
readonly running: boolean;
|
|
667
|
-
/** Elapsed seconds since last reset/restart. */
|
|
668
|
-
readonly elapsed: number;
|
|
669
|
-
/** Remaining seconds (clamped to 0). */
|
|
670
|
-
readonly remaining: number;
|
|
671
|
-
/** Progress from 0 (just started) to 1 (complete). */
|
|
672
|
-
readonly progress: number;
|
|
673
|
-
}
|
|
674
|
-
declare function createTimer(duration: number, onComplete?: () => void, autoStart?: boolean): GameTimer;
|
|
860
|
+
declare function useInputRecorder(): InputRecorderControls;
|
|
675
861
|
|
|
676
862
|
interface GamepadState {
|
|
677
863
|
/** Whether a gamepad is connected at this player index. */
|
|
@@ -720,65 +906,4 @@ interface PauseControls {
|
|
|
720
906
|
*/
|
|
721
907
|
declare function usePause(): PauseControls;
|
|
722
908
|
|
|
723
|
-
|
|
724
|
-
/** Only fire if the other entity has this tag */
|
|
725
|
-
tag?: string;
|
|
726
|
-
/** Only fire if the other entity's BoxCollider is on this layer */
|
|
727
|
-
layer?: string;
|
|
728
|
-
}
|
|
729
|
-
/**
|
|
730
|
-
* Fires once when another entity's collider first overlaps this entity's trigger.
|
|
731
|
-
* Must be used inside an `<Entity>`.
|
|
732
|
-
*
|
|
733
|
-
* @example
|
|
734
|
-
* function CoinPickup() {
|
|
735
|
-
* useTriggerEnter((other) => collectCoin(), { tag: 'player' })
|
|
736
|
-
* return null
|
|
737
|
-
* }
|
|
738
|
-
*/
|
|
739
|
-
declare function useTriggerEnter(handler: (other: EntityId) => void, opts?: ContactOpts): void;
|
|
740
|
-
/**
|
|
741
|
-
* Fires once when an overlapping entity's collider leaves this entity's trigger.
|
|
742
|
-
* Must be used inside an `<Entity>`.
|
|
743
|
-
*/
|
|
744
|
-
declare function useTriggerExit(handler: (other: EntityId) => void, opts?: ContactOpts): void;
|
|
745
|
-
/**
|
|
746
|
-
* Fires once on the first frame two solid dynamic bodies touch.
|
|
747
|
-
* Must be used inside an `<Entity>`.
|
|
748
|
-
*
|
|
749
|
-
* @example
|
|
750
|
-
* function Enemy() {
|
|
751
|
-
* useCollisionEnter((other) => takeDamage(), { tag: 'player' })
|
|
752
|
-
* return null
|
|
753
|
-
* }
|
|
754
|
-
*/
|
|
755
|
-
declare function useCollisionEnter(handler: (other: EntityId) => void, opts?: ContactOpts): void;
|
|
756
|
-
/**
|
|
757
|
-
* Fires once when two solid dynamic bodies separate.
|
|
758
|
-
* Must be used inside an `<Entity>`.
|
|
759
|
-
*/
|
|
760
|
-
declare function useCollisionExit(handler: (other: EntityId) => void, opts?: ContactOpts): void;
|
|
761
|
-
/**
|
|
762
|
-
* Fires once when another entity's CircleCollider first overlaps this entity's CircleCollider.
|
|
763
|
-
* Also fires when a CircleCollider overlaps a BoxCollider.
|
|
764
|
-
* Must be used inside an `<Entity>`.
|
|
765
|
-
*
|
|
766
|
-
* @example
|
|
767
|
-
* function Asteroid() {
|
|
768
|
-
* useCircleEnter((other) => onHit(other), { tag: 'bullet' })
|
|
769
|
-
* return null
|
|
770
|
-
* }
|
|
771
|
-
*/
|
|
772
|
-
declare function useCircleEnter(handler: (other: EntityId) => void, opts?: ContactOpts): void;
|
|
773
|
-
/**
|
|
774
|
-
* Fires once when two CircleCollider entities stop overlapping.
|
|
775
|
-
* Must be used inside an `<Entity>`.
|
|
776
|
-
*/
|
|
777
|
-
declare function useCircleExit(handler: (other: EntityId) => void, opts?: ContactOpts): void;
|
|
778
|
-
|
|
779
|
-
interface DevToolsHandle {
|
|
780
|
-
buffer: WorldSnapshot[];
|
|
781
|
-
onFrame?: () => void;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
export { Animation, type BoundInputMap, BoxCollider, Camera2D, type CameraControls, Checkpoint, CircleCollider, type DevToolsHandle, type EngineState, Entity, Game, type GameControls, type GameTimer, type GamepadState, MovingPlatform, ParallaxLayer, ParticleEmitter, type ParticlePreset, type PauseControls, type PlatformerControllerOptions, RigidBody, ScreenFlash, type ScreenFlashHandle, Script, type SnapshotControls, type SoundControls, Sprite, type SpriteAtlas, SquashStretch, Text, type TiledLayer, type TiledObject, Tilemap, type TopDownMovementOptions, Transform, World, createAtlas, createTimer, useCamera, useCircleEnter, useCircleExit, useCollisionEnter, useCollisionExit, useDestroyEntity, useEntity, useEvent, useEvents, useGame, useGamepad, useInput, useInputMap, usePause, usePlatformerController, useSnapshot, useSound, useTopDownMovement, useTriggerEnter, useTriggerExit };
|
|
909
|
+
export { Animation, AssetLoader, type BoundInputMap, BoxCollider, Camera2D, type CameraControls, CameraZone, CapsuleCollider, Checkpoint, CircleCollider, type CoordinateHelpers, Entity, Game, type GameControls, type GamepadState, type InputContextControls, MovingPlatform, ParallaxLayer, ParticleEmitter, type ParticlePreset, type PauseControls, type PreloadState, RigidBody, ScreenFlash, type ScreenFlashHandle, Script, type SnapshotControls, Sprite, type SpriteAtlas, SquashStretch, Text, type TiledLayer, type TiledObject, Tilemap, Trail, Transform, type VirtualInputState, VirtualJoystick, type VirtualJoystickProps, World, createAtlas, useCamera, useCoordinates, useDestroyEntity, useEntity, useEvent, useEvents, useGame, useGamepad, useInput, useInputContext, useInputMap, useInputRecorder, useLocalMultiplayer, usePause, usePlayerInput, usePreload, useSnapshot, useVirtualInput };
|