@nayan-ui/games 1.19.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -191
- package/lib/module/assets/fonts/Inter-SemiBold.ttf +0 -0
- package/lib/module/assets/models/explorer/explorer.glb +0 -0
- package/lib/module/assets/models/explorer/params.json +51 -0
- package/lib/module/assets/models/explorer/source.json +222 -0
- package/lib/module/assets/models/play-with-tua/play-with-tua.glb +0 -0
- package/lib/module/assets/models/play-with-tua/sources.json +141 -0
- package/lib/module/assets/sfx/balloon_pop.wav +0 -0
- package/lib/module/assets/sfx/blocked.wav +0 -0
- package/lib/module/assets/sfx/boing.wav +0 -0
- package/lib/module/assets/sfx/bonus.wav +0 -0
- package/lib/module/assets/sfx/boom.wav +0 -0
- package/lib/module/assets/sfx/bump.wav +0 -0
- package/lib/module/assets/sfx/cannon.wav +0 -0
- package/lib/module/assets/sfx/capture.wav +0 -0
- package/lib/module/assets/sfx/card_flip.wav +0 -0
- package/lib/module/assets/sfx/card_place.wav +0 -0
- package/lib/module/assets/sfx/catch.wav +0 -0
- package/lib/module/assets/sfx/chime.wav +0 -0
- package/lib/module/assets/sfx/chomp.wav +0 -0
- package/lib/module/assets/sfx/chomp_alt.wav +0 -0
- package/lib/module/assets/sfx/clack.wav +0 -0
- package/lib/module/assets/sfx/clang.wav +0 -0
- package/lib/module/assets/sfx/clash.wav +0 -0
- package/lib/module/assets/sfx/click.wav +0 -0
- package/lib/module/assets/sfx/coin.wav +0 -0
- package/lib/module/assets/sfx/combo.wav +0 -0
- package/lib/module/assets/sfx/crash.wav +0 -0
- package/lib/module/assets/sfx/crunch.wav +0 -0
- package/lib/module/assets/sfx/dance.wav +0 -0
- package/lib/module/assets/sfx/deselect.wav +0 -0
- package/lib/module/assets/sfx/dice_roll.wav +0 -0
- package/lib/module/assets/sfx/die.wav +0 -0
- package/lib/module/assets/sfx/draw.wav +0 -0
- package/lib/module/assets/sfx/drop.wav +0 -0
- package/lib/module/assets/sfx/eat.wav +0 -0
- package/lib/module/assets/sfx/engine.wav +0 -0
- package/lib/module/assets/sfx/error.wav +0 -0
- package/lib/module/assets/sfx/flag.wav +0 -0
- package/lib/module/assets/sfx/flap.wav +0 -0
- package/lib/module/assets/sfx/flip_disc.wav +0 -0
- package/lib/module/assets/sfx/footstep_run.wav +0 -0
- package/lib/module/assets/sfx/footstep_walk.wav +0 -0
- package/lib/module/assets/sfx/game_over.wav +0 -0
- package/lib/module/assets/sfx/gate.wav +0 -0
- package/lib/module/assets/sfx/hit.wav +0 -0
- package/lib/module/assets/sfx/hop.wav +0 -0
- package/lib/module/assets/sfx/hurt.wav +0 -0
- package/lib/module/assets/sfx/invalid.wav +0 -0
- package/lib/module/assets/sfx/jump.wav +0 -0
- package/lib/module/assets/sfx/ladder.wav +0 -0
- package/lib/module/assets/sfx/land.wav +0 -0
- package/lib/module/assets/sfx/laugh.wav +0 -0
- package/lib/module/assets/sfx/lose.wav +0 -0
- package/lib/module/assets/sfx/merge.wav +0 -0
- package/lib/module/assets/sfx/miss.wav +0 -0
- package/lib/module/assets/sfx/nitro.wav +0 -0
- package/lib/module/assets/sfx/pew.wav +0 -0
- package/lib/module/assets/sfx/place.wav +0 -0
- package/lib/module/assets/sfx/pling.wav +0 -0
- package/lib/module/assets/sfx/point.wav +0 -0
- package/lib/module/assets/sfx/pop.wav +0 -0
- package/lib/module/assets/sfx/pop_soft.wav +0 -0
- package/lib/module/assets/sfx/power_up.wav +0 -0
- package/lib/module/assets/sfx/reveal.wav +0 -0
- package/lib/module/assets/sfx/robot.wav +0 -0
- package/lib/module/assets/sfx/rotate.wav +0 -0
- package/lib/module/assets/sfx/run_steps.wav +0 -0
- package/lib/module/assets/sfx/select.wav +0 -0
- package/lib/module/assets/sfx/shuffle.wav +0 -0
- package/lib/module/assets/sfx/six.wav +0 -0
- package/lib/module/assets/sfx/slice.wav +0 -0
- package/lib/module/assets/sfx/slide.wav +0 -0
- package/lib/module/assets/sfx/snake.wav +0 -0
- package/lib/module/assets/sfx/snap.wav +0 -0
- package/lib/module/assets/sfx/splash.wav +0 -0
- package/lib/module/assets/sfx/star.wav +0 -0
- package/lib/module/assets/sfx/start.wav +0 -0
- package/lib/module/assets/sfx/swoosh.wav +0 -0
- package/lib/module/assets/sfx/tap.wav +0 -0
- package/lib/module/assets/sfx/thud.wav +0 -0
- package/lib/module/assets/sfx/thunk.wav +0 -0
- package/lib/module/assets/sfx/tick.wav +0 -0
- package/lib/module/assets/sfx/time_up.wav +0 -0
- package/lib/module/assets/sfx/tock.wav +0 -0
- package/lib/module/assets/sfx/walk_steps.wav +0 -0
- package/lib/module/assets/sfx/warning.wav +0 -0
- package/lib/module/assets/sfx/whack.wav +0 -0
- package/lib/module/assets/sfx/whoosh.wav +0 -0
- package/lib/module/assets/sfx/win.wav +0 -0
- package/lib/module/assets/sfx/zap.wav +0 -0
- package/lib/module/assets/textures/ad_bolt.png +0 -0
- package/lib/module/assets/textures/ad_bubbles.png +0 -0
- package/lib/module/assets/textures/ad_chevrons.png +0 -0
- package/lib/module/assets/textures/asphalt.png +0 -0
- package/lib/module/assets/textures/bark.jpg +0 -0
- package/lib/module/assets/textures/explorer-atlas.png +0 -0
- package/lib/module/assets/textures/facade.png +0 -0
- package/lib/module/assets/textures/grass.png +0 -0
- package/lib/module/assets/textures/leaves.png +0 -0
- package/lib/module/assets/textures/limestone.jpg +0 -0
- package/lib/module/assets/textures/meadow.jpg +0 -0
- package/lib/module/assets/textures/nature-sources.json +87 -0
- package/lib/module/assets/textures/pine.png +0 -0
- package/lib/module/assets/textures/river.jpg +0 -0
- package/lib/module/assets/textures/soft_glow.png +0 -0
- package/lib/module/games/arrows/Arrows.js +1 -1
- package/lib/module/games/arrows/ArrowsConstants.js +1 -1
- package/lib/module/games/arrows/ArrowsGame.js +1 -0
- package/lib/module/games/arrows/ArrowsScene.js +1 -0
- package/lib/module/games/balloon-blaster/BalloonBlaster.js +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterConstants.js +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterGame.js +1 -0
- package/lib/module/games/balloon-blaster/BalloonBlasterPhysics.js +1 -0
- package/lib/module/games/balloon-blaster/BalloonBlasterScene.js +1 -0
- package/lib/module/games/bike-racing/BikeMeshes.js +1 -0
- package/lib/module/games/bike-racing/BikeRacing.js +1 -1
- package/lib/module/games/bike-racing/BikeRacingConstants.js +1 -1
- package/lib/module/games/bike-racing/BikeRacingGame.js +1 -0
- package/lib/module/games/bike-racing/BikeRacingScene.js +1 -0
- package/lib/module/games/block-blast/BlockBlast.js +1 -1
- package/lib/module/games/block-blast/BlockBlastConstants.js +1 -1
- package/lib/module/games/block-blast/BlockBlastGame.js +1 -0
- package/lib/module/games/block-blast/BlockBlastScene.js +1 -0
- package/lib/module/games/block-breaker/BlockBreaker.js +1 -1
- package/lib/module/games/block-breaker/BlockBreakerConstants.js +1 -1
- package/lib/module/games/block-breaker/BlockBreakerGame.js +1 -0
- package/lib/module/games/block-breaker/BlockBreakerScene.js +1 -0
- package/lib/module/games/bluk/Bluk.js +1 -1
- package/lib/module/games/bluk/BlukConstants.js +1 -1
- package/lib/module/games/bluk/BlukGame.js +1 -0
- package/lib/module/games/bluk/BlukRules.js +1 -0
- package/lib/module/games/bluk/BlukScene.js +1 -0
- package/lib/module/games/bubble-shooter/BubbleShooter.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooterConstants.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooterGame.js +1 -0
- package/lib/module/games/bubble-shooter/BubbleShooterScene.js +1 -0
- package/lib/module/games/candy-crush/CandyCrush.js +1 -1
- package/lib/module/games/candy-crush/CandyCrushConstants.js +1 -1
- package/lib/module/games/candy-crush/CandyCrushGame.js +1 -0
- package/lib/module/games/candy-crush/CandyCrushScene.js +1 -0
- package/lib/module/games/car-racing/CarMeshes.js +1 -0
- package/lib/module/games/car-racing/CarRacing.js +1 -1
- package/lib/module/games/car-racing/CarRacingConstants.js +1 -1
- package/lib/module/games/car-racing/CarRacingFacade.js +1 -0
- package/lib/module/games/car-racing/CarRacingGame.js +1 -0
- package/lib/module/games/car-racing/CarRacingScene.js +1 -0
- package/lib/module/games/car-racing/CarRacingScenery.js +1 -0
- package/lib/module/games/chameleon-run/ChameleonRun.js +1 -1
- package/lib/module/games/chameleon-run/ChameleonRunBackdrop.js +1 -0
- package/lib/module/games/chameleon-run/ChameleonRunConstants.js +1 -1
- package/lib/module/games/chameleon-run/ChameleonRunGame.js +1 -0
- package/lib/module/games/chameleon-run/ChameleonRunMeshes.js +1 -0
- package/lib/module/games/chameleon-run/ChameleonRunRules.js +1 -0
- package/lib/module/games/chameleon-run/ChameleonRunScene.js +1 -0
- package/lib/module/games/checkers/Checkers.js +1 -1
- package/lib/module/games/checkers/CheckersAI.js +1 -0
- package/lib/module/games/checkers/CheckersConstants.js +1 -1
- package/lib/module/games/checkers/CheckersGame.js +1 -0
- package/lib/module/games/checkers/CheckersRules.js +1 -0
- package/lib/module/games/checkers/CheckersScene.js +1 -0
- package/lib/module/games/color-switch/ColorSwitch.js +1 -1
- package/lib/module/games/color-switch/ColorSwitchConstants.js +1 -1
- package/lib/module/games/color-switch/ColorSwitchGame.js +1 -0
- package/lib/module/games/color-switch/ColorSwitchScene.js +1 -0
- package/lib/module/games/colors-sort/ColorsSort.js +1 -1
- package/lib/module/games/colors-sort/ColorsSortConstants.js +1 -1
- package/lib/module/games/colors-sort/ColorsSortGame.js +1 -0
- package/lib/module/games/colors-sort/ColorsSortScene.js +1 -0
- package/lib/module/games/connect-em-all/ConnectEmAll.js +1 -1
- package/lib/module/games/connect-em-all/ConnectEmAllConstants.js +1 -1
- package/lib/module/games/connect-em-all/ConnectEmAllGame.js +1 -0
- package/lib/module/games/connect-em-all/ConnectEmAllScene.js +1 -0
- package/lib/module/games/crossy-road/CrossyRoad.js +1 -1
- package/lib/module/games/crossy-road/CrossyRoadCamera.js +1 -0
- package/lib/module/games/crossy-road/CrossyRoadConstants.js +1 -1
- package/lib/module/games/crossy-road/CrossyRoadGame.js +1 -0
- package/lib/module/games/crossy-road/CrossyRoadMeshes.js +1 -0
- package/lib/module/games/crossy-road/CrossyRoadPerson.js +1 -0
- package/lib/module/games/crossy-road/CrossyRoadRules.js +1 -0
- package/lib/module/games/crossy-road/CrossyRoadScene.js +1 -0
- package/lib/module/games/dino-jump/DinoJump.js +1 -1
- package/lib/module/games/dino-jump/DinoJumpConstants.js +1 -1
- package/lib/module/games/dino-jump/DinoJumpGame.js +1 -0
- package/lib/module/games/dino-jump/DinoJumpScene.js +1 -0
- package/lib/module/games/dots-and-boxes/DotsAndBoxes.js +1 -1
- package/lib/module/games/dots-and-boxes/DotsAndBoxesConstants.js +1 -1
- package/lib/module/games/dots-and-boxes/DotsAndBoxesGame.js +1 -0
- package/lib/module/games/dots-and-boxes/DotsAndBoxesScene.js +1 -0
- package/lib/module/games/falling-sticks/FallingSticks.js +1 -1
- package/lib/module/games/falling-sticks/FallingSticksConstants.js +1 -1
- package/lib/module/games/falling-sticks/FallingSticksGame.js +1 -0
- package/lib/module/games/falling-sticks/FallingSticksRules.js +1 -0
- package/lib/module/games/falling-sticks/FallingSticksScene.js +1 -0
- package/lib/module/games/find-different-number/FindDifferentNumber.js +1 -1
- package/lib/module/games/find-different-number/FindDifferentNumberConstants.js +1 -1
- package/lib/module/games/find-different-number/FindDifferentNumberGame.js +1 -0
- package/lib/module/games/find-different-number/FindDifferentNumberRules.js +1 -0
- package/lib/module/games/find-different-number/FindDifferentNumberScene.js +1 -0
- package/lib/module/games/flappy-bird/FlappyBird.js +1 -1
- package/lib/module/games/flappy-bird/FlappyBirdConstants.js +1 -1
- package/lib/module/games/flappy-bird/FlappyBirdGame.js +1 -0
- package/lib/module/games/flappy-bird/FlappyBirdScene.js +1 -0
- package/lib/module/games/fruit-merger/FruitMerger.js +1 -1
- package/lib/module/games/fruit-merger/FruitMergerConstants.js +1 -1
- package/lib/module/games/fruit-merger/FruitMergerGame.js +1 -0
- package/lib/module/games/fruit-merger/FruitMergerRules.js +1 -0
- package/lib/module/games/fruit-merger/FruitMergerScene.js +1 -0
- package/lib/module/games/fruit-ninja/FruitNinja.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaConstants.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaGame.js +1 -0
- package/lib/module/games/fruit-ninja/FruitNinjaScene.js +1 -0
- package/lib/module/games/fruit-ninja/FruitNinjaWorld.js +1 -0
- package/lib/module/games/game-2048/Game2048.js +1 -1
- package/lib/module/games/game-2048/Game2048Constants.js +1 -1
- package/lib/module/games/game-2048/Game2048Game.js +1 -0
- package/lib/module/games/game-2048/Game2048Rules.js +1 -0
- package/lib/module/games/game-2048/Game2048Scene.js +1 -0
- package/lib/module/games/knife-hit/KnifeHit.js +1 -1
- package/lib/module/games/knife-hit/KnifeHitConstants.js +1 -1
- package/lib/module/games/knife-hit/KnifeHitGame.js +1 -0
- package/lib/module/games/knife-hit/KnifeHitScene.js +1 -0
- package/lib/module/games/ludo-king/LudoKing.js +1 -1
- package/lib/module/games/ludo-king/LudoKingConstants.js +1 -1
- package/lib/module/games/ludo-king/LudoKingGame.js +1 -0
- package/lib/module/games/ludo-king/LudoKingRules.js +1 -0
- package/lib/module/games/ludo-king/LudoKingScene.js +1 -0
- package/lib/module/games/maze-runner/MazeRunner.js +1 -1
- package/lib/module/games/maze-runner/MazeRunnerConstants.js +1 -1
- package/lib/module/games/maze-runner/MazeRunnerGame.js +1 -0
- package/lib/module/games/maze-runner/MazeRunnerRules.js +1 -0
- package/lib/module/games/maze-runner/MazeRunnerScene.js +1 -0
- package/lib/module/games/memory-match/MemoryMatch.js +1 -1
- package/lib/module/games/memory-match/MemoryMatchConstants.js +1 -1
- package/lib/module/games/memory-match/MemoryMatchGame.js +1 -0
- package/lib/module/games/memory-match/MemoryMatchRules.js +1 -0
- package/lib/module/games/memory-match/MemoryMatchScene.js +1 -0
- package/lib/module/games/mine-sweeper/MineSweeper.js +1 -1
- package/lib/module/games/mine-sweeper/MineSweeperConstants.js +1 -1
- package/lib/module/games/mine-sweeper/MineSweeperGame.js +1 -0
- package/lib/module/games/mine-sweeper/MineSweeperRules.js +1 -0
- package/lib/module/games/mine-sweeper/MineSweeperScene.js +1 -0
- package/lib/module/games/mob-control/MobControl.js +1 -1
- package/lib/module/games/mob-control/MobControlConstants.js +1 -1
- package/lib/module/games/mob-control/MobControlGame.js +1 -0
- package/lib/module/games/mob-control/MobControlMeshes.js +1 -0
- package/lib/module/games/mob-control/MobControlRenderer.js +1 -0
- package/lib/module/games/mob-control/MobControlRules.js +1 -0
- package/lib/module/games/mob-control/MobControlScene.js +1 -0
- package/lib/module/games/number-search/NumberSearch.js +1 -1
- package/lib/module/games/number-search/NumberSearchNumbers.js +1 -0
- package/lib/module/games/nuts-and-bolts/NutsAndBolts.js +1 -1
- package/lib/module/games/nuts-and-bolts/NutsAndBoltsConstants.js +1 -1
- package/lib/module/games/nuts-and-bolts/NutsAndBoltsGame.js +1 -0
- package/lib/module/games/nuts-and-bolts/NutsAndBoltsRules.js +1 -0
- package/lib/module/games/nuts-and-bolts/NutsAndBoltsScene.js +1 -0
- package/lib/module/games/pac-man/PacMan.js +1 -1
- package/lib/module/games/pac-man/PacManConstants.js +1 -1
- package/lib/module/games/pac-man/PacManGame.js +1 -0
- package/lib/module/games/pac-man/PacManRules.js +1 -0
- package/lib/module/games/pac-man/PacManScene.js +1 -0
- package/lib/module/games/paper-io/PaperIo.js +1 -1
- package/lib/module/games/paper-io/PaperIoConstants.js +1 -1
- package/lib/module/games/paper-io/PaperIoGame.js +1 -0
- package/lib/module/games/paper-io/PaperIoMeshes.js +1 -0
- package/lib/module/games/paper-io/PaperIoRules.js +1 -0
- package/lib/module/games/paper-io/PaperIoScene.js +1 -0
- package/lib/module/games/penguin-run/PenguinMeshes.js +1 -0
- package/lib/module/games/penguin-run/PenguinModel.js +1 -0
- package/lib/module/games/penguin-run/PenguinRun.js +1 -0
- package/lib/module/games/penguin-run/PenguinRunConstants.js +1 -0
- package/lib/module/games/penguin-run/PenguinRunGame.js +1 -0
- package/lib/module/games/penguin-run/PenguinRunScene.js +1 -0
- package/lib/module/games/perfect-circle/PerfectCircle.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircleConstants.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircleGame.js +1 -0
- package/lib/module/games/perfect-circle/PerfectCircleRules.js +1 -0
- package/lib/module/games/perfect-circle/PerfectCircleScene.js +1 -0
- package/lib/module/games/pipe-connect/PipeConnect.js +1 -1
- package/lib/module/games/pipe-connect/PipeConnectConstants.js +1 -1
- package/lib/module/games/pipe-connect/PipeConnectGame.js +1 -0
- package/lib/module/games/pipe-connect/PipeConnectRules.js +1 -0
- package/lib/module/games/pipe-connect/PipeConnectScene.js +1 -0
- package/lib/module/games/play-with-tua/PlayWithTua.js +1 -0
- package/lib/module/games/play-with-tua/PlayWithTuaConstants.js +1 -0
- package/lib/module/games/play-with-tua/PlayWithTuaGame.js +1 -0
- package/lib/module/games/play-with-tua/PlayWithTuaModel.js +1 -0
- package/lib/module/games/play-with-tua/PlayWithTuaScene.js +1 -0
- package/lib/module/games/popit-fidget/PopitFidget.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetConstants.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetGame.js +1 -0
- package/lib/module/games/popit-fidget/PopitFidgetScene.js +1 -0
- package/lib/module/games/reversi/Reversi.js +1 -1
- package/lib/module/games/reversi/ReversiConstants.js +1 -1
- package/lib/module/games/reversi/ReversiGame.js +1 -0
- package/lib/module/games/reversi/ReversiRules.js +1 -0
- package/lib/module/games/reversi/ReversiScene.js +1 -0
- package/lib/module/games/search-grid/SearchGrid.js +1 -0
- package/lib/module/games/search-grid/SearchGridConstants.js +1 -0
- package/lib/module/games/search-grid/SearchGridGame.js +1 -0
- package/lib/module/games/search-grid/SearchGridScene.js +1 -0
- package/lib/module/games/shared/BackdropCard.js +1 -0
- package/lib/module/games/shared/EngineBackdrop.js +1 -0
- package/lib/module/games/shared/EngineBlasts.js +1 -0
- package/lib/module/games/shared/EngineBlocks.js +1 -0
- package/lib/module/games/shared/EngineControlText.js +1 -0
- package/lib/module/games/shared/EngineDice.js +1 -0
- package/lib/module/games/shared/EngineFootprint.js +1 -0
- package/lib/module/games/shared/EngineFruits.js +1 -0
- package/lib/module/games/shared/EngineGameLoader.js +1 -0
- package/lib/module/games/shared/EngineGameScreen.js +1 -0
- package/lib/module/games/shared/EngineGameWidth.js +1 -0
- package/lib/module/games/shared/EngineGameWidth.web.js +1 -0
- package/lib/module/games/shared/EngineGlyphs.js +1 -0
- package/lib/module/games/shared/EngineHud.js +1 -0
- package/lib/module/games/shared/EngineLoading.js +1 -0
- package/lib/module/games/shared/EngineMeadow.js +1 -0
- package/lib/module/games/shared/EngineMeshCache.js +1 -0
- package/lib/module/games/shared/EngineMeshes.js +1 -0
- package/lib/module/games/shared/EngineRacingChase.js +1 -0
- package/lib/module/games/shared/EngineRacingHandling.js +1 -0
- package/lib/module/games/shared/EngineReadyContext.js +1 -0
- package/lib/module/games/shared/EngineTilt.js +1 -0
- package/lib/module/games/shared/EngineTouchSurface.js +1 -0
- package/lib/module/games/shared/EngineUtils.js +1 -0
- package/lib/module/games/shared/GameActivity.js +1 -0
- package/lib/module/games/shared/GameLoading.js +1 -0
- package/lib/module/games/shared/GameLoadingTransition.js +1 -0
- package/lib/module/games/shared/ProceduralCacheVersion.js +1 -0
- package/lib/module/games/shared/useEngineGame.js +1 -0
- package/lib/module/games/shared/useGameResource.js +1 -0
- package/lib/module/games/shared/useLiveState.js +1 -0
- package/lib/module/games/sliding-numbers/SlidingNumbers.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersConstants.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersGame.js +1 -0
- package/lib/module/games/sliding-numbers/SlidingNumbersRules.js +1 -0
- package/lib/module/games/sliding-numbers/SlidingNumbersScene.js +1 -0
- package/lib/module/games/snake-3d/Snake3D.js +1 -1
- package/lib/module/games/snake-3d/Snake3DConstants.js +1 -1
- package/lib/module/games/snake-3d/Snake3DGame.js +1 -0
- package/lib/module/games/snake-3d/Snake3DMotion.js +1 -0
- package/lib/module/games/snake-3d/Snake3DRules.js +1 -0
- package/lib/module/games/snake-3d/Snake3DScene.js +1 -0
- package/lib/module/games/snakes-and-ladders/SnakesAndLadders.js +1 -1
- package/lib/module/games/snakes-and-ladders/SnakesAndLaddersConstants.js +1 -1
- package/lib/module/games/snakes-and-ladders/SnakesAndLaddersGame.js +1 -0
- package/lib/module/games/snakes-and-ladders/SnakesAndLaddersScene.js +1 -0
- package/lib/module/games/space-fighter/SpaceFighter.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighterConstants.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighterGame.js +1 -0
- package/lib/module/games/space-fighter/SpaceFighterScene.js +1 -0
- package/lib/module/games/spider-solitaire/SpiderSolitaire.js +1 -1
- package/lib/module/games/spider-solitaire/SpiderSolitaireConstants.js +1 -1
- package/lib/module/games/spider-solitaire/SpiderSolitaireGame.js +1 -0
- package/lib/module/games/spider-solitaire/SpiderSolitaireRules.js +1 -0
- package/lib/module/games/spider-solitaire/SpiderSolitaireScene.js +1 -0
- package/lib/module/games/stack-tower/StackTower.js +1 -1
- package/lib/module/games/stack-tower/StackTowerConstants.js +1 -1
- package/lib/module/games/stack-tower/StackTowerGame.js +1 -0
- package/lib/module/games/stack-tower/StackTowerScene.js +1 -0
- package/lib/module/games/sudoku/Sudoku.js +1 -1
- package/lib/module/games/sudoku/SudokuConstants.js +1 -1
- package/lib/module/games/sudoku/SudokuGame.js +1 -0
- package/lib/module/games/sudoku/SudokuRules.js +1 -0
- package/lib/module/games/sudoku/SudokuScene.js +1 -0
- package/lib/module/games/tangram/Tangram.js +1 -1
- package/lib/module/games/tangram/TangramConstants.js +1 -1
- package/lib/module/games/tangram/TangramGame.js +1 -0
- package/lib/module/games/tangram/TangramRules.js +1 -0
- package/lib/module/games/tangram/TangramScene.js +1 -0
- package/lib/module/games/tank-1990/Tank1990.js +1 -1
- package/lib/module/games/tank-1990/Tank1990Constants.js +1 -1
- package/lib/module/games/tank-1990/Tank1990Game.js +1 -0
- package/lib/module/games/tank-1990/Tank1990Rules.js +1 -0
- package/lib/module/games/tank-1990/Tank1990Scene.js +1 -0
- package/lib/module/games/tic-tac-toe/TicTacToe.js +1 -1
- package/lib/module/games/tic-tac-toe/TicTacToeConstants.js +1 -1
- package/lib/module/games/tic-tac-toe/TicTacToeGame.js +1 -0
- package/lib/module/games/tic-tac-toe/TicTacToeRules.js +1 -0
- package/lib/module/games/tic-tac-toe/TicTacToeScene.js +1 -0
- package/lib/module/games/tile-home/TileHome.js +1 -1
- package/lib/module/games/tile-home/TileHomeConstants.js +1 -1
- package/lib/module/games/tile-home/TileHomeGame.js +1 -0
- package/lib/module/games/tile-home/TileHomeScene.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHunt.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHuntConstants.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHuntControls.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHuntGame.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHuntMeshes.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHuntModel.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHuntRules.js +1 -0
- package/lib/module/games/treasure-hunt/TreasureHuntScene.js +1 -0
- package/lib/module/games/whack-a-mole/WhackAMole.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleConstants.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleGame.js +1 -0
- package/lib/module/games/whack-a-mole/WhackAMoleScene.js +1 -0
- package/lib/module/games/word-search/WordSearch.js +1 -1
- package/lib/module/games/word-search/WordSearchWords.js +1 -0
- package/lib/module/helpers/GamePatternData.js +1 -0
- package/lib/module/helpers/GameSettingsModal.js +1 -1
- package/lib/module/helpers/GameTheme.js +1 -0
- package/lib/module/helpers/IconPaths.js +1 -0
- package/lib/module/helpers/index.js +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/services/GameAssetLoader.js +1 -0
- package/lib/module/services/GameAssets.js +1 -0
- package/lib/module/services/GameLoaders.js +1 -0
- package/lib/module/services/GamesConstants.js +1 -1
- package/lib/module/services/GamesMetadata.js +1 -1
- package/lib/module/services/GamesService.js +1 -1
- package/lib/module/services/HapticsService.js +1 -1
- package/lib/module/services/ScoringService.js +1 -1
- package/lib/module/services/SfxSources.js +1 -0
- package/lib/module/services/SoundsService.js +1 -1
- package/lib/module/services/ThemeService.js +1 -0
- package/lib/module/services/UtilsService.js +1 -1
- package/lib/module/services/index.js +1 -1
- package/lib/typescript/src/games/arrows/Arrows.d.ts +1 -3
- package/lib/typescript/src/games/arrows/ArrowsConstants.d.ts +48 -32
- package/lib/typescript/src/games/arrows/ArrowsGame.d.ts +60 -0
- package/lib/typescript/src/games/arrows/ArrowsScene.d.ts +67 -0
- package/lib/typescript/src/games/balloon-blaster/BalloonBlaster.d.ts +1 -3
- package/lib/typescript/src/games/balloon-blaster/BalloonBlasterConstants.d.ts +39 -131
- package/lib/typescript/src/games/balloon-blaster/BalloonBlasterGame.d.ts +57 -0
- package/lib/typescript/src/games/balloon-blaster/BalloonBlasterPhysics.d.ts +16 -0
- package/lib/typescript/src/games/balloon-blaster/BalloonBlasterScene.d.ts +31 -0
- package/lib/typescript/src/games/bike-racing/BikeMeshes.d.ts +14 -0
- package/lib/typescript/src/games/bike-racing/BikeRacing.d.ts +2 -1
- package/lib/typescript/src/games/bike-racing/BikeRacingConstants.d.ts +38 -29
- package/lib/typescript/src/games/bike-racing/BikeRacingGame.d.ts +104 -0
- package/lib/typescript/src/games/bike-racing/BikeRacingScene.d.ts +25 -0
- package/lib/typescript/src/games/block-blast/BlockBlast.d.ts +1 -3
- package/lib/typescript/src/games/block-blast/BlockBlastConstants.d.ts +48 -30
- package/lib/typescript/src/games/block-blast/BlockBlastGame.d.ts +77 -0
- package/lib/typescript/src/games/block-blast/BlockBlastScene.d.ts +36 -0
- package/lib/typescript/src/games/block-breaker/BlockBreaker.d.ts +1 -3
- package/lib/typescript/src/games/block-breaker/BlockBreakerConstants.d.ts +88 -35
- package/lib/typescript/src/games/block-breaker/BlockBreakerGame.d.ts +82 -0
- package/lib/typescript/src/games/block-breaker/BlockBreakerScene.d.ts +48 -0
- package/lib/typescript/src/games/bluk/Bluk.d.ts +1 -3
- package/lib/typescript/src/games/bluk/BlukConstants.d.ts +65 -54
- package/lib/typescript/src/games/bluk/BlukGame.d.ts +65 -0
- package/lib/typescript/src/games/bluk/BlukRules.d.ts +51 -0
- package/lib/typescript/src/games/bluk/BlukScene.d.ts +54 -0
- package/lib/typescript/src/games/bubble-shooter/BubbleShooter.d.ts +1 -3
- package/lib/typescript/src/games/bubble-shooter/BubbleShooterConstants.d.ts +56 -24
- package/lib/typescript/src/games/bubble-shooter/BubbleShooterGame.d.ts +70 -0
- package/lib/typescript/src/games/bubble-shooter/BubbleShooterScene.d.ts +26 -0
- package/lib/typescript/src/games/candy-crush/CandyCrush.d.ts +1 -3
- package/lib/typescript/src/games/candy-crush/CandyCrushConstants.d.ts +63 -32
- package/lib/typescript/src/games/candy-crush/CandyCrushGame.d.ts +65 -0
- package/lib/typescript/src/games/candy-crush/CandyCrushScene.d.ts +28 -0
- package/lib/typescript/src/games/car-racing/CarMeshes.d.ts +44 -0
- package/lib/typescript/src/games/car-racing/CarRacing.d.ts +2 -1
- package/lib/typescript/src/games/car-racing/CarRacingConstants.d.ts +60 -29
- package/lib/typescript/src/games/car-racing/CarRacingFacade.d.ts +5 -0
- package/lib/typescript/src/games/car-racing/CarRacingGame.d.ts +96 -0
- package/lib/typescript/src/games/car-racing/CarRacingScene.d.ts +97 -0
- package/lib/typescript/src/games/car-racing/CarRacingScenery.d.ts +22 -0
- package/lib/typescript/src/games/chameleon-run/ChameleonRun.d.ts +1 -3
- package/lib/typescript/src/games/chameleon-run/ChameleonRunBackdrop.d.ts +14 -0
- package/lib/typescript/src/games/chameleon-run/ChameleonRunConstants.d.ts +44 -42
- package/lib/typescript/src/games/chameleon-run/ChameleonRunGame.d.ts +60 -0
- package/lib/typescript/src/games/chameleon-run/ChameleonRunMeshes.d.ts +20 -0
- package/lib/typescript/src/games/chameleon-run/ChameleonRunRules.d.ts +52 -0
- package/lib/typescript/src/games/chameleon-run/ChameleonRunScene.d.ts +44 -0
- package/lib/typescript/src/games/checkers/Checkers.d.ts +1 -3
- package/lib/typescript/src/games/checkers/CheckersAI.d.ts +11 -0
- package/lib/typescript/src/games/checkers/CheckersConstants.d.ts +32 -72
- package/lib/typescript/src/games/checkers/CheckersGame.d.ts +56 -0
- package/lib/typescript/src/games/checkers/CheckersRules.d.ts +48 -0
- package/lib/typescript/src/games/checkers/CheckersScene.d.ts +41 -0
- package/lib/typescript/src/games/color-switch/ColorSwitch.d.ts +1 -3
- package/lib/typescript/src/games/color-switch/ColorSwitchConstants.d.ts +27 -31
- package/lib/typescript/src/games/color-switch/ColorSwitchGame.d.ts +61 -0
- package/lib/typescript/src/games/color-switch/ColorSwitchScene.d.ts +43 -0
- package/lib/typescript/src/games/colors-sort/ColorsSort.d.ts +1 -3
- package/lib/typescript/src/games/colors-sort/ColorsSortConstants.d.ts +37 -44
- package/lib/typescript/src/games/colors-sort/ColorsSortGame.d.ts +41 -0
- package/lib/typescript/src/games/colors-sort/ColorsSortScene.d.ts +33 -0
- package/lib/typescript/src/games/connect-em-all/ConnectEmAll.d.ts +1 -3
- package/lib/typescript/src/games/connect-em-all/ConnectEmAllConstants.d.ts +43 -17
- package/lib/typescript/src/games/connect-em-all/ConnectEmAllGame.d.ts +54 -0
- package/lib/typescript/src/games/connect-em-all/ConnectEmAllScene.d.ts +49 -0
- package/lib/typescript/src/games/crossy-road/CrossyRoad.d.ts +1 -3
- package/lib/typescript/src/games/crossy-road/CrossyRoadCamera.d.ts +14 -0
- package/lib/typescript/src/games/crossy-road/CrossyRoadConstants.d.ts +82 -50
- package/lib/typescript/src/games/crossy-road/CrossyRoadGame.d.ts +64 -0
- package/lib/typescript/src/games/crossy-road/CrossyRoadMeshes.d.ts +16 -0
- package/lib/typescript/src/games/crossy-road/CrossyRoadPerson.d.ts +10 -0
- package/lib/typescript/src/games/crossy-road/CrossyRoadRules.d.ts +36 -0
- package/lib/typescript/src/games/crossy-road/CrossyRoadScene.d.ts +38 -0
- package/lib/typescript/src/games/dino-jump/DinoJump.d.ts +1 -3
- package/lib/typescript/src/games/dino-jump/DinoJumpConstants.d.ts +48 -72
- package/lib/typescript/src/games/dino-jump/DinoJumpGame.d.ts +60 -0
- package/lib/typescript/src/games/dino-jump/DinoJumpScene.d.ts +35 -0
- package/lib/typescript/src/games/dots-and-boxes/DotsAndBoxes.d.ts +1 -3
- package/lib/typescript/src/games/dots-and-boxes/DotsAndBoxesConstants.d.ts +31 -36
- package/lib/typescript/src/games/dots-and-boxes/DotsAndBoxesGame.d.ts +44 -0
- package/lib/typescript/src/games/dots-and-boxes/DotsAndBoxesScene.d.ts +31 -0
- package/lib/typescript/src/games/falling-sticks/FallingSticks.d.ts +1 -3
- package/lib/typescript/src/games/falling-sticks/FallingSticksConstants.d.ts +31 -43
- package/lib/typescript/src/games/falling-sticks/FallingSticksGame.d.ts +42 -0
- package/lib/typescript/src/games/falling-sticks/FallingSticksRules.d.ts +36 -0
- package/lib/typescript/src/games/falling-sticks/FallingSticksScene.d.ts +26 -0
- package/lib/typescript/src/games/find-different-number/FindDifferentNumber.d.ts +1 -3
- package/lib/typescript/src/games/find-different-number/FindDifferentNumberConstants.d.ts +33 -29
- package/lib/typescript/src/games/find-different-number/FindDifferentNumberGame.d.ts +43 -0
- package/lib/typescript/src/games/find-different-number/FindDifferentNumberRules.d.ts +8 -0
- package/lib/typescript/src/games/find-different-number/FindDifferentNumberScene.d.ts +31 -0
- package/lib/typescript/src/games/flappy-bird/FlappyBird.d.ts +1 -3
- package/lib/typescript/src/games/flappy-bird/FlappyBirdConstants.d.ts +39 -35
- package/lib/typescript/src/games/flappy-bird/FlappyBirdGame.d.ts +66 -0
- package/lib/typescript/src/games/flappy-bird/FlappyBirdScene.d.ts +41 -0
- package/lib/typescript/src/games/fruit-merger/FruitMerger.d.ts +1 -3
- package/lib/typescript/src/games/fruit-merger/FruitMergerConstants.d.ts +71 -44
- package/lib/typescript/src/games/fruit-merger/FruitMergerGame.d.ts +63 -0
- package/lib/typescript/src/games/fruit-merger/FruitMergerRules.d.ts +39 -0
- package/lib/typescript/src/games/fruit-merger/FruitMergerScene.d.ts +49 -0
- package/lib/typescript/src/games/fruit-ninja/FruitNinja.d.ts +1 -3
- package/lib/typescript/src/games/fruit-ninja/FruitNinjaConstants.d.ts +51 -76
- package/lib/typescript/src/games/fruit-ninja/FruitNinjaGame.d.ts +76 -0
- package/lib/typescript/src/games/fruit-ninja/FruitNinjaScene.d.ts +52 -0
- package/lib/typescript/src/games/fruit-ninja/FruitNinjaWorld.d.ts +8 -0
- package/lib/typescript/src/games/game-2048/Game2048.d.ts +1 -3
- package/lib/typescript/src/games/game-2048/Game2048Constants.d.ts +25 -120
- package/lib/typescript/src/games/game-2048/Game2048Game.d.ts +45 -0
- package/lib/typescript/src/games/game-2048/Game2048Rules.d.ts +32 -0
- package/lib/typescript/src/games/game-2048/Game2048Scene.d.ts +34 -0
- package/lib/typescript/src/games/knife-hit/KnifeHit.d.ts +1 -3
- package/lib/typescript/src/games/knife-hit/KnifeHitConstants.d.ts +41 -49
- package/lib/typescript/src/games/knife-hit/KnifeHitGame.d.ts +49 -0
- package/lib/typescript/src/games/knife-hit/KnifeHitScene.d.ts +37 -0
- package/lib/typescript/src/games/ludo-king/LudoKing.d.ts +1 -3
- package/lib/typescript/src/games/ludo-king/LudoKingConstants.d.ts +50 -28
- package/lib/typescript/src/games/ludo-king/LudoKingGame.d.ts +40 -0
- package/lib/typescript/src/games/ludo-king/LudoKingRules.d.ts +42 -0
- package/lib/typescript/src/games/ludo-king/LudoKingScene.d.ts +53 -0
- package/lib/typescript/src/games/maze-runner/MazeRunner.d.ts +1 -3
- package/lib/typescript/src/games/maze-runner/MazeRunnerConstants.d.ts +34 -10
- package/lib/typescript/src/games/maze-runner/MazeRunnerGame.d.ts +44 -0
- package/lib/typescript/src/games/maze-runner/MazeRunnerRules.d.ts +34 -0
- package/lib/typescript/src/games/maze-runner/MazeRunnerScene.d.ts +29 -0
- package/lib/typescript/src/games/memory-match/MemoryMatch.d.ts +1 -3
- package/lib/typescript/src/games/memory-match/MemoryMatchConstants.d.ts +42 -42
- package/lib/typescript/src/games/memory-match/MemoryMatchGame.d.ts +53 -0
- package/lib/typescript/src/games/memory-match/MemoryMatchRules.d.ts +14 -0
- package/lib/typescript/src/games/memory-match/MemoryMatchScene.d.ts +35 -0
- package/lib/typescript/src/games/mine-sweeper/MineSweeper.d.ts +1 -3
- package/lib/typescript/src/games/mine-sweeper/MineSweeperConstants.d.ts +43 -82
- package/lib/typescript/src/games/mine-sweeper/MineSweeperGame.d.ts +59 -0
- package/lib/typescript/src/games/mine-sweeper/MineSweeperRules.d.ts +18 -0
- package/lib/typescript/src/games/mine-sweeper/MineSweeperScene.d.ts +23 -0
- package/lib/typescript/src/games/mob-control/MobControl.d.ts +1 -3
- package/lib/typescript/src/games/mob-control/MobControlConstants.d.ts +99 -85
- package/lib/typescript/src/games/mob-control/MobControlGame.d.ts +45 -0
- package/lib/typescript/src/games/mob-control/MobControlMeshes.d.ts +2 -0
- package/lib/typescript/src/games/mob-control/MobControlRenderer.d.ts +20 -0
- package/lib/typescript/src/games/mob-control/MobControlRules.d.ts +68 -0
- package/lib/typescript/src/games/mob-control/MobControlScene.d.ts +58 -0
- package/lib/typescript/src/games/number-search/NumberSearch.d.ts +1 -3
- package/lib/typescript/src/games/number-search/NumberSearchNumbers.d.ts +1 -0
- package/lib/typescript/src/games/nuts-and-bolts/NutsAndBolts.d.ts +1 -3
- package/lib/typescript/src/games/nuts-and-bolts/NutsAndBoltsConstants.d.ts +27 -79
- package/lib/typescript/src/games/nuts-and-bolts/NutsAndBoltsGame.d.ts +56 -0
- package/lib/typescript/src/games/nuts-and-bolts/NutsAndBoltsRules.d.ts +65 -0
- package/lib/typescript/src/games/nuts-and-bolts/NutsAndBoltsScene.d.ts +48 -0
- package/lib/typescript/src/games/pac-man/PacMan.d.ts +1 -3
- package/lib/typescript/src/games/pac-man/PacManConstants.d.ts +66 -106
- package/lib/typescript/src/games/pac-man/PacManGame.d.ts +48 -0
- package/lib/typescript/src/games/pac-man/PacManRules.d.ts +52 -0
- package/lib/typescript/src/games/pac-man/PacManScene.d.ts +44 -0
- package/lib/typescript/src/games/paper-io/PaperIo.d.ts +1 -3
- package/lib/typescript/src/games/paper-io/PaperIoConstants.d.ts +60 -40
- package/lib/typescript/src/games/paper-io/PaperIoGame.d.ts +49 -0
- package/lib/typescript/src/games/paper-io/PaperIoMeshes.d.ts +13 -0
- package/lib/typescript/src/games/paper-io/PaperIoRules.d.ts +71 -0
- package/lib/typescript/src/games/paper-io/PaperIoScene.d.ts +39 -0
- package/lib/typescript/src/games/penguin-run/PenguinMeshes.d.ts +9 -0
- package/lib/typescript/src/games/penguin-run/PenguinModel.d.ts +42 -0
- package/lib/typescript/src/games/penguin-run/PenguinRun.d.ts +1 -0
- package/lib/typescript/src/games/penguin-run/PenguinRunConstants.d.ts +58 -0
- package/lib/typescript/src/games/penguin-run/PenguinRunGame.d.ts +64 -0
- package/lib/typescript/src/games/penguin-run/PenguinRunScene.d.ts +65 -0
- package/lib/typescript/src/games/perfect-circle/PerfectCircle.d.ts +1 -3
- package/lib/typescript/src/games/perfect-circle/PerfectCircleConstants.d.ts +23 -45
- package/lib/typescript/src/games/perfect-circle/PerfectCircleGame.d.ts +40 -0
- package/lib/typescript/src/games/perfect-circle/PerfectCircleRules.d.ts +55 -0
- package/lib/typescript/src/games/perfect-circle/PerfectCircleScene.d.ts +32 -0
- package/lib/typescript/src/games/pipe-connect/PipeConnect.d.ts +1 -3
- package/lib/typescript/src/games/pipe-connect/PipeConnectConstants.d.ts +36 -32
- package/lib/typescript/src/games/pipe-connect/PipeConnectGame.d.ts +40 -0
- package/lib/typescript/src/games/pipe-connect/PipeConnectRules.d.ts +16 -0
- package/lib/typescript/src/games/pipe-connect/PipeConnectScene.d.ts +28 -0
- package/lib/typescript/src/games/play-with-tua/PlayWithTua.d.ts +2 -0
- package/lib/typescript/src/games/play-with-tua/PlayWithTuaConstants.d.ts +64 -0
- package/lib/typescript/src/games/play-with-tua/PlayWithTuaGame.d.ts +34 -0
- package/lib/typescript/src/games/play-with-tua/PlayWithTuaModel.d.ts +9 -0
- package/lib/typescript/src/games/play-with-tua/PlayWithTuaScene.d.ts +13 -0
- package/lib/typescript/src/games/popit-fidget/PopitFidget.d.ts +1 -4
- package/lib/typescript/src/games/popit-fidget/PopitFidgetConstants.d.ts +25 -36
- package/lib/typescript/src/games/popit-fidget/PopitFidgetGame.d.ts +37 -0
- package/lib/typescript/src/games/popit-fidget/PopitFidgetScene.d.ts +19 -0
- package/lib/typescript/src/games/reversi/Reversi.d.ts +1 -3
- package/lib/typescript/src/games/reversi/ReversiConstants.d.ts +31 -62
- package/lib/typescript/src/games/reversi/ReversiGame.d.ts +54 -0
- package/lib/typescript/src/games/reversi/ReversiRules.d.ts +22 -0
- package/lib/typescript/src/games/reversi/ReversiScene.d.ts +27 -0
- package/lib/typescript/src/games/search-grid/SearchGrid.d.ts +20 -0
- package/lib/typescript/src/games/search-grid/SearchGridConstants.d.ts +60 -0
- package/lib/typescript/src/games/search-grid/SearchGridGame.d.ts +52 -0
- package/lib/typescript/src/games/search-grid/SearchGridScene.d.ts +43 -0
- package/lib/typescript/src/games/shared/BackdropCard.d.ts +2 -0
- package/lib/typescript/src/games/shared/EngineBackdrop.d.ts +19 -0
- package/lib/typescript/src/games/shared/EngineBlasts.d.ts +26 -0
- package/lib/typescript/src/games/shared/EngineBlocks.d.ts +19 -0
- package/lib/typescript/src/games/shared/EngineControlText.d.ts +2 -0
- package/lib/typescript/src/games/shared/EngineDice.d.ts +24 -0
- package/lib/typescript/src/games/shared/EngineFootprint.d.ts +17 -0
- package/lib/typescript/src/games/shared/EngineFruits.d.ts +27 -0
- package/lib/typescript/src/games/shared/EngineGameLoader.d.ts +4 -0
- package/lib/typescript/src/games/shared/EngineGameScreen.d.ts +48 -0
- package/lib/typescript/src/games/shared/EngineGameWidth.d.ts +3 -0
- package/lib/typescript/src/games/shared/EngineGameWidth.web.d.ts +3 -0
- package/lib/typescript/src/games/shared/EngineGlyphs.d.ts +15 -0
- package/lib/typescript/src/games/shared/EngineHud.d.ts +138 -0
- package/lib/typescript/src/games/shared/EngineLoading.d.ts +77 -0
- package/lib/typescript/src/games/shared/EngineMeadow.d.ts +90 -0
- package/lib/typescript/src/games/shared/EngineMeshCache.d.ts +3 -0
- package/lib/typescript/src/games/shared/EngineMeshes.d.ts +3 -0
- package/lib/typescript/src/games/shared/EngineRacingChase.d.ts +11 -0
- package/lib/typescript/src/games/shared/EngineRacingHandling.d.ts +15 -0
- package/lib/typescript/src/games/shared/EngineReadyContext.d.ts +2 -0
- package/lib/typescript/src/games/shared/EngineTilt.d.ts +19 -0
- package/lib/typescript/src/games/shared/EngineTouchSurface.d.ts +20 -0
- package/lib/typescript/src/games/shared/EngineUtils.d.ts +18 -0
- package/lib/typescript/src/games/shared/GameActivity.d.ts +3 -0
- package/lib/typescript/src/games/shared/GameLoading.d.ts +14 -0
- package/lib/typescript/src/games/shared/GameLoadingTransition.d.ts +9 -0
- package/lib/typescript/src/games/shared/ProceduralCacheVersion.d.ts +1 -0
- package/lib/typescript/src/games/shared/useEngineGame.d.ts +69 -0
- package/lib/typescript/src/games/shared/useGameResource.d.ts +2 -0
- package/lib/typescript/src/games/shared/useLiveState.d.ts +4 -0
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbers.d.ts +1 -3
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbersConstants.d.ts +32 -40
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbersGame.d.ts +48 -0
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbersRules.d.ts +22 -0
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbersScene.d.ts +30 -0
- package/lib/typescript/src/games/snake-3d/Snake3D.d.ts +1 -3
- package/lib/typescript/src/games/snake-3d/Snake3DConstants.d.ts +31 -68
- package/lib/typescript/src/games/snake-3d/Snake3DGame.d.ts +42 -0
- package/lib/typescript/src/games/snake-3d/Snake3DMotion.d.ts +3 -0
- package/lib/typescript/src/games/snake-3d/Snake3DRules.d.ts +42 -0
- package/lib/typescript/src/games/snake-3d/Snake3DScene.d.ts +35 -0
- package/lib/typescript/src/games/snakes-and-ladders/SnakesAndLadders.d.ts +1 -3
- package/lib/typescript/src/games/snakes-and-ladders/SnakesAndLaddersConstants.d.ts +58 -50
- package/lib/typescript/src/games/snakes-and-ladders/SnakesAndLaddersGame.d.ts +45 -0
- package/lib/typescript/src/games/snakes-and-ladders/SnakesAndLaddersScene.d.ts +50 -0
- package/lib/typescript/src/games/space-fighter/SpaceFighter.d.ts +1 -3
- package/lib/typescript/src/games/space-fighter/SpaceFighterConstants.d.ts +33 -23
- package/lib/typescript/src/games/space-fighter/SpaceFighterGame.d.ts +58 -0
- package/lib/typescript/src/games/space-fighter/SpaceFighterScene.d.ts +51 -0
- package/lib/typescript/src/games/spider-solitaire/SpiderSolitaire.d.ts +1 -3
- package/lib/typescript/src/games/spider-solitaire/SpiderSolitaireConstants.d.ts +52 -35
- package/lib/typescript/src/games/spider-solitaire/SpiderSolitaireGame.d.ts +67 -0
- package/lib/typescript/src/games/spider-solitaire/SpiderSolitaireRules.d.ts +39 -0
- package/lib/typescript/src/games/spider-solitaire/SpiderSolitaireScene.d.ts +60 -0
- package/lib/typescript/src/games/stack-tower/StackTower.d.ts +1 -3
- package/lib/typescript/src/games/stack-tower/StackTowerConstants.d.ts +31 -23
- package/lib/typescript/src/games/stack-tower/StackTowerGame.d.ts +58 -0
- package/lib/typescript/src/games/stack-tower/StackTowerScene.d.ts +27 -0
- package/lib/typescript/src/games/sudoku/Sudoku.d.ts +1 -3
- package/lib/typescript/src/games/sudoku/SudokuConstants.d.ts +50 -55
- package/lib/typescript/src/games/sudoku/SudokuGame.d.ts +56 -0
- package/lib/typescript/src/games/sudoku/SudokuRules.d.ts +23 -0
- package/lib/typescript/src/games/sudoku/SudokuScene.d.ts +44 -0
- package/lib/typescript/src/games/tangram/Tangram.d.ts +1 -3
- package/lib/typescript/src/games/tangram/TangramConstants.d.ts +33 -52
- package/lib/typescript/src/games/tangram/TangramGame.d.ts +68 -0
- package/lib/typescript/src/games/tangram/TangramRules.d.ts +61 -0
- package/lib/typescript/src/games/tangram/TangramScene.d.ts +42 -0
- package/lib/typescript/src/games/tank-1990/Tank1990.d.ts +1 -3
- package/lib/typescript/src/games/tank-1990/Tank1990Constants.d.ts +44 -127
- package/lib/typescript/src/games/tank-1990/Tank1990Game.d.ts +50 -0
- package/lib/typescript/src/games/tank-1990/Tank1990Rules.d.ts +67 -0
- package/lib/typescript/src/games/tank-1990/Tank1990Scene.d.ts +38 -0
- package/lib/typescript/src/games/tic-tac-toe/TicTacToe.d.ts +1 -3
- package/lib/typescript/src/games/tic-tac-toe/TicTacToeConstants.d.ts +35 -72
- package/lib/typescript/src/games/tic-tac-toe/TicTacToeGame.d.ts +54 -0
- package/lib/typescript/src/games/tic-tac-toe/TicTacToeRules.d.ts +10 -0
- package/lib/typescript/src/games/tic-tac-toe/TicTacToeScene.d.ts +26 -0
- package/lib/typescript/src/games/tile-home/TileHome.d.ts +1 -3
- package/lib/typescript/src/games/tile-home/TileHomeConstants.d.ts +72 -70
- package/lib/typescript/src/games/tile-home/TileHomeGame.d.ts +72 -0
- package/lib/typescript/src/games/tile-home/TileHomeScene.d.ts +28 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHunt.d.ts +3 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHuntConstants.d.ts +144 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHuntControls.d.ts +75 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHuntGame.d.ts +41 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHuntMeshes.d.ts +26 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHuntModel.d.ts +57 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHuntRules.d.ts +198 -0
- package/lib/typescript/src/games/treasure-hunt/TreasureHuntScene.d.ts +40 -0
- package/lib/typescript/src/games/whack-a-mole/WhackAMole.d.ts +1 -3
- package/lib/typescript/src/games/whack-a-mole/WhackAMoleConstants.d.ts +35 -45
- package/lib/typescript/src/games/whack-a-mole/WhackAMoleGame.d.ts +51 -0
- package/lib/typescript/src/games/whack-a-mole/WhackAMoleScene.d.ts +31 -0
- package/lib/typescript/src/games/word-search/WordSearch.d.ts +1 -3
- package/lib/typescript/src/games/word-search/WordSearchWords.d.ts +1 -0
- package/lib/typescript/src/helpers/GamePatternData.d.ts +46 -0
- package/lib/typescript/src/helpers/GameSettingsModal.d.ts +1 -1
- package/lib/typescript/src/helpers/GameTheme.d.ts +18 -0
- package/lib/typescript/src/helpers/IconPaths.d.ts +4 -0
- package/lib/typescript/src/helpers/index.d.ts +1 -19
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/services/GameAssetLoader.d.ts +32 -0
- package/lib/typescript/src/services/GameAssets.d.ts +11 -0
- package/lib/typescript/src/services/GameLoaders.d.ts +18 -0
- package/lib/typescript/src/services/GamesConstants.d.ts +11 -0
- package/lib/typescript/src/services/GamesMetadata.d.ts +2 -0
- package/lib/typescript/src/services/HapticsService.d.ts +1 -1
- package/lib/typescript/src/services/SfxSources.d.ts +79 -0
- package/lib/typescript/src/services/SoundsService.d.ts +487 -1566
- package/lib/typescript/src/services/ThemeService.d.ts +117 -0
- package/lib/typescript/src/services/UtilsService.d.ts +20 -2
- package/lib/typescript/src/services/index.d.ts +3 -0
- package/lib/web/assets/005ea2045b17-explorer.glb +0 -0
- package/lib/web/assets/01e2f0a0bbf6-hurt.wav +0 -0
- package/lib/web/assets/01fc0ecf658c-explorer-atlas.png +0 -0
- package/lib/web/assets/029329b2c7c0-asphalt.png +0 -0
- package/lib/web/assets/0376bda32be3-robot.wav +0 -0
- package/lib/web/assets/0719fb0bb38e-soft_glow.png +0 -0
- package/lib/web/assets/0b21278bffba-boing.wav +0 -0
- package/lib/web/assets/1333c9d1273c-flip_disc.wav +0 -0
- package/lib/web/assets/15785f62ee5f-time_up.wav +0 -0
- package/lib/web/assets/177f00502e08-bonus.wav +0 -0
- package/lib/web/assets/19e47dcfda1f-pling.wav +0 -0
- package/lib/web/assets/1a677e0f7f6c-laugh.wav +0 -0
- package/lib/web/assets/1ad2914478b1-eat.wav +0 -0
- package/lib/web/assets/1b0d703ddd1a-dance.wav +0 -0
- package/lib/web/assets/1e4330fddd74-chime.wav +0 -0
- package/lib/web/assets/2432a97b0af1-cannon.wav +0 -0
- package/lib/web/assets/2574370d6aa0-blocked.wav +0 -0
- package/lib/web/assets/2699065037ad-select.wav +0 -0
- package/lib/web/assets/28d30f53ad73-ladder.wav +0 -0
- package/lib/web/assets/2c1ec05270b2-point.wav +0 -0
- package/lib/web/assets/2e1dd99a0213-tick.wav +0 -0
- package/lib/web/assets/3084575cecdb-card_flip.wav +0 -0
- package/lib/web/assets/308bc31b6af5-engine.wav +0 -0
- package/lib/web/assets/336d63b739b5-combo.wav +0 -0
- package/lib/web/assets/3a369e2596e4-clash.wav +0 -0
- package/lib/web/assets/3a816e20212f-capture.wav +0 -0
- package/lib/web/assets/40240217810a-nitro.wav +0 -0
- package/lib/web/assets/46edaa54d1ea-crunch.wav +0 -0
- package/lib/web/assets/501994226995-coin.wav +0 -0
- package/lib/web/assets/5525d7f6a4b8-rotate.wav +0 -0
- package/lib/web/assets/5e816e1f0929-dice_roll.wav +0 -0
- package/lib/web/assets/60e2dec3cf41-deselect.wav +0 -0
- package/lib/web/assets/6ab86ea29e5c-six.wav +0 -0
- package/lib/web/assets/6da3b101926d-merge.wav +0 -0
- package/lib/web/assets/6e686dea513c-bark.jpg +0 -0
- package/lib/web/assets/6ff9a6a13714-limestone.jpg +0 -0
- package/lib/web/assets/735c4a1cd22e-invalid.wav +0 -0
- package/lib/web/assets/73f75c35ff5d-snake.wav +0 -0
- package/lib/web/assets/7506e3efe264-catch.wav +0 -0
- package/lib/web/assets/76493a2ada2d-ad_bolt.png +0 -0
- package/lib/web/assets/793abe620201-card_place.wav +0 -0
- package/lib/web/assets/7da09c57f52d-facade.png +0 -0
- package/lib/web/assets/7e1a902176f6-pine.png +0 -0
- package/lib/web/assets/7eb943b85c21-play-with-tua.glb +0 -0
- package/lib/web/assets/837d43c06dba-ad_bubbles.png +0 -0
- package/lib/web/assets/84f1a7dfa368-game_over.wav +0 -0
- package/lib/web/assets/850e26ce3b0a-flap.wav +0 -0
- package/lib/web/assets/854b31683cb2-draw.wav +0 -0
- package/lib/web/assets/8616150393b7-error.wav +0 -0
- package/lib/web/assets/87cc6d503ec6-river.jpg +0 -0
- package/lib/web/assets/88755845922c-hop.wav +0 -0
- package/lib/web/assets/8ec8f469492d-chomp_alt.wav +0 -0
- package/lib/web/assets/8f17f89b138c-pew.wav +0 -0
- package/lib/web/assets/9210a24472d1-place.wav +0 -0
- package/lib/web/assets/930d833ebf89-splash.wav +0 -0
- package/lib/web/assets/970f7c59265d-swoosh.wav +0 -0
- package/lib/web/assets/9900b8d1b6ad-flag.wav +0 -0
- package/lib/web/assets/9ab04403898b-clang.wav +0 -0
- package/lib/web/assets/9d8b97a10d45-drop.wav +0 -0
- package/lib/web/assets/9d9c02ddc7ed-boom.wav +0 -0
- package/lib/web/assets/9e1b5114d56d-pop_soft.wav +0 -0
- package/lib/web/assets/a01f22d6dbb3-thud.wav +0 -0
- package/lib/web/assets/a44a1cf1a1a8-bump.wav +0 -0
- package/lib/web/assets/a76940a48c68-hit.wav +0 -0
- package/lib/web/assets/a98ddb724460-leaves.png +0 -0
- package/lib/web/assets/aa0960e8bee6-footstep_run.wav +0 -0
- package/lib/web/assets/aa570c9d3e15-star.wav +0 -0
- package/lib/web/assets/aacb999f3c49-tock.wav +0 -0
- package/lib/web/assets/aae0c16c5e89-reveal.wav +0 -0
- package/lib/web/assets/ab37cd128509-click.wav +0 -0
- package/lib/web/assets/b0bc66f49005-warning.wav +0 -0
- package/lib/web/assets/b1edd756ac43-zap.wav +0 -0
- package/lib/web/assets/b3894545cf71-slice.wav +0 -0
- package/lib/web/assets/b3c6225d055a-meadow.jpg +0 -0
- package/lib/web/assets/b60ca65cdfcb-gate.wav +0 -0
- package/lib/web/assets/b8900bb2c5c7-win.wav +0 -0
- package/lib/web/assets/baff6feda846-lose.wav +0 -0
- package/lib/web/assets/bed31305d60d-ad_chevrons.png +0 -0
- package/lib/web/assets/c26f4a624e7d-shuffle.wav +0 -0
- package/lib/web/assets/c3a9edfad195-die.wav +0 -0
- package/lib/web/assets/c4aa9d773f2a-footstep_walk.wav +0 -0
- package/lib/web/assets/c5ab3ff0003f-crash.wav +0 -0
- package/lib/web/assets/c5eb07deddd4-start.wav +0 -0
- package/lib/web/assets/c6c58d9ae452-pop.wav +0 -0
- package/lib/web/assets/cea48c3cd9c7-balloon_pop.wav +0 -0
- package/lib/web/assets/d15591767778-tap.wav +0 -0
- package/lib/web/assets/d1781a52234f-slide.wav +0 -0
- package/lib/web/assets/d3bf2d9f793b-snap.wav +0 -0
- package/lib/web/assets/d8f59ebd3537-jump.wav +0 -0
- package/lib/web/assets/dafea2f28854-power_up.wav +0 -0
- package/lib/web/assets/e2e7f5ae2d1b-whoosh.wav +0 -0
- package/lib/web/assets/e2f90a23e1bd-chomp.wav +0 -0
- package/lib/web/assets/e454e56df89a-clack.wav +0 -0
- package/lib/web/assets/e8cbc2b88bc4-Inter-SemiBold.ttf +0 -0
- package/lib/web/assets/ed6496b891fc-land.wav +0 -0
- package/lib/web/assets/f21920200a81-thunk.wav +0 -0
- package/lib/web/assets/f753b43be89d-whack.wav +0 -0
- package/lib/web/assets/f798c4b5cf4d-miss.wav +0 -0
- package/lib/web/assets/fbe299716916-grass.png +0 -0
- package/lib/web/chunk-52ez2s9z.js +15 -0
- package/lib/web/chunk-8675t224.js +1 -0
- package/lib/web/index.js +2 -0
- package/lib/web/package.json +1 -0
- package/lib/web/services.js +2 -0
- package/package.json +94 -73
- package/src/assets/fonts/Inter-SemiBold.ttf +0 -0
- package/src/assets/models/explorer/explorer.glb +0 -0
- package/src/assets/models/explorer/params.json +51 -0
- package/src/assets/models/explorer/source.json +222 -0
- package/src/assets/models/play-with-tua/play-with-tua.glb +0 -0
- package/src/assets/models/play-with-tua/sources.json +141 -0
- package/src/assets/sfx/balloon_pop.wav +0 -0
- package/src/assets/sfx/blocked.wav +0 -0
- package/src/assets/sfx/boing.wav +0 -0
- package/src/assets/sfx/bonus.wav +0 -0
- package/src/assets/sfx/boom.wav +0 -0
- package/src/assets/sfx/bump.wav +0 -0
- package/src/assets/sfx/cannon.wav +0 -0
- package/src/assets/sfx/capture.wav +0 -0
- package/src/assets/sfx/card_flip.wav +0 -0
- package/src/assets/sfx/card_place.wav +0 -0
- package/src/assets/sfx/catch.wav +0 -0
- package/src/assets/sfx/chime.wav +0 -0
- package/src/assets/sfx/chomp.wav +0 -0
- package/src/assets/sfx/chomp_alt.wav +0 -0
- package/src/assets/sfx/clack.wav +0 -0
- package/src/assets/sfx/clang.wav +0 -0
- package/src/assets/sfx/clash.wav +0 -0
- package/src/assets/sfx/click.wav +0 -0
- package/src/assets/sfx/coin.wav +0 -0
- package/src/assets/sfx/combo.wav +0 -0
- package/src/assets/sfx/crash.wav +0 -0
- package/src/assets/sfx/crunch.wav +0 -0
- package/src/assets/sfx/dance.wav +0 -0
- package/src/assets/sfx/deselect.wav +0 -0
- package/src/assets/sfx/dice_roll.wav +0 -0
- package/src/assets/sfx/die.wav +0 -0
- package/src/assets/sfx/draw.wav +0 -0
- package/src/assets/sfx/drop.wav +0 -0
- package/src/assets/sfx/eat.wav +0 -0
- package/src/assets/sfx/engine.wav +0 -0
- package/src/assets/sfx/error.wav +0 -0
- package/src/assets/sfx/flag.wav +0 -0
- package/src/assets/sfx/flap.wav +0 -0
- package/src/assets/sfx/flip_disc.wav +0 -0
- package/src/assets/sfx/footstep_run.wav +0 -0
- package/src/assets/sfx/footstep_walk.wav +0 -0
- package/src/assets/sfx/game_over.wav +0 -0
- package/src/assets/sfx/gate.wav +0 -0
- package/src/assets/sfx/hit.wav +0 -0
- package/src/assets/sfx/hop.wav +0 -0
- package/src/assets/sfx/hurt.wav +0 -0
- package/src/assets/sfx/invalid.wav +0 -0
- package/src/assets/sfx/jump.wav +0 -0
- package/src/assets/sfx/ladder.wav +0 -0
- package/src/assets/sfx/land.wav +0 -0
- package/src/assets/sfx/laugh.wav +0 -0
- package/src/assets/sfx/lose.wav +0 -0
- package/src/assets/sfx/merge.wav +0 -0
- package/src/assets/sfx/miss.wav +0 -0
- package/src/assets/sfx/nitro.wav +0 -0
- package/src/assets/sfx/pew.wav +0 -0
- package/src/assets/sfx/place.wav +0 -0
- package/src/assets/sfx/pling.wav +0 -0
- package/src/assets/sfx/point.wav +0 -0
- package/src/assets/sfx/pop.wav +0 -0
- package/src/assets/sfx/pop_soft.wav +0 -0
- package/src/assets/sfx/power_up.wav +0 -0
- package/src/assets/sfx/reveal.wav +0 -0
- package/src/assets/sfx/robot.wav +0 -0
- package/src/assets/sfx/rotate.wav +0 -0
- package/src/assets/sfx/run_steps.wav +0 -0
- package/src/assets/sfx/select.wav +0 -0
- package/src/assets/sfx/shuffle.wav +0 -0
- package/src/assets/sfx/six.wav +0 -0
- package/src/assets/sfx/slice.wav +0 -0
- package/src/assets/sfx/slide.wav +0 -0
- package/src/assets/sfx/snake.wav +0 -0
- package/src/assets/sfx/snap.wav +0 -0
- package/src/assets/sfx/splash.wav +0 -0
- package/src/assets/sfx/star.wav +0 -0
- package/src/assets/sfx/start.wav +0 -0
- package/src/assets/sfx/swoosh.wav +0 -0
- package/src/assets/sfx/tap.wav +0 -0
- package/src/assets/sfx/thud.wav +0 -0
- package/src/assets/sfx/thunk.wav +0 -0
- package/src/assets/sfx/tick.wav +0 -0
- package/src/assets/sfx/time_up.wav +0 -0
- package/src/assets/sfx/tock.wav +0 -0
- package/src/assets/sfx/walk_steps.wav +0 -0
- package/src/assets/sfx/warning.wav +0 -0
- package/src/assets/sfx/whack.wav +0 -0
- package/src/assets/sfx/whoosh.wav +0 -0
- package/src/assets/sfx/win.wav +0 -0
- package/src/assets/sfx/zap.wav +0 -0
- package/src/assets/textures/ad_bolt.png +0 -0
- package/src/assets/textures/ad_bubbles.png +0 -0
- package/src/assets/textures/ad_chevrons.png +0 -0
- package/src/assets/textures/asphalt.png +0 -0
- package/src/assets/textures/bark.jpg +0 -0
- package/src/assets/textures/explorer-atlas.png +0 -0
- package/src/assets/textures/facade.png +0 -0
- package/src/assets/textures/grass.png +0 -0
- package/src/assets/textures/leaves.png +0 -0
- package/src/assets/textures/limestone.jpg +0 -0
- package/src/assets/textures/meadow.jpg +0 -0
- package/src/assets/textures/nature-sources.json +87 -0
- package/src/assets/textures/pine.png +0 -0
- package/src/assets/textures/river.jpg +0 -0
- package/src/assets/textures/soft_glow.png +0 -0
- package/src/games/arrows/Arrows.tsx +69 -0
- package/src/games/arrows/ArrowsConstants.ts +107 -0
- package/src/games/arrows/ArrowsGame.ts +735 -0
- package/src/games/arrows/ArrowsScene.ts +395 -0
- package/src/games/balloon-blaster/BalloonBlaster.tsx +75 -0
- package/src/games/balloon-blaster/BalloonBlasterConstants.ts +79 -0
- package/src/games/balloon-blaster/BalloonBlasterGame.ts +287 -0
- package/src/games/balloon-blaster/BalloonBlasterPhysics.ts +95 -0
- package/src/games/balloon-blaster/BalloonBlasterScene.ts +225 -0
- package/src/games/bike-racing/BikeMeshes.ts +273 -0
- package/src/games/bike-racing/BikeRacing.tsx +211 -0
- package/src/games/bike-racing/BikeRacingConstants.ts +103 -0
- package/src/games/bike-racing/BikeRacingGame.ts +557 -0
- package/src/games/bike-racing/BikeRacingScene.ts +119 -0
- package/src/games/block-blast/BlockBlast.tsx +73 -0
- package/src/games/block-blast/BlockBlastConstants.ts +179 -0
- package/src/games/block-blast/BlockBlastGame.ts +471 -0
- package/src/games/block-blast/BlockBlastScene.ts +156 -0
- package/src/games/block-breaker/BlockBreaker.tsx +79 -0
- package/src/games/block-breaker/BlockBreakerConstants.ts +139 -0
- package/src/games/block-breaker/BlockBreakerGame.ts +459 -0
- package/src/games/block-breaker/BlockBreakerScene.ts +257 -0
- package/src/games/bluk/Bluk.tsx +82 -0
- package/src/games/bluk/BlukConstants.ts +121 -0
- package/src/games/bluk/BlukGame.ts +323 -0
- package/src/games/bluk/BlukRules.ts +154 -0
- package/src/games/bluk/BlukScene.ts +514 -0
- package/src/games/bubble-shooter/BubbleShooter.tsx +76 -0
- package/src/games/bubble-shooter/BubbleShooterConstants.ts +103 -0
- package/src/games/bubble-shooter/BubbleShooterGame.ts +459 -0
- package/src/games/bubble-shooter/BubbleShooterScene.ts +158 -0
- package/src/games/candy-crush/CandyCrush.tsx +77 -0
- package/src/games/candy-crush/CandyCrushConstants.ts +94 -0
- package/src/games/candy-crush/CandyCrushGame.ts +477 -0
- package/src/games/candy-crush/CandyCrushScene.ts +209 -0
- package/src/games/car-racing/CarMeshes.ts +440 -0
- package/src/games/car-racing/CarRacing.tsx +211 -0
- package/src/games/car-racing/CarRacingConstants.ts +167 -0
- package/src/games/car-racing/CarRacingFacade.ts +40 -0
- package/src/games/car-racing/CarRacingGame.ts +539 -0
- package/src/games/car-racing/CarRacingScene.ts +1026 -0
- package/src/games/car-racing/CarRacingScenery.ts +265 -0
- package/src/games/chameleon-run/ChameleonRun.tsx +96 -0
- package/src/games/chameleon-run/ChameleonRunBackdrop.ts +186 -0
- package/src/games/chameleon-run/ChameleonRunConstants.ts +47 -0
- package/src/games/chameleon-run/ChameleonRunGame.ts +309 -0
- package/src/games/chameleon-run/ChameleonRunMeshes.ts +305 -0
- package/src/games/chameleon-run/ChameleonRunRules.ts +252 -0
- package/src/games/chameleon-run/ChameleonRunScene.ts +310 -0
- package/src/games/checkers/Checkers.tsx +83 -0
- package/src/games/checkers/CheckersAI.ts +255 -0
- package/src/games/checkers/CheckersConstants.ts +68 -0
- package/src/games/checkers/CheckersGame.ts +322 -0
- package/src/games/checkers/CheckersRules.ts +167 -0
- package/src/games/checkers/CheckersScene.ts +308 -0
- package/src/games/color-switch/ColorSwitch.tsx +75 -0
- package/src/games/color-switch/ColorSwitchConstants.ts +61 -0
- package/src/games/color-switch/ColorSwitchGame.ts +329 -0
- package/src/games/color-switch/ColorSwitchScene.ts +220 -0
- package/src/games/colors-sort/ColorsSort.tsx +82 -0
- package/src/games/colors-sort/ColorsSortConstants.ts +119 -0
- package/src/games/colors-sort/ColorsSortGame.ts +246 -0
- package/src/games/colors-sort/ColorsSortScene.ts +315 -0
- package/src/games/connect-em-all/ConnectEmAll.tsx +70 -0
- package/src/games/connect-em-all/ConnectEmAllConstants.ts +77 -0
- package/src/games/connect-em-all/ConnectEmAllGame.ts +401 -0
- package/src/games/connect-em-all/ConnectEmAllScene.ts +235 -0
- package/src/games/crossy-road/CrossyRoad.tsx +74 -0
- package/src/games/crossy-road/CrossyRoadCamera.ts +59 -0
- package/src/games/crossy-road/CrossyRoadConstants.ts +132 -0
- package/src/games/crossy-road/CrossyRoadGame.ts +293 -0
- package/src/games/crossy-road/CrossyRoadMeshes.ts +195 -0
- package/src/games/crossy-road/CrossyRoadPerson.ts +198 -0
- package/src/games/crossy-road/CrossyRoadRules.ts +99 -0
- package/src/games/crossy-road/CrossyRoadScene.ts +355 -0
- package/src/games/dino-jump/DinoJump.tsx +77 -0
- package/src/games/dino-jump/DinoJumpConstants.ts +80 -0
- package/src/games/dino-jump/DinoJumpGame.ts +344 -0
- package/src/games/dino-jump/DinoJumpScene.ts +686 -0
- package/src/games/dots-and-boxes/DotsAndBoxes.tsx +83 -0
- package/src/games/dots-and-boxes/DotsAndBoxesConstants.ts +77 -0
- package/src/games/dots-and-boxes/DotsAndBoxesGame.ts +271 -0
- package/src/games/dots-and-boxes/DotsAndBoxesScene.ts +249 -0
- package/src/games/falling-sticks/FallingSticks.tsx +72 -0
- package/src/games/falling-sticks/FallingSticksConstants.ts +62 -0
- package/src/games/falling-sticks/FallingSticksGame.ts +220 -0
- package/src/games/falling-sticks/FallingSticksRules.ts +145 -0
- package/src/games/falling-sticks/FallingSticksScene.ts +245 -0
- package/src/games/find-different-number/FindDifferentNumber.tsx +74 -0
- package/src/games/find-different-number/FindDifferentNumberConstants.ts +74 -0
- package/src/games/find-different-number/FindDifferentNumberGame.ts +174 -0
- package/src/games/find-different-number/FindDifferentNumberRules.ts +43 -0
- package/src/games/find-different-number/FindDifferentNumberScene.ts +193 -0
- package/src/games/flappy-bird/FlappyBird.tsx +73 -0
- package/src/games/flappy-bird/FlappyBirdConstants.ts +95 -0
- package/src/games/flappy-bird/FlappyBirdGame.ts +375 -0
- package/src/games/flappy-bird/FlappyBirdScene.ts +630 -0
- package/src/games/fruit-merger/FruitMerger.tsx +73 -0
- package/src/games/fruit-merger/FruitMergerConstants.ts +102 -0
- package/src/games/fruit-merger/FruitMergerGame.ts +285 -0
- package/src/games/fruit-merger/FruitMergerRules.ts +286 -0
- package/src/games/fruit-merger/FruitMergerScene.ts +498 -0
- package/src/games/fruit-ninja/FruitNinja.tsx +129 -0
- package/src/games/fruit-ninja/FruitNinjaConstants.ts +107 -0
- package/src/games/fruit-ninja/FruitNinjaGame.ts +391 -0
- package/src/games/fruit-ninja/FruitNinjaScene.ts +319 -0
- package/src/games/fruit-ninja/FruitNinjaWorld.ts +17 -0
- package/src/games/game-2048/Game2048.tsx +84 -0
- package/src/games/game-2048/Game2048Constants.ts +68 -0
- package/src/games/game-2048/Game2048Game.ts +181 -0
- package/src/games/game-2048/Game2048Rules.ts +101 -0
- package/src/games/game-2048/Game2048Scene.ts +206 -0
- package/src/games/knife-hit/KnifeHit.tsx +78 -0
- package/src/games/knife-hit/KnifeHitConstants.ts +89 -0
- package/src/games/knife-hit/KnifeHitGame.ts +264 -0
- package/src/games/knife-hit/KnifeHitScene.ts +360 -0
- package/src/games/ludo-king/LudoKing.tsx +86 -0
- package/src/games/ludo-king/LudoKingConstants.ts +212 -0
- package/src/games/ludo-king/LudoKingGame.ts +326 -0
- package/src/games/ludo-king/LudoKingRules.ts +143 -0
- package/src/games/ludo-king/LudoKingScene.ts +397 -0
- package/src/games/maze-runner/MazeRunner.tsx +88 -0
- package/src/games/maze-runner/MazeRunnerConstants.ts +65 -0
- package/src/games/maze-runner/MazeRunnerGame.ts +176 -0
- package/src/games/maze-runner/MazeRunnerRules.ts +161 -0
- package/src/games/maze-runner/MazeRunnerScene.ts +245 -0
- package/src/games/memory-match/MemoryMatch.tsx +77 -0
- package/src/games/memory-match/MemoryMatchConstants.ts +105 -0
- package/src/games/memory-match/MemoryMatchGame.ts +222 -0
- package/src/games/memory-match/MemoryMatchRules.ts +38 -0
- package/src/games/memory-match/MemoryMatchScene.ts +268 -0
- package/src/games/mine-sweeper/MineSweeper.tsx +77 -0
- package/src/games/mine-sweeper/MineSweeperConstants.ts +94 -0
- package/src/games/mine-sweeper/MineSweeperGame.ts +234 -0
- package/src/games/mine-sweeper/MineSweeperRules.ts +67 -0
- package/src/games/mine-sweeper/MineSweeperScene.ts +262 -0
- package/src/games/mob-control/MobControl.tsx +73 -0
- package/src/games/mob-control/MobControlConstants.ts +106 -0
- package/src/games/mob-control/MobControlGame.ts +176 -0
- package/src/games/mob-control/MobControlMeshes.ts +85 -0
- package/src/games/mob-control/MobControlRenderer.ts +108 -0
- package/src/games/mob-control/MobControlRules.ts +522 -0
- package/src/games/mob-control/MobControlScene.ts +399 -0
- package/src/games/number-search/NumberSearch.tsx +18 -0
- package/src/games/number-search/NumberSearchNumbers.ts +623 -0
- package/src/games/nuts-and-bolts/NutsAndBolts.tsx +85 -0
- package/src/games/nuts-and-bolts/NutsAndBoltsConstants.ts +75 -0
- package/src/games/nuts-and-bolts/NutsAndBoltsGame.ts +298 -0
- package/src/games/nuts-and-bolts/NutsAndBoltsRules.ts +474 -0
- package/src/games/nuts-and-bolts/NutsAndBoltsScene.ts +498 -0
- package/src/games/pac-man/PacMan.tsx +86 -0
- package/src/games/pac-man/PacManConstants.ts +169 -0
- package/src/games/pac-man/PacManGame.ts +406 -0
- package/src/games/pac-man/PacManRules.ts +255 -0
- package/src/games/pac-man/PacManScene.ts +387 -0
- package/src/games/paper-io/PaperIo.tsx +91 -0
- package/src/games/paper-io/PaperIoConstants.ts +86 -0
- package/src/games/paper-io/PaperIoGame.ts +193 -0
- package/src/games/paper-io/PaperIoMeshes.ts +233 -0
- package/src/games/paper-io/PaperIoRules.ts +315 -0
- package/src/games/paper-io/PaperIoScene.ts +310 -0
- package/src/games/penguin-run/PenguinMeshes.ts +269 -0
- package/src/games/penguin-run/PenguinModel.ts +712 -0
- package/src/games/penguin-run/PenguinRun.tsx +77 -0
- package/src/games/penguin-run/PenguinRunConstants.ts +69 -0
- package/src/games/penguin-run/PenguinRunGame.ts +406 -0
- package/src/games/penguin-run/PenguinRunScene.ts +949 -0
- package/src/games/perfect-circle/PerfectCircle.tsx +74 -0
- package/src/games/perfect-circle/PerfectCircleConstants.ts +52 -0
- package/src/games/perfect-circle/PerfectCircleGame.ts +153 -0
- package/src/games/perfect-circle/PerfectCircleRules.ts +111 -0
- package/src/games/perfect-circle/PerfectCircleScene.ts +176 -0
- package/src/games/pipe-connect/PipeConnect.tsx +69 -0
- package/src/games/pipe-connect/PipeConnectConstants.ts +101 -0
- package/src/games/pipe-connect/PipeConnectGame.ts +179 -0
- package/src/games/pipe-connect/PipeConnectRules.ts +326 -0
- package/src/games/pipe-connect/PipeConnectScene.ts +271 -0
- package/src/games/play-with-tua/PlayWithTua.tsx +123 -0
- package/src/games/play-with-tua/PlayWithTuaConstants.ts +70 -0
- package/src/games/play-with-tua/PlayWithTuaGame.ts +167 -0
- package/src/games/play-with-tua/PlayWithTuaModel.ts +42 -0
- package/src/games/play-with-tua/PlayWithTuaScene.ts +36 -0
- package/src/games/popit-fidget/PopitFidget.tsx +72 -0
- package/src/games/popit-fidget/PopitFidgetConstants.ts +71 -0
- package/src/games/popit-fidget/PopitFidgetGame.ts +148 -0
- package/src/games/popit-fidget/PopitFidgetScene.ts +242 -0
- package/src/games/reversi/Reversi.tsx +94 -0
- package/src/games/reversi/ReversiConstants.ts +67 -0
- package/src/games/reversi/ReversiGame.ts +266 -0
- package/src/games/reversi/ReversiRules.ts +176 -0
- package/src/games/reversi/ReversiScene.ts +240 -0
- package/src/games/search-grid/SearchGrid.tsx +92 -0
- package/src/games/search-grid/SearchGridConstants.ts +178 -0
- package/src/games/search-grid/SearchGridGame.ts +209 -0
- package/src/games/search-grid/SearchGridScene.ts +301 -0
- package/src/games/shared/BackdropCard.tsx +54 -0
- package/src/games/shared/EngineBackdrop.ts +300 -0
- package/src/games/shared/EngineBlasts.ts +136 -0
- package/src/games/shared/EngineBlocks.ts +91 -0
- package/src/games/shared/EngineControlText.ts +17 -0
- package/src/games/shared/EngineDice.ts +250 -0
- package/src/games/shared/EngineFootprint.ts +35 -0
- package/src/games/shared/EngineFruits.ts +1435 -0
- package/src/games/shared/EngineGameLoader.tsx +88 -0
- package/src/games/shared/EngineGameScreen.tsx +325 -0
- package/src/games/shared/EngineGameWidth.ts +3 -0
- package/src/games/shared/EngineGameWidth.web.ts +3 -0
- package/src/games/shared/EngineGlyphs.ts +178 -0
- package/src/games/shared/EngineHud.ts +815 -0
- package/src/games/shared/EngineLoading.ts +477 -0
- package/src/games/shared/EngineMeadow.ts +725 -0
- package/src/games/shared/EngineMeshCache.ts +15 -0
- package/src/games/shared/EngineMeshes.ts +10 -0
- package/src/games/shared/EngineRacingChase.ts +21 -0
- package/src/games/shared/EngineRacingHandling.ts +48 -0
- package/src/games/shared/EngineReadyContext.ts +4 -0
- package/src/games/shared/EngineTilt.ts +44 -0
- package/src/games/shared/EngineTouchSurface.tsx +103 -0
- package/src/games/shared/EngineUtils.ts +52 -0
- package/src/games/shared/GameActivity.ts +13 -0
- package/src/games/shared/GameLoading.tsx +202 -0
- package/src/games/shared/GameLoadingTransition.tsx +61 -0
- package/src/games/shared/ProceduralCacheVersion.ts +2 -0
- package/src/games/shared/useEngineGame.ts +240 -0
- package/src/games/shared/useGameResource.ts +21 -0
- package/src/games/shared/useLiveState.ts +58 -0
- package/src/games/sliding-numbers/SlidingNumbers.tsx +71 -0
- package/src/games/sliding-numbers/SlidingNumbersConstants.ts +65 -0
- package/src/games/sliding-numbers/SlidingNumbersGame.ts +192 -0
- package/src/games/sliding-numbers/SlidingNumbersRules.ts +79 -0
- package/src/games/sliding-numbers/SlidingNumbersScene.ts +193 -0
- package/src/games/snake-3d/Snake3D.tsx +76 -0
- package/src/games/snake-3d/Snake3DConstants.ts +61 -0
- package/src/games/snake-3d/Snake3DGame.ts +192 -0
- package/src/games/snake-3d/Snake3DMotion.ts +22 -0
- package/src/games/snake-3d/Snake3DRules.ts +116 -0
- package/src/games/snake-3d/Snake3DScene.ts +322 -0
- package/src/games/snakes-and-ladders/SnakesAndLadders.tsx +87 -0
- package/src/games/snakes-and-ladders/SnakesAndLaddersConstants.ts +136 -0
- package/src/games/snakes-and-ladders/SnakesAndLaddersGame.ts +310 -0
- package/src/games/snakes-and-ladders/SnakesAndLaddersScene.ts +515 -0
- package/src/games/space-fighter/SpaceFighter.tsx +74 -0
- package/src/games/space-fighter/SpaceFighterConstants.ts +86 -0
- package/src/games/space-fighter/SpaceFighterGame.ts +292 -0
- package/src/games/space-fighter/SpaceFighterScene.ts +550 -0
- package/src/games/spider-solitaire/SpiderSolitaire.tsx +80 -0
- package/src/games/spider-solitaire/SpiderSolitaireConstants.ts +107 -0
- package/src/games/spider-solitaire/SpiderSolitaireGame.ts +387 -0
- package/src/games/spider-solitaire/SpiderSolitaireRules.ts +123 -0
- package/src/games/spider-solitaire/SpiderSolitaireScene.ts +352 -0
- package/src/games/stack-tower/StackTower.tsx +76 -0
- package/src/games/stack-tower/StackTowerConstants.ts +74 -0
- package/src/games/stack-tower/StackTowerGame.ts +236 -0
- package/src/games/stack-tower/StackTowerScene.ts +186 -0
- package/src/games/sudoku/Sudoku.tsx +73 -0
- package/src/games/sudoku/SudokuConstants.ts +127 -0
- package/src/games/sudoku/SudokuGame.ts +250 -0
- package/src/games/sudoku/SudokuRules.ts +125 -0
- package/src/games/sudoku/SudokuScene.ts +304 -0
- package/src/games/tangram/Tangram.tsx +79 -0
- package/src/games/tangram/TangramConstants.ts +64 -0
- package/src/games/tangram/TangramGame.ts +356 -0
- package/src/games/tangram/TangramRules.ts +409 -0
- package/src/games/tangram/TangramScene.ts +203 -0
- package/src/games/tank-1990/Tank1990.tsx +78 -0
- package/src/games/tank-1990/Tank1990Constants.ts +81 -0
- package/src/games/tank-1990/Tank1990Game.ts +331 -0
- package/src/games/tank-1990/Tank1990Rules.ts +390 -0
- package/src/games/tank-1990/Tank1990Scene.ts +434 -0
- package/src/games/tic-tac-toe/TicTacToe.tsx +98 -0
- package/src/games/tic-tac-toe/TicTacToeConstants.ts +69 -0
- package/src/games/tic-tac-toe/TicTacToeGame.ts +200 -0
- package/src/games/tic-tac-toe/TicTacToeRules.ts +103 -0
- package/src/games/tic-tac-toe/TicTacToeScene.ts +245 -0
- package/src/games/tile-home/TileHome.tsx +92 -0
- package/src/games/tile-home/TileHomeConstants.ts +139 -0
- package/src/games/tile-home/TileHomeGame.ts +435 -0
- package/src/games/tile-home/TileHomeScene.ts +154 -0
- package/src/games/treasure-hunt/TreasureHunt.tsx +206 -0
- package/src/games/treasure-hunt/TreasureHuntConstants.ts +266 -0
- package/src/games/treasure-hunt/TreasureHuntControls.ts +280 -0
- package/src/games/treasure-hunt/TreasureHuntGame.ts +402 -0
- package/src/games/treasure-hunt/TreasureHuntMeshes.ts +422 -0
- package/src/games/treasure-hunt/TreasureHuntModel.ts +506 -0
- package/src/games/treasure-hunt/TreasureHuntRules.ts +1210 -0
- package/src/games/treasure-hunt/TreasureHuntScene.ts +586 -0
- package/src/games/whack-a-mole/WhackAMole.tsx +79 -0
- package/src/games/whack-a-mole/WhackAMoleConstants.ts +94 -0
- package/src/games/whack-a-mole/WhackAMoleGame.ts +233 -0
- package/src/games/whack-a-mole/WhackAMoleScene.ts +349 -0
- package/src/games/word-search/WordSearch.tsx +18 -0
- package/src/games/word-search/WordSearchWords.ts +1642 -0
- package/src/helpers/GamePatternData.ts +120 -0
- package/src/helpers/GameSettingsModal.tsx +384 -0
- package/src/helpers/GameTheme.tsx +37 -0
- package/src/helpers/IconPaths.ts +6 -0
- package/src/helpers/index.ts +2 -0
- package/src/index.tsx +60 -0
- package/src/services/GameAssetLoader.ts +111 -0
- package/src/services/GameAssets.ts +149 -0
- package/src/services/GameLoaders.ts +93 -0
- package/src/services/GamesConstants.ts +193 -0
- package/src/services/GamesMetadata.ts +711 -0
- package/src/services/GamesService.ts +116 -0
- package/src/services/HapticsService.ts +48 -0
- package/src/services/ScoringService.ts +19 -0
- package/src/services/SfxSources.ts +81 -0
- package/src/services/SoundsService.ts +582 -0
- package/src/services/ThemeService.ts +281 -0
- package/src/services/UtilsService.ts +134 -0
- package/src/services/index.ts +6 -0
- package/lib/module/games/arrows/ArrowsService.js +0 -1
- package/lib/module/games/arrows/ArrowsStore.js +0 -1
- package/lib/module/games/arrows/components/ArrowsGrid.js +0 -1
- package/lib/module/games/arrows/components/ScoreBoard.js +0 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterService.js +0 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterStore.js +0 -1
- package/lib/module/games/balloon-blaster/components/BalloonComponent.js +0 -1
- package/lib/module/games/balloon-blaster/components/GameArea.js +0 -1
- package/lib/module/games/balloon-blaster/components/GameBackground.js +0 -1
- package/lib/module/games/balloon-blaster/components/ScoreBoard.js +0 -1
- package/lib/module/games/bike-racing/BikeRacingService.js +0 -1
- package/lib/module/games/bike-racing/BikeRacingStore.js +0 -1
- package/lib/module/games/bike-racing/components/BikeComponent.js +0 -1
- package/lib/module/games/bike-racing/components/GameBackground.js +0 -1
- package/lib/module/games/bike-racing/components/ScoreBoard.js +0 -1
- package/lib/module/games/block-blast/BlockBlastService.js +0 -1
- package/lib/module/games/block-blast/BlockBlastStore.js +0 -1
- package/lib/module/games/block-blast/components/BlockPieceComponent.js +0 -1
- package/lib/module/games/block-blast/components/GameArea.js +0 -1
- package/lib/module/games/block-blast/components/GridComponent.js +0 -1
- package/lib/module/games/block-blast/components/ScoreBoard.js +0 -1
- package/lib/module/games/block-breaker/BlockBreakerService.js +0 -1
- package/lib/module/games/block-breaker/BlockBreakerStore.js +0 -1
- package/lib/module/games/block-breaker/components/BlastAnimation.js +0 -1
- package/lib/module/games/block-breaker/components/GameArea.js +0 -1
- package/lib/module/games/block-breaker/components/ScoreBoard.js +0 -1
- package/lib/module/games/bluk/BlukService.js +0 -1
- package/lib/module/games/bluk/BlukStore.js +0 -1
- package/lib/module/games/bluk/components/GameArea.js +0 -1
- package/lib/module/games/bluk/components/GameBackground.js +0 -1
- package/lib/module/games/bluk/components/ScoreBoard.js +0 -1
- package/lib/module/games/bubble-shooter/BubbleShooterService.js +0 -1
- package/lib/module/games/bubble-shooter/BubbleShooterStore.js +0 -1
- package/lib/module/games/bubble-shooter/components/GameArea.js +0 -1
- package/lib/module/games/bubble-shooter/components/ScoreBoard.js +0 -1
- package/lib/module/games/candy-crush/CandyCrushService.js +0 -1
- package/lib/module/games/candy-crush/CandyCrushStore.js +0 -1
- package/lib/module/games/candy-crush/components/CandyItem.js +0 -1
- package/lib/module/games/candy-crush/components/GameGrid.js +0 -1
- package/lib/module/games/candy-crush/components/ScoreBoard.js +0 -1
- package/lib/module/games/car-racing/CarRacingService.js +0 -1
- package/lib/module/games/car-racing/CarRacingStore.js +0 -1
- package/lib/module/games/car-racing/components/CarComponent.js +0 -1
- package/lib/module/games/car-racing/components/GameBackground.js +0 -1
- package/lib/module/games/car-racing/components/ScoreBoard.js +0 -1
- package/lib/module/games/chameleon-run/ChameleonRunService.js +0 -1
- package/lib/module/games/chameleon-run/ChameleonRunStore.js +0 -1
- package/lib/module/games/chameleon-run/components/GameArea.js +0 -1
- package/lib/module/games/chameleon-run/components/GameBackground.js +0 -1
- package/lib/module/games/chameleon-run/components/ScoreBoard.js +0 -1
- package/lib/module/games/checkers/CheckersService.js +0 -1
- package/lib/module/games/checkers/CheckersStore.js +0 -1
- package/lib/module/games/checkers/components/GameBoard.js +0 -1
- package/lib/module/games/checkers/components/ScoreBoard.js +0 -1
- package/lib/module/games/color-switch/ColorSwitchService.js +0 -1
- package/lib/module/games/color-switch/ColorSwitchStore.js +0 -1
- package/lib/module/games/color-switch/components/GameArea.js +0 -1
- package/lib/module/games/color-switch/components/ScoreBoard.js +0 -1
- package/lib/module/games/colors-sort/ColorsSortService.js +0 -1
- package/lib/module/games/colors-sort/ColorsSortStore.js +0 -1
- package/lib/module/games/colors-sort/components/ColorContainer.js +0 -1
- package/lib/module/games/colors-sort/components/ScoreBoard.js +0 -1
- package/lib/module/games/connect-em-all/ConnectEmAllService.js +0 -1
- package/lib/module/games/connect-em-all/ConnectEmAllStore.js +0 -1
- package/lib/module/games/connect-em-all/components/GameBoard.js +0 -1
- package/lib/module/games/connect-em-all/components/ScoreBoard.js +0 -1
- package/lib/module/games/crossy-road/CrossyRoadService.js +0 -1
- package/lib/module/games/crossy-road/CrossyRoadStore.js +0 -1
- package/lib/module/games/crossy-road/components/GameArea.js +0 -1
- package/lib/module/games/crossy-road/components/ScoreBoard.js +0 -1
- package/lib/module/games/dino-jump/DinoJumpService.js +0 -1
- package/lib/module/games/dino-jump/DinoJumpStore.js +0 -1
- package/lib/module/games/dino-jump/components/DinoSprite.js +0 -1
- package/lib/module/games/dino-jump/components/GameArea.js +0 -1
- package/lib/module/games/dino-jump/components/GameBackground.js +0 -1
- package/lib/module/games/dino-jump/components/ObstacleSprite.js +0 -1
- package/lib/module/games/dino-jump/components/ScoreBoard.js +0 -1
- package/lib/module/games/dino-jump/components/StarSprite.js +0 -1
- package/lib/module/games/dots-and-boxes/DotsAndBoxesService.js +0 -1
- package/lib/module/games/dots-and-boxes/DotsAndBoxesStore.js +0 -1
- package/lib/module/games/dots-and-boxes/components/GameBoard.js +0 -1
- package/lib/module/games/dots-and-boxes/components/ScoreBoard.js +0 -1
- package/lib/module/games/falling-sticks/FallingSticksService.js +0 -1
- package/lib/module/games/falling-sticks/FallingSticksStore.js +0 -1
- package/lib/module/games/falling-sticks/components/GameArea.js +0 -1
- package/lib/module/games/falling-sticks/components/GameBackground.js +0 -1
- package/lib/module/games/falling-sticks/components/ScoreBoard.js +0 -1
- package/lib/module/games/find-different-number/FindDifferentNumberService.js +0 -1
- package/lib/module/games/find-different-number/FindDifferentNumberStore.js +0 -1
- package/lib/module/games/find-different-number/components/GameGrid.js +0 -1
- package/lib/module/games/find-different-number/components/ScoreBoard.js +0 -1
- package/lib/module/games/flappy-bird/FlappyBirdStore.js +0 -1
- package/lib/module/games/flappy-bird/components/Bird.js +0 -1
- package/lib/module/games/flappy-bird/components/GameArea.js +0 -1
- package/lib/module/games/flappy-bird/components/GameBackground.js +0 -1
- package/lib/module/games/flappy-bird/components/Pipes.js +0 -1
- package/lib/module/games/flappy-bird/components/ScoreBoard.js +0 -1
- package/lib/module/games/fruit-merger/FruitMergerService.js +0 -1
- package/lib/module/games/fruit-merger/FruitMergerStore.js +0 -1
- package/lib/module/games/fruit-merger/components/FruitItem.js +0 -1
- package/lib/module/games/fruit-merger/components/GameArea.js +0 -1
- package/lib/module/games/fruit-merger/components/ScoreBoard.js +0 -1
- package/lib/module/games/fruit-ninja/FruitNinjaService.js +0 -1
- package/lib/module/games/fruit-ninja/FruitNinjaStore.js +0 -1
- package/lib/module/games/fruit-ninja/components/FruitComponent.js +0 -1
- package/lib/module/games/fruit-ninja/components/GameArea.js +0 -1
- package/lib/module/games/fruit-ninja/components/GameBackground.js +0 -1
- package/lib/module/games/fruit-ninja/components/ScoreBoard.js +0 -1
- package/lib/module/games/game-2048/Game2048Service.js +0 -1
- package/lib/module/games/game-2048/Game2048Store.js +0 -1
- package/lib/module/games/game-2048/components/GameGrid.js +0 -1
- package/lib/module/games/game-2048/components/ScoreBoard.js +0 -1
- package/lib/module/games/knife-hit/KnifeHitService.js +0 -1
- package/lib/module/games/knife-hit/KnifeHitStore.js +0 -1
- package/lib/module/games/knife-hit/components/GameArea.js +0 -1
- package/lib/module/games/knife-hit/components/ScoreBoard.js +0 -1
- package/lib/module/games/ludo-king/LudoKingService.js +0 -1
- package/lib/module/games/ludo-king/LudoKingStore.js +0 -1
- package/lib/module/games/ludo-king/components/Dice.js +0 -1
- package/lib/module/games/ludo-king/components/GameBoard.js +0 -1
- package/lib/module/games/ludo-king/components/ScoreBoard.js +0 -1
- package/lib/module/games/maze-runner/MazeRunnerStore.js +0 -1
- package/lib/module/games/maze-runner/components/EnhancedBallComponent.js +0 -1
- package/lib/module/games/maze-runner/components/EnhancedGameArea.js +0 -1
- package/lib/module/games/maze-runner/components/ScoreBoard.js +0 -1
- package/lib/module/games/maze-runner/components/SkiaPipeComponent.js +0 -1
- package/lib/module/games/maze-runner/components/WallComponent.js +0 -1
- package/lib/module/games/memory-match/MemoryMatchService.js +0 -1
- package/lib/module/games/memory-match/MemoryMatchStore.js +0 -1
- package/lib/module/games/memory-match/components/Card.js +0 -1
- package/lib/module/games/memory-match/components/GameBoard.js +0 -1
- package/lib/module/games/memory-match/components/ScoreBoard.js +0 -1
- package/lib/module/games/mine-sweeper/MineSweeperService.js +0 -1
- package/lib/module/games/mine-sweeper/MineSweeperStore.js +0 -1
- package/lib/module/games/mine-sweeper/components/GameArea.js +0 -1
- package/lib/module/games/mine-sweeper/components/ScoreBoard.js +0 -1
- package/lib/module/games/mob-control/MobControlService.js +0 -1
- package/lib/module/games/mob-control/MobControlStore.js +0 -1
- package/lib/module/games/mob-control/components/GameArea.js +0 -1
- package/lib/module/games/mob-control/components/ScoreBoard.js +0 -1
- package/lib/module/games/number-search/NumberSearchConstants.js +0 -1
- package/lib/module/games/number-search/NumberSearchService.js +0 -1
- package/lib/module/games/number-search/NumberSearchStore.js +0 -1
- package/lib/module/games/number-search/components/GameBoard.js +0 -1
- package/lib/module/games/number-search/components/NumberList.js +0 -1
- package/lib/module/games/number-search/components/ScoreBoard.js +0 -1
- package/lib/module/games/nuts-and-bolts/NutsAndBoltsService.js +0 -1
- package/lib/module/games/nuts-and-bolts/NutsAndBoltsStore.js +0 -1
- package/lib/module/games/nuts-and-bolts/components/GameBoard.js +0 -1
- package/lib/module/games/nuts-and-bolts/components/ScoreBoard.js +0 -1
- package/lib/module/games/pac-man/PacManService.js +0 -1
- package/lib/module/games/pac-man/PacManStore.js +0 -1
- package/lib/module/games/pac-man/components/GameCanvas.js +0 -1
- package/lib/module/games/pac-man/components/ScoreBoard.js +0 -1
- package/lib/module/games/paper-io/PaperIoService.js +0 -1
- package/lib/module/games/paper-io/PaperIoStore.js +0 -1
- package/lib/module/games/paper-io/components/GameArea.js +0 -1
- package/lib/module/games/paper-io/components/ScoreBoard.js +0 -1
- package/lib/module/games/perfect-circle/PerfectCircleService.js +0 -1
- package/lib/module/games/perfect-circle/PerfectCircleStore.js +0 -1
- package/lib/module/games/perfect-circle/components/DrawingCanvas.js +0 -1
- package/lib/module/games/perfect-circle/components/ScoreBoard.js +0 -1
- package/lib/module/games/pipe-connect/PipeConnectService.js +0 -1
- package/lib/module/games/pipe-connect/PipeConnectStore.js +0 -1
- package/lib/module/games/pipe-connect/components/GameArea.js +0 -1
- package/lib/module/games/pipe-connect/components/ScoreBoard.js +0 -1
- package/lib/module/games/popit-fidget/PopitFidgetService.js +0 -1
- package/lib/module/games/popit-fidget/PopitFidgetStore.js +0 -1
- package/lib/module/games/popit-fidget/components/BubbleComponent.js +0 -1
- package/lib/module/games/popit-fidget/components/FidgetGrid.js +0 -1
- package/lib/module/games/popit-fidget/components/ScoreBoard.js +0 -1
- package/lib/module/games/reversi/ReversiStore.js +0 -1
- package/lib/module/games/reversi/components/GameBoard.js +0 -1
- package/lib/module/games/reversi/components/ScoreBoard.js +0 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersService.js +0 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersStore.js +0 -1
- package/lib/module/games/sliding-numbers/components/NumbersGrid.js +0 -1
- package/lib/module/games/sliding-numbers/components/ScoreBoard.js +0 -1
- package/lib/module/games/snake-3d/Snake3DService.js +0 -1
- package/lib/module/games/snake-3d/Snake3DStore.js +0 -1
- package/lib/module/games/snake-3d/components/GameGrid.js +0 -1
- package/lib/module/games/snake-3d/components/ScoreBoard.js +0 -1
- package/lib/module/games/snakes-and-ladders/SnakesAndLaddersService.js +0 -1
- package/lib/module/games/snakes-and-ladders/SnakesAndLaddersStore.js +0 -1
- package/lib/module/games/snakes-and-ladders/components/Dice.js +0 -1
- package/lib/module/games/snakes-and-ladders/components/GameBoard.js +0 -1
- package/lib/module/games/snakes-and-ladders/components/ScoreBoard.js +0 -1
- package/lib/module/games/space-fighter/SpaceFighterService.js +0 -1
- package/lib/module/games/space-fighter/SpaceFighterStore.js +0 -1
- package/lib/module/games/space-fighter/components/AsteroidComponent.js +0 -1
- package/lib/module/games/space-fighter/components/GameArea.js +0 -1
- package/lib/module/games/space-fighter/components/GameBackground.js +0 -1
- package/lib/module/games/space-fighter/components/ScoreBoard.js +0 -1
- package/lib/module/games/space-fighter/components/Spacecraft3D.js +0 -1
- package/lib/module/games/space-fighter/components/SpacecraftPath.js +0 -1
- package/lib/module/games/spider-solitaire/SpiderSolitaireService.js +0 -1
- package/lib/module/games/spider-solitaire/SpiderSolitaireStore.js +0 -1
- package/lib/module/games/spider-solitaire/components/Card.js +0 -1
- package/lib/module/games/spider-solitaire/components/CardPile.js +0 -1
- package/lib/module/games/spider-solitaire/components/ScoreBoard.js +0 -1
- package/lib/module/games/stack-tower/StackTowerService.js +0 -1
- package/lib/module/games/stack-tower/StackTowerStore.js +0 -1
- package/lib/module/games/stack-tower/components/GameArea.js +0 -1
- package/lib/module/games/stack-tower/components/ScoreBoard.js +0 -1
- package/lib/module/games/sudoku/SudokuService.js +0 -1
- package/lib/module/games/sudoku/SudokuStore.js +0 -1
- package/lib/module/games/sudoku/components/GameArea.js +0 -1
- package/lib/module/games/sudoku/components/ScoreBoard.js +0 -1
- package/lib/module/games/tangram/TangramService.js +0 -1
- package/lib/module/games/tangram/TangramStore.js +0 -1
- package/lib/module/games/tangram/components/GameBoard.js +0 -1
- package/lib/module/games/tangram/components/ScoreBoard.js +0 -1
- package/lib/module/games/tank-1990/Tank1990Service.js +0 -1
- package/lib/module/games/tank-1990/Tank1990Store.js +0 -1
- package/lib/module/games/tank-1990/components/Controls.js +0 -1
- package/lib/module/games/tank-1990/components/GameBoard.js +0 -1
- package/lib/module/games/tank-1990/components/ScoreBoard.js +0 -1
- package/lib/module/games/tic-tac-toe/TicTacToeService.js +0 -1
- package/lib/module/games/tic-tac-toe/TicTacToeStore.js +0 -1
- package/lib/module/games/tic-tac-toe/components/GameBoard.js +0 -1
- package/lib/module/games/tic-tac-toe/components/ScoreBoard.js +0 -1
- package/lib/module/games/tile-home/TileHomeService.js +0 -1
- package/lib/module/games/tile-home/TileHomeStore.js +0 -1
- package/lib/module/games/tile-home/components/AnimatingTile.js +0 -1
- package/lib/module/games/tile-home/components/FlyingTile.js +0 -1
- package/lib/module/games/tile-home/components/GameBoard.js +0 -1
- package/lib/module/games/tile-home/components/ScoreBoard.js +0 -1
- package/lib/module/games/tile-home/components/TileItem.js +0 -1
- package/lib/module/games/tile-home/components/TileSlot.js +0 -1
- package/lib/module/games/whack-a-mole/WhackAMoleService.js +0 -1
- package/lib/module/games/whack-a-mole/WhackAMoleStore.js +0 -1
- package/lib/module/games/whack-a-mole/components/GameBackground.js +0 -1
- package/lib/module/games/whack-a-mole/components/GameGrid.js +0 -1
- package/lib/module/games/whack-a-mole/components/GameHole.js +0 -1
- package/lib/module/games/whack-a-mole/components/MoleCharacter.js +0 -1
- package/lib/module/games/whack-a-mole/components/ScoreBoard.js +0 -1
- package/lib/module/games/word-search/WordSearchConstants.js +0 -1
- package/lib/module/games/word-search/WordSearchService.js +0 -1
- package/lib/module/games/word-search/WordSearchStore.js +0 -1
- package/lib/module/games/word-search/components/GameBoard.js +0 -1
- package/lib/module/games/word-search/components/ScoreBoard.js +0 -1
- package/lib/module/games/word-search/components/WordList.js +0 -1
- package/lib/module/helpers/AnimatedScore.js +0 -1
- package/lib/module/helpers/AnimationFrame.js +0 -1
- package/lib/module/helpers/AnimationTracker.js +0 -1
- package/lib/module/helpers/BlastAnimation.js +0 -1
- package/lib/module/helpers/ErrorHandler.js +0 -1
- package/lib/module/helpers/GameBackgroundPattern.js +0 -1
- package/lib/module/helpers/GameControlButton.js +0 -1
- package/lib/module/helpers/GameOverModal.js +0 -1
- package/lib/module/helpers/GameTimer.js +0 -1
- package/lib/module/helpers/Icons.js +0 -1
- package/lib/module/helpers/ParticleBlast.js +0 -1
- package/lib/module/helpers/ScoreBoardContainer.js +0 -1
- package/lib/module/helpers/assets/apple-fruit.js +0 -1
- package/lib/module/helpers/assets/avocado-item.js +0 -1
- package/lib/module/helpers/assets/banana-fruit.js +0 -1
- package/lib/module/helpers/assets/bomb-item.js +0 -1
- package/lib/module/helpers/assets/broccoli-item.js +0 -1
- package/lib/module/helpers/assets/cherries-fruit.js +0 -1
- package/lib/module/helpers/assets/donut-item.js +0 -1
- package/lib/module/helpers/assets/dragonfruit-item.js +0 -1
- package/lib/module/helpers/assets/fries-item.js +0 -1
- package/lib/module/helpers/assets/fruit-helpers.js +0 -1
- package/lib/module/helpers/assets/grapes-fruit.js +0 -1
- package/lib/module/helpers/assets/icecream-item.js +0 -1
- package/lib/module/helpers/assets/index.js +0 -1
- package/lib/module/helpers/assets/kiwi-fruit.js +0 -1
- package/lib/module/helpers/assets/mango-fruit.js +0 -1
- package/lib/module/helpers/assets/orange-fruit.js +0 -1
- package/lib/module/helpers/assets/papaya-fruit.js +0 -1
- package/lib/module/helpers/assets/papaya-full-fruit.js +0 -1
- package/lib/module/helpers/assets/peach-fruit.js +0 -1
- package/lib/module/helpers/assets/pineapple-fruit.js +0 -1
- package/lib/module/helpers/assets/pomegranate-fruit.js +0 -1
- package/lib/module/helpers/assets/pumpkin-fruit.js +0 -1
- package/lib/module/helpers/assets/raspberry-item.js +0 -1
- package/lib/module/helpers/assets/star-item.js +0 -1
- package/lib/module/helpers/assets/strawberry-fruit.js +0 -1
- package/lib/module/helpers/assets/watermelon-fruit.js +0 -1
- package/lib/module/types.d.js +0 -1
- package/lib/typescript/src/games/arrows/ArrowsService.d.ts +0 -6
- package/lib/typescript/src/games/arrows/ArrowsStore.d.ts +0 -51
- package/lib/typescript/src/games/arrows/components/ArrowsGrid.d.ts +0 -13
- package/lib/typescript/src/games/arrows/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/balloon-blaster/BalloonBlasterService.d.ts +0 -80
- package/lib/typescript/src/games/balloon-blaster/BalloonBlasterStore.d.ts +0 -30
- package/lib/typescript/src/games/balloon-blaster/components/BalloonComponent.d.ts +0 -9
- package/lib/typescript/src/games/balloon-blaster/components/GameArea.d.ts +0 -9
- package/lib/typescript/src/games/balloon-blaster/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/balloon-blaster/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/bike-racing/BikeRacingService.d.ts +0 -44
- package/lib/typescript/src/games/bike-racing/BikeRacingStore.d.ts +0 -68
- package/lib/typescript/src/games/bike-racing/components/BikeComponent.d.ts +0 -12
- package/lib/typescript/src/games/bike-racing/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/bike-racing/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/block-blast/BlockBlastService.d.ts +0 -16
- package/lib/typescript/src/games/block-blast/BlockBlastStore.d.ts +0 -70
- package/lib/typescript/src/games/block-blast/components/BlockPieceComponent.d.ts +0 -11
- package/lib/typescript/src/games/block-blast/components/GameArea.d.ts +0 -11
- package/lib/typescript/src/games/block-blast/components/GridComponent.d.ts +0 -8
- package/lib/typescript/src/games/block-blast/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/block-breaker/BlockBreakerService.d.ts +0 -88
- package/lib/typescript/src/games/block-breaker/BlockBreakerStore.d.ts +0 -47
- package/lib/typescript/src/games/block-breaker/components/BlastAnimation.d.ts +0 -15
- package/lib/typescript/src/games/block-breaker/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/block-breaker/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/bluk/BlukService.d.ts +0 -71
- package/lib/typescript/src/games/bluk/BlukStore.d.ts +0 -52
- package/lib/typescript/src/games/bluk/components/GameArea.d.ts +0 -17
- package/lib/typescript/src/games/bluk/components/GameBackground.d.ts +0 -9
- package/lib/typescript/src/games/bluk/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/bubble-shooter/BubbleShooterService.d.ts +0 -35
- package/lib/typescript/src/games/bubble-shooter/BubbleShooterStore.d.ts +0 -63
- package/lib/typescript/src/games/bubble-shooter/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/bubble-shooter/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/candy-crush/CandyCrushService.d.ts +0 -37
- package/lib/typescript/src/games/candy-crush/CandyCrushStore.d.ts +0 -53
- package/lib/typescript/src/games/candy-crush/components/CandyItem.d.ts +0 -11
- package/lib/typescript/src/games/candy-crush/components/GameGrid.d.ts +0 -2
- package/lib/typescript/src/games/candy-crush/components/ScoreBoard.d.ts +0 -5
- package/lib/typescript/src/games/car-racing/CarRacingService.d.ts +0 -44
- package/lib/typescript/src/games/car-racing/CarRacingStore.d.ts +0 -68
- package/lib/typescript/src/games/car-racing/components/CarComponent.d.ts +0 -12
- package/lib/typescript/src/games/car-racing/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/car-racing/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/chameleon-run/ChameleonRunService.d.ts +0 -76
- package/lib/typescript/src/games/chameleon-run/ChameleonRunStore.d.ts +0 -48
- package/lib/typescript/src/games/chameleon-run/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/chameleon-run/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/chameleon-run/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/checkers/CheckersService.d.ts +0 -6
- package/lib/typescript/src/games/checkers/CheckersStore.d.ts +0 -48
- package/lib/typescript/src/games/checkers/components/GameBoard.d.ts +0 -6
- package/lib/typescript/src/games/checkers/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/color-switch/ColorSwitchService.d.ts +0 -63
- package/lib/typescript/src/games/color-switch/ColorSwitchStore.d.ts +0 -43
- package/lib/typescript/src/games/color-switch/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/color-switch/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/colors-sort/ColorsSortService.d.ts +0 -61
- package/lib/typescript/src/games/colors-sort/ColorsSortStore.d.ts +0 -56
- package/lib/typescript/src/games/colors-sort/components/ColorContainer.d.ts +0 -7
- package/lib/typescript/src/games/colors-sort/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/connect-em-all/ConnectEmAllService.d.ts +0 -20
- package/lib/typescript/src/games/connect-em-all/ConnectEmAllStore.d.ts +0 -48
- package/lib/typescript/src/games/connect-em-all/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/connect-em-all/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/crossy-road/CrossyRoadService.d.ts +0 -89
- package/lib/typescript/src/games/crossy-road/CrossyRoadStore.d.ts +0 -39
- package/lib/typescript/src/games/crossy-road/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/crossy-road/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/dino-jump/DinoJumpService.d.ts +0 -39
- package/lib/typescript/src/games/dino-jump/DinoJumpStore.d.ts +0 -97
- package/lib/typescript/src/games/dino-jump/components/DinoSprite.d.ts +0 -2
- package/lib/typescript/src/games/dino-jump/components/GameArea.d.ts +0 -7
- package/lib/typescript/src/games/dino-jump/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/dino-jump/components/ObstacleSprite.d.ts +0 -8
- package/lib/typescript/src/games/dino-jump/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/dino-jump/components/StarSprite.d.ts +0 -2
- package/lib/typescript/src/games/dots-and-boxes/DotsAndBoxesService.d.ts +0 -45
- package/lib/typescript/src/games/dots-and-boxes/DotsAndBoxesStore.d.ts +0 -37
- package/lib/typescript/src/games/dots-and-boxes/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/dots-and-boxes/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/falling-sticks/FallingSticksService.d.ts +0 -40
- package/lib/typescript/src/games/falling-sticks/FallingSticksStore.d.ts +0 -31
- package/lib/typescript/src/games/falling-sticks/components/GameArea.d.ts +0 -7
- package/lib/typescript/src/games/falling-sticks/components/GameBackground.d.ts +0 -6
- package/lib/typescript/src/games/falling-sticks/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/find-different-number/FindDifferentNumberService.d.ts +0 -6
- package/lib/typescript/src/games/find-different-number/FindDifferentNumberStore.d.ts +0 -36
- package/lib/typescript/src/games/find-different-number/components/GameGrid.d.ts +0 -7
- package/lib/typescript/src/games/find-different-number/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/flappy-bird/FlappyBirdStore.d.ts +0 -68
- package/lib/typescript/src/games/flappy-bird/components/Bird.d.ts +0 -2
- package/lib/typescript/src/games/flappy-bird/components/GameArea.d.ts +0 -7
- package/lib/typescript/src/games/flappy-bird/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/flappy-bird/components/Pipes.d.ts +0 -8
- package/lib/typescript/src/games/flappy-bird/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/fruit-merger/FruitMergerService.d.ts +0 -3
- package/lib/typescript/src/games/fruit-merger/FruitMergerStore.d.ts +0 -66
- package/lib/typescript/src/games/fruit-merger/components/FruitItem.d.ts +0 -8
- package/lib/typescript/src/games/fruit-merger/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/fruit-merger/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/fruit-ninja/FruitNinjaService.d.ts +0 -73
- package/lib/typescript/src/games/fruit-ninja/FruitNinjaStore.d.ts +0 -38
- package/lib/typescript/src/games/fruit-ninja/components/FruitComponent.d.ts +0 -8
- package/lib/typescript/src/games/fruit-ninja/components/GameArea.d.ts +0 -7
- package/lib/typescript/src/games/fruit-ninja/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/fruit-ninja/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/game-2048/Game2048Service.d.ts +0 -102
- package/lib/typescript/src/games/game-2048/Game2048Store.d.ts +0 -44
- package/lib/typescript/src/games/game-2048/components/GameGrid.d.ts +0 -2
- package/lib/typescript/src/games/game-2048/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/knife-hit/KnifeHitService.d.ts +0 -48
- package/lib/typescript/src/games/knife-hit/KnifeHitStore.d.ts +0 -41
- package/lib/typescript/src/games/knife-hit/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/knife-hit/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/ludo-king/LudoKingService.d.ts +0 -33
- package/lib/typescript/src/games/ludo-king/LudoKingStore.d.ts +0 -34
- package/lib/typescript/src/games/ludo-king/components/Dice.d.ts +0 -7
- package/lib/typescript/src/games/ludo-king/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/ludo-king/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/maze-runner/MazeRunnerStore.d.ts +0 -62
- package/lib/typescript/src/games/maze-runner/components/EnhancedBallComponent.d.ts +0 -10
- package/lib/typescript/src/games/maze-runner/components/EnhancedGameArea.d.ts +0 -33
- package/lib/typescript/src/games/maze-runner/components/ScoreBoard.d.ts +0 -24
- package/lib/typescript/src/games/maze-runner/components/SkiaPipeComponent.d.ts +0 -24
- package/lib/typescript/src/games/maze-runner/components/WallComponent.d.ts +0 -9
- package/lib/typescript/src/games/memory-match/MemoryMatchService.d.ts +0 -6
- package/lib/typescript/src/games/memory-match/MemoryMatchStore.d.ts +0 -42
- package/lib/typescript/src/games/memory-match/components/Card.d.ts +0 -6
- package/lib/typescript/src/games/memory-match/components/GameBoard.d.ts +0 -6
- package/lib/typescript/src/games/memory-match/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/mine-sweeper/MineSweeperService.d.ts +0 -22
- package/lib/typescript/src/games/mine-sweeper/MineSweeperStore.d.ts +0 -73
- package/lib/typescript/src/games/mine-sweeper/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/mine-sweeper/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/mob-control/MobControlService.d.ts +0 -74
- package/lib/typescript/src/games/mob-control/MobControlStore.d.ts +0 -66
- package/lib/typescript/src/games/mob-control/components/GameArea.d.ts +0 -11
- package/lib/typescript/src/games/mob-control/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/number-search/NumberSearchConstants.d.ts +0 -63
- package/lib/typescript/src/games/number-search/NumberSearchService.d.ts +0 -34
- package/lib/typescript/src/games/number-search/NumberSearchStore.d.ts +0 -70
- package/lib/typescript/src/games/number-search/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/number-search/components/NumberList.d.ts +0 -2
- package/lib/typescript/src/games/number-search/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/nuts-and-bolts/NutsAndBoltsService.d.ts +0 -67
- package/lib/typescript/src/games/nuts-and-bolts/NutsAndBoltsStore.d.ts +0 -45
- package/lib/typescript/src/games/nuts-and-bolts/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/nuts-and-bolts/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/pac-man/PacManService.d.ts +0 -73
- package/lib/typescript/src/games/pac-man/PacManStore.d.ts +0 -89
- package/lib/typescript/src/games/pac-man/components/GameCanvas.d.ts +0 -2
- package/lib/typescript/src/games/pac-man/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/paper-io/PaperIoService.d.ts +0 -70
- package/lib/typescript/src/games/paper-io/PaperIoStore.d.ts +0 -51
- package/lib/typescript/src/games/paper-io/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/paper-io/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/perfect-circle/PerfectCircleService.d.ts +0 -15
- package/lib/typescript/src/games/perfect-circle/PerfectCircleStore.d.ts +0 -55
- package/lib/typescript/src/games/perfect-circle/components/DrawingCanvas.d.ts +0 -8
- package/lib/typescript/src/games/perfect-circle/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/pipe-connect/PipeConnectService.d.ts +0 -17
- package/lib/typescript/src/games/pipe-connect/PipeConnectStore.d.ts +0 -31
- package/lib/typescript/src/games/pipe-connect/components/GameArea.d.ts +0 -7
- package/lib/typescript/src/games/pipe-connect/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/popit-fidget/PopitFidgetService.d.ts +0 -30
- package/lib/typescript/src/games/popit-fidget/PopitFidgetStore.d.ts +0 -33
- package/lib/typescript/src/games/popit-fidget/components/BubbleComponent.d.ts +0 -10
- package/lib/typescript/src/games/popit-fidget/components/FidgetGrid.d.ts +0 -10
- package/lib/typescript/src/games/popit-fidget/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/reversi/ReversiStore.d.ts +0 -46
- package/lib/typescript/src/games/reversi/components/GameBoard.d.ts +0 -6
- package/lib/typescript/src/games/reversi/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbersService.d.ts +0 -6
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbersStore.d.ts +0 -38
- package/lib/typescript/src/games/sliding-numbers/components/NumbersGrid.d.ts +0 -7
- package/lib/typescript/src/games/sliding-numbers/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/snake-3d/Snake3DService.d.ts +0 -29
- package/lib/typescript/src/games/snake-3d/Snake3DStore.d.ts +0 -49
- package/lib/typescript/src/games/snake-3d/components/GameGrid.d.ts +0 -2
- package/lib/typescript/src/games/snake-3d/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/snakes-and-ladders/SnakesAndLaddersService.d.ts +0 -22
- package/lib/typescript/src/games/snakes-and-ladders/SnakesAndLaddersStore.d.ts +0 -40
- package/lib/typescript/src/games/snakes-and-ladders/components/Dice.d.ts +0 -7
- package/lib/typescript/src/games/snakes-and-ladders/components/GameBoard.d.ts +0 -2
- package/lib/typescript/src/games/snakes-and-ladders/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/space-fighter/SpaceFighterService.d.ts +0 -117
- package/lib/typescript/src/games/space-fighter/SpaceFighterStore.d.ts +0 -54
- package/lib/typescript/src/games/space-fighter/components/AsteroidComponent.d.ts +0 -9
- package/lib/typescript/src/games/space-fighter/components/GameArea.d.ts +0 -9
- package/lib/typescript/src/games/space-fighter/components/GameBackground.d.ts +0 -6
- package/lib/typescript/src/games/space-fighter/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/space-fighter/components/Spacecraft3D.d.ts +0 -11
- package/lib/typescript/src/games/space-fighter/components/SpacecraftPath.d.ts +0 -9
- package/lib/typescript/src/games/spider-solitaire/SpiderSolitaireService.d.ts +0 -23
- package/lib/typescript/src/games/spider-solitaire/SpiderSolitaireStore.d.ts +0 -71
- package/lib/typescript/src/games/spider-solitaire/components/Card.d.ts +0 -10
- package/lib/typescript/src/games/spider-solitaire/components/CardPile.d.ts +0 -12
- package/lib/typescript/src/games/spider-solitaire/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/stack-tower/StackTowerService.d.ts +0 -51
- package/lib/typescript/src/games/stack-tower/StackTowerStore.d.ts +0 -52
- package/lib/typescript/src/games/stack-tower/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/stack-tower/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/sudoku/SudokuService.d.ts +0 -24
- package/lib/typescript/src/games/sudoku/SudokuStore.d.ts +0 -65
- package/lib/typescript/src/games/sudoku/components/GameArea.d.ts +0 -8
- package/lib/typescript/src/games/sudoku/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/tangram/TangramService.d.ts +0 -6
- package/lib/typescript/src/games/tangram/TangramStore.d.ts +0 -34
- package/lib/typescript/src/games/tangram/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/tangram/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/tank-1990/Tank1990Service.d.ts +0 -80
- package/lib/typescript/src/games/tank-1990/Tank1990Store.d.ts +0 -48
- package/lib/typescript/src/games/tank-1990/components/Controls.d.ts +0 -2
- package/lib/typescript/src/games/tank-1990/components/GameBoard.d.ts +0 -2
- package/lib/typescript/src/games/tank-1990/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/tic-tac-toe/TicTacToeService.d.ts +0 -0
- package/lib/typescript/src/games/tic-tac-toe/TicTacToeStore.d.ts +0 -51
- package/lib/typescript/src/games/tic-tac-toe/components/GameBoard.d.ts +0 -6
- package/lib/typescript/src/games/tic-tac-toe/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/tile-home/TileHomeService.d.ts +0 -1
- package/lib/typescript/src/games/tile-home/TileHomeStore.d.ts +0 -57
- package/lib/typescript/src/games/tile-home/components/AnimatingTile.d.ts +0 -9
- package/lib/typescript/src/games/tile-home/components/FlyingTile.d.ts +0 -16
- package/lib/typescript/src/games/tile-home/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/tile-home/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/tile-home/components/TileItem.d.ts +0 -11
- package/lib/typescript/src/games/tile-home/components/TileSlot.d.ts +0 -7
- package/lib/typescript/src/games/whack-a-mole/WhackAMoleService.d.ts +0 -32
- package/lib/typescript/src/games/whack-a-mole/WhackAMoleStore.d.ts +0 -39
- package/lib/typescript/src/games/whack-a-mole/components/GameBackground.d.ts +0 -7
- package/lib/typescript/src/games/whack-a-mole/components/GameGrid.d.ts +0 -10
- package/lib/typescript/src/games/whack-a-mole/components/GameHole.d.ts +0 -11
- package/lib/typescript/src/games/whack-a-mole/components/MoleCharacter.d.ts +0 -6
- package/lib/typescript/src/games/whack-a-mole/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/word-search/WordSearchConstants.d.ts +0 -63
- package/lib/typescript/src/games/word-search/WordSearchService.d.ts +0 -34
- package/lib/typescript/src/games/word-search/WordSearchStore.d.ts +0 -70
- package/lib/typescript/src/games/word-search/components/GameBoard.d.ts +0 -7
- package/lib/typescript/src/games/word-search/components/ScoreBoard.d.ts +0 -6
- package/lib/typescript/src/games/word-search/components/WordList.d.ts +0 -2
- package/lib/typescript/src/helpers/AnimatedScore.d.ts +0 -36
- package/lib/typescript/src/helpers/AnimationFrame.d.ts +0 -40
- package/lib/typescript/src/helpers/AnimationTracker.d.ts +0 -44
- package/lib/typescript/src/helpers/BlastAnimation.d.ts +0 -16
- package/lib/typescript/src/helpers/ErrorHandler.d.ts +0 -123
- package/lib/typescript/src/helpers/GameBackgroundPattern.d.ts +0 -7
- package/lib/typescript/src/helpers/GameControlButton.d.ts +0 -11
- package/lib/typescript/src/helpers/GameOverModal.d.ts +0 -15
- package/lib/typescript/src/helpers/GameTimer.d.ts +0 -26
- package/lib/typescript/src/helpers/Icons.d.ts +0 -12
- package/lib/typescript/src/helpers/ParticleBlast.d.ts +0 -11
- package/lib/typescript/src/helpers/ScoreBoardContainer.d.ts +0 -85
- package/lib/typescript/src/helpers/assets/apple-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/avocado-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/banana-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/bomb-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/broccoli-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/cherries-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/donut-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/dragonfruit-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/fries-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/fruit-helpers.d.ts +0 -154
- package/lib/typescript/src/helpers/assets/grapes-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/icecream-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/index.d.ts +0 -31
- package/lib/typescript/src/helpers/assets/kiwi-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/mango-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/orange-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/papaya-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/papaya-full-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/peach-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/pineapple-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/pomegranate-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/pumpkin-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/raspberry-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/star-item.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/strawberry-fruit.d.ts +0 -4
- package/lib/typescript/src/helpers/assets/watermelon-fruit.d.ts +0 -4
|
@@ -0,0 +1,1435 @@
|
|
|
1
|
+
// Fruit models for the Nayan engine games (from the engine's example, games/shapes/fruits.ts).
|
|
2
|
+
// Fruit built from the engine's custom shapes: lathed bodies with painted skins (blushes, streaks,
|
|
3
|
+
// stripes, speckles) and dimpled peel, tube stems and bananas, folded serrated leaves, seeds; each
|
|
4
|
+
// merged into one mesh. Every fruit also comes in two pieces for slicing, as in Fruit Ninja.
|
|
5
|
+
//
|
|
6
|
+
// Pieces share the whole fruit's origin and size. Each has its cut face toward +Z and its solid
|
|
7
|
+
// toward -Z: spawn pieces[0] turned a quarter turn about Y (cut facing +X, so it's the left piece)
|
|
8
|
+
// and pieces[1] turned the other way, where the fruit was, and push them apart.
|
|
9
|
+
import {
|
|
10
|
+
type Color,
|
|
11
|
+
extrude,
|
|
12
|
+
type Geometry,
|
|
13
|
+
type GeometryPart,
|
|
14
|
+
lathe,
|
|
15
|
+
merge,
|
|
16
|
+
type Model,
|
|
17
|
+
Path,
|
|
18
|
+
type Quat,
|
|
19
|
+
recolor,
|
|
20
|
+
tube,
|
|
21
|
+
type Vec3
|
|
22
|
+
} from '@nayan-ui/engine';
|
|
23
|
+
import { cacheGameAsset, createGameMesh as createShape } from './EngineMeshes';
|
|
24
|
+
|
|
25
|
+
export type FruitKind =
|
|
26
|
+
| 'apple'
|
|
27
|
+
| 'orange'
|
|
28
|
+
| 'lemon'
|
|
29
|
+
| 'pear'
|
|
30
|
+
| 'strawberry'
|
|
31
|
+
| 'watermelon'
|
|
32
|
+
| 'banana'
|
|
33
|
+
| 'cherries'
|
|
34
|
+
| 'grapes'
|
|
35
|
+
| 'kiwi'
|
|
36
|
+
| 'mango'
|
|
37
|
+
| 'peach'
|
|
38
|
+
| 'pineapple'
|
|
39
|
+
| 'pomegranate'
|
|
40
|
+
| 'papaya';
|
|
41
|
+
export type Fruit = {
|
|
42
|
+
whole: Model;
|
|
43
|
+
/** The left and right pieces after a slice. */
|
|
44
|
+
pieces: [Model, Model];
|
|
45
|
+
/** Color of its juice (for splashes). */
|
|
46
|
+
juice: Color;
|
|
47
|
+
/** Centre of the whole fruit's bounding box (stems and leaves included), in its own units. */
|
|
48
|
+
center: Vec3;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** The middle of a geometry's bounding box. */
|
|
52
|
+
function boxCenter(g: Geometry): Vec3 {
|
|
53
|
+
const lo = [Infinity, Infinity, Infinity];
|
|
54
|
+
const hi = [-Infinity, -Infinity, -Infinity];
|
|
55
|
+
for (let i = 0; i < g.vertices.length; i += 11) {
|
|
56
|
+
for (let k = 0; k < 3; k++) {
|
|
57
|
+
lo[k] = Math.min(lo[k]!, g.vertices[i + k]!);
|
|
58
|
+
hi[k] = Math.max(hi[k]!, g.vertices[i + k]!);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return [(lo[0]! + hi[0]!) / 2, (lo[1]! + hi[1]!) / 2, (lo[2]! + hi[2]!) / 2];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const TAU = Math.PI * 2;
|
|
65
|
+
|
|
66
|
+
// ── Little helpers: noise, colors, rotations ─────────────────────────────
|
|
67
|
+
|
|
68
|
+
const fract = (x: number) => x - Math.floor(x);
|
|
69
|
+
const hash = (x: number, y: number) => fract(Math.sin(x * 127.1 + y * 311.7) * 43758.5453);
|
|
70
|
+
const smooth = (t: number) => t * t * (3 - 2 * t);
|
|
71
|
+
const clamp01 = (x: number) => Math.max(0, Math.min(1, x));
|
|
72
|
+
const smoothstep = (a: number, b: number, x: number) => smooth(clamp01((x - a) / (b - a)));
|
|
73
|
+
|
|
74
|
+
/** Value noise, 0..1, repeating every `cu` cells in u (so it wraps around a lathe without a seam). */
|
|
75
|
+
function noise(u: number, v: number, cu: number, cv: number) {
|
|
76
|
+
const x = u * cu;
|
|
77
|
+
const y = v * cv;
|
|
78
|
+
const ix = Math.floor(x);
|
|
79
|
+
const iy = Math.floor(y);
|
|
80
|
+
const fx = smooth(x - ix);
|
|
81
|
+
const fy = smooth(y - iy);
|
|
82
|
+
const h = (i: number, j: number) => hash(((i % cu) + cu) % cu, j);
|
|
83
|
+
const top = h(ix, iy) + (h(ix + 1, iy) - h(ix, iy)) * fx;
|
|
84
|
+
const bottom = h(ix, iy + 1) + (h(ix + 1, iy + 1) - h(ix, iy + 1)) * fx;
|
|
85
|
+
return top + (bottom - top) * fy;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const mix = (a: Color, b: Color, t: number): Color => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
|
|
89
|
+
const shade = (c: Color, k: number): Color => [c[0] * k, c[1] * k, c[2] * k];
|
|
90
|
+
|
|
91
|
+
const turn = (axis: Vec3, angle: number): Quat => [
|
|
92
|
+
axis[0] * Math.sin(angle / 2),
|
|
93
|
+
axis[1] * Math.sin(angle / 2),
|
|
94
|
+
axis[2] * Math.sin(angle / 2),
|
|
95
|
+
Math.cos(angle / 2)
|
|
96
|
+
];
|
|
97
|
+
function mul(a: Quat, b: Quat): Quat {
|
|
98
|
+
const [ax, ay, az, aw] = a;
|
|
99
|
+
const [bx, by, bz, bw] = b;
|
|
100
|
+
return [
|
|
101
|
+
aw * bx + ax * bw + ay * bz - az * by,
|
|
102
|
+
aw * by - ax * bz + ay * bw + az * bx,
|
|
103
|
+
aw * bz + ax * by - ay * bx + az * bw,
|
|
104
|
+
aw * bw - ax * bx - ay * by - az * bz
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
/** The rotation taking +Y to direction `n` (unit). */
|
|
108
|
+
function upTo(n: Vec3): Quat {
|
|
109
|
+
const axis: Vec3 = [n[2], 0, -n[0]];
|
|
110
|
+
const len = Math.hypot(axis[0], axis[2]);
|
|
111
|
+
if (len < 1e-6) return n[1] > 0 ? [0, 0, 0, 1] : [1, 0, 0, 0];
|
|
112
|
+
return turn([axis[0] / len, 0, axis[2] / len], Math.acos(Math.max(-1, Math.min(1, n[1]))));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** A rotation about Y (pieces are turned so their cut faces +Z). */
|
|
116
|
+
const yTurn = (angle: number) => turn([0, 1, 0], angle);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Bends geometry in place: every vertex moved by `f`, its normal carried along (by the inverse
|
|
120
|
+
* transpose of f's derivative), so curves, leans and grooves still catch the light. For shapes a
|
|
121
|
+
* lathe can't make alone: a mango's kidney curve, a peach's groove. Cut faces bend with the skin.
|
|
122
|
+
*/
|
|
123
|
+
function warp(g: Geometry, f: (p: Vec3) => Vec3): Geometry {
|
|
124
|
+
const v = g.vertices;
|
|
125
|
+
const e = 1e-4;
|
|
126
|
+
const sub = (a: Vec3, b: Vec3): Vec3 => [(a[0] - b[0]) / e, (a[1] - b[1]) / e, (a[2] - b[2]) / e];
|
|
127
|
+
const cross = (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
|
|
128
|
+
for (let i = 0; i < v.length; i += 11) {
|
|
129
|
+
const [x, y, z] = [v[i]!, v[i + 1]!, v[i + 2]!];
|
|
130
|
+
const q = f([x, y, z]);
|
|
131
|
+
const [jx, jy, jz] = [sub(f([x + e, y, z]), q), sub(f([x, y + e, z]), q), sub(f([x, y, z + e]), q)];
|
|
132
|
+
const [a, b, c] = [cross(jy, jz), cross(jz, jx), cross(jx, jy)];
|
|
133
|
+
const [nx, ny, nz] = [v[i + 3]!, v[i + 4]!, v[i + 5]!];
|
|
134
|
+
const n = [0, 1, 2].map((k) => nx * a[k]! + ny * b[k]! + nz * c[k]!);
|
|
135
|
+
const len = Math.hypot(n[0]!, n[1]!, n[2]!);
|
|
136
|
+
v.set(q, i);
|
|
137
|
+
if (len > 1e-12) v.set([n[0]! / len, n[1]! / len, n[2]! / len], i + 3);
|
|
138
|
+
}
|
|
139
|
+
return g;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ── Profiles ─────────────────────────────────────────────────────────────
|
|
143
|
+
|
|
144
|
+
type Profile = [number, number][];
|
|
145
|
+
|
|
146
|
+
/** A profile from r(t), t going 0 (top) to 1 (bottom), `height` tall. */
|
|
147
|
+
/**
|
|
148
|
+
* Mesh detail for the fruit being built (1 = full). Games that show fruit small (Tile Home's 72 tiles)
|
|
149
|
+
* build lighter meshes: around and along each lathe, vertex counts scale by this.
|
|
150
|
+
*/
|
|
151
|
+
let detail = 1;
|
|
152
|
+
/** A segment / step count at the current detail (small counts are kept: seeds, grapes). */
|
|
153
|
+
const seg = (n: number) => (n <= 8 ? n : Math.max(8, Math.round(n * detail)));
|
|
154
|
+
|
|
155
|
+
function profile(height: number, r: (t: number) => number, steps = 48): Profile {
|
|
156
|
+
steps = seg(steps);
|
|
157
|
+
const out: Profile = [];
|
|
158
|
+
for (let i = 0; i <= steps; i++) {
|
|
159
|
+
const t = i / steps;
|
|
160
|
+
out.push([Math.max(0, r(t)), height / 2 - t * height]);
|
|
161
|
+
}
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/** Evenly spaced points along a profile, so painted details have vertices to land on. */
|
|
166
|
+
function resample(p: Profile, n: number): Profile {
|
|
167
|
+
n = seg(n);
|
|
168
|
+
const lengths = [0];
|
|
169
|
+
for (let i = 1; i < p.length; i++) lengths.push(lengths[i - 1]! + Math.hypot(p[i]![0] - p[i - 1]![0], p[i]![1] - p[i - 1]![1]));
|
|
170
|
+
const total = lengths[lengths.length - 1]!;
|
|
171
|
+
const out: Profile = [];
|
|
172
|
+
let k = 0;
|
|
173
|
+
for (let i = 0; i <= n; i++) {
|
|
174
|
+
const at = (i / n) * total;
|
|
175
|
+
while (k < p.length - 2 && lengths[k + 1]! < at) k++;
|
|
176
|
+
const t = (at - lengths[k]!) / (lengths[k + 1]! - lengths[k]! || 1);
|
|
177
|
+
out.push([p[k]![0] + (p[k + 1]![0] - p[k]![0]) * t, p[k]![1] + (p[k + 1]![1] - p[k]![1]) * t]);
|
|
178
|
+
}
|
|
179
|
+
return out;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** A rounded profile: an ellipse when `power` is 2, blunter above (a barrel, a kiwi), `height` tall. */
|
|
183
|
+
const rounded = (height: number, radius: number, power = 2, steps = 64) =>
|
|
184
|
+
profile(height, (t) => radius * Math.pow(Math.max(0, 1 - Math.pow(Math.abs(2 * t - 1), power)), 1 / power), steps);
|
|
185
|
+
|
|
186
|
+
/** A profile's radius at height `y` (for placing things on a cut face). */
|
|
187
|
+
function radiusAt(p: Profile, y: number) {
|
|
188
|
+
let best = 0;
|
|
189
|
+
for (let i = 0; i < p.length - 1; i++) {
|
|
190
|
+
const [r0, y0] = p[i]!;
|
|
191
|
+
const [r1, y1] = p[i + 1]!;
|
|
192
|
+
if ((y - y0) * (y - y1) <= 0 && y0 !== y1) best = Math.max(best, r0 + ((y - y0) / (y1 - y0)) * (r1 - r0));
|
|
193
|
+
}
|
|
194
|
+
return best;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* A dimpled profile from its highest point to its lowest, for a piece cut through the core: the cut
|
|
199
|
+
* face of a profile that turns back is filled without inner points, so painted cores wouldn't show.
|
|
200
|
+
*/
|
|
201
|
+
function undimpled(p: Profile): Profile {
|
|
202
|
+
let [top, bottom] = [0, 0];
|
|
203
|
+
p.forEach((q, i) => {
|
|
204
|
+
if (q[1] > p[top]![1]) top = i;
|
|
205
|
+
if (q[1] < p[bottom]![1]) bottom = i;
|
|
206
|
+
});
|
|
207
|
+
return p.slice(top, bottom + 1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Scales a profile so its lathe is 1 unit across its largest side, centered on the origin. */
|
|
211
|
+
function normalize(p: Profile): Profile {
|
|
212
|
+
const top = Math.max(...p.map((q) => q[1]));
|
|
213
|
+
const bottom = Math.min(...p.map((q) => q[1]));
|
|
214
|
+
const width = 2 * Math.max(...p.map((q) => q[0]));
|
|
215
|
+
const s = 1 / Math.max(width, top - bottom);
|
|
216
|
+
const mid = (top + bottom) / 2;
|
|
217
|
+
return p.map(([r, y]) => [r * s, (y - mid) * s]);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** The point and outward normal of a lathe of `p` at `v` down the profile and `angle` around. */
|
|
221
|
+
function onSurface(p: Profile, v: number, angle: number): [Vec3, Vec3] {
|
|
222
|
+
const f = v * (p.length - 1);
|
|
223
|
+
const i = Math.min(p.length - 2, Math.floor(f));
|
|
224
|
+
const t = f - i;
|
|
225
|
+
const [r0, y0] = p[i]!;
|
|
226
|
+
const [r1, y1] = p[i + 1]!;
|
|
227
|
+
const r = r0 + (r1 - r0) * t;
|
|
228
|
+
const y = y0 + (y1 - y0) * t;
|
|
229
|
+
const len = Math.hypot(r1 - r0, y1 - y0) || 1;
|
|
230
|
+
const [nr, ny] = [(y0 - y1) / len, (r1 - r0) / len];
|
|
231
|
+
const [c, s] = [Math.cos(angle), -Math.sin(angle)];
|
|
232
|
+
return [
|
|
233
|
+
[r * c, y, r * s],
|
|
234
|
+
[nr * c, ny, nr * s]
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// ── Parts: leaves, stems, seeds ──────────────────────────────────────────
|
|
239
|
+
|
|
240
|
+
const LEAF_TOP: Color = [0.24, 0.56, 0.17];
|
|
241
|
+
const LEAF_UNDER: Color = [0.19, 0.46, 0.14];
|
|
242
|
+
const VEIN: Color = [0.55, 0.74, 0.36];
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* A leaf from its base at the origin to its tip at +X, `length` long: two serrated halves folded up
|
|
246
|
+
* along a pale midrib (a V, like a real leaf), on a short stalk.
|
|
247
|
+
*/
|
|
248
|
+
function leaf(length: number, width: number, { fold = 0.38, teeth = 14, stalk = 0.16 } = {}): Geometry {
|
|
249
|
+
// One half's outline (y up): along the serrated edge to the tip, then back down the midrib.
|
|
250
|
+
const half = (sign: 1 | -1) => {
|
|
251
|
+
const pts: [number, number][] = [[0, 0]];
|
|
252
|
+
const steps = teeth * 2;
|
|
253
|
+
for (let i = 1; i < steps; i++) {
|
|
254
|
+
const s = i / steps;
|
|
255
|
+
const tooth = i % 2 ? 0.07 : 0; // little saw teeth along the edge
|
|
256
|
+
const w = width * Math.pow(Math.sin(Math.PI * s), 0.75) * (1 - 0.25 * s) * (1 + tooth);
|
|
257
|
+
pts.push([length * s, sign * w]);
|
|
258
|
+
}
|
|
259
|
+
pts.push([length, 0]);
|
|
260
|
+
// Path coordinates are y down.
|
|
261
|
+
return extrude(new Path().addPolygon(pts.map(([x, y]) => [x, -y] as [number, number])), { depth: 0.006 });
|
|
262
|
+
};
|
|
263
|
+
return merge([
|
|
264
|
+
{ geometry: half(1), rotation: turn([1, 0, 0], fold), color: LEAF_TOP },
|
|
265
|
+
{ geometry: half(-1), rotation: turn([1, 0, 0], -fold), color: LEAF_UNDER },
|
|
266
|
+
{
|
|
267
|
+
geometry: tube(
|
|
268
|
+
[
|
|
269
|
+
[0, 0, 0],
|
|
270
|
+
[length * 0.5, 0.004, 0],
|
|
271
|
+
[length * 0.96, 0, 0]
|
|
272
|
+
],
|
|
273
|
+
{ radius: (t) => 0.007 * (1 - t) + 0.002, sides: seg(6) }
|
|
274
|
+
),
|
|
275
|
+
color: VEIN
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
geometry: tube(
|
|
279
|
+
[
|
|
280
|
+
[-length * stalk, -0.01, 0],
|
|
281
|
+
[0, 0, 0]
|
|
282
|
+
],
|
|
283
|
+
{ radius: 0.008, sides: seg(6) }
|
|
284
|
+
),
|
|
285
|
+
color: [0.36, 0.42, 0.18]
|
|
286
|
+
}
|
|
287
|
+
]);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** A woody stem curving up from the origin, `height` tall, with a knobbly, paler cut end. */
|
|
291
|
+
function stem(height: number, radius = 0.024, bend = 0.06): Geometry {
|
|
292
|
+
return tube(
|
|
293
|
+
[
|
|
294
|
+
[0, -0.03, 0],
|
|
295
|
+
[0.005, height * 0.4, 0],
|
|
296
|
+
[bend * 0.5, height * 0.8, 0],
|
|
297
|
+
[bend, height, 0]
|
|
298
|
+
],
|
|
299
|
+
{
|
|
300
|
+
radius: (t) => radius * (1.25 - 0.45 * t + (t > 0.9 ? 0.5 * (t - 0.9) * 10 : 0)),
|
|
301
|
+
sides: seg(8),
|
|
302
|
+
color: (p) => mix([0.33, 0.21, 0.1], [0.5, 0.42, 0.28], smoothstep(0.75, 1, p.v) + 0.15 * noise(p.u, p.v, 6, 10)),
|
|
303
|
+
capColor: [0.62, 0.55, 0.4]
|
|
304
|
+
}
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** A seed: a small teardrop, 1 unit tall before scaling, pointing up. */
|
|
309
|
+
const seed = (segments = 8) =>
|
|
310
|
+
lathe(
|
|
311
|
+
[
|
|
312
|
+
[0, 0.5],
|
|
313
|
+
[0.22, 0.32],
|
|
314
|
+
[0.4, 0.02],
|
|
315
|
+
[0.36, -0.28],
|
|
316
|
+
[0.2, -0.45],
|
|
317
|
+
[0, -0.5]
|
|
318
|
+
],
|
|
319
|
+
{ segments }
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
/** A flat, pointed star (a calyx or the scar where a stem was). */
|
|
323
|
+
const calyx = (outer: number, inner: number, points: number, depth = 0.012) => extrude(new Path().addStar(0, 0, outer, inner, points), { depth });
|
|
324
|
+
|
|
325
|
+
/** Faces a geometry made facing +Z (an extrusion) up (+Y) instead. */
|
|
326
|
+
const FACE_UP = turn([1, 0, 0], -Math.PI / 2);
|
|
327
|
+
/** Turns a piece cut across (cut face down, -Y, solid up) to the convention: cut face +Z, solid -Z. */
|
|
328
|
+
const CUT_ACROSS = turn([1, 0, 0], -Math.PI / 2);
|
|
329
|
+
|
|
330
|
+
// ── The fruit ────────────────────────────────────────────────────────────
|
|
331
|
+
|
|
332
|
+
const SKIN_SEGMENTS = 72;
|
|
333
|
+
|
|
334
|
+
type Skin = (p: { u: number; v: number }) => Color;
|
|
335
|
+
/** A piece's painter: its u (around half a turn) or v (down half the profile) mapped onto the whole's. */
|
|
336
|
+
const halfTurn =
|
|
337
|
+
(skin: Skin): Skin =>
|
|
338
|
+
(q) =>
|
|
339
|
+
skin({ u: q.u * 0.5, v: q.v });
|
|
340
|
+
const upperHalf =
|
|
341
|
+
(skin: Skin): Skin =>
|
|
342
|
+
(q) =>
|
|
343
|
+
skin({ u: q.u, v: q.v * 0.5 });
|
|
344
|
+
const upperDisplace = (d: (u: number, v: number) => number) => (u: number, v: number) => d(u, v * 0.5);
|
|
345
|
+
|
|
346
|
+
function apple(): Fruit {
|
|
347
|
+
// Drawn as a path (x = distance from the core, y down): dimpled at the top and bottom.
|
|
348
|
+
const outline = Path.fromSVG('M0 0.1 C 0.12 -0.03 0.42 -0.06 0.5 0.3 C 0.55 0.62 0.36 0.9 0.14 0.93 Q 0.05 0.94 0 0.88');
|
|
349
|
+
const p = normalize(
|
|
350
|
+
resample(
|
|
351
|
+
outline.toContours()[0]!.map(([x, y]) => [x, -y]),
|
|
352
|
+
64
|
|
353
|
+
)
|
|
354
|
+
);
|
|
355
|
+
const RED: Color = [0.68, 0.04, 0.06];
|
|
356
|
+
const DEEP: Color = [0.45, 0.02, 0.05];
|
|
357
|
+
const GOLD: Color = [0.86, 0.66, 0.18];
|
|
358
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
359
|
+
// Streaky red over a gold-green ground that shows near the stem and the bottom.
|
|
360
|
+
const streak = noise(u, v, 90, 4);
|
|
361
|
+
let c = mix(RED, DEEP, smoothstep(0.35, 0.9, streak) * 0.7);
|
|
362
|
+
c = mix(c, GOLD, smoothstep(0.55, 0.8, noise(u, v, 7, 3)) * 0.35); // a sunny patch
|
|
363
|
+
c = mix(c, [0.72, 0.68, 0.22], smoothstep(0.16, 0.02, v) * 0.75 + smoothstep(0.86, 0.99, v) * 0.6);
|
|
364
|
+
// Lenticels: tiny pale dots.
|
|
365
|
+
if (hash(Math.floor(u * 140), Math.floor(v * 70)) > 0.975) c = mix(c, [0.95, 0.85, 0.55], 0.55);
|
|
366
|
+
return c;
|
|
367
|
+
};
|
|
368
|
+
const top = p[0]![1];
|
|
369
|
+
const bottom = p[p.length - 1]![1];
|
|
370
|
+
const body = lathe(p, { segments: seg(SKIN_SEGMENTS), color: skin });
|
|
371
|
+
const whole = merge([
|
|
372
|
+
{ geometry: body },
|
|
373
|
+
{ geometry: stem(0.17, 0.022, 0.05), position: [0, top, 0] },
|
|
374
|
+
{ geometry: leaf(0.32, 0.075), position: [0.03, top + 0.11, 0], rotation: mul(turn([0, 1, 0], -0.5), turn([0, 0, 1], 0.55)) },
|
|
375
|
+
{ geometry: calyx(0.05, 0.015, 5), position: [0, bottom - 0.004, 0], rotation: turn([1, 0, 0], Math.PI / 2), color: [0.3, 0.2, 0.1] }
|
|
376
|
+
]);
|
|
377
|
+
// Cut through the core: cream flesh, a faint core outline around the axis, two seeds.
|
|
378
|
+
const flesh = (r: number, y: number): Color => {
|
|
379
|
+
const core = Math.hypot(r / 0.2, y / 0.24);
|
|
380
|
+
let c: Color = [0.97, 0.93, 0.74];
|
|
381
|
+
c = mix(c, [0.92, 0.88, 0.62], smoothstep(1.05, 0.85, core)); // the core is a touch greener
|
|
382
|
+
c = mix(c, [0.82, 0.76, 0.5], smoothstep(0.12, 0, Math.abs(core - 1)) * 0.6); // its outline
|
|
383
|
+
return mix(c, [1, 0.97, 0.88], smoothstep(0.88, 1, r) * 0.6); // paler just under the skin
|
|
384
|
+
};
|
|
385
|
+
const pieces = (): [Model, Model] => {
|
|
386
|
+
const half = merge([
|
|
387
|
+
{
|
|
388
|
+
geometry: lathe(undimpled(p), {
|
|
389
|
+
segments: seg(SKIN_SEGMENTS),
|
|
390
|
+
sweep: Math.PI,
|
|
391
|
+
color: halfTurn(skin),
|
|
392
|
+
cutColor: flesh,
|
|
393
|
+
cutSteps: 24,
|
|
394
|
+
capColor: [0.7, 0.62, 0.25]
|
|
395
|
+
})
|
|
396
|
+
},
|
|
397
|
+
...[-1, 1].map((side): GeometryPart => ({
|
|
398
|
+
geometry: seed(),
|
|
399
|
+
position: [side * 0.06, -0.02, 0.004],
|
|
400
|
+
scale: [0.045, 0.075, 0.02],
|
|
401
|
+
rotation: turn([0, 0, 1], side * 0.35),
|
|
402
|
+
color: [0.3, 0.17, 0.08]
|
|
403
|
+
}))
|
|
404
|
+
]);
|
|
405
|
+
const piece = createShape(half, { center: false, shine: 0.3 });
|
|
406
|
+
return [piece, piece];
|
|
407
|
+
};
|
|
408
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.65 }), juice: [0.98, 0.94, 0.75] }, pieces);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/** Citrus segments on a face cut across: rind, white pith, wedges with pale membranes, a pithy core. */
|
|
412
|
+
function citrusFace(rind: Color, pith: Color, pulp: Color, wedges: number, pithWidth: number) {
|
|
413
|
+
return (r: number, angle: number): Color => {
|
|
414
|
+
if (r > 1 - pithWidth * 0.45) return rind;
|
|
415
|
+
if (r > 1 - pithWidth) return pith;
|
|
416
|
+
if (r < 0.12) return mix(pith, pulp, smoothstep(0.08, 0.12, r));
|
|
417
|
+
const w = TAU / wedges;
|
|
418
|
+
const across = Math.abs(fract(angle / w) - 0.5) * w * r; // distance from the wedge's middle, along the arc
|
|
419
|
+
const membrane = smoothstep(0.5 * w * r - 0.02, 0.5 * w * r - 0.006, across);
|
|
420
|
+
// Juice sacs: slightly lighter and darker grains, longer toward the rim.
|
|
421
|
+
const grain = noise(angle / TAU, r, wedges * 6, 9);
|
|
422
|
+
return mix(shade(pulp, 0.92 + 0.16 * grain), pith, membrane * 0.85);
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/** Pitted peel: shallow pores pushed into the surface. */
|
|
427
|
+
const peel = (depth: number, fine: number) => (u: number, v: number) =>
|
|
428
|
+
-depth * Math.pow(noise(u, v, fine, fine * 0.55), 2) - depth * 0.5 * noise(u, v, fine * 2.5, fine * 1.4);
|
|
429
|
+
|
|
430
|
+
function orange(): Fruit {
|
|
431
|
+
const p = normalize(rounded(0.94, 0.5, 2, 64));
|
|
432
|
+
const ORANGE: Color = [1, 0.47, 0.03];
|
|
433
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
434
|
+
let c = shade(ORANGE, 0.9 + 0.14 * noise(u, v, 40, 22));
|
|
435
|
+
c = mix(c, [0.82, 0.55, 0.12], smoothstep(0.05, 0, v) * 0.6); // green-brown around the stem
|
|
436
|
+
return mix(c, [0.75, 0.35, 0.05], smoothstep(0.95, 1, v) * 0.7); // the navel
|
|
437
|
+
};
|
|
438
|
+
const displace = peel(0.006, 64);
|
|
439
|
+
const top = p[0]![1];
|
|
440
|
+
const whole = merge([
|
|
441
|
+
{ geometry: lathe(p, { segments: seg(120), color: skin, displace }) },
|
|
442
|
+
{ geometry: calyx(0.06, 0.025, 5, 0.01), position: [0, top - 0.002, 0], rotation: FACE_UP, color: [0.3, 0.42, 0.14] },
|
|
443
|
+
{
|
|
444
|
+
geometry: tube(
|
|
445
|
+
[
|
|
446
|
+
[0, top - 0.01, 0],
|
|
447
|
+
[0, top + 0.035, 0]
|
|
448
|
+
],
|
|
449
|
+
{ radius: 0.014, sides: seg(6) }
|
|
450
|
+
),
|
|
451
|
+
color: [0.42, 0.4, 0.2]
|
|
452
|
+
}
|
|
453
|
+
]);
|
|
454
|
+
const pieces = (): [Model, Model] => {
|
|
455
|
+
// Cut across the middle: the top half, its cut face showing ten segments.
|
|
456
|
+
const upper = p.slice(0, Math.floor(p.length / 2) + 1);
|
|
457
|
+
const face = citrusFace(shade(ORANGE, 0.95), [0.99, 0.95, 0.84], [1, 0.58, 0.08], 10, 0.12);
|
|
458
|
+
const piece = createShape(
|
|
459
|
+
merge([
|
|
460
|
+
{
|
|
461
|
+
geometry: lathe(upper, { segments: seg(120), color: upperHalf(skin), displace: upperDisplace(displace), capColor: face, capRings: 24 }),
|
|
462
|
+
rotation: CUT_ACROSS
|
|
463
|
+
}
|
|
464
|
+
]),
|
|
465
|
+
{
|
|
466
|
+
center: false,
|
|
467
|
+
shine: 0.25
|
|
468
|
+
}
|
|
469
|
+
);
|
|
470
|
+
return [piece, piece];
|
|
471
|
+
};
|
|
472
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.35 }), juice: [1, 0.6, 0.1] }, pieces);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function lemon(): Fruit {
|
|
476
|
+
// Pointed at both ends; laid on its side.
|
|
477
|
+
const p = normalize(profile(1, (t) => 0.34 * Math.pow(Math.sin(Math.PI * t), 0.75), 64));
|
|
478
|
+
const YELLOW: Color = [1, 0.86, 0.12];
|
|
479
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
480
|
+
const c = shade(YELLOW, 0.9 + 0.14 * noise(u, v, 36, 20));
|
|
481
|
+
return mix(c, [0.62, 0.72, 0.15], (smoothstep(0.06, 0, v) + smoothstep(0.94, 1, v)) * 0.6); // greenish tips
|
|
482
|
+
};
|
|
483
|
+
const displace = peel(0.005, 56);
|
|
484
|
+
const side = turn([0, 0, 1], Math.PI / 2);
|
|
485
|
+
const whole = merge([{ geometry: lathe(p, { segments: seg(96), color: skin, displace }), rotation: side }]);
|
|
486
|
+
const pieces = (): [Model, Model] => {
|
|
487
|
+
const upper = p.slice(0, Math.floor(p.length / 2) + 1);
|
|
488
|
+
const face = citrusFace(YELLOW, [0.99, 0.97, 0.86], [1, 0.93, 0.5], 9, 0.1);
|
|
489
|
+
// Cut across the middle of its length (the cut face toward +Z, the rest along -Z, as the whole lies).
|
|
490
|
+
const piece = createShape(
|
|
491
|
+
merge([
|
|
492
|
+
{
|
|
493
|
+
geometry: lathe(upper, { segments: seg(96), color: upperHalf(skin), displace: upperDisplace(displace), capColor: face, capRings: 20 }),
|
|
494
|
+
rotation: CUT_ACROSS
|
|
495
|
+
}
|
|
496
|
+
]),
|
|
497
|
+
{
|
|
498
|
+
center: false,
|
|
499
|
+
shine: 0.3
|
|
500
|
+
}
|
|
501
|
+
);
|
|
502
|
+
return [piece, piece];
|
|
503
|
+
};
|
|
504
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.4 }), juice: [1, 0.95, 0.55] }, pieces);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
function pear(): Fruit {
|
|
508
|
+
// Narrow neck, round bottom, a slight dimple where the stem goes in.
|
|
509
|
+
const p = normalize(
|
|
510
|
+
profile(1, (t) => Math.pow(Math.sin(Math.PI * t), 0.55) * (0.18 + 0.37 * Math.pow(t, 1.35)) * (1 - 0.15 * Math.exp(-t * 30)), 64)
|
|
511
|
+
);
|
|
512
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
513
|
+
let c = mix([0.62, 0.74, 0.2], [0.84, 0.8, 0.28], noise(u, v, 6, 4));
|
|
514
|
+
const blush = Math.pow(Math.max(0, Math.cos((u - 0.2) * TAU)), 2) * smoothstep(0.3, 0.8, v);
|
|
515
|
+
c = mix(c, [0.78, 0.28, 0.12], blush * 0.55); // a red cheek on the sunny side
|
|
516
|
+
c = mix(c, [0.55, 0.42, 0.18], smoothstep(0.12, 0, v) * 0.6); // russet neck
|
|
517
|
+
if (hash(Math.floor(u * 120), Math.floor(v * 64)) > 0.95) c = mix(c, [0.5, 0.38, 0.18], 0.65); // speckles
|
|
518
|
+
return c;
|
|
519
|
+
};
|
|
520
|
+
const top = p[0]![1];
|
|
521
|
+
const bottom = p[p.length - 1]![1];
|
|
522
|
+
const whole = merge([
|
|
523
|
+
{ geometry: lathe(p, { segments: seg(SKIN_SEGMENTS), color: skin }) },
|
|
524
|
+
{ geometry: stem(0.2, 0.02, 0.07), position: [0, top, 0] },
|
|
525
|
+
{ geometry: calyx(0.035, 0.012, 5), position: [0, bottom - 0.003, 0], rotation: turn([1, 0, 0], Math.PI / 2), color: [0.32, 0.22, 0.12] }
|
|
526
|
+
]);
|
|
527
|
+
// The core sits low in a pear, with its seeds.
|
|
528
|
+
const flesh = (r: number, y: number): Color => {
|
|
529
|
+
const core = Math.hypot(r / 0.17, (y + 0.15) / 0.17);
|
|
530
|
+
let c: Color = [0.98, 0.96, 0.82];
|
|
531
|
+
c = mix(c, [0.92, 0.9, 0.7], smoothstep(1.1, 0.8, core));
|
|
532
|
+
return mix(c, [0.86, 0.82, 0.58], smoothstep(0.1, 0, Math.abs(core - 1)) * 0.6);
|
|
533
|
+
};
|
|
534
|
+
const pieces = (): [Model, Model] => {
|
|
535
|
+
const half = merge([
|
|
536
|
+
{ geometry: lathe(p, { segments: seg(SKIN_SEGMENTS), sweep: Math.PI, color: halfTurn(skin), cutColor: flesh }) },
|
|
537
|
+
...[-1, 1].map((side): GeometryPart => ({
|
|
538
|
+
geometry: seed(),
|
|
539
|
+
position: [side * 0.05, -0.16, 0.004],
|
|
540
|
+
scale: [0.035, 0.06, 0.018],
|
|
541
|
+
rotation: turn([0, 0, 1], side * 0.3),
|
|
542
|
+
color: [0.25, 0.14, 0.07]
|
|
543
|
+
}))
|
|
544
|
+
]);
|
|
545
|
+
const piece = createShape(half, { center: false, shine: 0.25 });
|
|
546
|
+
return [piece, piece];
|
|
547
|
+
};
|
|
548
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.45 }), juice: [0.98, 0.96, 0.8] }, pieces);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function strawberry(): Fruit {
|
|
552
|
+
// Broad shoulders, a pointed tip.
|
|
553
|
+
const p = normalize(profile(1, (t) => 0.5 * Math.pow(Math.sin(Math.PI * Math.min(1, t * 1.02)), 0.45) * (1 - 0.62 * Math.pow(t, 1.2)), 64));
|
|
554
|
+
const skin = ({ v }: { v: number }): Color => {
|
|
555
|
+
let c: Color = [0.82, 0.05, 0.1];
|
|
556
|
+
c = mix(c, [0.95, 0.8, 0.62], smoothstep(0.1, 0.02, v) * 0.7); // pale under the leaves
|
|
557
|
+
return mix(c, [0.95, 0.25, 0.12], smoothstep(0.8, 1, v) * 0.5); // a lighter, orange-red tip
|
|
558
|
+
};
|
|
559
|
+
// Seeds (achenes) spiral over the surface, every one at the golden angle from the last.
|
|
560
|
+
const seeds = (sweep: number): GeometryPart[] => {
|
|
561
|
+
const out: GeometryPart[] = [];
|
|
562
|
+
const n = 80;
|
|
563
|
+
for (let i = 0; i < n; i++) {
|
|
564
|
+
const v = 0.14 + (0.8 * i) / n;
|
|
565
|
+
const angle = fract(i * 0.381966) * TAU;
|
|
566
|
+
if (angle > sweep) continue;
|
|
567
|
+
const [pos, normal] = onSurface(p, v, angle);
|
|
568
|
+
out.push({
|
|
569
|
+
geometry: seed(6),
|
|
570
|
+
position: [pos[0] - normal[0] * 0.003, pos[1] - normal[1] * 0.003, pos[2] - normal[2] * 0.003], // half sunk into the skin
|
|
571
|
+
rotation: upTo(normal),
|
|
572
|
+
scale: [0.022, 0.018, 0.03],
|
|
573
|
+
color: [0.95, 0.8, 0.3]
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
return out;
|
|
577
|
+
};
|
|
578
|
+
const top = p[0]![1];
|
|
579
|
+
// Sepals: narrow pointed leaves fanned around the top, drooping over the shoulders.
|
|
580
|
+
const sepals: GeometryPart[] = [];
|
|
581
|
+
for (let i = 0; i < 8; i++) {
|
|
582
|
+
const around = (i / 8) * TAU + 0.2;
|
|
583
|
+
sepals.push({
|
|
584
|
+
geometry: leaf(0.26 + 0.05 * Math.sin(i * 2.3), 0.05, { fold: 0.2, teeth: 4, stalk: 0 }),
|
|
585
|
+
position: [0, top + 0.012, 0],
|
|
586
|
+
rotation: mul(turn([0, 1, 0], around), turn([0, 0, 1], 0.08 - 0.1 * Math.cos(i * 1.7)))
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
const crown: GeometryPart[] = [...sepals, { geometry: stem(0.12, 0.018, 0.02), position: [0, top - 0.02, 0], color: [0.55, 1.2, 0.5] }];
|
|
590
|
+
const whole = merge([{ geometry: lathe(p, { segments: seg(SKIN_SEGMENTS), color: skin }) }, ...seeds(TAU), ...crown]);
|
|
591
|
+
// Cut lengthwise: a pale heart fading to red at the edge.
|
|
592
|
+
const flesh = (r: number, y: number): Color => {
|
|
593
|
+
const c = mix([1, 0.85, 0.82], [0.88, 0.12, 0.16], smoothstep(0.35, 0.85, r));
|
|
594
|
+
return mix(c, [0.98, 0.75, 0.72], smoothstep(0.12, 0, Math.abs(r - 0.32)) * 0.4 * smoothstep(-0.4, 0.2, y)); // faint vascular ring
|
|
595
|
+
};
|
|
596
|
+
const pieces = (): [Model, Model] => {
|
|
597
|
+
const piece = createShape(
|
|
598
|
+
merge([{ geometry: lathe(p, { segments: seg(SKIN_SEGMENTS), sweep: Math.PI, color: halfTurn(skin), cutColor: flesh }) }, ...seeds(Math.PI)]),
|
|
599
|
+
{
|
|
600
|
+
center: false,
|
|
601
|
+
shine: 0.4
|
|
602
|
+
}
|
|
603
|
+
);
|
|
604
|
+
return [piece, piece];
|
|
605
|
+
};
|
|
606
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.55 }), juice: [0.95, 0.15, 0.2] }, pieces);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
function watermelon(): Fruit {
|
|
610
|
+
// Oblong: lathed along its length, then laid on its side.
|
|
611
|
+
const p = normalize(rounded(1, 0.36, 2.2, 64));
|
|
612
|
+
const DARK: Color = [0.07, 0.27, 0.08];
|
|
613
|
+
const LIGHT: Color = [0.42, 0.62, 0.26];
|
|
614
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
615
|
+
// Dark, jagged stripes running end to end over a pale ground.
|
|
616
|
+
const wobble = (noise(u, v, 16, 10) - 0.5) * 0.9;
|
|
617
|
+
const stripe = Math.sin((u * 16 + wobble) * TAU);
|
|
618
|
+
let c = mix(LIGHT, DARK, smoothstep(-0.35, 0.1, stripe));
|
|
619
|
+
c = shade(c, 0.9 + 0.15 * noise(u, v, 50, 30));
|
|
620
|
+
// The field spot where it lay on the ground: a creamy yellow patch on one side.
|
|
621
|
+
const spot = smoothstep(0.16, 0.05, Math.hypot((fract(u - 0.75 + 0.5) - 0.5) * 2.2, v - 0.5));
|
|
622
|
+
return mix(c, [0.82, 0.76, 0.38], spot * 0.85);
|
|
623
|
+
};
|
|
624
|
+
const side = turn([0, 0, 1], Math.PI / 2);
|
|
625
|
+
const whole = merge([{ geometry: lathe(p, { segments: seg(96), color: skin }), rotation: side }]);
|
|
626
|
+
// Cut across the middle: dark rind, a pale band, white, then red flesh, deeper toward the middle.
|
|
627
|
+
const face = (r: number): Color => {
|
|
628
|
+
if (r > 0.965) return DARK;
|
|
629
|
+
if (r > 0.92) return mix([0.62, 0.8, 0.45], [0.85, 0.93, 0.7], (0.965 - r) / 0.045);
|
|
630
|
+
if (r > 0.86) return mix([0.97, 0.97, 0.85], [0.98, 0.55, 0.5], smoothstep(0.92, 0.86, r));
|
|
631
|
+
return mix([0.98, 0.3, 0.32], [0.88, 0.1, 0.16], smoothstep(0.85, 0.2, r));
|
|
632
|
+
};
|
|
633
|
+
const pieces = (): [Model, Model] => {
|
|
634
|
+
const upper = p.slice(0, Math.floor(p.length / 2) + 1);
|
|
635
|
+
const r0 = upper[upper.length - 1]![0]; // the cut face's radius
|
|
636
|
+
const blackSeeds: GeometryPart[] = [];
|
|
637
|
+
for (let i = 0; i < 14; i++) {
|
|
638
|
+
const a = (i / 14) * TAU + (i % 2) * 0.12;
|
|
639
|
+
const rr = r0 * (0.5 + 0.1 * (i % 3));
|
|
640
|
+
// On the cut face (y = 0, facing -Y in the lathe), pointing out from the middle.
|
|
641
|
+
blackSeeds.push({
|
|
642
|
+
geometry: seed(),
|
|
643
|
+
position: [Math.cos(a) * rr, -0.004, -Math.sin(a) * rr],
|
|
644
|
+
rotation: mul(turn([0, 1, 0], a + Math.PI / 2), turn([1, 0, 0], Math.PI / 2)), // lying flat, pointing outward
|
|
645
|
+
scale: [0.03, 0.05, 0.012],
|
|
646
|
+
color: [0.08, 0.05, 0.04]
|
|
647
|
+
});
|
|
648
|
+
}
|
|
649
|
+
const half = merge([
|
|
650
|
+
{
|
|
651
|
+
geometry: merge([{ geometry: lathe(upper, { segments: seg(96), color: upperHalf(skin), capColor: face, capRings: 24 }) }, ...blackSeeds]),
|
|
652
|
+
rotation: CUT_ACROSS
|
|
653
|
+
}
|
|
654
|
+
]);
|
|
655
|
+
const piece = createShape(half, { center: false, shine: 0.25 });
|
|
656
|
+
return [piece, piece];
|
|
657
|
+
};
|
|
658
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.35 }), juice: [0.95, 0.2, 0.25] }, pieces);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function banana(): Fruit {
|
|
662
|
+
// A tapering, five-sided curve along X, centered, 1 unit from tip to stem.
|
|
663
|
+
const raw: Vec3[] = [];
|
|
664
|
+
for (let i = 0; i <= 12; i++) {
|
|
665
|
+
const a = Math.PI * (0.12 + (0.76 * i) / 12);
|
|
666
|
+
raw.push([-Math.cos(a) * 0.5, -Math.sin(a) * 0.3, 0]);
|
|
667
|
+
}
|
|
668
|
+
const xs = raw.map((q) => q[0]);
|
|
669
|
+
const ys = raw.map((q) => q[1]);
|
|
670
|
+
const [cx, cy] = [(Math.min(...xs) + Math.max(...xs)) / 2, (Math.min(...ys) + Math.max(...ys)) / 2];
|
|
671
|
+
const scale = 0.92 / (Math.max(...xs) - Math.min(...xs));
|
|
672
|
+
const arc: Vec3[] = raw.map(([x, y]) => [(x - cx) * scale, (y - cy) * scale + 0.06, 0]);
|
|
673
|
+
const radius = (t: number) => 0.014 + 0.09 * Math.pow(Math.sin(Math.PI * Math.min(1, 0.03 + t * 0.97)), 0.55);
|
|
674
|
+
const ridges = (around: number) => 1 + 0.06 * Math.cos(around * TAU * 5);
|
|
675
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
676
|
+
let c: Color = [1, 0.84, 0.16];
|
|
677
|
+
c = mix(c, [0.82, 0.76, 0.18], 0.4 * (0.5 + 0.5 * Math.cos(u * TAU * 5))); // darker in the grooves
|
|
678
|
+
c = mix(c, [0.62, 0.72, 0.2], smoothstep(0.82, 1, v) * 0.6); // still green by the stem
|
|
679
|
+
c = mix(c, [0.18, 0.12, 0.06], smoothstep(0.05, 0, v)); // the dark blossom tip
|
|
680
|
+
// Sugar spots.
|
|
681
|
+
const spot = noise(u, v, 18, 26);
|
|
682
|
+
if (spot > 0.78) c = mix(c, [0.45, 0.28, 0.08], smoothstep(0.78, 0.88, spot) * 0.9);
|
|
683
|
+
return c;
|
|
684
|
+
};
|
|
685
|
+
const flesh = (r: number): Color => (r > 0.9 ? [1, 0.84, 0.16] : r < 0.22 ? [0.86, 0.8, 0.58] : [0.99, 0.95, 0.78]);
|
|
686
|
+
// The stalk: green-brown, a little square, with a darker cut end.
|
|
687
|
+
const end = arc[arc.length - 1]!;
|
|
688
|
+
const prev = arc[arc.length - 2]!;
|
|
689
|
+
const dir = [end[0] - prev[0], end[1] - prev[1]];
|
|
690
|
+
const len = Math.hypot(dir[0]!, dir[1]!);
|
|
691
|
+
const stalkEnd: Vec3 = [end[0] + (dir[0]! / len) * 0.1, end[1] + (dir[1]! / len) * 0.1 + 0.015, 0];
|
|
692
|
+
const stalk = tube([end, stalkEnd], {
|
|
693
|
+
radius: (t) => 0.026 - 0.006 * t,
|
|
694
|
+
shape: (around) => 1 + 0.12 * Math.cos(around * TAU * 4),
|
|
695
|
+
sides: seg(12),
|
|
696
|
+
color: [0.45, 0.48, 0.2],
|
|
697
|
+
capColor: [0.3, 0.25, 0.12]
|
|
698
|
+
});
|
|
699
|
+
const body = (points: Vec3[], t0: number, t1: number) =>
|
|
700
|
+
tube(points, {
|
|
701
|
+
radius: (t) => radius(t0 + (t1 - t0) * t),
|
|
702
|
+
shape: ridges,
|
|
703
|
+
sides: seg(30),
|
|
704
|
+
smoothness: 6,
|
|
705
|
+
color: (p) => skin({ u: p.u, v: t0 + (t1 - t0) * p.v }),
|
|
706
|
+
capColor: (r) => flesh(r)
|
|
707
|
+
});
|
|
708
|
+
const whole = merge([{ geometry: body(arc, 0, 1) }, { geometry: stalk }]);
|
|
709
|
+
// Cut in the middle: the tip end on the left, the stalk end on the right, each turned so its cut faces +Z.
|
|
710
|
+
const pieces = (): [Model, Model] => {
|
|
711
|
+
const mid = Math.floor(arc.length / 2);
|
|
712
|
+
const left = body(arc.slice(0, mid + 1), 0, mid / (arc.length - 1));
|
|
713
|
+
const right = merge([{ geometry: body(arc.slice(mid), mid / (arc.length - 1), 1) }, { geometry: stalk }]);
|
|
714
|
+
return [
|
|
715
|
+
createShape(merge([{ geometry: left, rotation: turn([0, 1, 0], -Math.PI / 2) }]), { center: false, shine: 0.3 }),
|
|
716
|
+
createShape(merge([{ geometry: right, rotation: turn([0, 1, 0], Math.PI / 2) }]), { center: false, shine: 0.3 })
|
|
717
|
+
];
|
|
718
|
+
};
|
|
719
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.3 }), juice: [1, 0.95, 0.72] }, pieces);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
function cherries(): Fruit {
|
|
723
|
+
// Two glossy cherries, dimpled where the stems go in, hanging from stems joined at the top.
|
|
724
|
+
const outline = Path.fromSVG('M0 0.12 C 0.1 0.01 0.46 -0.04 0.5 0.42 C 0.53 0.76 0.3 0.98 0 0.96');
|
|
725
|
+
const p = normalize(
|
|
726
|
+
resample(
|
|
727
|
+
outline.toContours()[0]!.map(([x, y]) => [x, -y]),
|
|
728
|
+
40
|
|
729
|
+
)
|
|
730
|
+
);
|
|
731
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
732
|
+
let c = mix([0.55, 0.02, 0.07], [0.26, 0.0, 0.04], smoothstep(0.3, 0.75, noise(u, v, 5, 3)) * 0.6 + smoothstep(0.5, 1, v) * 0.35);
|
|
733
|
+
c = mix(c, [0.78, 0.12, 0.12], smoothstep(0.2, 0.05, v) * 0.4); // lighter around the stem
|
|
734
|
+
return mix(c, [0.2, 0.02, 0.03], smoothstep(0.92, 1, v) * 0.7); // the dark blossom point
|
|
735
|
+
};
|
|
736
|
+
const top = p[0]![1];
|
|
737
|
+
const S = 0.42;
|
|
738
|
+
const at: Vec3[] = [
|
|
739
|
+
[-0.2, -0.2, 0.02],
|
|
740
|
+
[0.19, -0.28, -0.04]
|
|
741
|
+
];
|
|
742
|
+
const join: Vec3 = [0.06, 0.55, 0];
|
|
743
|
+
const stemFrom = (c: Vec3, bow: number) =>
|
|
744
|
+
tube([[c[0], c[1] + top * S - 0.02, c[2]], [c[0] + bow * 0.4, c[1] + 0.38, c[2] * 0.5], [join[0] + bow * 0.15, join[1] - 0.12, 0], join], {
|
|
745
|
+
radius: (t) => 0.012 + 0.003 * t,
|
|
746
|
+
sides: seg(7),
|
|
747
|
+
color: (q) => mix([0.4, 0.55, 0.16], [0.42, 0.32, 0.14], smoothstep(0.75, 1, q.v)),
|
|
748
|
+
capColor: [0.35, 0.25, 0.12]
|
|
749
|
+
});
|
|
750
|
+
const stems: GeometryPart[] = [
|
|
751
|
+
{ geometry: stemFrom(at[0]!, -0.1) },
|
|
752
|
+
{ geometry: stemFrom(at[1]!, 0.08) },
|
|
753
|
+
{ geometry: leaf(0.3, 0.07), position: join, rotation: mul(turn([0, 1, 0], 0.6), turn([0, 0, 1], 0.4)) }
|
|
754
|
+
];
|
|
755
|
+
const body = lathe(p, { segments: seg(40), color: skin });
|
|
756
|
+
const whole = merge([...at.map((position): GeometryPart => ({ geometry: body, position, scale: S })), ...stems]);
|
|
757
|
+
// Cut through: dark red flesh around a pale stone.
|
|
758
|
+
const flesh = (r: number, y: number): Color => {
|
|
759
|
+
const stone = Math.hypot(r / 0.42, (y + 0.02) / 0.32);
|
|
760
|
+
if (stone < 1) return mix([0.93, 0.84, 0.66], [0.8, 0.66, 0.5], stone * stone);
|
|
761
|
+
return mix([0.62, 0.04, 0.1], [0.42, 0.01, 0.06], smoothstep(1, 2.2, stone));
|
|
762
|
+
};
|
|
763
|
+
const pieces = (): [Model, Model] => {
|
|
764
|
+
const half = lathe(undimpled(p), {
|
|
765
|
+
segments: seg(40),
|
|
766
|
+
sweep: Math.PI,
|
|
767
|
+
color: halfTurn(skin),
|
|
768
|
+
cutColor: flesh,
|
|
769
|
+
cutSteps: 20,
|
|
770
|
+
capColor: [0.5, 0.04, 0.08]
|
|
771
|
+
});
|
|
772
|
+
return [
|
|
773
|
+
createShape(merge([{ geometry: half, position: [0, at[0]![1], 0], scale: S }]), { center: false, shine: 0.7 }),
|
|
774
|
+
createShape(
|
|
775
|
+
merge([
|
|
776
|
+
{ geometry: half, position: [0, at[1]![1], 0], scale: S },
|
|
777
|
+
{ geometry: merge(stems), position: [-at[1]![0], 0, 0], rotation: yTurn(Math.PI / 2) }
|
|
778
|
+
]),
|
|
779
|
+
{
|
|
780
|
+
center: false,
|
|
781
|
+
shine: 0.7
|
|
782
|
+
}
|
|
783
|
+
)
|
|
784
|
+
];
|
|
785
|
+
};
|
|
786
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.85 }), juice: [0.6, 0.03, 0.1] }, pieces);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
function grapes(): Fruit {
|
|
790
|
+
// A bunch: dusky purple grapes with a waxy bloom, packed in a hanging cone below a woody stalk.
|
|
791
|
+
const p = normalize(rounded(1.12, 0.5, 2, 16));
|
|
792
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
793
|
+
let c = mix([0.3, 0.07, 0.27], [0.17, 0.03, 0.17], smoothstep(0.2, 0.9, noise(u, v, 4, 3)));
|
|
794
|
+
c = mix(c, [0.52, 0.46, 0.62], 0.3 * smoothstep(0.35, 0.8, noise(u, v, 9, 6))); // the powdery bloom
|
|
795
|
+
return mix(c, [0.36, 0.14, 0.25], smoothstep(0.6, 0.1, v) * 0.3); // a touch redder on top
|
|
796
|
+
};
|
|
797
|
+
const grape = lathe(p, { segments: seg(24), color: skin });
|
|
798
|
+
const half = lathe(p, {
|
|
799
|
+
segments: seg(24),
|
|
800
|
+
sweep: Math.PI,
|
|
801
|
+
color: halfTurn(skin),
|
|
802
|
+
cutColor: (r) => (r > 0.93 ? [0.3, 0.08, 0.25] : mix([0.86, 0.9, 0.62], [0.58, 0.68, 0.32], r * r)),
|
|
803
|
+
cutSteps: 6
|
|
804
|
+
});
|
|
805
|
+
const R = 0.085; // a grape's radius
|
|
806
|
+
// Rings of grapes, wide at the shoulders and narrowing to a single grape at the tip.
|
|
807
|
+
const spots: { at: Vec3; tint: Color; turn: number }[] = [];
|
|
808
|
+
const LAYERS = 8;
|
|
809
|
+
for (let i = 0; i < LAYERS; i++) {
|
|
810
|
+
const t = i / (LAYERS - 1);
|
|
811
|
+
const y = 0.32 - t * 0.78;
|
|
812
|
+
const ring = 0.26 * Math.pow(1 - t, 0.85) * (1 - 0.35 * Math.pow(1 - t, 6));
|
|
813
|
+
for (const [radius, offset] of [
|
|
814
|
+
[ring, 0],
|
|
815
|
+
[ring * 0.45, 0.5]
|
|
816
|
+
] as const) {
|
|
817
|
+
const count = radius < 0.03 ? (offset ? 0 : 1) : Math.max(1, Math.floor((TAU * radius) / (R * 1.85)));
|
|
818
|
+
for (let k = 0; k < count; k++) {
|
|
819
|
+
const a = ((k + offset + i * 0.37) / count) * TAU;
|
|
820
|
+
const j = hash(i, k + offset * 10);
|
|
821
|
+
spots.push({
|
|
822
|
+
at: [Math.cos(a) * radius, y + (j - 0.5) * 0.04, Math.sin(a) * radius],
|
|
823
|
+
tint: shade([1, 0.95 + 0.1 * j, 1], 0.85 + 0.3 * hash(k, i + 3)),
|
|
824
|
+
turn: j * 2
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
const scale: Vec3 = [R * 2, R * 2, R * 2];
|
|
830
|
+
const placed = (s: (typeof spots)[number]): GeometryPart => ({
|
|
831
|
+
geometry: grape,
|
|
832
|
+
position: s.at,
|
|
833
|
+
scale,
|
|
834
|
+
color: s.tint,
|
|
835
|
+
rotation: mul(turn([0, 0, 1], (s.turn - 1) * 0.5), yTurn(s.turn * 3))
|
|
836
|
+
});
|
|
837
|
+
// The stalk, a few branches into the bunch, a vine leaf and a curly tendril.
|
|
838
|
+
const WOOD = (q: { v: number; u: number }): Color => mix([0.42, 0.35, 0.16], [0.32, 0.22, 0.1], noise(q.u, q.v, 4, 6));
|
|
839
|
+
const stalk = tube(
|
|
840
|
+
[
|
|
841
|
+
[0.02, 0.62, 0],
|
|
842
|
+
[0, 0.48, 0],
|
|
843
|
+
[0.01, 0.3, 0],
|
|
844
|
+
[0, 0.1, 0]
|
|
845
|
+
],
|
|
846
|
+
{ radius: (t) => 0.022 - 0.008 * t, sides: seg(8), color: WOOD, capColor: [0.55, 0.48, 0.3] }
|
|
847
|
+
);
|
|
848
|
+
const branches: GeometryPart[] = [0, 1, 2, 3].map((k) => {
|
|
849
|
+
const a = (k / 4) * TAU + 0.4;
|
|
850
|
+
return {
|
|
851
|
+
geometry: tube(
|
|
852
|
+
[
|
|
853
|
+
[0, 0.42 - k * 0.04, 0],
|
|
854
|
+
[Math.cos(a) * 0.12, 0.36 - k * 0.05, Math.sin(a) * 0.12],
|
|
855
|
+
[Math.cos(a) * 0.2, 0.3 - k * 0.06, Math.sin(a) * 0.2]
|
|
856
|
+
],
|
|
857
|
+
{ radius: 0.009, sides: seg(6), color: WOOD }
|
|
858
|
+
)
|
|
859
|
+
};
|
|
860
|
+
});
|
|
861
|
+
const vine: [number, number][] = [];
|
|
862
|
+
for (let i = 0; i < 160; i++) {
|
|
863
|
+
const a = (i / 160) * TAU;
|
|
864
|
+
// Five pointed lobes (deepest toward the stalk, at the bottom) with saw teeth.
|
|
865
|
+
const lobes = 0.6 + 0.4 * Math.pow(Math.abs(Math.cos(2.5 * (a - Math.PI / 2))), 0.7);
|
|
866
|
+
const notch = 1 - 0.55 * Math.exp(-Math.pow((a - Math.PI / 2) / 0.22, 2)); // y down: the stalk end is +y
|
|
867
|
+
const r = 0.22 * lobes * notch * (1 + (i % 4 === 0 ? 0.06 : 0));
|
|
868
|
+
vine.push([Math.cos(a) * r, Math.sin(a) * r - 0.05]);
|
|
869
|
+
}
|
|
870
|
+
const vineLeaf = recolor(extrude(new Path().addPolygon(vine), { depth: 0.008 }), ({ position }) => {
|
|
871
|
+
const a = Math.atan2(position[1] + 0.05, position[0]);
|
|
872
|
+
const vein = Math.min(...[0, 1, 2, 3, 4].map((k) => Math.abs(Math.sin(a - (Math.PI / 2 + (k * TAU) / 5)))));
|
|
873
|
+
return mix([0.22, 0.48, 0.14], [0.55, 0.72, 0.3], smoothstep(0.08, 0, vein * Math.hypot(position[0], position[1] + 0.05) * 6) * 0.8);
|
|
874
|
+
});
|
|
875
|
+
const helix: Vec3[] = [];
|
|
876
|
+
for (let i = 0; i <= 24; i++) helix.push([-0.04 - i * 0.008, 0.56 + 0.05 * Math.sin(i * 0.8), 0.05 * Math.cos(i * 0.8)]);
|
|
877
|
+
const top: GeometryPart[] = [
|
|
878
|
+
{ geometry: stalk },
|
|
879
|
+
...branches,
|
|
880
|
+
{ geometry: vineLeaf, position: [0.17, 0.56, -0.06], rotation: mul(turn([0, 1, 0], -0.4), turn([1, 0, 0], -0.9)) },
|
|
881
|
+
{ geometry: tube(helix, { radius: 0.005, sides: seg(5), color: [0.45, 0.6, 0.2] }) }
|
|
882
|
+
];
|
|
883
|
+
const whole = merge([...spots.map(placed), ...top]);
|
|
884
|
+
// Sliced down the middle: the grapes on the cut halved (pale green inside), the rest to each side.
|
|
885
|
+
const side = (sign: 1 | -1): GeometryPart[] => {
|
|
886
|
+
const parts: GeometryPart[] = [];
|
|
887
|
+
for (const s of spots) {
|
|
888
|
+
if (Math.abs(s.at[0]) < R * 0.7)
|
|
889
|
+
parts.push({ geometry: half, position: [0, s.at[1], s.at[2]], scale, color: s.tint, rotation: yTurn((sign * Math.PI) / 2) });
|
|
890
|
+
else if (Math.sign(s.at[0]) === -sign) parts.push(placed(s));
|
|
891
|
+
}
|
|
892
|
+
return sign === 1 ? [...parts, ...top] : parts;
|
|
893
|
+
};
|
|
894
|
+
const pieces = (): [Model, Model] => {
|
|
895
|
+
return [
|
|
896
|
+
createShape(merge([{ geometry: merge(side(1)), rotation: yTurn(-Math.PI / 2) }]), { center: false, shine: 0.4 }),
|
|
897
|
+
createShape(merge([{ geometry: merge(side(-1)), rotation: yTurn(Math.PI / 2) }]), { center: false, shine: 0.4 })
|
|
898
|
+
];
|
|
899
|
+
};
|
|
900
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.4 }), juice: [0.75, 0.85, 0.45] }, pieces);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
function kiwi(): Fruit {
|
|
904
|
+
// A blunt oval with fuzzy brown skin, laid on its side.
|
|
905
|
+
const p = normalize(rounded(1, 0.4, 2.4, 72));
|
|
906
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
907
|
+
let c = mix([0.5, 0.35, 0.18], [0.36, 0.24, 0.11], noise(u, v, 12, 8));
|
|
908
|
+
c = shade(c, 0.85 + 0.3 * hash(Math.floor(u * 200), Math.floor(v * 90))); // the fuzz
|
|
909
|
+
return mix(c, [0.3, 0.2, 0.1], (smoothstep(0.05, 0, v) + smoothstep(0.95, 1, v)) * 0.6);
|
|
910
|
+
};
|
|
911
|
+
const displace = (u: number, v: number) => -0.004 * noise(u, v, 60, 30);
|
|
912
|
+
const SIDE = turn([0, 0, 1], Math.PI / 2);
|
|
913
|
+
// Cut across: bright green flesh streaked toward a creamy core, ringed with tiny black seeds.
|
|
914
|
+
const face = (r: number, angle: number): Color => {
|
|
915
|
+
if (r > 0.975) return [0.42, 0.3, 0.14];
|
|
916
|
+
if (r > 0.94) return mix([0.55, 0.72, 0.2], [0.4, 0.58, 0.12], (r - 0.94) / 0.035);
|
|
917
|
+
const ray = noise(angle / TAU, r, 70, 3); // fine streaks running out from the core
|
|
918
|
+
if (r < 0.26) return mix([0.97, 0.96, 0.78], [0.86, 0.9, 0.55], smoothstep(0.18, 0.26, r) * 0.6 + ray * 0.1);
|
|
919
|
+
const n = 56;
|
|
920
|
+
const cell = Math.floor((angle / TAU) * n);
|
|
921
|
+
const jitter = hash(cell, 7);
|
|
922
|
+
const off = (Math.abs(fract((angle / TAU) * n) - 0.5) / n) * TAU * r; // arc distance from the seed's middle
|
|
923
|
+
const mid = 0.34 + 0.06 * jitter;
|
|
924
|
+
if (Math.hypot(off / 0.016, (r - mid) / 0.045) < 1) return [0.06, 0.05, 0.03];
|
|
925
|
+
const c = mix([0.62, 0.86, 0.22], [0.44, 0.7, 0.08], smoothstep(0.3, 0.9, r));
|
|
926
|
+
return mix(c, [0.85, 0.95, 0.5], ray * 0.25 * smoothstep(0.95, 0.4, r));
|
|
927
|
+
};
|
|
928
|
+
const whole = merge([{ geometry: lathe(p, { segments: seg(96), color: skin, displace }), rotation: SIDE }]);
|
|
929
|
+
const pieces = (): [Model, Model] => {
|
|
930
|
+
const upper = p.slice(0, Math.floor(p.length / 2) + 1);
|
|
931
|
+
const piece = createShape(
|
|
932
|
+
merge([
|
|
933
|
+
{
|
|
934
|
+
geometry: lathe(upper, { segments: seg(168), color: upperHalf(skin), displace: upperDisplace(displace), capColor: face, capRings: 48 }),
|
|
935
|
+
rotation: CUT_ACROSS
|
|
936
|
+
}
|
|
937
|
+
]),
|
|
938
|
+
{
|
|
939
|
+
center: false,
|
|
940
|
+
shine: 0.45
|
|
941
|
+
}
|
|
942
|
+
);
|
|
943
|
+
return [piece, piece];
|
|
944
|
+
};
|
|
945
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.05 }), juice: [0.6, 0.85, 0.25] }, pieces);
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
/** A mango's bean curve and flattened sides, applied after lathing (so cut faces bend too). */
|
|
949
|
+
const mangoShape = ([x, y, z]: Vec3): Vec3 => [x - 0.22 * y * y + 0.05 * y, y, z * 0.8];
|
|
950
|
+
|
|
951
|
+
function mango(): Fruit {
|
|
952
|
+
// An egg, broad at the shoulders, curved like a bean and flattened, blushing from green to red.
|
|
953
|
+
const p = normalize(profile(1, (t) => 0.36 * Math.sqrt(Math.max(0, 1 - Math.pow(2 * t - 1, 2))) * (1.08 - 0.2 * t), 64));
|
|
954
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
955
|
+
const sun = Math.max(0, Math.cos(u * TAU)) * smoothstep(0.85, 0.15, v) + 0.4 * noise(u, v, 5, 3) - 0.15; // the side facing the sun
|
|
956
|
+
let c = mix([0.42, 0.6, 0.16], [0.96, 0.72, 0.15], smoothstep(0.95, 0.3, v) * 0.8 + 0.25 * noise(u, v, 4, 3));
|
|
957
|
+
c = mix(c, [0.98, 0.5, 0.12], smoothstep(0.1, 0.5, sun) * 0.8);
|
|
958
|
+
c = mix(c, [0.78, 0.12, 0.12], smoothstep(0.35, 0.85, sun) * 0.85);
|
|
959
|
+
if (hash(Math.floor(u * 110), Math.floor(v * 60)) > 0.965) c = mix(c, [0.98, 0.9, 0.55], 0.5); // lenticels
|
|
960
|
+
return c;
|
|
961
|
+
};
|
|
962
|
+
const top = p[0]![1];
|
|
963
|
+
const stemAt = mangoShape([0, top, 0]);
|
|
964
|
+
const stub: GeometryPart = { geometry: stem(0.05, 0.018, 0.01), position: [stemAt[0], stemAt[1] - 0.01, 0] };
|
|
965
|
+
const whole = merge([{ geometry: warp(lathe(p, { segments: seg(SKIN_SEGMENTS), color: skin }), mangoShape) }, stub]);
|
|
966
|
+
// Cut through the flat sides: deep yellow flesh around a pale, fibrous, flat stone.
|
|
967
|
+
const flesh = (r: number, y: number): Color => {
|
|
968
|
+
const stone = Math.hypot(r / 0.24, y / 0.34);
|
|
969
|
+
if (stone < 1) return mix([0.98, 0.86, 0.5], [0.9, 0.72, 0.32], noise(r, y + 1, 3, 40) * 0.5 + stone * 0.4);
|
|
970
|
+
const c = mix([1, 0.62, 0.08], [1, 0.76, 0.22], smoothstep(1, 2.6, stone));
|
|
971
|
+
return mix(c, [0.62, 0.7, 0.2], smoothstep(0.93, 1, r) * 0.6);
|
|
972
|
+
};
|
|
973
|
+
const pieces = (): [Model, Model] => {
|
|
974
|
+
const half = merge([
|
|
975
|
+
{
|
|
976
|
+
geometry: warp(lathe(p, { segments: seg(SKIN_SEGMENTS), sweep: Math.PI, color: halfTurn(skin), cutColor: flesh, cutSteps: 32 }), mangoShape)
|
|
977
|
+
},
|
|
978
|
+
stub
|
|
979
|
+
]);
|
|
980
|
+
const piece = createShape(half, { center: false, shine: 0.4 });
|
|
981
|
+
return [piece, piece];
|
|
982
|
+
};
|
|
983
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.5 }), juice: [1, 0.7, 0.15] }, pieces);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
/** A peach's groove (suture), down the side facing +Z, pinched toward the core. */
|
|
987
|
+
const peachShape = ([x, y, z]: Vec3): Vec3 => {
|
|
988
|
+
const k = 1 - 0.09 * Math.exp(-Math.pow(x / 0.08, 2)) * smoothstep(0, 0.3, z) * smoothstep(0.48, 0.15, Math.abs(y + 0.03));
|
|
989
|
+
return [x, y, z * k];
|
|
990
|
+
};
|
|
991
|
+
|
|
992
|
+
function peach(): Fruit {
|
|
993
|
+
// Round, with a dimpled top, a little point at the bottom, a groove down one side; velvety skin.
|
|
994
|
+
const outline = Path.fromSVG('M0 0.08 C 0.14 -0.02 0.48 -0.02 0.5 0.42 C 0.52 0.78 0.3 0.96 0.04 0.98 L 0 1.0');
|
|
995
|
+
const p = normalize(
|
|
996
|
+
resample(
|
|
997
|
+
outline.toContours()[0]!.map(([x, y]) => [x, -y]),
|
|
998
|
+
64
|
|
999
|
+
)
|
|
1000
|
+
);
|
|
1001
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
1002
|
+
const blush = smoothstep(0.3, 0.8, noise(u, v, 5, 4) * 0.6 + Math.max(0, Math.cos((u - 0.75) * TAU)) * 0.6);
|
|
1003
|
+
let c = mix([1, 0.74, 0.3], [1, 0.62, 0.22], noise(u, v, 10, 6));
|
|
1004
|
+
c = mix(c, [0.92, 0.3, 0.2], blush * 0.85);
|
|
1005
|
+
c = mix(c, [0.7, 0.1, 0.12], blush * smoothstep(0.6, 0.9, noise(u, v, 48, 28)) * 0.45); // freckled red
|
|
1006
|
+
return mix(shade(c, 0.97 + 0.05 * hash(Math.floor(u * 220), Math.floor(v * 110))), [1, 0.85, 0.7], 0.06); // the fuzz
|
|
1007
|
+
};
|
|
1008
|
+
const top = p[0]![1];
|
|
1009
|
+
const crown: GeometryPart[] = [
|
|
1010
|
+
{ geometry: stem(0.05, 0.02, 0.01), position: [0, top - 0.015, 0] },
|
|
1011
|
+
{
|
|
1012
|
+
geometry: leaf(0.4, 0.07, { teeth: 18, fold: 0.3 }),
|
|
1013
|
+
position: [0.01, top + 0.02, 0],
|
|
1014
|
+
rotation: mul(turn([0, 1, 0], 2.4), turn([0, 0, 1], 0.35))
|
|
1015
|
+
}
|
|
1016
|
+
];
|
|
1017
|
+
const whole = merge([{ geometry: warp(lathe(p, { segments: seg(SKIN_SEGMENTS), color: skin }), peachShape) }, ...crown]);
|
|
1018
|
+
// Cut down the groove: golden flesh blushing red around a wrinkled brown stone.
|
|
1019
|
+
const flesh = (r: number, y: number): Color => {
|
|
1020
|
+
const stone = Math.hypot(r / 0.4, (y + 0.02) / 0.34);
|
|
1021
|
+
if (stone < 1) return mix([0.55, 0.28, 0.14], [0.36, 0.17, 0.08], smoothstep(0.3, 0.7, noise(r * 3, y + 1, 7, 9)));
|
|
1022
|
+
let c = mix([1, 0.74, 0.3], [1, 0.82, 0.42], smoothstep(1.2, 2.6, stone));
|
|
1023
|
+
c = mix(c, [0.88, 0.3, 0.16], smoothstep(1.35, 1, stone) * 0.85); // red around the stone
|
|
1024
|
+
return mix(c, [0.85, 0.3, 0.18], smoothstep(0.94, 1, r) * 0.7);
|
|
1025
|
+
};
|
|
1026
|
+
const pieces = (): [Model, Model] => {
|
|
1027
|
+
const half = merge([
|
|
1028
|
+
{
|
|
1029
|
+
geometry: warp(
|
|
1030
|
+
lathe(undimpled(p), {
|
|
1031
|
+
segments: seg(SKIN_SEGMENTS),
|
|
1032
|
+
sweep: Math.PI,
|
|
1033
|
+
color: halfTurn(skin),
|
|
1034
|
+
cutColor: flesh,
|
|
1035
|
+
cutSteps: 32,
|
|
1036
|
+
capColor: [0.95, 0.5, 0.2]
|
|
1037
|
+
}),
|
|
1038
|
+
peachShape
|
|
1039
|
+
)
|
|
1040
|
+
},
|
|
1041
|
+
...crown
|
|
1042
|
+
]);
|
|
1043
|
+
const piece = createShape(half, { center: false, shine: 0.25 });
|
|
1044
|
+
return [piece, piece];
|
|
1045
|
+
};
|
|
1046
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.12 }), juice: [1, 0.75, 0.35] }, pieces);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
function pineapple(): Fruit {
|
|
1050
|
+
// A barrel covered in diamond scales ("eyes") on two spirals, under a crown of spiky leaves.
|
|
1051
|
+
const p = normalize(resample(rounded(1, 0.34, 2.6, 96), 110));
|
|
1052
|
+
const AROUND = 13;
|
|
1053
|
+
const DOWN = 7;
|
|
1054
|
+
// Each scale's coordinates: which cell, and where in it (0..1 both ways).
|
|
1055
|
+
const scale = (u: number, v: number) => {
|
|
1056
|
+
const a = u * AROUND + v * DOWN;
|
|
1057
|
+
const b = u * AROUND - v * DOWN;
|
|
1058
|
+
return { fa: fract(a), fb: fract(b), cell: Math.floor(a) * 31 + Math.floor(b) };
|
|
1059
|
+
};
|
|
1060
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
1061
|
+
const { fa, fb, cell } = scale(u, v);
|
|
1062
|
+
const edge = Math.max(Math.abs(fa - 0.5), Math.abs(fb - 0.5)) * 2; // 0 middle .. 1 groove
|
|
1063
|
+
const ripe = smoothstep(0.95, 0.3, v) * 0.8 + 0.3 * hash(cell, 3);
|
|
1064
|
+
let c = mix([0.42, 0.42, 0.12], [0.86, 0.58, 0.14], ripe);
|
|
1065
|
+
c = mix(c, [0.64, 0.42, 0.14], smoothstep(0.45, 0.15, edge) * 0.8); // the eye's brown middle
|
|
1066
|
+
// The spike at the top of each eye.
|
|
1067
|
+
if (Math.hypot(fa - 0.62, fb - 0.62) < 0.1) c = [0.3, 0.2, 0.08];
|
|
1068
|
+
return mix(c, [0.2, 0.18, 0.06], smoothstep(0.75, 1, edge) * 0.85); // dark grooves
|
|
1069
|
+
};
|
|
1070
|
+
const displace = (u: number, v: number) => {
|
|
1071
|
+
const { fa, fb } = scale(u, v);
|
|
1072
|
+
const edge = Math.max(Math.abs(fa - 0.5), Math.abs(fb - 0.5)) * 2;
|
|
1073
|
+
return 0.018 * (Math.sqrt(Math.max(0, 1 - edge * edge)) - 1) * smoothstep(0, 0.06, v) * smoothstep(1, 0.94, v);
|
|
1074
|
+
};
|
|
1075
|
+
const top = p[0]![1];
|
|
1076
|
+
// Crown leaves: flat, tapering, curling outward, in tiers (the inner ones tallest and most upright).
|
|
1077
|
+
const flat = (around: number) => 1 / Math.sqrt(Math.cos(around * TAU) ** 2 + (Math.sin(around * TAU) / 0.16) ** 2);
|
|
1078
|
+
const leaves: GeometryPart[] = [];
|
|
1079
|
+
const tiers = [
|
|
1080
|
+
{ n: 7, tilt: 0.45, length: 0.62 },
|
|
1081
|
+
{ n: 9, tilt: 0.8, length: 0.55 },
|
|
1082
|
+
{ n: 11, tilt: 1.15, length: 0.42 },
|
|
1083
|
+
{ n: 9, tilt: 1.45, length: 0.3 }
|
|
1084
|
+
];
|
|
1085
|
+
tiers.forEach(({ n, tilt, length }, tier) => {
|
|
1086
|
+
for (let k = 0; k < n; k++) {
|
|
1087
|
+
const around = ((k + tier * 0.5) / n) * TAU;
|
|
1088
|
+
const L = length * (0.85 + 0.3 * hash(k, tier));
|
|
1089
|
+
const pts: Vec3[] = [];
|
|
1090
|
+
for (let s = 0; s <= 5; s++) {
|
|
1091
|
+
const t = s / 5;
|
|
1092
|
+
const lean = tilt + t * 0.5; // curling outward toward the tip
|
|
1093
|
+
pts.push([Math.sin(lean) * L * t, Math.cos(lean) * L * t, 0]);
|
|
1094
|
+
}
|
|
1095
|
+
leaves.push({
|
|
1096
|
+
geometry: tube(pts, {
|
|
1097
|
+
radius: (t) => 0.045 * Math.pow(1 - t, 0.9) + 0.002,
|
|
1098
|
+
shape: flat,
|
|
1099
|
+
sides: seg(10),
|
|
1100
|
+
smoothness: 4,
|
|
1101
|
+
color: (q) => mix(mix([0.24, 0.42, 0.22], [0.36, 0.55, 0.3], q.v), [0.6, 0.55, 0.3], smoothstep(0.8, 1, q.v) * 0.7)
|
|
1102
|
+
}),
|
|
1103
|
+
position: [0, top + 0.01, 0],
|
|
1104
|
+
rotation: yTurn(around)
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
});
|
|
1108
|
+
const crown: GeometryPart = { geometry: merge(leaves) };
|
|
1109
|
+
const whole = merge([{ geometry: lathe(p, { segments: seg(130), color: skin, displace }) }, crown]);
|
|
1110
|
+
// Cut across: a ring of rind and eyes, juicy golden flesh with radial fibres, a paler woody core.
|
|
1111
|
+
const face = (r: number, angle: number): Color => {
|
|
1112
|
+
if (r > 0.95) return [0.55, 0.42, 0.14];
|
|
1113
|
+
const fibre = noise(angle / TAU, r, 90, 4);
|
|
1114
|
+
if (r > 0.86) return Math.abs(fract((angle / TAU) * AROUND * 2) - 0.5) < 0.12 && r > 0.89 ? [0.55, 0.35, 0.12] : [0.96, 0.84, 0.45];
|
|
1115
|
+
if (r < 0.2) return mix([1, 0.92, 0.62], [0.98, 0.86, 0.5], fibre * 0.4);
|
|
1116
|
+
return shade(mix([1, 0.78, 0.18], [1, 0.84, 0.3], smoothstep(0.8, 0.3, r)), 0.9 + 0.15 * fibre);
|
|
1117
|
+
};
|
|
1118
|
+
const pieces = (): [Model, Model] => {
|
|
1119
|
+
const mid = Math.floor(p.length / 2);
|
|
1120
|
+
const upper = p.slice(0, mid + 1);
|
|
1121
|
+
const lower = p.slice(mid);
|
|
1122
|
+
const upperSkin = (q: { u: number; v: number }) => skin({ u: q.u, v: q.v * 0.5 });
|
|
1123
|
+
const lowerSkin = (q: { u: number; v: number }) => skin({ u: q.u, v: 0.5 + q.v * 0.5 });
|
|
1124
|
+
const opts = { segments: seg(130), capColor: face, capRings: 30 };
|
|
1125
|
+
return [
|
|
1126
|
+
createShape(
|
|
1127
|
+
merge([
|
|
1128
|
+
{
|
|
1129
|
+
geometry: merge([{ geometry: lathe(upper, { ...opts, color: upperSkin, displace: (u, v) => displace(u, v * 0.5) }) }, crown]),
|
|
1130
|
+
rotation: CUT_ACROSS
|
|
1131
|
+
}
|
|
1132
|
+
]),
|
|
1133
|
+
{ center: false, shine: 0.3 }
|
|
1134
|
+
),
|
|
1135
|
+
createShape(
|
|
1136
|
+
merge([
|
|
1137
|
+
{
|
|
1138
|
+
geometry: lathe(lower, { ...opts, color: lowerSkin, displace: (u, v) => displace(u, 0.5 + v * 0.5) }),
|
|
1139
|
+
rotation: turn([1, 0, 0], Math.PI / 2)
|
|
1140
|
+
}
|
|
1141
|
+
]),
|
|
1142
|
+
{ center: false, shine: 0.3 }
|
|
1143
|
+
)
|
|
1144
|
+
];
|
|
1145
|
+
};
|
|
1146
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.3 }), juice: [1, 0.85, 0.3] }, pieces);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
function pomegranate(): Fruit {
|
|
1150
|
+
// A leathery red ball, slightly flattened and faceted, under a crown of pointed sepals.
|
|
1151
|
+
const p = normalize(rounded(0.9, 0.5, 2, 64));
|
|
1152
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
1153
|
+
let c = mix([0.72, 0.1, 0.1], [0.5, 0.04, 0.07], smoothstep(0.3, 0.8, noise(u, v, 6, 4)));
|
|
1154
|
+
c = mix(c, [0.88, 0.5, 0.32], smoothstep(0.6, 0.85, noise(u + 0.3, v, 5, 3)) * 0.55); // pale, sun-faded patches
|
|
1155
|
+
c = mix(c, [0.45, 0.06, 0.06], smoothstep(0.7, 0.95, noise(u, v, 60, 30)) * 0.4); // fine marks
|
|
1156
|
+
return mix(c, [0.62, 0.3, 0.2], smoothstep(0.08, 0, v) * 0.6);
|
|
1157
|
+
};
|
|
1158
|
+
const displace = (u: number, v: number) => -0.008 * Math.abs(Math.sin(u * TAU * 3)) * Math.sin(Math.PI * v); // six soft facets
|
|
1159
|
+
const top = p[0]![1];
|
|
1160
|
+
const SEPAL = (q: { v: number }): Color => mix([0.6, 0.14, 0.12], [0.42, 0.22, 0.12], smoothstep(0.6, 1, q.v));
|
|
1161
|
+
const crown: GeometryPart[] = [
|
|
1162
|
+
{
|
|
1163
|
+
geometry: tube(
|
|
1164
|
+
[
|
|
1165
|
+
[0, top - 0.04, 0],
|
|
1166
|
+
[0, top + 0.06, 0]
|
|
1167
|
+
],
|
|
1168
|
+
{ radius: (t) => 0.07 + 0.015 * t, sides: seg(18), color: SEPAL, capColor: [0.35, 0.12, 0.08] }
|
|
1169
|
+
)
|
|
1170
|
+
}
|
|
1171
|
+
];
|
|
1172
|
+
for (let k = 0; k < 6; k++) {
|
|
1173
|
+
const a = (k / 6) * TAU;
|
|
1174
|
+
crown.push({
|
|
1175
|
+
geometry: tube(
|
|
1176
|
+
[
|
|
1177
|
+
[0.07, 0, 0],
|
|
1178
|
+
[0.09, 0.05, 0],
|
|
1179
|
+
[0.12, 0.1, 0]
|
|
1180
|
+
],
|
|
1181
|
+
{ radius: (t) => 0.025 * (1 - t) + 0.002, sides: seg(6), color: SEPAL }
|
|
1182
|
+
),
|
|
1183
|
+
position: [0, top + 0.04, 0],
|
|
1184
|
+
rotation: yTurn(a)
|
|
1185
|
+
});
|
|
1186
|
+
}
|
|
1187
|
+
const whole = merge([{ geometry: lathe(p, { segments: seg(SKIN_SEGMENTS), color: skin, displace }) }, ...crown]);
|
|
1188
|
+
// Cut across: pale membranes between chambers packed with glossy, ruby seeds (arils).
|
|
1189
|
+
const face = (r: number): Color => (r > 0.95 ? [0.62, 0.08, 0.09] : r > 0.88 ? [0.98, 0.82, 0.68] : [0.96, 0.9, 0.72]);
|
|
1190
|
+
const pieces = (): [Model, Model] => {
|
|
1191
|
+
const upper = p.slice(0, Math.floor(p.length / 2) + 1);
|
|
1192
|
+
const r0 = upper[upper.length - 1]![0];
|
|
1193
|
+
const aril = lathe(rounded(1.2, 0.5, 2, 8), { segments: seg(8), color: [1, 1, 1] });
|
|
1194
|
+
const arils: GeometryPart[] = [];
|
|
1195
|
+
const GAP = 0.052;
|
|
1196
|
+
for (let gy = -1; gy <= 1; gy += GAP / r0) {
|
|
1197
|
+
for (let gx = -1; gx <= 1; gx += GAP / r0) {
|
|
1198
|
+
const jx = gx + (hash(gx * 13, gy * 7) - 0.5) * 0.04;
|
|
1199
|
+
const jy = gy + (hash(gy * 11, gx * 5) - 0.5) * 0.04 + ((Math.round(gx / (GAP / r0)) % 2) * GAP) / r0 / 2;
|
|
1200
|
+
const r = Math.hypot(jx, jy);
|
|
1201
|
+
const a = Math.atan2(jy, jx);
|
|
1202
|
+
const membrane = Math.abs(Math.sin(a * 3 + 0.3)) * r; // six chambers
|
|
1203
|
+
if (r > 0.84 || r < 0.1 || membrane < 0.05) continue;
|
|
1204
|
+
const h = hash(jx * 31, jy * 17);
|
|
1205
|
+
arils.push({
|
|
1206
|
+
geometry: aril,
|
|
1207
|
+
position: [jx * r0, -0.006, jy * r0],
|
|
1208
|
+
rotation: mul(yTurn(h * TAU), turn([1, 0, 0], Math.PI / 2 + (h - 0.5) * 0.6)),
|
|
1209
|
+
scale: [0.044, 0.05, 0.03],
|
|
1210
|
+
color: mix([0.85, 0.06, 0.14], [0.62, 0.02, 0.1], h)
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
const half = merge([
|
|
1215
|
+
{
|
|
1216
|
+
geometry: merge([
|
|
1217
|
+
{
|
|
1218
|
+
geometry: lathe(upper, {
|
|
1219
|
+
segments: seg(SKIN_SEGMENTS),
|
|
1220
|
+
color: upperHalf(skin),
|
|
1221
|
+
displace: upperDisplace(displace),
|
|
1222
|
+
capColor: face,
|
|
1223
|
+
capRings: 12
|
|
1224
|
+
})
|
|
1225
|
+
},
|
|
1226
|
+
...crown,
|
|
1227
|
+
...arils
|
|
1228
|
+
]),
|
|
1229
|
+
rotation: CUT_ACROSS
|
|
1230
|
+
}
|
|
1231
|
+
]);
|
|
1232
|
+
const piece = createShape(half, { center: false, shine: 0.55 });
|
|
1233
|
+
return [piece, piece];
|
|
1234
|
+
};
|
|
1235
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.45 }), juice: [0.8, 0.05, 0.15] }, pieces);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
function papaya(): Fruit {
|
|
1239
|
+
// Long, narrow at the stem end, green ripening to yellow-orange; laid on its side.
|
|
1240
|
+
const p = normalize(profile(1, (t) => 0.25 * Math.pow(Math.max(0, 1 - Math.pow(Math.abs(2 * t - 1), 2.2)), 1 / 2.2) * (0.7 + 0.42 * t), 72));
|
|
1241
|
+
const ribs = (u: number, v: number) => -0.006 * Math.pow(Math.abs(Math.cos(u * TAU * 2.5)), 3) * Math.sin(Math.PI * v); // five faint lobes
|
|
1242
|
+
const skin = ({ u, v }: { u: number; v: number }): Color => {
|
|
1243
|
+
const ripe = smoothstep(0.35, 0.8, v * 0.7 + noise(u, v, 5, 6) * 0.55);
|
|
1244
|
+
let c = mix([0.3, 0.5, 0.14], [0.98, 0.7, 0.16], ripe);
|
|
1245
|
+
c = mix(c, [0.95, 0.5, 0.12], ripe * smoothstep(0.55, 0.85, noise(u, v, 8, 10)) * 0.5);
|
|
1246
|
+
if (hash(Math.floor(u * 140), Math.floor(v * 90)) > 0.97) c = mix(c, [0.25, 0.35, 0.1], 0.5); // speckles
|
|
1247
|
+
return mix(c, [0.4, 0.5, 0.18], smoothstep(0.06, 0, v) * 0.6);
|
|
1248
|
+
};
|
|
1249
|
+
const SIDE = turn([0, 0, 1], -Math.PI / 2); // the stem end to +X
|
|
1250
|
+
const top = p[0]![1];
|
|
1251
|
+
const whole = merge([
|
|
1252
|
+
{
|
|
1253
|
+
geometry: merge([
|
|
1254
|
+
{ geometry: lathe(p, { segments: seg(SKIN_SEGMENTS), color: skin, displace: ribs }) },
|
|
1255
|
+
{ geometry: stem(0.04, 0.02, 0), position: [0, top - 0.01, 0], color: [1.3, 1.6, 0.9] }
|
|
1256
|
+
]),
|
|
1257
|
+
rotation: SIDE
|
|
1258
|
+
}
|
|
1259
|
+
]);
|
|
1260
|
+
// Cut lengthwise: salmon-orange flesh around a glistening hollow full of black seeds.
|
|
1261
|
+
const cavity = (y: number) => Math.max(0, 0.5 * Math.sin(Math.PI * smoothstep(0.25, -0.42, y)));
|
|
1262
|
+
const flesh = (r: number, y: number): Color => {
|
|
1263
|
+
const hollow = cavity(y);
|
|
1264
|
+
if (r > 0.96) return [0.5, 0.6, 0.15];
|
|
1265
|
+
if (r < hollow) return mix([0.5, 0.12, 0.07], [0.95, 0.42, 0.22], smoothstep(0.75, 1, r / hollow)); // the glistening hollow
|
|
1266
|
+
return mix([1, 0.5, 0.26], [1, 0.62, 0.34], smoothstep(hollow, 0.9, r));
|
|
1267
|
+
};
|
|
1268
|
+
const pieces = (): [Model, Model] => {
|
|
1269
|
+
const seeds: GeometryPart[] = [];
|
|
1270
|
+
for (let i = 0; i < 90; i++) {
|
|
1271
|
+
const y = 0.2 - 0.58 * hash(i, 1);
|
|
1272
|
+
const reach = cavity(y) * radiusAt(p, y) * 0.85;
|
|
1273
|
+
if (reach < 0.025) continue;
|
|
1274
|
+
const x = (hash(i, 2) * 2 - 1) * reach;
|
|
1275
|
+
seeds.push({
|
|
1276
|
+
geometry: lathe(rounded(1, 0.5, 2, 8), { segments: seg(10) }),
|
|
1277
|
+
position: [x, y, 0.004 + 0.01 * hash(i, 3)],
|
|
1278
|
+
scale: 0.042,
|
|
1279
|
+
color: [0.06, 0.05, 0.04]
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
const half = merge([
|
|
1283
|
+
{
|
|
1284
|
+
geometry: merge([
|
|
1285
|
+
{
|
|
1286
|
+
geometry: lathe(p, {
|
|
1287
|
+
segments: seg(SKIN_SEGMENTS),
|
|
1288
|
+
sweep: Math.PI,
|
|
1289
|
+
color: halfTurn(skin),
|
|
1290
|
+
displace: (u, v) => ribs(u * 0.5, v),
|
|
1291
|
+
cutColor: flesh,
|
|
1292
|
+
cutSteps: 24
|
|
1293
|
+
})
|
|
1294
|
+
},
|
|
1295
|
+
...seeds
|
|
1296
|
+
]),
|
|
1297
|
+
rotation: SIDE
|
|
1298
|
+
}
|
|
1299
|
+
]);
|
|
1300
|
+
const piece = createShape(half, { center: false, shine: 0.45 });
|
|
1301
|
+
return [piece, piece];
|
|
1302
|
+
};
|
|
1303
|
+
return withPieces({ center: boxCenter(whole), whole: createShape(whole, { center: false, shine: 0.4 }), juice: [1, 0.55, 0.3] }, pieces);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const sliced = new WeakSet<Fruit>();
|
|
1307
|
+
/** A fruit whose sliced pieces are only built if a game asks for them (Tile Home never does). */
|
|
1308
|
+
function withPieces(fruit: Omit<Fruit, 'pieces'>, build: (() => [Model, Model]) | undefined): Fruit {
|
|
1309
|
+
let pieces: [Model, Model] | undefined;
|
|
1310
|
+
const level = detail;
|
|
1311
|
+
const make = () => {
|
|
1312
|
+
detail = level;
|
|
1313
|
+
try {
|
|
1314
|
+
return build!();
|
|
1315
|
+
} finally {
|
|
1316
|
+
detail = 1;
|
|
1317
|
+
}
|
|
1318
|
+
};
|
|
1319
|
+
return Object.defineProperty(fruit, 'pieces', {
|
|
1320
|
+
get: () => {
|
|
1321
|
+
if (!pieces) {
|
|
1322
|
+
pieces = make();
|
|
1323
|
+
build = undefined; // release the builder's temporary geometry once both models are cached
|
|
1324
|
+
sliced.add(fruit as Fruit);
|
|
1325
|
+
}
|
|
1326
|
+
return pieces;
|
|
1327
|
+
},
|
|
1328
|
+
enumerable: true
|
|
1329
|
+
}) as Fruit;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
const BUILDERS: Record<FruitKind, () => Fruit> = {
|
|
1333
|
+
apple,
|
|
1334
|
+
orange,
|
|
1335
|
+
lemon,
|
|
1336
|
+
pear,
|
|
1337
|
+
strawberry,
|
|
1338
|
+
watermelon,
|
|
1339
|
+
banana,
|
|
1340
|
+
cherries,
|
|
1341
|
+
grapes,
|
|
1342
|
+
kiwi,
|
|
1343
|
+
mango,
|
|
1344
|
+
peach,
|
|
1345
|
+
pineapple,
|
|
1346
|
+
pomegranate,
|
|
1347
|
+
papaya
|
|
1348
|
+
};
|
|
1349
|
+
const built = new Map<string, Fruit>();
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* One fruit, built on first use (mesh ids last for the whole app). Needs the native core.
|
|
1353
|
+
* `level` < 1 builds a lighter mesh for fruit shown small (0.35 still looks round at 60 points).
|
|
1354
|
+
*/
|
|
1355
|
+
export function getFruit(kind: FruitKind, level = 1): Fruit {
|
|
1356
|
+
const key = `${kind}@${level}`;
|
|
1357
|
+
let fruit = built.get(key);
|
|
1358
|
+
if (!fruit) {
|
|
1359
|
+
let generated: Fruit | undefined;
|
|
1360
|
+
const generate = () => {
|
|
1361
|
+
detail = level;
|
|
1362
|
+
try {
|
|
1363
|
+
return BUILDERS[kind]();
|
|
1364
|
+
} finally {
|
|
1365
|
+
detail = 1;
|
|
1366
|
+
}
|
|
1367
|
+
};
|
|
1368
|
+
const whole = cacheGameAsset(`fruit:${key}:whole`, () => {
|
|
1369
|
+
generated = generate();
|
|
1370
|
+
return { whole: generated.whole, center: generated.center, juice: generated.juice };
|
|
1371
|
+
});
|
|
1372
|
+
let pieces: [Model, Model] | undefined;
|
|
1373
|
+
fruit = Object.defineProperty({ ...whole }, 'pieces', {
|
|
1374
|
+
enumerable: true,
|
|
1375
|
+
get: () => {
|
|
1376
|
+
if (!pieces) {
|
|
1377
|
+
pieces = cacheGameAsset(`fruit:${key}:pieces`, () => (generated ??= generate()).pieces);
|
|
1378
|
+
generated = undefined;
|
|
1379
|
+
sliced.add(fruit!);
|
|
1380
|
+
}
|
|
1381
|
+
return pieces;
|
|
1382
|
+
}
|
|
1383
|
+
}) as Fruit;
|
|
1384
|
+
built.set(key, fruit);
|
|
1385
|
+
}
|
|
1386
|
+
return fruit;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/** Whether `kind` is cached at `level`, including its sliced models when `withSlices` is true. */
|
|
1390
|
+
export const isFruitBuilt = (kind: FruitKind, level = 1, withSlices = false) => {
|
|
1391
|
+
const fruit = built.get(`${kind}@${level}`);
|
|
1392
|
+
return fruit !== undefined && (!withSlices || sliced.has(fruit));
|
|
1393
|
+
};
|
|
1394
|
+
|
|
1395
|
+
/**
|
|
1396
|
+
* Builds `kinds` one per frame, so the screen keeps animating while they're made, then calls `done`.
|
|
1397
|
+
* Already built fruit cost nothing. Returns a cancel function.
|
|
1398
|
+
*/
|
|
1399
|
+
export function loadFruits(kinds: readonly FruitKind[], done: () => void, level = 1): () => void {
|
|
1400
|
+
const queue = kinds.filter((k) => !built.has(`${k}@${level}`));
|
|
1401
|
+
let frame = 0;
|
|
1402
|
+
let cancelled = false;
|
|
1403
|
+
const step = () => {
|
|
1404
|
+
if (cancelled) return;
|
|
1405
|
+
const kind = queue.shift();
|
|
1406
|
+
if (kind) getFruit(kind, level);
|
|
1407
|
+
if (queue.length) frame = requestAnimationFrame(step);
|
|
1408
|
+
else done();
|
|
1409
|
+
};
|
|
1410
|
+
frame = requestAnimationFrame(step);
|
|
1411
|
+
return () => {
|
|
1412
|
+
cancelled = true;
|
|
1413
|
+
cancelAnimationFrame(frame);
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
let fruits: Record<FruitKind, Fruit> | undefined;
|
|
1418
|
+
/** Every fruit, built once (mesh ids last for the whole app). Needs the native core. */
|
|
1419
|
+
export function getFruits(): Record<FruitKind, Fruit> {
|
|
1420
|
+
if (!fruits) {
|
|
1421
|
+
// Each fruit is built when a game first reads it.
|
|
1422
|
+
const all = {} as Record<FruitKind, Fruit>;
|
|
1423
|
+
for (const kind of Object.keys(BUILDERS) as FruitKind[]) Object.defineProperty(all, kind, { get: () => getFruit(kind), enumerable: true });
|
|
1424
|
+
fruits = all;
|
|
1425
|
+
}
|
|
1426
|
+
return fruits;
|
|
1427
|
+
}
|
|
1428
|
+
|
|
1429
|
+
/** Whole bodies and cut pieces are separate jobs; board games never build unused slices. */
|
|
1430
|
+
export function* warmAssets(kinds: readonly FruitKind[], level: number, pieces = false): Iterable<() => unknown> {
|
|
1431
|
+
for (const kind of kinds) {
|
|
1432
|
+
yield () => getFruit(kind, level).whole;
|
|
1433
|
+
if (pieces) yield () => getFruit(kind, level).pieces;
|
|
1434
|
+
}
|
|
1435
|
+
}
|