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
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Swept collision queries (T11.3, repaired in T11-F2, allocation-disciplined
|
|
3
|
+
* in T11-FF7).
|
|
4
|
+
*
|
|
5
|
+
* `time` is normalized to `[0, 1]` along the displacement. A starting
|
|
6
|
+
* overlap returns `time: 0` with the static manifold normal; zero
|
|
7
|
+
* displacement returns `undefined` (never NaN). At equal times the
|
|
8
|
+
* candidate evaluated FIRST wins — the X face before the Y face, faces
|
|
9
|
+
* before corners, corners in index order (T11-TF1). Circle-sweep misses
|
|
10
|
+
* allocate nothing; AABB-AABB sweep misses still allocate the expanded
|
|
11
|
+
* box, segment endpoints, and axis array (GS-COLLISION-03: the old blanket
|
|
12
|
+
* claim overstated this path, which stays scalar-simple by design).
|
|
13
|
+
*
|
|
14
|
+
* Circle-AABB sweeps raycast against the exact Minkowski geometry: the
|
|
15
|
+
* target expanded by the radius with ROUNDED corners. Face candidates come
|
|
16
|
+
* from the four expanded faces (valid only within the face's extent), and
|
|
17
|
+
* corner candidates come from radius circles around each target corner
|
|
18
|
+
* (valid only in the corner's exterior quadrant). AABB-AABB sweeps use the
|
|
19
|
+
* asymmetric expansion for the moving AABB's top-left reference point —
|
|
20
|
+
* the Minkowski sum of two AABBs is an AABB, so the slab method is exact.
|
|
21
|
+
*
|
|
22
|
+
* T11-FF7 allocation discipline: the four corner descriptors are derived
|
|
23
|
+
* arithmetically from the corner index (no per-call arrays or predicate
|
|
24
|
+
* closures), the two quadratic roots are evaluated as scalars, and the best
|
|
25
|
+
* candidate is tracked in scalars; only the final public `SweepHit2D` is
|
|
26
|
+
* allocated.
|
|
27
|
+
*/
|
|
28
|
+
import type { Aabb2D, Circle2D, Point2D, Vector2D } from '../geometry/types';
|
|
29
|
+
import {
|
|
30
|
+
assertValidAabb2D,
|
|
31
|
+
assertValidCircle2D,
|
|
32
|
+
assertValidVector2D,
|
|
33
|
+
} from '../geometry/validation';
|
|
34
|
+
import { collideAabbAabb2D, collideCircleAabb2D, type CollisionHit2D } from './manifolds';
|
|
35
|
+
import { intersectsCircleAabb2D } from './intersections';
|
|
36
|
+
import { intersectSegmentAabb2D } from './segments';
|
|
37
|
+
|
|
38
|
+
/** Earliest impact of a swept circle against an AABB. */
|
|
39
|
+
export interface SweepCircleAabb2DOptions {
|
|
40
|
+
/** The moving circle at the start of the step. */
|
|
41
|
+
readonly circle: Circle2D;
|
|
42
|
+
/** Displacement over the step (velocity times delta time). */
|
|
43
|
+
readonly displacement: Vector2D;
|
|
44
|
+
/** The stationary target. */
|
|
45
|
+
readonly target: Aabb2D;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Earliest impact of a swept AABB against an AABB. */
|
|
49
|
+
export interface SweepAabbAabb2DOptions {
|
|
50
|
+
/** The moving AABB at the start of the step. */
|
|
51
|
+
readonly aabb: Aabb2D;
|
|
52
|
+
/** Displacement over the step. */
|
|
53
|
+
readonly displacement: Vector2D;
|
|
54
|
+
/** The stationary target. */
|
|
55
|
+
readonly target: Aabb2D;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Earliest impact of a swept shape against a target. */
|
|
59
|
+
export interface SweepHit2D {
|
|
60
|
+
/** Normalized impact time in `[0, 1]`. */
|
|
61
|
+
readonly time: number;
|
|
62
|
+
/** Unit normal moving the swept shape out of the target. */
|
|
63
|
+
readonly normal: Vector2D;
|
|
64
|
+
/** Contact point on the target at impact. */
|
|
65
|
+
readonly point: Point2D;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Corner descriptors for index 0..3, derived arithmetically: bit 0 selects
|
|
70
|
+
* the max-x face (else min-x) and bit 1 selects the max-y face (else
|
|
71
|
+
* min-y). The quadrant validity of a hit point is the same bit test.
|
|
72
|
+
*/
|
|
73
|
+
function cornerFaceX(index: number, minX: number, maxX: number): number {
|
|
74
|
+
return index & 1 ? maxX : minX;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function cornerFaceY(index: number, minY: number, maxY: number): number {
|
|
78
|
+
return index & 2 ? maxY : minY;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function beyondFaceX(index: number, pointX: number, minX: number, maxX: number): boolean {
|
|
82
|
+
return index & 1 ? pointX >= maxX : pointX <= minX;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function beyondFaceY(index: number, pointY: number, minY: number, maxY: number): boolean {
|
|
86
|
+
return index & 2 ? pointY >= maxY : pointY <= minY;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Swept circle-AABB against the exact rounded-rectangle Minkowski shape. */
|
|
90
|
+
export function sweepCircleAabb2D(options: SweepCircleAabb2DOptions): SweepHit2D | undefined {
|
|
91
|
+
const { circle, displacement, target } = options;
|
|
92
|
+
assertValidCircle2D(circle);
|
|
93
|
+
assertValidVector2D(displacement, 'displacement');
|
|
94
|
+
assertValidAabb2D(target, 'target');
|
|
95
|
+
|
|
96
|
+
// The starting-overlap check uses the allocation-free predicate; the
|
|
97
|
+
// manifold (and its contact object) runs only after contact is confirmed
|
|
98
|
+
// (T11-SF3).
|
|
99
|
+
if (intersectsCircleAabb2D(circle, target)) {
|
|
100
|
+
const overlap = collideCircleAabb2D(circle, target);
|
|
101
|
+
if (overlap !== undefined) {
|
|
102
|
+
return hitFromManifold(0, overlap);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (displacement.x === 0 && displacement.y === 0) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const radius = circle.radius;
|
|
110
|
+
const minX = target.x;
|
|
111
|
+
const maxX = target.x + target.width;
|
|
112
|
+
const minY = target.y;
|
|
113
|
+
const maxY = target.y + target.height;
|
|
114
|
+
const x0 = circle.x;
|
|
115
|
+
const y0 = circle.y;
|
|
116
|
+
const dx = displacement.x;
|
|
117
|
+
const dy = displacement.y;
|
|
118
|
+
|
|
119
|
+
// Scalar best-candidate tracking: nothing is allocated until a hit.
|
|
120
|
+
let hasBest = false;
|
|
121
|
+
let bestTime = 0;
|
|
122
|
+
let bestNX = 0;
|
|
123
|
+
let bestNY = 0;
|
|
124
|
+
let bestPX = 0;
|
|
125
|
+
let bestPY = 0;
|
|
126
|
+
|
|
127
|
+
// Face candidates: the four expanded faces, valid within the face extent.
|
|
128
|
+
// The accept logic is inlined as scalar updates (no local closure). A
|
|
129
|
+
// candidate REPLACES only when strictly earlier; at equal times the
|
|
130
|
+
// candidate evaluated first retains the result (T11-TF1).
|
|
131
|
+
if (dx !== 0) {
|
|
132
|
+
const faceX = dx > 0 ? minX - radius : maxX + radius;
|
|
133
|
+
const time = (faceX - x0) / dx;
|
|
134
|
+
const yAt = y0 + dy * time;
|
|
135
|
+
if (yAt >= minY && yAt <= maxY && time >= 0 && time <= 1 && (!hasBest || bestTime > time)) {
|
|
136
|
+
// The contact point is the closest point on the ORIGINAL target to
|
|
137
|
+
// the impact position (both coordinates clamped).
|
|
138
|
+
hasBest = true;
|
|
139
|
+
bestTime = time;
|
|
140
|
+
bestNX = dx > 0 ? -1 : 1;
|
|
141
|
+
bestNY = 0;
|
|
142
|
+
bestPX = clamp(faceX, minX, maxX);
|
|
143
|
+
bestPY = clamp(yAt, minY, maxY);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (dy !== 0) {
|
|
147
|
+
const faceY = dy > 0 ? minY - radius : maxY + radius;
|
|
148
|
+
const time = (faceY - y0) / dy;
|
|
149
|
+
const xAt = x0 + dx * time;
|
|
150
|
+
if (xAt >= minX && xAt <= maxX && time >= 0 && time <= 1 && (!hasBest || bestTime > time)) {
|
|
151
|
+
hasBest = true;
|
|
152
|
+
bestTime = time;
|
|
153
|
+
bestNX = 0;
|
|
154
|
+
bestNY = dy > 0 ? -1 : 1;
|
|
155
|
+
bestPX = clamp(xAt, minX, maxX);
|
|
156
|
+
bestPY = clamp(faceY, minY, maxY);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Corner candidates: radius circles around each corner, valid in the
|
|
161
|
+
// corner's exterior quadrant. The four descriptors are derived from the
|
|
162
|
+
// corner index arithmetically; both quadratic roots are scalars.
|
|
163
|
+
const a = dx * dx + dy * dy;
|
|
164
|
+
for (let corner = 0; corner < 4; corner += 1) {
|
|
165
|
+
const cornerX = cornerFaceX(corner, minX, maxX);
|
|
166
|
+
const cornerY = cornerFaceY(corner, minY, maxY);
|
|
167
|
+
const fx = x0 - cornerX;
|
|
168
|
+
const fy = y0 - cornerY;
|
|
169
|
+
const b = 2 * (fx * dx + fy * dy);
|
|
170
|
+
const c = fx * fx + fy * fy - radius * radius;
|
|
171
|
+
const discriminant = b * b - 4 * a * c;
|
|
172
|
+
if (discriminant < 0) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const root = Math.sqrt(discriminant);
|
|
176
|
+
const firstRoot = (-b - root) / (2 * a);
|
|
177
|
+
const secondRoot = (-b + root) / (2 * a);
|
|
178
|
+
for (let pass = 0; pass < 2; pass += 1) {
|
|
179
|
+
const time = pass === 0 ? firstRoot : secondRoot;
|
|
180
|
+
if (time < 0 || time > 1 || (hasBest && bestTime < time)) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
const hitX = x0 + dx * time;
|
|
184
|
+
const hitY = y0 + dy * time;
|
|
185
|
+
if (!beyondFaceX(corner, hitX, minX, maxX) || !beyondFaceY(corner, hitY, minY, maxY)) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const outX = hitX - cornerX;
|
|
189
|
+
const outY = hitY - cornerY;
|
|
190
|
+
const outDistance = Math.hypot(outX, outY);
|
|
191
|
+
const nx = outDistance === 0 ? 0 : outX / outDistance;
|
|
192
|
+
const ny = outDistance === 0 ? 1 : outY / outDistance;
|
|
193
|
+
if (!hasBest || time < bestTime) {
|
|
194
|
+
hasBest = true;
|
|
195
|
+
bestTime = time;
|
|
196
|
+
bestNX = nx;
|
|
197
|
+
bestNY = ny;
|
|
198
|
+
bestPX = cornerX;
|
|
199
|
+
bestPY = cornerY;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (!hasBest) {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
return Object.freeze({
|
|
208
|
+
time: bestTime,
|
|
209
|
+
normal: Object.freeze({ x: bestNX, y: bestNY }),
|
|
210
|
+
point: Object.freeze({ x: bestPX, y: bestPY }),
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Swept AABB-AABB with the exact asymmetric reference expansion. */
|
|
215
|
+
export function sweepAabbAabb2D(options: SweepAabbAabb2DOptions): SweepHit2D | undefined {
|
|
216
|
+
const { aabb, displacement, target } = options;
|
|
217
|
+
assertValidAabb2D(aabb, 'aabb');
|
|
218
|
+
assertValidVector2D(displacement, 'displacement');
|
|
219
|
+
assertValidAabb2D(target, 'target');
|
|
220
|
+
|
|
221
|
+
const startingOverlap = collideAabbAabb2D(aabb, target);
|
|
222
|
+
if (startingOverlap !== undefined) {
|
|
223
|
+
return hitFromManifold(0, startingOverlap);
|
|
224
|
+
}
|
|
225
|
+
if (displacement.x === 0 && displacement.y === 0) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Top-left reference: the valid x interval is [target.min - w, target.max]
|
|
230
|
+
// and the valid y interval is [target.min - h, target.max] (asymmetric).
|
|
231
|
+
const expanded: Aabb2D = {
|
|
232
|
+
x: target.x - aabb.width,
|
|
233
|
+
y: target.y - aabb.height,
|
|
234
|
+
width: target.width + aabb.width,
|
|
235
|
+
height: target.height + aabb.height,
|
|
236
|
+
};
|
|
237
|
+
const segmentHit = intersectSegmentAabb2D(
|
|
238
|
+
{ start: { x: aabb.x, y: aabb.y }, end: { x: aabb.x + displacement.x, y: aabb.y + displacement.y } },
|
|
239
|
+
expanded,
|
|
240
|
+
);
|
|
241
|
+
if (segmentHit === undefined) {
|
|
242
|
+
return undefined;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const originAtImpact = {
|
|
246
|
+
x: aabb.x + displacement.x * segmentHit.time,
|
|
247
|
+
y: aabb.y + displacement.y * segmentHit.time,
|
|
248
|
+
};
|
|
249
|
+
return Object.freeze({
|
|
250
|
+
time: segmentHit.time,
|
|
251
|
+
normal: segmentHit.normal,
|
|
252
|
+
point: Object.freeze({
|
|
253
|
+
x: clamp(originAtImpact.x, target.x, target.x + target.width),
|
|
254
|
+
y: clamp(originAtImpact.y, target.y, target.y + target.height),
|
|
255
|
+
}),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function hitFromManifold(time: number, hit: CollisionHit2D): SweepHit2D {
|
|
260
|
+
return Object.freeze({
|
|
261
|
+
time,
|
|
262
|
+
normal: hit.normal,
|
|
263
|
+
point: hit.point,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function clamp(value: number, min: number, max: number): number {
|
|
268
|
+
return value < min ? min : value > max ? max : value;
|
|
269
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multitouch button-pad controller (headless).
|
|
3
|
+
*
|
|
4
|
+
* Maps every active pointer to the button zone it covers and turns touch
|
|
5
|
+
* transitions into press/release diffs for a session input buffer. Pure and
|
|
6
|
+
* React-free: the React surface (`GameButtonPad`) only registers zone rects,
|
|
7
|
+
* feeds touch lists in, and applies the returned diffs to
|
|
8
|
+
* `session.input`.
|
|
9
|
+
*
|
|
10
|
+
* Semantics:
|
|
11
|
+
* - A zone is a rectangle; an optional global hit slop expands it.
|
|
12
|
+
* - Each pointer maps to AT MOST one action (first registered zone wins).
|
|
13
|
+
* - An action is pressed while ANY pointer covers its zone (refcounted);
|
|
14
|
+
* it releases when the last pointer leaves or lifts. Edges fire only on
|
|
15
|
+
* 0-to-1 (press) and 1-to-0 (release) owner transitions — a second owner
|
|
16
|
+
* never re-presses and an unbalanced release never emits.
|
|
17
|
+
* - Sliding between zones reassigns the pointer: release + press diff.
|
|
18
|
+
* - Moves acquire: a pointer that begins in empty space and slides into a
|
|
19
|
+
* zone presses it; leaving a zone releases. Every touch in a move list
|
|
20
|
+
* is hit-tested, mapped or not.
|
|
21
|
+
* - Zone rects are cloned at registration: later caller mutation of the
|
|
22
|
+
* passed object cannot alter hit areas invisibly.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** A rectangular hit area, in the pad's local coordinate space. */
|
|
26
|
+
export interface ButtonPadRect {
|
|
27
|
+
readonly x: number;
|
|
28
|
+
readonly y: number;
|
|
29
|
+
readonly width: number;
|
|
30
|
+
readonly height: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** One active pointer sample. */
|
|
34
|
+
export interface ButtonPadTouch {
|
|
35
|
+
/** Native pointer id; stable for the lifetime of one touch. */
|
|
36
|
+
readonly id: number;
|
|
37
|
+
readonly x: number;
|
|
38
|
+
readonly y: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Press/release transitions derived from one touch event. */
|
|
42
|
+
export interface ButtonPadDiff {
|
|
43
|
+
/** Actions that transitioned to held. */
|
|
44
|
+
readonly pressed: readonly string[];
|
|
45
|
+
/** Actions that transitioned to released. */
|
|
46
|
+
readonly released: readonly string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const EMPTY_DIFF: ButtonPadDiff = { pressed: [], released: [] };
|
|
50
|
+
|
|
51
|
+
function contains(
|
|
52
|
+
rect: ButtonPadRect,
|
|
53
|
+
hitSlop: number,
|
|
54
|
+
x: number,
|
|
55
|
+
y: number,
|
|
56
|
+
): boolean {
|
|
57
|
+
return (
|
|
58
|
+
x >= rect.x - hitSlop &&
|
|
59
|
+
x <= rect.x + rect.width + hitSlop &&
|
|
60
|
+
y >= rect.y - hitSlop &&
|
|
61
|
+
y <= rect.y + rect.height + hitSlop
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Create a controller bound to no particular session (diffs are applied by the caller). */
|
|
66
|
+
export function createButtonPadController(options?: { readonly hitSlop?: number }): {
|
|
67
|
+
setZone(action: string, rect: ButtonPadRect): void;
|
|
68
|
+
removeZone(action: string): readonly string[];
|
|
69
|
+
touchesDown(touches: readonly ButtonPadTouch[]): ButtonPadDiff;
|
|
70
|
+
touchesMove(touches: readonly ButtonPadTouch[]): ButtonPadDiff;
|
|
71
|
+
touchesUp(changed: readonly ButtonPadTouch[]): ButtonPadDiff;
|
|
72
|
+
touchesCancel(changed: readonly ButtonPadTouch[]): ButtonPadDiff;
|
|
73
|
+
releaseAll(): readonly string[];
|
|
74
|
+
invalidateOwnership(): void;
|
|
75
|
+
held(): readonly string[];
|
|
76
|
+
} {
|
|
77
|
+
const hitSlop = options?.hitSlop ?? 0;
|
|
78
|
+
const zones = new Map<string, ButtonPadRect>();
|
|
79
|
+
const pointerAction = new Map<number, string>();
|
|
80
|
+
const holdCounts = new Map<string, number>();
|
|
81
|
+
// GS-INPUT-04: pointers that were active across an invalidation (pause,
|
|
82
|
+
// session replacement) must produce a fresh down before their moves can
|
|
83
|
+
// acquire again. A fresh down rehabilitates; lift clears the mark.
|
|
84
|
+
const stalePointerIds = new Set<number>();
|
|
85
|
+
|
|
86
|
+
const apply = (action: string, direction: 1 | -1): 'pressed' | 'released' | undefined => {
|
|
87
|
+
// GS-INPUT-02: edges fire only on ownership transitions. A second owner
|
|
88
|
+
// (0 stays > 0) never re-presses; an unbalanced release from zero
|
|
89
|
+
// count never emits.
|
|
90
|
+
const previous = holdCounts.get(action) ?? 0;
|
|
91
|
+
const next = previous + direction;
|
|
92
|
+
if (next <= 0) {
|
|
93
|
+
holdCounts.delete(action);
|
|
94
|
+
return previous > 0 && direction === -1 ? 'released' : undefined;
|
|
95
|
+
}
|
|
96
|
+
holdCounts.set(action, next);
|
|
97
|
+
return previous === 0 && direction === 1 ? 'pressed' : undefined;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const hitTest = (x: number, y: number): string | undefined => {
|
|
101
|
+
for (const [action, rect] of zones) {
|
|
102
|
+
if (contains(rect, hitSlop, x, y)) {
|
|
103
|
+
return action;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const retarget = (touchId: number, action: string | undefined): ButtonPadDiff => {
|
|
110
|
+
const previous = pointerAction.get(touchId);
|
|
111
|
+
if (previous === action) {
|
|
112
|
+
return EMPTY_DIFF;
|
|
113
|
+
}
|
|
114
|
+
const pressed: string[] = [];
|
|
115
|
+
const released: string[] = [];
|
|
116
|
+
if (previous !== undefined) {
|
|
117
|
+
pointerAction.delete(touchId);
|
|
118
|
+
const result = apply(previous, -1);
|
|
119
|
+
if (result === 'released') {
|
|
120
|
+
released.push(previous);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (action !== undefined) {
|
|
124
|
+
pointerAction.set(touchId, action);
|
|
125
|
+
const result = apply(action, 1);
|
|
126
|
+
if (result === 'pressed') {
|
|
127
|
+
pressed.push(action);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return { pressed, released };
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const dropPointers = (changed: readonly ButtonPadTouch[]): ButtonPadDiff => {
|
|
134
|
+
const released: string[] = [];
|
|
135
|
+
for (const touch of changed) {
|
|
136
|
+
stalePointerIds.delete(touch.id);
|
|
137
|
+
const previous = pointerAction.get(touch.id);
|
|
138
|
+
if (previous === undefined) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
pointerAction.delete(touch.id);
|
|
142
|
+
if (apply(previous, -1) === 'released') {
|
|
143
|
+
released.push(previous);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return { pressed: [], released };
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
setZone(action: string, rect: ButtonPadRect): void {
|
|
151
|
+
// GS-INPUT-02: clone the rect so later caller mutation of the passed
|
|
152
|
+
// object cannot alter hit areas invisibly.
|
|
153
|
+
zones.set(action, { x: rect.x, y: rect.y, width: rect.width, height: rect.height });
|
|
154
|
+
},
|
|
155
|
+
removeZone(action: string): readonly string[] {
|
|
156
|
+
zones.delete(action);
|
|
157
|
+
// GS-INPUT-02: drop every pointer mapped to the removed zone, then
|
|
158
|
+
// release and delete the ENTIRE action count — a single decrement
|
|
159
|
+
// would strand a phantom hold. Pointers stay physically tracked only
|
|
160
|
+
// through future touch events, which re-acquire via hit test.
|
|
161
|
+
for (const [pointerId, mapped] of [...pointerAction]) {
|
|
162
|
+
if (mapped === action) {
|
|
163
|
+
pointerAction.delete(pointerId);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if ((holdCounts.get(action) ?? 0) > 0) {
|
|
167
|
+
holdCounts.delete(action);
|
|
168
|
+
return [action];
|
|
169
|
+
}
|
|
170
|
+
return [];
|
|
171
|
+
},
|
|
172
|
+
touchesDown(touches: readonly ButtonPadTouch[]): ButtonPadDiff {
|
|
173
|
+
const merged: { pressed: string[]; released: string[] } = { pressed: [], released: [] };
|
|
174
|
+
for (const touch of touches) {
|
|
175
|
+
stalePointerIds.delete(touch.id);
|
|
176
|
+
const diff = retarget(touch.id, hitTest(touch.x, touch.y));
|
|
177
|
+
merged.pressed.push(...diff.pressed);
|
|
178
|
+
merged.released.push(...diff.released);
|
|
179
|
+
}
|
|
180
|
+
return merged;
|
|
181
|
+
},
|
|
182
|
+
touchesMove(touches: readonly ButtonPadTouch[]): ButtonPadDiff {
|
|
183
|
+
// GS-INPUT-02: every touch in the move list is hit-tested, mapped or
|
|
184
|
+
// not — a pointer that left its zone releases, and one that entered
|
|
185
|
+
// a zone (including from empty space) presses it.
|
|
186
|
+
// GS-INPUT-04: pointers marked stale by an invalidation wait for a
|
|
187
|
+
// fresh down first.
|
|
188
|
+
const merged: { pressed: string[]; released: string[] } = { pressed: [], released: [] };
|
|
189
|
+
for (const touch of touches) {
|
|
190
|
+
if (stalePointerIds.has(touch.id)) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const diff = retarget(touch.id, hitTest(touch.x, touch.y));
|
|
194
|
+
merged.pressed.push(...diff.pressed);
|
|
195
|
+
merged.released.push(...diff.released);
|
|
196
|
+
}
|
|
197
|
+
return merged;
|
|
198
|
+
},
|
|
199
|
+
touchesUp(changed: readonly ButtonPadTouch[]): ButtonPadDiff {
|
|
200
|
+
return dropPointers(changed);
|
|
201
|
+
},
|
|
202
|
+
touchesCancel(changed: readonly ButtonPadTouch[]): ButtonPadDiff {
|
|
203
|
+
return dropPointers(changed);
|
|
204
|
+
},
|
|
205
|
+
releaseAll(): readonly string[] {
|
|
206
|
+
const released = new Set<string>();
|
|
207
|
+
for (const action of pointerAction.values()) {
|
|
208
|
+
released.add(action);
|
|
209
|
+
}
|
|
210
|
+
pointerAction.clear();
|
|
211
|
+
for (const action of holdCounts.keys()) {
|
|
212
|
+
released.add(action);
|
|
213
|
+
}
|
|
214
|
+
holdCounts.clear();
|
|
215
|
+
stalePointerIds.clear();
|
|
216
|
+
return [...released];
|
|
217
|
+
},
|
|
218
|
+
/**
|
|
219
|
+
* GS-INPUT-04: invalidate ownership without touching zones — pause,
|
|
220
|
+
* session replacement, or layout teardown snapshot the active pointers
|
|
221
|
+
* as stale and drop all holds. Stale pointers must produce a fresh down
|
|
222
|
+
* before their moves can acquire again; a fresh down rehabilitates.
|
|
223
|
+
*/
|
|
224
|
+
invalidateOwnership(): void {
|
|
225
|
+
for (const pointerId of pointerAction.keys()) {
|
|
226
|
+
stalePointerIds.add(pointerId);
|
|
227
|
+
}
|
|
228
|
+
pointerAction.clear();
|
|
229
|
+
holdCounts.clear();
|
|
230
|
+
},
|
|
231
|
+
held(): readonly string[] {
|
|
232
|
+
return [...holdCounts.keys()];
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
}
|