rn-gamekit 0.1.0 → 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/CHANGELOG.md +68 -0
- package/README.md +95 -14
- package/lib/module/assets/defineAssets.js +28 -3
- package/lib/module/assets/defineAssets.js.map +1 -1
- package/lib/module/assets.js +11 -0
- package/lib/module/assets.js.map +1 -0
- package/lib/module/audio/createGameAudio.js +784 -0
- package/lib/module/audio/createGameAudio.js.map +1 -0
- package/lib/module/audio/errors.js +12 -0
- package/lib/module/audio/errors.js.map +1 -0
- package/lib/module/audio/index.js +5 -0
- package/lib/module/audio/index.js.map +1 -0
- package/lib/module/audio/resolver.js +37 -0
- package/lib/module/audio/resolver.js.map +1 -0
- package/lib/module/audio/types.js +4 -0
- package/lib/module/audio/types.js.map +1 -0
- package/lib/module/audio.js +9 -0
- package/lib/module/audio.js.map +1 -0
- package/lib/module/camera2d/bounds.js +59 -0
- package/lib/module/camera2d/bounds.js.map +1 -0
- package/lib/module/camera2d/extents.js +25 -0
- package/lib/module/camera2d/extents.js.map +1 -0
- package/lib/module/camera2d/follow.js +138 -0
- package/lib/module/camera2d/follow.js.map +1 -0
- package/lib/module/camera2d/index.js +20 -0
- package/lib/module/camera2d/index.js.map +1 -0
- package/lib/module/camera2d/interpolation.js +98 -0
- package/lib/module/camera2d/interpolation.js.map +1 -0
- package/lib/module/camera2d/shake.js +85 -0
- package/lib/module/camera2d/shake.js.map +1 -0
- package/lib/module/camera2d/transform.js +151 -0
- package/lib/module/camera2d/transform.js.map +1 -0
- package/lib/module/camera2d/types.js +4 -0
- package/lib/module/camera2d/types.js.map +1 -0
- package/lib/module/camera2d/validation.js +98 -0
- package/lib/module/camera2d/validation.js.map +1 -0
- package/lib/module/camera2d/visibility.js +138 -0
- package/lib/module/camera2d/visibility.js.map +1 -0
- package/lib/module/camera2d.js +9 -0
- package/lib/module/camera2d.js.map +1 -0
- package/lib/module/collision2d/colliders.js +266 -0
- package/lib/module/collision2d/colliders.js.map +1 -0
- package/lib/module/collision2d/debug.js +105 -0
- package/lib/module/collision2d/debug.js.map +1 -0
- package/lib/module/collision2d/filters.js +40 -0
- package/lib/module/collision2d/filters.js.map +1 -0
- package/lib/module/collision2d/index.js +12 -0
- package/lib/module/collision2d/index.js.map +1 -0
- package/lib/module/collision2d/intersections.js +67 -0
- package/lib/module/collision2d/intersections.js.map +1 -0
- package/lib/module/collision2d/manifolds.js +218 -0
- package/lib/module/collision2d/manifolds.js.map +1 -0
- package/lib/module/collision2d/segments.js +187 -0
- package/lib/module/collision2d/segments.js.map +1 -0
- package/lib/module/collision2d/spatialHash.js +167 -0
- package/lib/module/collision2d/spatialHash.js.map +1 -0
- package/lib/module/collision2d/sweeps.js +255 -0
- package/lib/module/collision2d/sweeps.js.map +1 -0
- package/lib/module/collision2d.js +9 -0
- package/lib/module/collision2d.js.map +1 -0
- package/lib/module/core/input/buttonPad.js +214 -0
- package/lib/module/core/input/buttonPad.js.map +1 -0
- package/lib/module/core/input/createInputBuffer.js +66 -14
- package/lib/module/core/input/createInputBuffer.js.map +1 -1
- package/lib/module/core/session/createGameSession.js +454 -50
- package/lib/module/core/session/createGameSession.js.map +1 -1
- package/lib/module/core/session/deepFreeze.js +92 -2
- package/lib/module/core/session/deepFreeze.js.map +1 -1
- package/lib/module/core/session/types.js +12 -0
- package/lib/module/core/session/types.js.map +1 -1
- package/lib/module/definition/defineGame.js +23 -0
- package/lib/module/definition/defineGame.js.map +1 -1
- package/lib/module/events/defineGameEvents.js +46 -0
- package/lib/module/events/defineGameEvents.js.map +1 -0
- package/lib/module/events/errors.js +16 -0
- package/lib/module/events/errors.js.map +1 -0
- package/lib/module/events/index.js +7 -0
- package/lib/module/events/index.js.map +1 -0
- package/lib/module/events/payload.js +219 -0
- package/lib/module/events/payload.js.map +1 -0
- package/lib/module/events/seed.js +33 -0
- package/lib/module/events/seed.js.map +1 -0
- package/lib/module/events/types.js +4 -0
- package/lib/module/events/types.js.map +1 -0
- package/lib/module/events.js +13 -0
- package/lib/module/events.js.map +1 -0
- package/lib/module/geometry/helpers.js +140 -0
- package/lib/module/geometry/helpers.js.map +1 -0
- package/lib/module/geometry/index.js +5 -0
- package/lib/module/geometry/index.js.map +1 -0
- package/lib/module/geometry/validation.js +104 -0
- package/lib/module/geometry/validation.js.map +1 -0
- package/lib/module/geometry.js +9 -0
- package/lib/module/geometry.js.map +1 -0
- package/lib/module/haptics/createGameHaptics.js +214 -0
- package/lib/module/haptics/createGameHaptics.js.map +1 -0
- package/lib/module/haptics/errors.js +12 -0
- package/lib/module/haptics/errors.js.map +1 -0
- package/lib/module/haptics/index.js +5 -0
- package/lib/module/haptics/index.js.map +1 -0
- package/lib/module/haptics/resolver.js +37 -0
- package/lib/module/haptics/resolver.js.map +1 -0
- package/lib/module/haptics/types.js +4 -0
- package/lib/module/haptics/types.js.map +1 -0
- package/lib/module/haptics.js +9 -0
- package/lib/module/haptics.js.map +1 -0
- package/lib/module/index.js +8 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/particles/createParticleSystem.js +481 -0
- package/lib/module/particles/createParticleSystem.js.map +1 -0
- package/lib/module/particles/defineParticleEffect.js +178 -0
- package/lib/module/particles/defineParticleEffect.js.map +1 -0
- package/lib/module/particles/errors.js +9 -0
- package/lib/module/particles/errors.js.map +1 -0
- package/lib/module/particles/index.js +8 -0
- package/lib/module/particles/index.js.map +1 -0
- package/lib/module/particles/sampling.js +121 -0
- package/lib/module/particles/sampling.js.map +1 -0
- package/lib/module/particles/types.js +4 -0
- package/lib/module/particles/types.js.map +1 -0
- package/lib/module/particles.js +4 -0
- package/lib/module/particles.js.map +1 -0
- package/lib/module/react/GameButtonPad.js +344 -0
- package/lib/module/react/GameButtonPad.js.map +1 -0
- package/lib/module/react/GamePointerInput.js +74 -16
- package/lib/module/react/GamePointerInput.js.map +1 -1
- package/lib/module/react/GameView.js +139 -60
- package/lib/module/react/GameView.js.map +1 -1
- package/lib/module/react/assets/createGameAssetStore.js +145 -95
- package/lib/module/react/assets/createGameAssetStore.js.map +1 -1
- package/lib/module/react/assets/useGameAssets.js +60 -35
- package/lib/module/react/assets/useGameAssets.js.map +1 -1
- package/lib/module/react/bindAppLifecycle.js +46 -17
- package/lib/module/react/bindAppLifecycle.js.map +1 -1
- package/lib/module/react/bindGameSession.js +13 -2
- package/lib/module/react/bindGameSession.js.map +1 -1
- package/lib/module/react/camera2d/GameLayer2D.js +50 -0
- package/lib/module/react/camera2d/GameLayer2D.js.map +1 -0
- package/lib/module/react/camera2d/defineGameCamera2D.js +30 -0
- package/lib/module/react/camera2d/defineGameCamera2D.js.map +1 -0
- package/lib/module/react/camera2d/usePresentedCameraBinding.js +177 -0
- package/lib/module/react/camera2d/usePresentedCameraBinding.js.map +1 -0
- package/lib/module/react/cleanupList.js +38 -0
- package/lib/module/react/cleanupList.js.map +1 -0
- package/lib/module/react/lifecycleSource.js +49 -0
- package/lib/module/react/lifecycleSource.js.map +1 -0
- package/lib/module/react/particles/ParticleView.js +308 -0
- package/lib/module/react/particles/ParticleView.js.map +1 -0
- package/lib/module/react/particles/culling.js +115 -0
- package/lib/module/react/particles/culling.js.map +1 -0
- package/lib/module/react/particles/index.js +7 -0
- package/lib/module/react/particles/index.js.map +1 -0
- package/lib/module/react/particles/spriteXForm.js +45 -0
- package/lib/module/react/particles/spriteXForm.js.map +1 -0
- package/lib/module/react/particles/useParticlePresentation.js +204 -0
- package/lib/module/react/particles/useParticlePresentation.js.map +1 -0
- package/lib/module/react/pointerBinding.js +55 -17
- package/lib/module/react/pointerBinding.js.map +1 -1
- package/lib/module/react/pointerCamera.js +28 -0
- package/lib/module/react/pointerCamera.js.map +1 -0
- package/lib/module/react/pointerCoalescer.js +16 -9
- package/lib/module/react/pointerCoalescer.js.map +1 -1
- package/lib/module/react/sprites/GameSprite.js +5 -17
- package/lib/module/react/sprites/GameSprite.js.map +1 -1
- package/lib/module/react/sprites/GameWorld2D.js +112 -9
- package/lib/module/react/sprites/GameWorld2D.js.map +1 -1
- package/lib/module/react/sprites/Sprite.js +48 -63
- package/lib/module/react/sprites/Sprite.js.map +1 -1
- package/lib/module/react/sprites/SpriteBatch.js +53 -28
- package/lib/module/react/sprites/SpriteBatch.js.map +1 -1
- package/lib/module/react/sprites/batchVisibility.js +58 -0
- package/lib/module/react/sprites/batchVisibility.js.map +1 -0
- package/lib/module/react/sprites/spriteSelection.js +103 -0
- package/lib/module/react/sprites/spriteSelection.js.map +1 -0
- package/lib/module/react/sprites/spriteTransform.js +46 -25
- package/lib/module/react/sprites/spriteTransform.js.map +1 -1
- package/lib/module/react/tilemap/TileMapLayer2D.js +217 -0
- package/lib/module/react/tilemap/TileMapLayer2D.js.map +1 -0
- package/lib/module/react/tilemap/tilePresentation.js +374 -0
- package/lib/module/react/tilemap/tilePresentation.js.map +1 -0
- package/lib/module/react/useGameSession.js +70 -0
- package/lib/module/react/useGameSession.js.map +1 -0
- package/lib/module/react/useGameSessionStatus.js +46 -0
- package/lib/module/react/useGameSessionStatus.js.map +1 -0
- package/lib/module/react/viewportBinding.js +5 -1
- package/lib/module/react/viewportBinding.js.map +1 -1
- package/lib/module/react.js +12 -1
- package/lib/module/react.js.map +1 -1
- package/lib/module/scene/defineScene.js +17 -0
- package/lib/module/scene/defineScene.js.map +1 -1
- package/lib/module/sprites/sampleSpriteClip.js +66 -6
- package/lib/module/sprites/sampleSpriteClip.js.map +1 -1
- package/lib/module/sprites/spriteAnimationState.js +10 -20
- package/lib/module/sprites/spriteAnimationState.js.map +1 -1
- package/lib/module/sprites.js +11 -0
- package/lib/module/sprites.js.map +1 -0
- package/lib/module/storage/adapters/asyncStorage.js +57 -0
- package/lib/module/storage/adapters/asyncStorage.js.map +1 -0
- package/lib/module/storage/adapters/memory.js +50 -0
- package/lib/module/storage/adapters/memory.js.map +1 -0
- package/lib/module/storage/errors.js +34 -0
- package/lib/module/storage/errors.js.map +1 -0
- package/lib/module/storage/index.js +11 -0
- package/lib/module/storage/index.js.map +1 -0
- package/lib/module/storage/schema.js +151 -0
- package/lib/module/storage/schema.js.map +1 -0
- package/lib/module/storage/serialization.js +249 -0
- package/lib/module/storage/serialization.js.map +1 -0
- package/lib/module/storage/store.js +387 -0
- package/lib/module/storage/store.js.map +1 -0
- package/lib/module/storage/types.js +16 -0
- package/lib/module/storage/types.js.map +1 -0
- package/lib/module/storage/validation.js +111 -0
- package/lib/module/storage/validation.js.map +1 -0
- package/lib/module/storage.js +4 -0
- package/lib/module/storage.js.map +1 -0
- package/lib/module/testing.js +4 -0
- package/lib/module/testing.js.map +1 -1
- package/lib/module/tilemap/chunkStats.js +27 -0
- package/lib/module/tilemap/chunkStats.js.map +1 -0
- package/lib/module/tilemap/definitions.js +308 -0
- package/lib/module/tilemap/definitions.js.map +1 -0
- package/lib/module/tilemap/errors.js +13 -0
- package/lib/module/tilemap/errors.js.map +1 -0
- package/lib/module/tilemap/index.js +10 -0
- package/lib/module/tilemap/index.js.map +1 -0
- package/lib/module/tilemap/movement.js +379 -0
- package/lib/module/tilemap/movement.js.map +1 -0
- package/lib/module/tilemap/queries.js +114 -0
- package/lib/module/tilemap/queries.js.map +1 -0
- package/lib/module/tilemap/tiledAdapter.js +141 -0
- package/lib/module/tilemap/tiledAdapter.js.map +1 -0
- package/lib/module/tilemap/types.js +4 -0
- package/lib/module/tilemap/types.js.map +1 -0
- package/lib/module/tilemap.js +4 -0
- package/lib/module/tilemap.js.map +1 -0
- package/lib/typescript/src/assets/defineAssets.d.ts +1 -1
- package/lib/typescript/src/assets/defineAssets.d.ts.map +1 -1
- package/lib/typescript/src/assets.d.ts +11 -0
- package/lib/typescript/src/assets.d.ts.map +1 -0
- package/lib/typescript/src/audio/createGameAudio.d.ts +5 -0
- package/lib/typescript/src/audio/createGameAudio.d.ts.map +1 -0
- package/lib/typescript/src/audio/errors.d.ts +6 -0
- package/lib/typescript/src/audio/errors.d.ts.map +1 -0
- package/lib/typescript/src/audio/index.d.ts +4 -0
- package/lib/typescript/src/audio/index.d.ts.map +1 -0
- package/lib/typescript/src/audio/resolver.d.ts +44 -0
- package/lib/typescript/src/audio/resolver.d.ts.map +1 -0
- package/lib/typescript/src/audio/types.d.ts +42 -0
- package/lib/typescript/src/audio/types.d.ts.map +1 -0
- package/lib/typescript/src/audio.d.ts +8 -0
- package/lib/typescript/src/audio.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/bounds.d.ts +25 -0
- package/lib/typescript/src/camera2d/bounds.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/extents.d.ts +17 -0
- package/lib/typescript/src/camera2d/extents.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/follow.d.ts +24 -0
- package/lib/typescript/src/camera2d/follow.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/index.d.ts +19 -0
- package/lib/typescript/src/camera2d/index.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/interpolation.d.ts +17 -0
- package/lib/typescript/src/camera2d/interpolation.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/shake.d.ts +20 -0
- package/lib/typescript/src/camera2d/shake.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/transform.d.ts +44 -0
- package/lib/typescript/src/camera2d/transform.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/types.d.ts +74 -0
- package/lib/typescript/src/camera2d/types.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/validation.d.ts +30 -0
- package/lib/typescript/src/camera2d/validation.d.ts.map +1 -0
- package/lib/typescript/src/camera2d/visibility.d.ts +47 -0
- package/lib/typescript/src/camera2d/visibility.d.ts.map +1 -0
- package/lib/typescript/src/camera2d.d.ts +7 -0
- package/lib/typescript/src/camera2d.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/colliders.d.ts +120 -0
- package/lib/typescript/src/collision2d/colliders.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/debug.d.ts +67 -0
- package/lib/typescript/src/collision2d/debug.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/filters.d.ts +28 -0
- package/lib/typescript/src/collision2d/filters.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/index.d.ts +17 -0
- package/lib/typescript/src/collision2d/index.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/intersections.d.ts +24 -0
- package/lib/typescript/src/collision2d/intersections.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/manifolds.d.ts +39 -0
- package/lib/typescript/src/collision2d/manifolds.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/segments.d.ts +24 -0
- package/lib/typescript/src/collision2d/segments.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/spatialHash.d.ts +50 -0
- package/lib/typescript/src/collision2d/spatialHash.d.ts.map +1 -0
- package/lib/typescript/src/collision2d/sweeps.d.ts +60 -0
- package/lib/typescript/src/collision2d/sweeps.d.ts.map +1 -0
- package/lib/typescript/src/collision2d.d.ts +7 -0
- package/lib/typescript/src/collision2d.d.ts.map +1 -0
- package/lib/typescript/src/core/input/buttonPad.d.ts +59 -0
- package/lib/typescript/src/core/input/buttonPad.d.ts.map +1 -0
- package/lib/typescript/src/core/input/createInputBuffer.d.ts +1 -1
- package/lib/typescript/src/core/input/createInputBuffer.d.ts.map +1 -1
- package/lib/typescript/src/core/input/types.d.ts +7 -0
- package/lib/typescript/src/core/input/types.d.ts.map +1 -1
- package/lib/typescript/src/core/session/createGameSession.d.ts +4 -2
- package/lib/typescript/src/core/session/createGameSession.d.ts.map +1 -1
- package/lib/typescript/src/core/session/deepFreeze.d.ts +21 -1
- package/lib/typescript/src/core/session/deepFreeze.d.ts.map +1 -1
- package/lib/typescript/src/core/session/diagnostics.d.ts +2 -0
- package/lib/typescript/src/core/session/diagnostics.d.ts.map +1 -1
- package/lib/typescript/src/core/session/types.d.ts +69 -4
- package/lib/typescript/src/core/session/types.d.ts.map +1 -1
- package/lib/typescript/src/definition/defineGame.d.ts +12 -1
- package/lib/typescript/src/definition/defineGame.d.ts.map +1 -1
- package/lib/typescript/src/definition/types.d.ts +10 -1
- package/lib/typescript/src/definition/types.d.ts.map +1 -1
- package/lib/typescript/src/events/defineGameEvents.d.ts +26 -0
- package/lib/typescript/src/events/defineGameEvents.d.ts.map +1 -0
- package/lib/typescript/src/events/errors.d.ts +12 -0
- package/lib/typescript/src/events/errors.d.ts.map +1 -0
- package/lib/typescript/src/events/index.d.ts +6 -0
- package/lib/typescript/src/events/index.d.ts.map +1 -0
- package/lib/typescript/src/events/payload.d.ts +21 -0
- package/lib/typescript/src/events/payload.d.ts.map +1 -0
- package/lib/typescript/src/events/seed.d.ts +3 -0
- package/lib/typescript/src/events/seed.d.ts.map +1 -0
- package/lib/typescript/src/events/types.d.ts +42 -0
- package/lib/typescript/src/events/types.d.ts.map +1 -0
- package/lib/typescript/src/events.d.ts +12 -0
- package/lib/typescript/src/events.d.ts.map +1 -0
- package/lib/typescript/src/geometry/helpers.d.ts +35 -0
- package/lib/typescript/src/geometry/helpers.d.ts.map +1 -0
- package/lib/typescript/src/geometry/index.d.ts +4 -0
- package/lib/typescript/src/geometry/index.d.ts.map +1 -0
- package/lib/typescript/src/geometry/types.d.ts +49 -0
- package/lib/typescript/src/geometry/types.d.ts.map +1 -1
- package/lib/typescript/src/geometry/validation.d.ts +44 -0
- package/lib/typescript/src/geometry/validation.d.ts.map +1 -0
- package/lib/typescript/src/geometry.d.ts +7 -0
- package/lib/typescript/src/geometry.d.ts.map +1 -0
- package/lib/typescript/src/haptics/createGameHaptics.d.ts +3 -0
- package/lib/typescript/src/haptics/createGameHaptics.d.ts.map +1 -0
- package/lib/typescript/src/haptics/errors.d.ts +6 -0
- package/lib/typescript/src/haptics/errors.d.ts.map +1 -0
- package/lib/typescript/src/haptics/index.d.ts +4 -0
- package/lib/typescript/src/haptics/index.d.ts.map +1 -0
- package/lib/typescript/src/haptics/resolver.d.ts +22 -0
- package/lib/typescript/src/haptics/resolver.d.ts.map +1 -0
- package/lib/typescript/src/haptics/types.d.ts +37 -0
- package/lib/typescript/src/haptics/types.d.ts.map +1 -0
- package/lib/typescript/src/haptics.d.ts +8 -0
- package/lib/typescript/src/haptics.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +10 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/particles/createParticleSystem.d.ts +5 -0
- package/lib/typescript/src/particles/createParticleSystem.d.ts.map +1 -0
- package/lib/typescript/src/particles/defineParticleEffect.d.ts +3 -0
- package/lib/typescript/src/particles/defineParticleEffect.d.ts.map +1 -0
- package/lib/typescript/src/particles/errors.d.ts +5 -0
- package/lib/typescript/src/particles/errors.d.ts.map +1 -0
- package/lib/typescript/src/particles/index.d.ts +6 -0
- package/lib/typescript/src/particles/index.d.ts.map +1 -0
- package/lib/typescript/src/particles/sampling.d.ts +54 -0
- package/lib/typescript/src/particles/sampling.d.ts.map +1 -0
- package/lib/typescript/src/particles/types.d.ts +292 -0
- package/lib/typescript/src/particles/types.d.ts.map +1 -0
- package/lib/typescript/src/particles.d.ts +2 -0
- package/lib/typescript/src/particles.d.ts.map +1 -0
- package/lib/typescript/src/react/GameButtonPad.d.ts +84 -0
- package/lib/typescript/src/react/GameButtonPad.d.ts.map +1 -0
- package/lib/typescript/src/react/GamePointerInput.d.ts.map +1 -1
- package/lib/typescript/src/react/GameView.d.ts +27 -1
- package/lib/typescript/src/react/GameView.d.ts.map +1 -1
- package/lib/typescript/src/react/assets/createGameAssetStore.d.ts.map +1 -1
- package/lib/typescript/src/react/assets/useGameAssets.d.ts.map +1 -1
- package/lib/typescript/src/react/bindAppLifecycle.d.ts +7 -1
- package/lib/typescript/src/react/bindAppLifecycle.d.ts.map +1 -1
- package/lib/typescript/src/react/bindGameSession.d.ts.map +1 -1
- package/lib/typescript/src/react/camera2d/GameLayer2D.d.ts +24 -0
- package/lib/typescript/src/react/camera2d/GameLayer2D.d.ts.map +1 -0
- package/lib/typescript/src/react/camera2d/defineGameCamera2D.d.ts +44 -0
- package/lib/typescript/src/react/camera2d/defineGameCamera2D.d.ts.map +1 -0
- package/lib/typescript/src/react/camera2d/usePresentedCameraBinding.d.ts +22 -0
- package/lib/typescript/src/react/camera2d/usePresentedCameraBinding.d.ts.map +1 -0
- package/lib/typescript/src/react/cleanupList.d.ts +21 -0
- package/lib/typescript/src/react/cleanupList.d.ts.map +1 -0
- package/lib/typescript/src/react/instrumentation.d.ts +33 -3
- package/lib/typescript/src/react/instrumentation.d.ts.map +1 -1
- package/lib/typescript/src/react/lifecycleSource.d.ts +21 -0
- package/lib/typescript/src/react/lifecycleSource.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/ParticleView.d.ts +65 -0
- package/lib/typescript/src/react/particles/ParticleView.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/culling.d.ts +70 -0
- package/lib/typescript/src/react/particles/culling.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/index.d.ts +7 -0
- package/lib/typescript/src/react/particles/index.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/spriteXForm.d.ts +28 -0
- package/lib/typescript/src/react/particles/spriteXForm.d.ts.map +1 -0
- package/lib/typescript/src/react/particles/useParticlePresentation.d.ts +48 -0
- package/lib/typescript/src/react/particles/useParticlePresentation.d.ts.map +1 -0
- package/lib/typescript/src/react/pointerBinding.d.ts +38 -8
- package/lib/typescript/src/react/pointerBinding.d.ts.map +1 -1
- package/lib/typescript/src/react/pointerCamera.d.ts +20 -0
- package/lib/typescript/src/react/pointerCamera.d.ts.map +1 -0
- package/lib/typescript/src/react/pointerCoalescer.d.ts +17 -1
- package/lib/typescript/src/react/pointerCoalescer.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/GameSprite.d.ts +3 -10
- package/lib/typescript/src/react/sprites/GameSprite.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/GameWorld2D.d.ts +51 -6
- package/lib/typescript/src/react/sprites/GameWorld2D.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/Sprite.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/SpriteBatch.d.ts +22 -1
- package/lib/typescript/src/react/sprites/SpriteBatch.d.ts.map +1 -1
- package/lib/typescript/src/react/sprites/batchVisibility.d.ts +28 -0
- package/lib/typescript/src/react/sprites/batchVisibility.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/spriteSelection.d.ts +58 -0
- package/lib/typescript/src/react/sprites/spriteSelection.d.ts.map +1 -0
- package/lib/typescript/src/react/sprites/spriteTransform.d.ts +27 -12
- package/lib/typescript/src/react/sprites/spriteTransform.d.ts.map +1 -1
- package/lib/typescript/src/react/tilemap/TileMapLayer2D.d.ts +69 -0
- package/lib/typescript/src/react/tilemap/TileMapLayer2D.d.ts.map +1 -0
- package/lib/typescript/src/react/tilemap/tilePresentation.d.ts +217 -0
- package/lib/typescript/src/react/tilemap/tilePresentation.d.ts.map +1 -0
- package/lib/typescript/src/react/useGameSession.d.ts +48 -0
- package/lib/typescript/src/react/useGameSession.d.ts.map +1 -0
- package/lib/typescript/src/react/useGameSessionStatus.d.ts +23 -0
- package/lib/typescript/src/react/useGameSessionStatus.d.ts.map +1 -0
- package/lib/typescript/src/react/viewportBinding.d.ts +5 -1
- package/lib/typescript/src/react/viewportBinding.d.ts.map +1 -1
- package/lib/typescript/src/react.d.ts +18 -1
- package/lib/typescript/src/react.d.ts.map +1 -1
- package/lib/typescript/src/scene/defineScene.d.ts +22 -2
- package/lib/typescript/src/scene/defineScene.d.ts.map +1 -1
- package/lib/typescript/src/scene/types.d.ts +24 -4
- package/lib/typescript/src/scene/types.d.ts.map +1 -1
- package/lib/typescript/src/sprites/sampleSpriteClip.d.ts +26 -2
- package/lib/typescript/src/sprites/sampleSpriteClip.d.ts.map +1 -1
- package/lib/typescript/src/sprites/spriteAnimationState.d.ts +6 -7
- package/lib/typescript/src/sprites/spriteAnimationState.d.ts.map +1 -1
- package/lib/typescript/src/sprites.d.ts +10 -0
- package/lib/typescript/src/sprites.d.ts.map +1 -0
- package/lib/typescript/src/storage/adapters/asyncStorage.d.ts +18 -0
- package/lib/typescript/src/storage/adapters/asyncStorage.d.ts.map +1 -0
- package/lib/typescript/src/storage/adapters/memory.d.ts +16 -0
- package/lib/typescript/src/storage/adapters/memory.d.ts.map +1 -0
- package/lib/typescript/src/storage/errors.d.ts +37 -0
- package/lib/typescript/src/storage/errors.d.ts.map +1 -0
- package/lib/typescript/src/storage/index.d.ts +11 -0
- package/lib/typescript/src/storage/index.d.ts.map +1 -0
- package/lib/typescript/src/storage/schema.d.ts +22 -0
- package/lib/typescript/src/storage/schema.d.ts.map +1 -0
- package/lib/typescript/src/storage/serialization.d.ts +23 -0
- package/lib/typescript/src/storage/serialization.d.ts.map +1 -0
- package/lib/typescript/src/storage/store.d.ts +3 -0
- package/lib/typescript/src/storage/store.d.ts.map +1 -0
- package/lib/typescript/src/storage/types.d.ts +69 -0
- package/lib/typescript/src/storage/types.d.ts.map +1 -0
- package/lib/typescript/src/storage/validation.d.ts +24 -0
- package/lib/typescript/src/storage/validation.d.ts.map +1 -0
- package/lib/typescript/src/storage.d.ts +2 -0
- package/lib/typescript/src/storage.d.ts.map +1 -0
- package/lib/typescript/src/testing.d.ts +1 -0
- package/lib/typescript/src/testing.d.ts.map +1 -1
- package/lib/typescript/src/tilemap/chunkStats.d.ts +14 -0
- package/lib/typescript/src/tilemap/chunkStats.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/definitions.d.ts +38 -0
- package/lib/typescript/src/tilemap/definitions.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/errors.d.ts +7 -0
- package/lib/typescript/src/tilemap/errors.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/index.d.ts +8 -0
- package/lib/typescript/src/tilemap/index.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/movement.d.ts +52 -0
- package/lib/typescript/src/tilemap/movement.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/queries.d.ts +21 -0
- package/lib/typescript/src/tilemap/queries.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/tiledAdapter.d.ts +32 -0
- package/lib/typescript/src/tilemap/tiledAdapter.d.ts.map +1 -0
- package/lib/typescript/src/tilemap/types.d.ts +127 -0
- package/lib/typescript/src/tilemap/types.d.ts.map +1 -0
- package/lib/typescript/src/tilemap.d.ts +2 -0
- package/lib/typescript/src/tilemap.d.ts.map +1 -0
- package/package.json +94 -4
- package/src/assets/defineAssets.ts +31 -5
- package/src/assets.ts +27 -0
- package/src/audio/createGameAudio.ts +749 -0
- package/src/audio/errors.ts +12 -0
- package/src/audio/index.ts +9 -0
- package/src/audio/resolver.ts +74 -0
- package/src/audio/types.ts +47 -0
- package/src/audio.ts +13 -0
- package/src/camera2d/bounds.ts +69 -0
- package/src/camera2d/extents.ts +25 -0
- package/src/camera2d/follow.ts +165 -0
- package/src/camera2d/index.ts +29 -0
- package/src/camera2d/interpolation.ts +113 -0
- package/src/camera2d/shake.ts +90 -0
- package/src/camera2d/transform.ts +148 -0
- package/src/camera2d/types.ts +73 -0
- package/src/camera2d/validation.ts +126 -0
- package/src/camera2d/visibility.ts +181 -0
- package/src/camera2d.ts +6 -0
- package/src/collision2d/colliders.ts +292 -0
- package/src/collision2d/debug.ts +133 -0
- package/src/collision2d/filters.ts +48 -0
- package/src/collision2d/index.ts +74 -0
- package/src/collision2d/intersections.ts +82 -0
- package/src/collision2d/manifolds.ts +191 -0
- package/src/collision2d/segments.ts +176 -0
- package/src/collision2d/spatialHash.ts +211 -0
- package/src/collision2d/sweeps.ts +269 -0
- package/src/collision2d.ts +6 -0
- package/src/core/input/buttonPad.ts +235 -0
- package/src/core/input/createInputBuffer.ts +95 -14
- package/src/core/input/types.ts +7 -0
- package/src/core/session/createGameSession.ts +480 -53
- package/src/core/session/deepFreeze.ts +104 -3
- package/src/core/session/diagnostics.ts +2 -0
- package/src/core/session/types.ts +77 -4
- package/src/definition/defineGame.ts +61 -3
- package/src/definition/types.ts +10 -0
- package/src/events/defineGameEvents.ts +46 -0
- package/src/events/errors.ts +14 -0
- package/src/events/index.ts +14 -0
- package/src/events/payload.ts +234 -0
- package/src/events/seed.ts +33 -0
- package/src/events/types.ts +53 -0
- package/src/events.ts +20 -0
- package/src/geometry/helpers.ts +136 -0
- package/src/geometry/index.ts +14 -0
- package/src/geometry/types.ts +54 -0
- package/src/geometry/validation.ts +131 -0
- package/src/geometry.ts +6 -0
- package/src/haptics/createGameHaptics.ts +214 -0
- package/src/haptics/errors.ts +12 -0
- package/src/haptics/index.ts +3 -0
- package/src/haptics/resolver.ts +58 -0
- package/src/haptics/types.ts +48 -0
- package/src/haptics.ts +7 -0
- package/src/index.ts +37 -1
- package/src/particles/createParticleSystem.ts +505 -0
- package/src/particles/defineParticleEffect.ts +164 -0
- package/src/particles/errors.ts +6 -0
- package/src/particles/index.ts +5 -0
- package/src/particles/sampling.ts +141 -0
- package/src/particles/types.ts +327 -0
- package/src/particles.ts +1 -0
- package/src/react/GameButtonPad.tsx +436 -0
- package/src/react/GamePointerInput.tsx +73 -8
- package/src/react/GameView.tsx +160 -61
- package/src/react/assets/createGameAssetStore.ts +140 -107
- package/src/react/assets/useGameAssets.ts +63 -31
- package/src/react/bindAppLifecycle.ts +55 -19
- package/src/react/bindGameSession.ts +12 -2
- package/src/react/camera2d/GameLayer2D.tsx +43 -0
- package/src/react/camera2d/defineGameCamera2D.ts +59 -0
- package/src/react/camera2d/usePresentedCameraBinding.ts +185 -0
- package/src/react/cleanupList.ts +48 -0
- package/src/react/instrumentation.ts +31 -3
- package/src/react/lifecycleSource.ts +58 -0
- package/src/react/particles/ParticleView.tsx +358 -0
- package/src/react/particles/culling.ts +145 -0
- package/src/react/particles/index.ts +6 -0
- package/src/react/particles/spriteXForm.ts +72 -0
- package/src/react/particles/useParticlePresentation.ts +261 -0
- package/src/react/pointerBinding.ts +74 -16
- package/src/react/pointerCamera.ts +33 -0
- package/src/react/pointerCoalescer.ts +36 -10
- package/src/react/sprites/GameSprite.tsx +4 -33
- package/src/react/sprites/GameWorld2D.tsx +113 -7
- package/src/react/sprites/Sprite.tsx +51 -72
- package/src/react/sprites/SpriteBatch.tsx +74 -22
- package/src/react/sprites/batchVisibility.ts +76 -0
- package/src/react/sprites/spriteSelection.ts +133 -0
- package/src/react/sprites/spriteTransform.ts +46 -26
- package/src/react/tilemap/TileMapLayer2D.tsx +274 -0
- package/src/react/tilemap/tilePresentation.ts +491 -0
- package/src/react/useGameSession.ts +90 -0
- package/src/react/useGameSessionStatus.ts +53 -0
- package/src/react/viewportBinding.ts +5 -1
- package/src/react.ts +18 -1
- package/src/scene/defineScene.ts +47 -5
- package/src/scene/types.ts +37 -3
- package/src/sprites/sampleSpriteClip.ts +82 -14
- package/src/sprites/spriteAnimationState.ts +29 -25
- package/src/sprites.ts +22 -0
- package/src/storage/adapters/asyncStorage.ts +77 -0
- package/src/storage/adapters/memory.ts +58 -0
- package/src/storage/errors.ts +88 -0
- package/src/storage/index.ts +18 -0
- package/src/storage/schema.ts +147 -0
- package/src/storage/serialization.ts +248 -0
- package/src/storage/store.ts +380 -0
- package/src/storage/types.ts +76 -0
- package/src/storage/validation.ts +102 -0
- package/src/storage.ts +1 -0
- package/src/testing.ts +4 -0
- package/src/tilemap/chunkStats.ts +24 -0
- package/src/tilemap/definitions.ts +327 -0
- package/src/tilemap/errors.ts +11 -0
- package/src/tilemap/index.ts +10 -0
- package/src/tilemap/movement.ts +368 -0
- package/src/tilemap/queries.ts +136 -0
- package/src/tilemap/tiledAdapter.ts +165 -0
- package/src/tilemap/types.ts +119 -0
- package/src/tilemap.ts +1 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera2D transforms (T12.1).
|
|
3
|
+
*
|
|
4
|
+
* The frozen transform model (T12.0):
|
|
5
|
+
*
|
|
6
|
+
* world point -> camera transform -> logical view point -> viewport -> surface
|
|
7
|
+
* logical = L + rotate(P - C, -R) * Z
|
|
8
|
+
* world = C + rotate((logical - L) / Z, R)
|
|
9
|
+
*
|
|
10
|
+
* where C is the camera center, Z the zoom, R the rotation, and L the
|
|
11
|
+
* center of the authored logical view rect. Rotation follows the Skia
|
|
12
|
+
* convention (positive radians in the y-down screen plane); zoom is
|
|
13
|
+
* uniform and greater than zero. The convenience surface functions derive
|
|
14
|
+
* the logical view from the resolved viewport's visible bounds, so
|
|
15
|
+
* rendering and pointer input share one composition.
|
|
16
|
+
*/
|
|
17
|
+
import type { Aabb2D, Point2D } from '../geometry/types';
|
|
18
|
+
import { GeometryError } from '../geometry/validation';
|
|
19
|
+
import type { ResolvedViewport2D } from '../viewport2d/types';
|
|
20
|
+
import { surfaceToWorld, worldToSurface } from '../viewport2d/math';
|
|
21
|
+
import type { Camera2D } from './types';
|
|
22
|
+
import { rotatedHalfExtents2D } from './extents';
|
|
23
|
+
import { assertFinitePoint2D, assertValidCamera2D, assertValidLogicalView } from './validation';
|
|
24
|
+
|
|
25
|
+
/** Rotate a point by an angle (Skia y-down convention). */
|
|
26
|
+
export function rotatePoint2D(point: Point2D, radians: number): Point2D {
|
|
27
|
+
const cos = Math.cos(radians);
|
|
28
|
+
const sin = Math.sin(radians);
|
|
29
|
+
return Object.freeze({
|
|
30
|
+
x: point.x * cos - point.y * sin,
|
|
31
|
+
y: point.x * sin + point.y * cos,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The center of the camera's authored logical view. */
|
|
36
|
+
export function logicalViewCenter2D(logicalView: Aabb2D): Point2D {
|
|
37
|
+
return Object.freeze({
|
|
38
|
+
x: logicalView.x + logicalView.width / 2,
|
|
39
|
+
y: logicalView.y + logicalView.height / 2,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Create a camera from optional partial values; missing fields default to
|
|
45
|
+
* the identity camera (`center` origin, `zoom` 1, no rotation).
|
|
46
|
+
*/
|
|
47
|
+
export function createCamera2D(value?: Partial<Camera2D>): Camera2D {
|
|
48
|
+
if (value !== undefined && (typeof value !== 'object' || value === null || Array.isArray(value))) {
|
|
49
|
+
throw new GeometryError(
|
|
50
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
51
|
+
'camera',
|
|
52
|
+
`expected a camera record, got ${value === null ? 'null' : typeof value}`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const camera: Camera2D = {
|
|
56
|
+
center: value?.center ?? { x: 0, y: 0 },
|
|
57
|
+
zoom: value?.zoom ?? 1,
|
|
58
|
+
rotationRadians: value?.rotationRadians ?? 0,
|
|
59
|
+
};
|
|
60
|
+
assertValidCamera2D(camera);
|
|
61
|
+
return Object.freeze({
|
|
62
|
+
center: Object.freeze({ x: camera.center.x, y: camera.center.y }),
|
|
63
|
+
zoom: camera.zoom,
|
|
64
|
+
rotationRadians: camera.rotationRadians,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** World -> logical view: `L + rotate(P - C, -R) * Z`. */
|
|
69
|
+
export function worldToLogical2D(point: Point2D, camera: Camera2D, logicalView: Aabb2D): Point2D {
|
|
70
|
+
assertValidCamera2D(camera);
|
|
71
|
+
assertFinitePoint2D(point, 'point');
|
|
72
|
+
assertValidLogicalView(logicalView);
|
|
73
|
+
const { center, zoom, rotationRadians } = camera;
|
|
74
|
+
const logical = logicalViewCenter2D(logicalView);
|
|
75
|
+
const delta = {
|
|
76
|
+
x: point.x - center.x,
|
|
77
|
+
y: point.y - center.y,
|
|
78
|
+
};
|
|
79
|
+
const rotated = rotatePoint2D(delta, -rotationRadians);
|
|
80
|
+
return Object.freeze({
|
|
81
|
+
x: logical.x + rotated.x * zoom,
|
|
82
|
+
y: logical.y + rotated.y * zoom,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Logical view -> world: `C + rotate((logical - L) / Z, R)`. */
|
|
87
|
+
export function logicalToWorld2D(point: Point2D, camera: Camera2D, logicalView: Aabb2D): Point2D {
|
|
88
|
+
assertValidCamera2D(camera);
|
|
89
|
+
assertFinitePoint2D(point, 'point');
|
|
90
|
+
assertValidLogicalView(logicalView);
|
|
91
|
+
const { center, zoom, rotationRadians } = camera;
|
|
92
|
+
const logical = logicalViewCenter2D(logicalView);
|
|
93
|
+
const scaled = {
|
|
94
|
+
x: (point.x - logical.x) / zoom,
|
|
95
|
+
y: (point.y - logical.y) / zoom,
|
|
96
|
+
};
|
|
97
|
+
const rotated = rotatePoint2D(scaled, rotationRadians);
|
|
98
|
+
return Object.freeze({
|
|
99
|
+
x: center.x + rotated.x,
|
|
100
|
+
y: center.y + rotated.y,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** The conservative world-space AABB visible through the camera. */
|
|
105
|
+
export function getCameraVisibleBounds2D(camera: Camera2D, logicalView: Aabb2D): Aabb2D {
|
|
106
|
+
assertValidCamera2D(camera);
|
|
107
|
+
assertValidLogicalView(logicalView);
|
|
108
|
+
const halfWidth = logicalView.width / 2 / camera.zoom;
|
|
109
|
+
const halfHeight = logicalView.height / 2 / camera.zoom;
|
|
110
|
+
const extent = rotatedHalfExtents2D(halfWidth, halfHeight, camera.rotationRadians);
|
|
111
|
+
const extentX = extent.x;
|
|
112
|
+
const extentY = extent.y;
|
|
113
|
+
return Object.freeze({
|
|
114
|
+
x: camera.center.x - extentX,
|
|
115
|
+
y: camera.center.y - extentY,
|
|
116
|
+
width: extentX * 2,
|
|
117
|
+
height: extentY * 2,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* World -> surface through the camera and the resolved viewport.
|
|
123
|
+
*
|
|
124
|
+
* The camera's logical view is the viewport's visible logical bounds, so
|
|
125
|
+
* this composes exactly the transform the renderer draws with.
|
|
126
|
+
*/
|
|
127
|
+
export function worldToSurface2D(
|
|
128
|
+
point: Point2D,
|
|
129
|
+
viewport: ResolvedViewport2D,
|
|
130
|
+
camera: Camera2D,
|
|
131
|
+
): Point2D {
|
|
132
|
+
assertValidCamera2D(camera);
|
|
133
|
+
assertFinitePoint2D(point, 'point');
|
|
134
|
+
const logical = worldToLogical2D(point, camera, viewport.visibleLogicalBounds);
|
|
135
|
+
return worldToSurface(viewport, logical);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Surface -> world through the viewport and the presented camera. */
|
|
139
|
+
export function surfaceToWorld2D(
|
|
140
|
+
point: Point2D,
|
|
141
|
+
viewport: ResolvedViewport2D,
|
|
142
|
+
camera: Camera2D,
|
|
143
|
+
): Point2D {
|
|
144
|
+
assertValidCamera2D(camera);
|
|
145
|
+
assertFinitePoint2D(point, 'point');
|
|
146
|
+
const logical = surfaceToWorld(viewport, point);
|
|
147
|
+
return logicalToWorld2D(logical, camera, viewport.visibleLogicalBounds);
|
|
148
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera2D public values (T12.1).
|
|
3
|
+
*
|
|
4
|
+
* A camera is immutable plain data: where the view is centered in world
|
|
5
|
+
* space, how much it zooms, and how it rotates. It carries no Skia
|
|
6
|
+
* matrices, no shared values, no viewport dimensions — presentation and
|
|
7
|
+
* conversion derive everything from this value plus the authored logical
|
|
8
|
+
* view.
|
|
9
|
+
*/
|
|
10
|
+
import type { Point2D } from '../geometry/types';
|
|
11
|
+
|
|
12
|
+
/** The authored 2D camera value. */
|
|
13
|
+
export interface Camera2D {
|
|
14
|
+
/** World-space point the camera looks at. */
|
|
15
|
+
readonly center: Point2D;
|
|
16
|
+
/** Finite uniform zoom, greater than zero. */
|
|
17
|
+
readonly zoom: number;
|
|
18
|
+
/** Rotation in radians, positive per the Skia coordinate convention. */
|
|
19
|
+
readonly rotationRadians: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A presented camera with an explicit cut signal.
|
|
24
|
+
*
|
|
25
|
+
* `cutId` increases monotonically across the lifetime of a camera binding.
|
|
26
|
+
* A changed `cutId` means the previous camera is unrelated: presentation
|
|
27
|
+
* snaps instead of interpolating (scene transitions, session replacement,
|
|
28
|
+
* binding-generation changes, explicit teleports, invalid prior data).
|
|
29
|
+
*/
|
|
30
|
+
export interface CameraCut2D {
|
|
31
|
+
/** The camera to present. */
|
|
32
|
+
readonly camera: Camera2D;
|
|
33
|
+
/** Monotonic cut signal; a new value disables interpolation. */
|
|
34
|
+
readonly cutId: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Per-axis follow enablement. Both default to true. */
|
|
38
|
+
export interface CameraFollowAxisOptions2D {
|
|
39
|
+
/** Follow on the horizontal axis. */
|
|
40
|
+
readonly x?: boolean;
|
|
41
|
+
/** Follow on the vertical axis. */
|
|
42
|
+
readonly y?: boolean;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Options for `followCamera2D`. */
|
|
46
|
+
export interface FollowCamera2DOptions2D {
|
|
47
|
+
/**
|
|
48
|
+
* Axis-aligned dead zone in world units, centered on the camera center.
|
|
49
|
+
* A target inside the zone leaves the camera untouched.
|
|
50
|
+
*/
|
|
51
|
+
readonly deadZone?: { readonly x: number; readonly y: number; readonly width: number; readonly height: number };
|
|
52
|
+
/** Per-axis follow enablement. */
|
|
53
|
+
readonly perAxis?: CameraFollowAxisOptions2D;
|
|
54
|
+
/**
|
|
55
|
+
* Damping half-life in seconds: after this many seconds the remaining
|
|
56
|
+
* follow distance halves. Requires `deltaSeconds` on the call.
|
|
57
|
+
*/
|
|
58
|
+
readonly dampingHalfLifeSeconds?: number;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Options for `sampleCameraShake2D`. */
|
|
62
|
+
export interface CameraShakeOptions2D {
|
|
63
|
+
/** Deterministic seed; equal seeds produce equal offsets. */
|
|
64
|
+
readonly seed: number;
|
|
65
|
+
/** Elapsed simulation time in seconds since the shake began. */
|
|
66
|
+
readonly elapsedSeconds: number;
|
|
67
|
+
/** Shake duration in seconds; the base camera returns exactly at end. */
|
|
68
|
+
readonly durationSeconds: number;
|
|
69
|
+
/** Peak offset magnitude in world units. */
|
|
70
|
+
readonly amplitude: number;
|
|
71
|
+
/** Angular frequency in radians per second (defaults to 2π). */
|
|
72
|
+
readonly frequency?: number;
|
|
73
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera2D validation (T12.1, T12-F6).
|
|
3
|
+
*
|
|
4
|
+
* Reuses the Task 11 structured `GeometryError` codes so failures identify
|
|
5
|
+
* the operation and the invalid field. Validation happens at public
|
|
6
|
+
* operation boundaries; values are never coerced. Outer shapes are checked
|
|
7
|
+
* BEFORE field dereferencing, so null, arrays, and missing nested objects
|
|
8
|
+
* produce structured errors instead of incidental `TypeError`s.
|
|
9
|
+
*/
|
|
10
|
+
import type { Aabb2D, Point2D } from '../geometry/types';
|
|
11
|
+
import { assertFiniteNumber, assertNonnegativeSize, GeometryError } from '../geometry/validation';
|
|
12
|
+
import type { Camera2D } from './types';
|
|
13
|
+
|
|
14
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
15
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Assert the outer shape of a camera before dereferencing fields. */
|
|
19
|
+
export function assertCameraShape(camera: unknown, field: string): asserts camera is Camera2D {
|
|
20
|
+
if (!isRecord(camera)) {
|
|
21
|
+
throw new GeometryError(
|
|
22
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
23
|
+
field,
|
|
24
|
+
`expected a camera record, got ${camera === null ? 'null' : typeof camera}`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
if (!isRecord(camera.center)) {
|
|
28
|
+
throw new GeometryError(
|
|
29
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
30
|
+
`${field}.center`,
|
|
31
|
+
`expected a point record, got ${camera.center === null ? 'null' : typeof camera.center}`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Assert a valid camera value (shape + fields). */
|
|
37
|
+
export function assertValidCamera2D(camera: Camera2D): void {
|
|
38
|
+
assertCameraShape(camera, 'camera');
|
|
39
|
+
assertFiniteNumber(camera.center.x, 'camera.center.x');
|
|
40
|
+
assertFiniteNumber(camera.center.y, 'camera.center.y');
|
|
41
|
+
assertFiniteNumber(camera.zoom, 'camera.zoom');
|
|
42
|
+
if (!(camera.zoom > 0)) {
|
|
43
|
+
throw new GeometryError(
|
|
44
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
45
|
+
'camera.zoom',
|
|
46
|
+
`expected a finite zoom greater than zero, got ${String(camera.zoom)}`,
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
assertFiniteNumber(camera.rotationRadians, 'camera.rotationRadians');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Assert a finite point (shape first). */
|
|
53
|
+
export function assertFinitePoint2D(point: unknown, field: string): asserts point is Point2D {
|
|
54
|
+
if (!isRecord(point)) {
|
|
55
|
+
throw new GeometryError(
|
|
56
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
57
|
+
field,
|
|
58
|
+
`expected a point record, got ${point === null ? 'null' : typeof point}`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const typed = point as unknown as Point2D;
|
|
62
|
+
assertFiniteNumber(typed.x, `${field}.x`);
|
|
63
|
+
assertFiniteNumber(typed.y, `${field}.y`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Assert a valid logical view rect (shape + finite positive size). */
|
|
67
|
+
export function assertValidLogicalView(view: unknown): asserts view is Aabb2D {
|
|
68
|
+
if (!isRecord(view)) {
|
|
69
|
+
throw new GeometryError(
|
|
70
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
71
|
+
'logicalView',
|
|
72
|
+
`expected a rect record, got ${view === null ? 'null' : typeof view}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
const typed = view as unknown as Aabb2D;
|
|
76
|
+
assertFiniteNumber(typed.x, 'logicalView.x');
|
|
77
|
+
assertFiniteNumber(typed.y, 'logicalView.y');
|
|
78
|
+
assertNonnegativeSize(typed.width, 'logicalView.width');
|
|
79
|
+
assertNonnegativeSize(typed.height, 'logicalView.height');
|
|
80
|
+
if (!(typed.width > 0) || !(typed.height > 0)) {
|
|
81
|
+
throw new GeometryError(
|
|
82
|
+
'GEOMETRY_INVALID_SIZE',
|
|
83
|
+
'logicalView',
|
|
84
|
+
`expected a positive logical view size, got ${view.width} x ${view.height}`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Assert a nonnegative padding. */
|
|
90
|
+
export function assertNonnegativePadding(padding: number): void {
|
|
91
|
+
assertNonnegativeSize(padding, 'padding');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Strict full-camera clone (T12-SF3): validates a COMPLETE runtime camera —
|
|
96
|
+
* every required field present and finite — and returns an owned frozen
|
|
97
|
+
* copy. Unlike `createCamera2D` (which fills partial authored options with
|
|
98
|
+
* identity defaults), a missing field is rejected. Used at publication
|
|
99
|
+
* boundaries where a partial value must never be silently completed.
|
|
100
|
+
*/
|
|
101
|
+
export function cloneValidCamera2D(camera: unknown, field = 'camera'): Camera2D {
|
|
102
|
+
assertCameraShape(camera, field);
|
|
103
|
+
const typed = camera as Camera2D;
|
|
104
|
+
const centerField = `${field}.center`;
|
|
105
|
+
assertFiniteNumber(typed.center.x, `${centerField}.x`);
|
|
106
|
+
assertFiniteNumber(typed.center.y, `${centerField}.y`);
|
|
107
|
+
if (typeof typed.zoom !== 'number' || !Number.isFinite(typed.zoom) || !(typed.zoom > 0)) {
|
|
108
|
+
throw new GeometryError(
|
|
109
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
110
|
+
`${field}.zoom`,
|
|
111
|
+
`expected a finite zoom greater than zero, got ${String(typed.zoom)}`,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
if (typeof typed.rotationRadians !== 'number' || !Number.isFinite(typed.rotationRadians)) {
|
|
115
|
+
throw new GeometryError(
|
|
116
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
117
|
+
`${field}.rotationRadians`,
|
|
118
|
+
`expected a finite rotation, got ${String(typed.rotationRadians)}`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return Object.freeze({
|
|
122
|
+
center: Object.freeze({ x: typed.center.x, y: typed.center.y }),
|
|
123
|
+
zoom: typed.zoom,
|
|
124
|
+
rotationRadians: typed.rotationRadians,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Camera2D visibility (T12.6).
|
|
3
|
+
*
|
|
4
|
+
* Presentation-only culling: computes what the camera can see and filters
|
|
5
|
+
* render records without changing simulation. An off-screen entity keeps
|
|
6
|
+
* simulating, colliding, and re-entering view. For rotated cameras the
|
|
7
|
+
* broad test uses the conservative visible AABB (a superset of the actual
|
|
8
|
+
* view polygon), so false positives are possible but false negatives are
|
|
9
|
+
* not — a visible object can never pop out.
|
|
10
|
+
*/
|
|
11
|
+
import type { Aabb2D, Circle2D, Point2D } from '../geometry/types';
|
|
12
|
+
import { assertFiniteNumber, assertNonnegativeSize, GeometryError } from '../geometry/validation';
|
|
13
|
+
import { intersectsAabbAabb2D, intersectsCircleAabb2D, pointInAabb2D } from '../collision2d/index';
|
|
14
|
+
import { getCameraVisibleBounds2D } from './transform';
|
|
15
|
+
import type { Camera2D } from './types';
|
|
16
|
+
import { assertValidCamera2D, assertValidLogicalView, assertNonnegativePadding } from './validation';
|
|
17
|
+
|
|
18
|
+
function assertPointPayload(value: unknown, field: string): void {
|
|
19
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
20
|
+
throw new GeometryError(
|
|
21
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
22
|
+
field,
|
|
23
|
+
`expected a point record, got ${value === null ? 'null' : typeof value}`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
const typed = value as { x?: unknown; y?: unknown };
|
|
27
|
+
assertFiniteNumber(typed.x as number, `${field}.x`);
|
|
28
|
+
assertFiniteNumber(typed.y as number, `${field}.y`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function assertShapeRecord(shape: unknown): asserts shape is CameraViewShape2D {
|
|
32
|
+
if (typeof shape !== 'object' || shape === null || Array.isArray(shape)) {
|
|
33
|
+
throw new GeometryError(
|
|
34
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
35
|
+
'shape',
|
|
36
|
+
`expected a visibility shape record, got ${shape === null ? 'null' : typeof shape}`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const kind = (shape as { kind?: unknown }).kind;
|
|
40
|
+
// T12-SF3: the payload is validated with Camera2D-prefixed nested paths
|
|
41
|
+
// BEFORE any Collision2D predicate dereferences it.
|
|
42
|
+
switch (kind) {
|
|
43
|
+
case 'aabb':
|
|
44
|
+
assertItemBounds((shape as { bounds?: unknown }).bounds, 'shape.bounds');
|
|
45
|
+
return;
|
|
46
|
+
case 'circle': {
|
|
47
|
+
const circle = (shape as { circle?: unknown }).circle;
|
|
48
|
+
if (typeof circle !== 'object' || circle === null || Array.isArray(circle)) {
|
|
49
|
+
throw new GeometryError(
|
|
50
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
51
|
+
'shape.circle',
|
|
52
|
+
`expected a circle record, got ${circle === null ? 'null' : typeof circle}`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const typed = circle as { x?: unknown; y?: unknown; radius?: unknown };
|
|
56
|
+
assertFiniteNumber(typed.x as number, 'shape.circle.x');
|
|
57
|
+
assertFiniteNumber(typed.y as number, 'shape.circle.y');
|
|
58
|
+
assertNonnegativeSize(typed.radius as number, 'shape.circle.radius');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
case 'point':
|
|
62
|
+
assertPointPayload((shape as { point?: unknown }).point, 'shape.point');
|
|
63
|
+
return;
|
|
64
|
+
default:
|
|
65
|
+
throw new GeometryError(
|
|
66
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
67
|
+
'shape.kind',
|
|
68
|
+
`expected 'aabb' | 'circle' | 'point', got ${String(kind)}`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function assertItemBounds(bounds: unknown, field = 'items.bounds'): asserts bounds is Aabb2D {
|
|
74
|
+
if (typeof bounds !== 'object' || bounds === null || Array.isArray(bounds)) {
|
|
75
|
+
throw new GeometryError(
|
|
76
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
77
|
+
field,
|
|
78
|
+
`expected a rect record, got ${bounds === null ? 'null' : typeof bounds}`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
const typed = bounds as Aabb2D;
|
|
82
|
+
assertFiniteNumber(typed.x, `${field}.x`);
|
|
83
|
+
assertFiniteNumber(typed.y, `${field}.y`);
|
|
84
|
+
assertNonnegativeSize(typed.width, `${field}.width`);
|
|
85
|
+
assertNonnegativeSize(typed.height, `${field}.height`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function assertItemsArray(items: unknown): asserts items is readonly { readonly id: string; readonly bounds: Aabb2D }[] {
|
|
89
|
+
if (!Array.isArray(items)) {
|
|
90
|
+
throw new GeometryError(
|
|
91
|
+
'GEOMETRY_INVALID_NUMBER',
|
|
92
|
+
'items',
|
|
93
|
+
`expected an array of indexed records, got ${items === null ? 'null' : typeof items}`,
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
for (const item of items) {
|
|
97
|
+
if (typeof item !== 'object' || item === null || Array.isArray(item)) {
|
|
98
|
+
throw new GeometryError('GEOMETRY_INVALID_NUMBER', 'items', 'expected item records');
|
|
99
|
+
}
|
|
100
|
+
const typed = item as { readonly id?: unknown; readonly bounds?: unknown };
|
|
101
|
+
if (typeof typed.id !== 'string') {
|
|
102
|
+
throw new GeometryError('GEOMETRY_INVALID_NUMBER', 'items.id', 'expected a string id');
|
|
103
|
+
}
|
|
104
|
+
assertItemBounds(typed.bounds);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** A shape queryable against the camera view. */
|
|
109
|
+
export type CameraViewShape2D =
|
|
110
|
+
| { readonly kind: 'aabb'; readonly bounds: Aabb2D }
|
|
111
|
+
| { readonly kind: 'circle'; readonly circle: Circle2D }
|
|
112
|
+
| { readonly kind: 'point'; readonly point: Point2D };
|
|
113
|
+
|
|
114
|
+
/** The visible world bounds expanded by an optional padding. */
|
|
115
|
+
export function paddedCameraBounds2D(
|
|
116
|
+
camera: Camera2D,
|
|
117
|
+
logicalView: Aabb2D,
|
|
118
|
+
padding = 0,
|
|
119
|
+
): Aabb2D {
|
|
120
|
+
assertValidCamera2D(camera);
|
|
121
|
+
assertValidLogicalView(logicalView);
|
|
122
|
+
assertNonnegativePadding(padding);
|
|
123
|
+
const bounds = getCameraVisibleBounds2D(camera, logicalView);
|
|
124
|
+
return Object.freeze({
|
|
125
|
+
x: bounds.x - padding,
|
|
126
|
+
y: bounds.y - padding,
|
|
127
|
+
width: bounds.width + padding * 2,
|
|
128
|
+
height: bounds.height + padding * 2,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Whether a shape intersects the camera's visible region.
|
|
134
|
+
*
|
|
135
|
+
* The test is conservative: it uses the visible world AABB (exact for
|
|
136
|
+
* unrotated cameras, a superset for rotated ones). `padding` extends the
|
|
137
|
+
* region in world units for sprites and effects that draw outside their
|
|
138
|
+
* logical bounds.
|
|
139
|
+
*/
|
|
140
|
+
export function intersectsCameraView2D(
|
|
141
|
+
shape: CameraViewShape2D,
|
|
142
|
+
camera: Camera2D,
|
|
143
|
+
logicalView: Aabb2D,
|
|
144
|
+
padding = 0,
|
|
145
|
+
): boolean {
|
|
146
|
+
assertShapeRecord(shape);
|
|
147
|
+
const visible = paddedCameraBounds2D(camera, logicalView, padding);
|
|
148
|
+
switch (shape.kind) {
|
|
149
|
+
case 'aabb':
|
|
150
|
+
return intersectsAabbAabb2D(shape.bounds, visible);
|
|
151
|
+
case 'circle':
|
|
152
|
+
return intersectsCircleAabb2D(shape.circle, visible);
|
|
153
|
+
case 'point':
|
|
154
|
+
return pointInAabb2D(shape.point, visible);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Filter indexed render records, preserving stable order.
|
|
160
|
+
*
|
|
161
|
+
* Returns a frozen copy containing only the records whose world bounds
|
|
162
|
+
* intersect the visible region (plus `padding`). Off-screen records keep
|
|
163
|
+
* their identity and order in the caller's array; nothing here mutates
|
|
164
|
+
* them or changes simulation.
|
|
165
|
+
*/
|
|
166
|
+
export function filterCameraVisible2D<T extends { readonly id: string; readonly bounds: Aabb2D }>(
|
|
167
|
+
items: readonly T[],
|
|
168
|
+
camera: Camera2D,
|
|
169
|
+
logicalView: Aabb2D,
|
|
170
|
+
padding = 0,
|
|
171
|
+
): readonly T[] {
|
|
172
|
+
assertItemsArray(items as unknown);
|
|
173
|
+
const visible = paddedCameraBounds2D(camera, logicalView, padding);
|
|
174
|
+
const kept: T[] = [];
|
|
175
|
+
for (const item of items) {
|
|
176
|
+
if (intersectsAabbAabb2D(item.bounds, visible)) {
|
|
177
|
+
kept.push(item);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return Object.freeze(kept);
|
|
181
|
+
}
|