rn-gamekit 0.1.0 → 0.2.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/CHANGELOG.md +75 -0
- package/README.md +97 -16
- 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 +100 -10
- 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
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `GameWorld2D` — the viewport transform group (T7.6).
|
|
2
|
+
* `GameWorld2D` — the viewport + camera transform group (T7.6, T12.5).
|
|
3
3
|
*
|
|
4
|
-
* Applies the resolved viewport offset/scale
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Applies the resolved viewport offset/scale to all child sprites, and —
|
|
5
|
+
* when the game opts into a camera — composes the presented camera
|
|
6
|
+
* transform BEFORE the viewport. The group's element list maps world ->
|
|
7
|
+
* surface directly; `GameLayer2D` children consume the same camera through
|
|
8
|
+
* the world context and apply only their parallax correction, so layers
|
|
9
|
+
* never double-apply the camera.
|
|
7
10
|
*/
|
|
8
|
-
import type
|
|
11
|
+
import { createContext, useContext, type ReactNode } from 'react';
|
|
9
12
|
import { Group } from '@shopify/react-native-skia';
|
|
10
13
|
import { useDerivedValue, type SharedValue } from 'react-native-reanimated';
|
|
11
14
|
|
|
15
|
+
import type { CameraCut2D } from '../../camera2d';
|
|
12
16
|
import type { ResolvedViewport2D } from '../../viewport2d/types';
|
|
13
17
|
|
|
14
18
|
/**
|
|
@@ -33,14 +37,116 @@ export function viewportTransform(viewport: ResolvedViewport2D | undefined): rea
|
|
|
33
37
|
];
|
|
34
38
|
}
|
|
35
39
|
|
|
40
|
+
/**
|
|
41
|
+
* The composed camera + viewport transform (T12.5).
|
|
42
|
+
*
|
|
43
|
+
* Skia applies the element list last-first, so the list below is the
|
|
44
|
+
* forward mapping `surface = viewport(L + rotate(P - C, -R) * Z)`:
|
|
45
|
+
* translate(-C) -> scale(Z) -> rotate(-R) -> translate(L) -> viewport.
|
|
46
|
+
*/
|
|
47
|
+
export function cameraViewportTransform2D(
|
|
48
|
+
camera: CameraCut2D | undefined,
|
|
49
|
+
viewport: ResolvedViewport2D | undefined,
|
|
50
|
+
): readonly (
|
|
51
|
+
| { readonly translateX: number }
|
|
52
|
+
| { readonly translateY: number }
|
|
53
|
+
| { readonly scaleX: number }
|
|
54
|
+
| { readonly scaleY: number }
|
|
55
|
+
| { readonly rotate: number }
|
|
56
|
+
)[] {
|
|
57
|
+
'worklet';
|
|
58
|
+
if (camera === undefined || viewport === undefined) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const { center, zoom, rotationRadians } = camera.camera;
|
|
62
|
+
const view = viewport.visibleLogicalBounds;
|
|
63
|
+
const logicalX = view.x + view.width / 2;
|
|
64
|
+
const logicalY = view.y + view.height / 2;
|
|
65
|
+
return [
|
|
66
|
+
{ translateX: viewport.offsetX },
|
|
67
|
+
{ translateY: viewport.offsetY },
|
|
68
|
+
{ scaleX: viewport.scale },
|
|
69
|
+
{ scaleY: viewport.scale },
|
|
70
|
+
{ translateX: logicalX },
|
|
71
|
+
{ translateY: logicalY },
|
|
72
|
+
{ rotate: -rotationRadians },
|
|
73
|
+
{ scaleX: zoom },
|
|
74
|
+
{ scaleY: zoom },
|
|
75
|
+
{ translateX: -center.x },
|
|
76
|
+
{ translateY: -center.y },
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The parallax correction for one layer (T12.5).
|
|
82
|
+
*
|
|
83
|
+
* A layer with factor p draws with the camera whose effective center is
|
|
84
|
+
* `C' = L + (C - L) * p` per axis. Since zoom and rotation apply fully at
|
|
85
|
+
* every factor, the correction relative to the parent camera is exactly a
|
|
86
|
+
* translation by `(C - L) * (1 - p)` in world units.
|
|
87
|
+
*/
|
|
88
|
+
export function layerParallaxTransform2D(
|
|
89
|
+
camera: CameraCut2D | undefined,
|
|
90
|
+
viewport: ResolvedViewport2D | undefined,
|
|
91
|
+
parallaxX: number,
|
|
92
|
+
parallaxY: number,
|
|
93
|
+
): readonly ({ readonly translateX: number } | { readonly translateY: number })[] {
|
|
94
|
+
'worklet';
|
|
95
|
+
if (camera === undefined || viewport === undefined) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
const view = viewport.visibleLogicalBounds;
|
|
99
|
+
const logicalX = view.x + view.width / 2;
|
|
100
|
+
const logicalY = view.y + view.height / 2;
|
|
101
|
+
const dx = (camera.camera.center.x - logicalX) * (1 - parallaxX);
|
|
102
|
+
const dy = (camera.camera.center.y - logicalY) * (1 - parallaxY);
|
|
103
|
+
const elements: ({ readonly translateX: number } | { readonly translateY: number })[] = [];
|
|
104
|
+
if (dx !== 0) {
|
|
105
|
+
elements.push({ translateX: dx });
|
|
106
|
+
}
|
|
107
|
+
if (dy !== 0) {
|
|
108
|
+
elements.push({ translateY: dy });
|
|
109
|
+
}
|
|
110
|
+
return elements;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** The camera + viewport context provided by `GameWorld2D`. */
|
|
114
|
+
export interface GameWorldContextValue {
|
|
115
|
+
readonly viewport: SharedValue<ResolvedViewport2D | undefined>;
|
|
116
|
+
readonly camera: SharedValue<CameraCut2D | undefined> | undefined;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export const GameWorldContext = createContext<GameWorldContextValue | null>(null);
|
|
120
|
+
|
|
36
121
|
export function GameWorld2D({
|
|
37
122
|
viewport,
|
|
123
|
+
camera,
|
|
38
124
|
children,
|
|
39
125
|
}: {
|
|
40
126
|
/** The resolved viewport shared value supplied to the renderer. */
|
|
41
127
|
readonly viewport: SharedValue<ResolvedViewport2D | undefined>;
|
|
128
|
+
/** The presented camera shared value (T12.5); absent keeps the viewport-only path. */
|
|
129
|
+
readonly camera?: SharedValue<CameraCut2D | undefined> | undefined;
|
|
42
130
|
readonly children: ReactNode;
|
|
43
131
|
}) {
|
|
44
|
-
const transform = useDerivedValue(() =>
|
|
45
|
-
|
|
132
|
+
const transform = useDerivedValue(() =>
|
|
133
|
+
camera === undefined
|
|
134
|
+
? viewportTransform(viewport.value)
|
|
135
|
+
: cameraViewportTransform2D(camera.value, viewport.value),
|
|
136
|
+
);
|
|
137
|
+
const context = { viewport, camera };
|
|
138
|
+
return (
|
|
139
|
+
<GameWorldContext.Provider value={context}>
|
|
140
|
+
<Group transform={transform as never}>{children}</Group>
|
|
141
|
+
</GameWorldContext.Provider>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Consume the world context; throws outside `GameWorld2D`. */
|
|
146
|
+
export function useGameWorldContext(): GameWorldContextValue {
|
|
147
|
+
const context = useContext(GameWorldContext);
|
|
148
|
+
if (context === null) {
|
|
149
|
+
throw new Error('GameLayer2D must be rendered inside a GameWorld2D');
|
|
150
|
+
}
|
|
151
|
+
return context;
|
|
46
152
|
}
|
|
@@ -17,10 +17,13 @@ import { useRectBuffer, useRSXformBuffer } from '@shopify/react-native-skia';
|
|
|
17
17
|
import type { LoadedImage, LoadedSpriteSheet } from '../../assets/types';
|
|
18
18
|
import {
|
|
19
19
|
computeSpriteRsxform,
|
|
20
|
-
resolveSpriteFrameRect,
|
|
21
20
|
spriteGroupCorrection,
|
|
22
|
-
type SpriteTransformInput,
|
|
23
21
|
} from './spriteTransform';
|
|
22
|
+
import {
|
|
23
|
+
applySpriteFrameSelection,
|
|
24
|
+
materializeSpriteSelection,
|
|
25
|
+
selectSpriteFrameRect,
|
|
26
|
+
} from './spriteSelection';
|
|
24
27
|
|
|
25
28
|
export { resolveSpriteFrameRect, type SpriteFrameRect } from './spriteTransform';
|
|
26
29
|
|
|
@@ -82,91 +85,67 @@ export function Sprite({
|
|
|
82
85
|
// Worklet-safe frame resolution: an explicit `frame` wins; otherwise the
|
|
83
86
|
// clip + elapsed time select the frame (the clip/elapsed may be animated
|
|
84
87
|
// shared values, so the resolution happens inside the rect modifier).
|
|
88
|
+
// The arithmetic lives in the shared selection contract — this modifier
|
|
89
|
+
// only adapts props into it (GS-ANIMATION-01).
|
|
85
90
|
const resolveFrameRectWorklet = (
|
|
86
91
|
rect: { setXYWH(x: number, y: number, width: number, height: number): void },
|
|
87
92
|
): void => {
|
|
88
93
|
'worklet';
|
|
89
94
|
const clipValue = typeof clip === 'string' ? clip : clip?.value;
|
|
90
95
|
const elapsedValue = typeof elapsedMs === 'number' ? elapsedMs : elapsedMs?.value;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (animation !== undefined && animation.frames.length > 0) {
|
|
98
|
-
const duration = animation.frameDurationMs;
|
|
99
|
-
const count = animation.frames.length;
|
|
100
|
-
const index =
|
|
101
|
-
animation.mode === 'once'
|
|
102
|
-
? Math.min(Math.floor((elapsedValue ?? 0) / duration), count - 1)
|
|
103
|
-
: Math.floor((elapsedValue ?? 0) / duration) % count;
|
|
104
|
-
name = animation.frames[index] ?? animation.frames[0];
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const frameRect =
|
|
108
|
-
source.descriptor.kind === 'image'
|
|
109
|
-
? { x: 0, y: 0, width: (source as LoadedImage).width, height: (source as LoadedImage).height }
|
|
110
|
-
: name === undefined
|
|
111
|
-
? undefined
|
|
112
|
-
: (source as LoadedSpriteSheet).frames[name];
|
|
113
|
-
if (frameRect === undefined) {
|
|
114
|
-
if (name === undefined) {
|
|
115
|
-
// RF4: the selection has not been published yet (scene mismatch or a
|
|
116
|
-
// shared frame before its first value): present nothing, never throw.
|
|
117
|
-
rect.setXYWH(0, 0, 0, 0);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
throw new Error(
|
|
121
|
-
`frame ${JSON.stringify(name)} does not belong to this sprite sheet (loaded frames: ${Object.keys((source as LoadedSpriteSheet).frames).join(', ')})`,
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
rect.setXYWH(frameRect.x, frameRect.y, frameRect.width, frameRect.height);
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const staticFrame = typeof frame === 'string' ? frame : undefined;
|
|
128
|
-
const frameSize = useMemo(() => resolveSpriteFrameRect(source, staticFrame), [source, staticFrame]);
|
|
129
|
-
const input: SpriteTransformInput = {
|
|
130
|
-
x,
|
|
131
|
-
y,
|
|
132
|
-
rotation,
|
|
133
|
-
scale,
|
|
134
|
-
flipX,
|
|
135
|
-
flipY,
|
|
136
|
-
anchorX: anchor.x,
|
|
137
|
-
anchorY: anchor.y,
|
|
138
|
-
frameWidth: frameSize.width,
|
|
139
|
-
frameHeight: frameSize.height,
|
|
96
|
+
const name: string | undefined = typeof frame === 'string' ? frame : frame?.value;
|
|
97
|
+
applySpriteFrameSelection(rect, source, {
|
|
98
|
+
...(name === undefined ? {} : { frame: name }),
|
|
99
|
+
...(clipValue === undefined ? {} : { clip: clipValue }),
|
|
100
|
+
...(elapsedValue === undefined ? {} : { elapsedMs: elapsedValue }),
|
|
101
|
+
});
|
|
140
102
|
};
|
|
141
103
|
|
|
142
104
|
const rects = useRectBuffer(1, resolveFrameRectWorklet);
|
|
143
105
|
const xforms = useRSXformBuffer(1, (xform) => {
|
|
144
106
|
'worklet';
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (rect !== undefined) {
|
|
153
|
-
width = rect.width;
|
|
154
|
-
height = rect.height;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
107
|
+
// GS-SPRITE-03: the same shared selection the rect modifier resolves,
|
|
108
|
+
// so clip-driven frame changes reach the anchor math with current
|
|
109
|
+
// dimensions. Absent selection draws nothing; its transform is finite.
|
|
110
|
+
const resolved = selectSpriteFrameRect(
|
|
111
|
+
source,
|
|
112
|
+
materializeSpriteSelection(frame, clip, elapsedMs),
|
|
113
|
+
);
|
|
157
114
|
const result = computeSpriteRsxform({
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
115
|
+
x,
|
|
116
|
+
y,
|
|
117
|
+
rotation,
|
|
118
|
+
scale,
|
|
119
|
+
flipX,
|
|
120
|
+
flipY,
|
|
121
|
+
anchorX: anchor.x,
|
|
122
|
+
anchorY: anchor.y,
|
|
123
|
+
frameWidth: resolved?.width ?? 0,
|
|
124
|
+
frameHeight: resolved?.height ?? 0,
|
|
161
125
|
});
|
|
162
126
|
xform.set(result.scos, result.ssin, result.tx, result.ty);
|
|
163
127
|
});
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
128
|
+
// GS-SPRITE-01: the correction depends on position, rotation, scale,
|
|
129
|
+
// flips, and the live frame dimensions, so it is derived on the UI
|
|
130
|
+
// runtime from live values — never memoized from React-render reads.
|
|
131
|
+
const groupTransform = useDerivedValue(() => {
|
|
132
|
+
const resolved = selectSpriteFrameRect(
|
|
133
|
+
source,
|
|
134
|
+
materializeSpriteSelection(frame, clip, elapsedMs),
|
|
135
|
+
);
|
|
136
|
+
return spriteGroupCorrection({
|
|
137
|
+
x,
|
|
138
|
+
y,
|
|
139
|
+
rotation,
|
|
140
|
+
scale,
|
|
141
|
+
flipX,
|
|
142
|
+
flipY,
|
|
143
|
+
anchorX: anchor.x,
|
|
144
|
+
anchorY: anchor.y,
|
|
145
|
+
frameWidth: resolved?.width ?? 0,
|
|
146
|
+
frameHeight: resolved?.height ?? 0,
|
|
147
|
+
});
|
|
148
|
+
}, [x, y, rotation, scale, flipX, flipY, frame, clip, elapsedMs, source, anchor.x, anchor.y]);
|
|
170
149
|
const colors = useMemo(() => (tint === undefined ? undefined : [tint]), [tint]);
|
|
171
150
|
|
|
172
151
|
// The Skia Group has no `visible` prop: hiding is expressed as a combined
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* `Atlas` with fixed-capacity, UI-owned buffers. The normal path owns all
|
|
6
6
|
* derived-value plumbing: `select` maps the committed snapshot to the item
|
|
7
7
|
* array and `write` is a UI-runtime setter that writes transforms in place —
|
|
8
|
-
* no per-frame
|
|
9
|
-
*
|
|
8
|
+
* no per-frame React and no author-written `useDerivedValue` side effects.
|
|
9
|
+
* Per commit the select array, one policy object, and one RSXform result
|
|
10
|
+
* per written item are allocated; buffers themselves are never reallocated.
|
|
10
11
|
*
|
|
11
12
|
* Contract:
|
|
12
13
|
* - `capacity` is fixed for the mounted batch; active count is explicit.
|
|
@@ -20,11 +21,17 @@ import { Atlas, type SkImage } from '@shopify/react-native-skia';
|
|
|
20
21
|
import { useDerivedValue, type SharedValue } from 'react-native-reanimated';
|
|
21
22
|
import { useRectBuffer, useRSXformBuffer } from '@shopify/react-native-skia';
|
|
22
23
|
|
|
24
|
+
import type { CameraCut2D } from '../../camera2d';
|
|
25
|
+
import type { Aabb2D } from '../../geometry/types';
|
|
23
26
|
import type { CommitFrame } from '../../core/session/types';
|
|
27
|
+
import { batchVisibleBounds2D, intersectsBounds2D } from './batchVisibility';
|
|
28
|
+
import type { ResolvedViewport2D } from '../../viewport2d/types';
|
|
29
|
+
export { batchVisibleBounds2D, intersectsBounds2D };
|
|
24
30
|
import type { SceneSnapshot } from '../../scene/types';
|
|
25
31
|
import type { SceneMap } from '../../definition/types';
|
|
26
32
|
import type { LoadedImage, LoadedSpriteSheet } from '../../assets/types';
|
|
27
33
|
import { computeSpriteRsxform } from './spriteTransform';
|
|
34
|
+
import { selectSpriteFrameRect } from './spriteSelection';
|
|
28
35
|
import { batchUpdatePolicy } from './spriteBatchPolicy';
|
|
29
36
|
|
|
30
37
|
/** The per-item write surface handed to the author's `write` mapper. */
|
|
@@ -70,6 +77,22 @@ export interface SpriteBatchProps<
|
|
|
70
77
|
readonly write: (write: SpriteBatchWrite, item: TItem, index: number) => void;
|
|
71
78
|
/** Uniform anchor in [0, 1] relative to the selected frame. */
|
|
72
79
|
readonly anchor?: { readonly x: number; readonly y: number };
|
|
80
|
+
/**
|
|
81
|
+
* Optional camera culling (T12.6): items whose authored world bounds fall
|
|
82
|
+
* outside the conservative visible region are hidden (zero-size slots)
|
|
83
|
+
* instead of drawn. Slot identity and capacity are unchanged; the
|
|
84
|
+
* simulation never knows culling happened. `bounds` maps an item to its
|
|
85
|
+
* world AABB and runs as a worklet on the UI runtime. A bounds record
|
|
86
|
+
* with non-finite values hides the item (fail-safe: invalid geometry is
|
|
87
|
+
* never drawn); padding must be finite and nonnegative (T12-F5).
|
|
88
|
+
*/
|
|
89
|
+
readonly cull?: {
|
|
90
|
+
readonly camera: SharedValue<CameraCut2D | undefined>;
|
|
91
|
+
readonly viewport: SharedValue<ResolvedViewport2D | undefined>;
|
|
92
|
+
readonly bounds: (item: TItem) => Aabb2D;
|
|
93
|
+
/** Optional world-space padding around the visible region. */
|
|
94
|
+
readonly padding?: number;
|
|
95
|
+
};
|
|
73
96
|
}
|
|
74
97
|
|
|
75
98
|
function frameRectOf(
|
|
@@ -77,11 +100,13 @@ function frameRectOf(
|
|
|
77
100
|
frame: string,
|
|
78
101
|
): { x: number; y: number; width: number; height: number } | undefined {
|
|
79
102
|
'worklet';
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
103
|
+
// GS-SPRITE-04: the shared selection contract resolves the rectangle, so
|
|
104
|
+
// unknown frames fail with the same actionable error as retained sprites.
|
|
105
|
+
const resolved = selectSpriteFrameRect(source, { frame });
|
|
106
|
+
if (resolved === undefined) {
|
|
107
|
+
throw new Error(`frame ${JSON.stringify(frame)} does not belong to this sprite sheet`);
|
|
83
108
|
}
|
|
84
|
-
return
|
|
109
|
+
return resolved;
|
|
85
110
|
}
|
|
86
111
|
|
|
87
112
|
export function SpriteBatch<
|
|
@@ -97,6 +122,7 @@ export function SpriteBatch<
|
|
|
97
122
|
select,
|
|
98
123
|
write,
|
|
99
124
|
anchor = { x: 0, y: 0 },
|
|
125
|
+
cull,
|
|
100
126
|
}: SpriteBatchProps<TScenes, TSceneName, TItem>) {
|
|
101
127
|
const image = source.image as SkImage;
|
|
102
128
|
if (!Number.isInteger(capacity) || capacity <= 0) {
|
|
@@ -104,6 +130,14 @@ export function SpriteBatch<
|
|
|
104
130
|
`SpriteBatch capacity must be a positive integer, got ${String(capacity)}`,
|
|
105
131
|
);
|
|
106
132
|
}
|
|
133
|
+
// T12-F5: culling padding is validated ONCE at the React boundary; the UI
|
|
134
|
+
// worklet consumes a trusted finite nonnegative scalar.
|
|
135
|
+
const cullPadding = cull?.padding ?? 0;
|
|
136
|
+
if (!Number.isFinite(cullPadding) || cullPadding < 0) {
|
|
137
|
+
throw new RangeError(
|
|
138
|
+
`SpriteBatch cull.padding must be a finite nonnegative number, got ${String(cullPadding)}`,
|
|
139
|
+
);
|
|
140
|
+
}
|
|
107
141
|
const rects = useRectBuffer(capacity, (rect) => {
|
|
108
142
|
'worklet';
|
|
109
143
|
rect.setXYWH(0, 0, 0, 0);
|
|
@@ -119,9 +153,11 @@ export function SpriteBatch<
|
|
|
119
153
|
() => ({
|
|
120
154
|
set: (index, frame, x, y, rotation, scale, visible = true) => {
|
|
121
155
|
'worklet';
|
|
122
|
-
|
|
156
|
+
// GS-SPRITE-04: the author-exposed index is validated as an integer
|
|
157
|
+
// slot — a fractional index would silently miss every buffer slot.
|
|
158
|
+
if (!Number.isInteger(index) || index < 0 || index >= capacity) {
|
|
123
159
|
throw new Error(
|
|
124
|
-
`SpriteBatch write index ${index} is outside the capacity ${capacity}`,
|
|
160
|
+
`SpriteBatch write index ${String(index)} is outside the capacity ${capacity}`,
|
|
125
161
|
);
|
|
126
162
|
}
|
|
127
163
|
const rectSlot = rects.value[index];
|
|
@@ -161,8 +197,10 @@ export function SpriteBatch<
|
|
|
161
197
|
|
|
162
198
|
// The batch's own UI mapper: one derived value reads the committed
|
|
163
199
|
// snapshot, runs the author's select + write per item, and reports the
|
|
164
|
-
// active count. Buffers are mutated in place
|
|
165
|
-
// per
|
|
200
|
+
// active count. Buffers are mutated in place with no per-frame React;
|
|
201
|
+
// per commit the select array, one policy object, and one RSXform result
|
|
202
|
+
// per written item are allocated (GS-SPRITE-04: scalar writers stay
|
|
203
|
+
// unjustified without a benchmark showing this matters).
|
|
166
204
|
const activeCount = useDerivedValue(() => {
|
|
167
205
|
'worklet';
|
|
168
206
|
const envelope = commit.value;
|
|
@@ -182,22 +220,36 @@ export function SpriteBatch<
|
|
|
182
220
|
alpha: alpha.value,
|
|
183
221
|
});
|
|
184
222
|
const policy = batchUpdatePolicy(items.length, capacity, __DEV__);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
223
|
+
// GS-SPRITE-04: no overflow loop — `policy.activeCount` already clamps
|
|
224
|
+
// production writes to capacity, and every buffer slot past capacity is
|
|
225
|
+
// absent by construction, so iterating [capacity, items.length) could
|
|
226
|
+
// only add unbounded dead work.
|
|
227
|
+
const count = policy.activeCount;
|
|
228
|
+
// T12.6 + T12-F5: culling hides off-screen slots in place, and
|
|
229
|
+
// authored writes run ONLY through `policy.activeCount`. In production
|
|
230
|
+
// an overflowing item (index >= capacity) is never written and never
|
|
231
|
+
// indexes a buffer — the [count, capacity) hide loop below clears the
|
|
232
|
+
// unused tail. The visible bounds are computed once per commit from the
|
|
233
|
+
// PRESENTED camera; hidden slots are cleared directly (zero size)
|
|
234
|
+
// without touching the author's write or reallocating buffers, so slot
|
|
235
|
+
// identity is stable across camera moves.
|
|
236
|
+
const visible =
|
|
237
|
+
cull === undefined
|
|
238
|
+
? undefined
|
|
239
|
+
: batchVisibleBounds2D(cull.camera.value, cull.viewport.value, cullPadding);
|
|
240
|
+
for (let index = 0; index < count; index += 1) {
|
|
241
|
+
const item = items[index];
|
|
242
|
+
if (item === undefined) {
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (visible !== undefined && !intersectsBounds2D(cull!.bounds(item), visible)) {
|
|
189
246
|
const slot = rects.value[index];
|
|
190
247
|
if (slot !== undefined) {
|
|
191
248
|
slot.setXYWH(0, 0, 0, 0);
|
|
192
249
|
}
|
|
250
|
+
continue;
|
|
193
251
|
}
|
|
194
|
-
|
|
195
|
-
const count = policy.activeCount;
|
|
196
|
-
for (let index = 0; index < items.length; index += 1) {
|
|
197
|
-
const item = items[index];
|
|
198
|
-
if (item !== undefined) {
|
|
199
|
-
write(writeApi, item, index);
|
|
200
|
-
}
|
|
252
|
+
write(writeApi, item, index);
|
|
201
253
|
}
|
|
202
254
|
// Hide every inactive slot.
|
|
203
255
|
for (let index = count; index < capacity; index += 1) {
|
|
@@ -207,7 +259,7 @@ export function SpriteBatch<
|
|
|
207
259
|
}
|
|
208
260
|
}
|
|
209
261
|
return count;
|
|
210
|
-
}, [commit, alpha, scene, select, write, writeApi]);
|
|
262
|
+
}, [commit, alpha, scene, select, write, writeApi, cull, cullPadding]);
|
|
211
263
|
|
|
212
264
|
void activeCount;
|
|
213
265
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch culling math (T12.6, T12-F5) — pure and worklet-safe, with no React
|
|
3
|
+
* imports, so the benchmark and headless tests can import them directly.
|
|
4
|
+
*/
|
|
5
|
+
import type { CameraCut2D } from '../../camera2d';
|
|
6
|
+
import { rotatedHalfExtents2D } from '../../camera2d/extents';
|
|
7
|
+
import type { Aabb2D } from '../../geometry/types';
|
|
8
|
+
import type { ResolvedViewport2D } from '../../viewport2d/types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Conservative visible bounds for batch culling (T12.6).
|
|
12
|
+
*
|
|
13
|
+
* Worklet-safe inline version of the headless `paddedCameraBounds2D` —
|
|
14
|
+
* the presented camera is already validated at the public boundary, so the
|
|
15
|
+
* per-frame path allocates nothing and validates nothing.
|
|
16
|
+
*/
|
|
17
|
+
export function batchVisibleBounds2D(
|
|
18
|
+
camera: CameraCut2D | undefined,
|
|
19
|
+
viewport: ResolvedViewport2D | undefined,
|
|
20
|
+
padding: number,
|
|
21
|
+
): Aabb2D | undefined {
|
|
22
|
+
'worklet';
|
|
23
|
+
if (camera === undefined || viewport === undefined) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const view = viewport.visibleLogicalBounds;
|
|
27
|
+
const extent = rotatedHalfExtents2D(
|
|
28
|
+
view.width / 2 / camera.camera.zoom,
|
|
29
|
+
view.height / 2 / camera.camera.zoom,
|
|
30
|
+
camera.camera.rotationRadians,
|
|
31
|
+
);
|
|
32
|
+
const extentX = extent.x + padding;
|
|
33
|
+
const extentY = extent.y + padding;
|
|
34
|
+
return {
|
|
35
|
+
x: camera.camera.center.x - extentX,
|
|
36
|
+
y: camera.camera.center.y - extentY,
|
|
37
|
+
width: extentX * 2,
|
|
38
|
+
height: extentY * 2,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function isFiniteBounds(bounds: Aabb2D): boolean {
|
|
43
|
+
'worklet';
|
|
44
|
+
return (
|
|
45
|
+
Number.isFinite(bounds.x) &&
|
|
46
|
+
Number.isFinite(bounds.y) &&
|
|
47
|
+
Number.isFinite(bounds.width) &&
|
|
48
|
+
Number.isFinite(bounds.height) &&
|
|
49
|
+
bounds.width >= 0 &&
|
|
50
|
+
bounds.height >= 0
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Axis-aligned intersection test, worklet-safe (no validation).
|
|
55
|
+
*
|
|
56
|
+
* Inclusive comparisons, matching the public `intersectsAabbAabb2D`
|
|
57
|
+
* contract (T12-F5): exact boundary contact IS an intersection, so a
|
|
58
|
+
* sprite touching the camera edge is never culled.
|
|
59
|
+
*
|
|
60
|
+
* T12-RF6 malformed-bounds fail-safe: any non-finite field or negative
|
|
61
|
+
* size in EITHER rect hides the item (returns false) before the
|
|
62
|
+
* intersection test — invalid geometry is never drawn. Scalar and
|
|
63
|
+
* allocation-free; no structured error construction on the UI path.
|
|
64
|
+
*/
|
|
65
|
+
export function intersectsBounds2D(first: Aabb2D, second: Aabb2D): boolean {
|
|
66
|
+
'worklet';
|
|
67
|
+
if (!isFiniteBounds(first) || !isFiniteBounds(second)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return (
|
|
71
|
+
first.x <= second.x + second.width &&
|
|
72
|
+
first.x + first.width >= second.x &&
|
|
73
|
+
first.y <= second.y + second.height &&
|
|
74
|
+
first.y + first.height >= second.y
|
|
75
|
+
);
|
|
76
|
+
}
|