@nayan-ui/games 1.20.0 → 1.21.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/lib/module/games/arrows/Arrows.js +1 -1
- package/lib/module/games/arrows/ArrowsScene.js +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlaster.js +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterScene.js +1 -1
- package/lib/module/games/bike-racing/BikeMeshes.js +1 -1
- 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/BikeRacingScene.js +1 -1
- package/lib/module/games/block-blast/BlockBlast.js +1 -1
- package/lib/module/games/block-blast/BlockBlastScene.js +1 -1
- package/lib/module/games/block-breaker/BlockBreaker.js +1 -1
- package/lib/module/games/block-breaker/BlockBreakerScene.js +1 -1
- package/lib/module/games/bluk/Bluk.js +1 -1
- package/lib/module/games/bluk/BlukScene.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooter.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooterScene.js +1 -1
- package/lib/module/games/candy-crush/CandyCrush.js +1 -1
- package/lib/module/games/candy-crush/CandyCrushScene.js +1 -1
- package/lib/module/games/car-racing/CarMeshes.js +1 -1
- package/lib/module/games/car-racing/CarRacing.js +1 -1
- package/lib/module/games/car-racing/CarRacingScene.js +1 -1
- package/lib/module/games/chameleon-run/ChameleonRun.js +1 -1
- package/lib/module/games/chameleon-run/ChameleonRunBackdrop.js +1 -1
- package/lib/module/games/chameleon-run/ChameleonRunMeshes.js +1 -1
- package/lib/module/games/checkers/Checkers.js +1 -1
- package/lib/module/games/checkers/CheckersScene.js +1 -1
- package/lib/module/games/color-switch/ColorSwitch.js +1 -1
- package/lib/module/games/color-switch/ColorSwitchScene.js +1 -1
- package/lib/module/games/colors-sort/ColorsSort.js +1 -1
- package/lib/module/games/colors-sort/ColorsSortScene.js +1 -1
- package/lib/module/games/connect-em-all/ConnectEmAll.js +1 -1
- package/lib/module/games/connect-em-all/ConnectEmAllScene.js +1 -1
- package/lib/module/games/crossy-road/CrossyRoad.js +1 -1
- package/lib/module/games/crossy-road/CrossyRoadMeshes.js +1 -1
- package/lib/module/games/crossy-road/CrossyRoadPerson.js +1 -1
- package/lib/module/games/dino-jump/DinoJump.js +1 -1
- package/lib/module/games/dino-jump/DinoJumpScene.js +1 -1
- package/lib/module/games/dots-and-boxes/DotsAndBoxes.js +1 -1
- package/lib/module/games/dots-and-boxes/DotsAndBoxesScene.js +1 -1
- package/lib/module/games/falling-sticks/FallingSticks.js +1 -1
- package/lib/module/games/falling-sticks/FallingSticksScene.js +1 -1
- package/lib/module/games/find-different-number/FindDifferentNumber.js +1 -1
- package/lib/module/games/find-different-number/FindDifferentNumberScene.js +1 -1
- package/lib/module/games/flappy-bird/FlappyBird.js +1 -1
- package/lib/module/games/flappy-bird/FlappyBirdScene.js +1 -1
- package/lib/module/games/fruit-merger/FruitMerger.js +1 -1
- package/lib/module/games/fruit-merger/FruitMergerScene.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinja.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaScene.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaWorld.js +1 -1
- package/lib/module/games/game-2048/Game2048.js +1 -1
- package/lib/module/games/game-2048/Game2048Scene.js +1 -1
- package/lib/module/games/knife-hit/KnifeHit.js +1 -1
- package/lib/module/games/knife-hit/KnifeHitScene.js +1 -1
- package/lib/module/games/ludo-king/LudoKing.js +1 -1
- package/lib/module/games/ludo-king/LudoKingScene.js +1 -1
- package/lib/module/games/maze-runner/MazeRunner.js +1 -1
- package/lib/module/games/maze-runner/MazeRunnerScene.js +1 -1
- package/lib/module/games/memory-match/MemoryMatch.js +1 -1
- package/lib/module/games/memory-match/MemoryMatchScene.js +1 -1
- package/lib/module/games/mine-sweeper/MineSweeper.js +1 -1
- package/lib/module/games/mine-sweeper/MineSweeperScene.js +1 -1
- package/lib/module/games/mob-control/MobControl.js +1 -1
- package/lib/module/games/mob-control/MobControlGame.js +1 -1
- package/lib/module/games/mob-control/MobControlMeshes.js +1 -1
- package/lib/module/games/mob-control/MobControlRenderer.js +1 -1
- package/lib/module/games/mob-control/MobControlRules.js +1 -1
- package/lib/module/games/mob-control/MobControlScene.js +1 -1
- package/lib/module/games/nuts-and-bolts/NutsAndBolts.js +1 -1
- package/lib/module/games/nuts-and-bolts/NutsAndBoltsScene.js +1 -1
- package/lib/module/games/pac-man/PacMan.js +1 -1
- package/lib/module/games/pac-man/PacManGame.js +1 -1
- package/lib/module/games/pac-man/PacManScene.js +1 -1
- package/lib/module/games/paper-io/PaperIo.js +1 -1
- package/lib/module/games/paper-io/PaperIoMeshes.js +1 -1
- package/lib/module/games/paper-io/PaperIoScene.js +1 -1
- package/lib/module/games/penguin-run/PenguinMeshes.js +1 -1
- package/lib/module/games/penguin-run/PenguinRun.js +1 -1
- package/lib/module/games/penguin-run/PenguinRunScene.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircle.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircleScene.js +1 -1
- package/lib/module/games/pipe-connect/PipeConnect.js +1 -1
- package/lib/module/games/pipe-connect/PipeConnectScene.js +1 -1
- package/lib/module/games/play-with-tua/PlayWithTua.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidget.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetScene.js +1 -1
- package/lib/module/games/reversi/Reversi.js +1 -1
- package/lib/module/games/reversi/ReversiScene.js +1 -1
- package/lib/module/games/search-grid/SearchGrid.js +1 -1
- package/lib/module/games/search-grid/SearchGridScene.js +1 -1
- package/lib/module/games/shared/BackdropCard.js +1 -1
- package/lib/module/games/shared/EngineBackdrop.js +1 -1
- package/lib/module/games/shared/EngineBlasts.js +1 -1
- package/lib/module/games/shared/EngineBlocks.js +1 -1
- package/lib/module/games/shared/EngineDice.js +1 -1
- package/lib/module/games/shared/EngineFruits.js +1 -1
- package/lib/module/games/shared/EngineGameLoader.js +1 -1
- package/lib/module/games/shared/EngineGameScreen.js +1 -1
- package/lib/module/games/shared/EngineGlyphs.js +1 -1
- package/lib/module/games/shared/EngineHud.js +1 -1
- package/lib/module/games/shared/EngineMeadow.js +1 -1
- package/lib/module/games/shared/EngineTouchSurface.js +1 -1
- package/lib/module/games/shared/GameActivity.js +1 -1
- package/lib/module/games/shared/GameLoading.js +1 -1
- package/lib/module/games/shared/GameLoadingTransition.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbers.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersScene.js +1 -1
- package/lib/module/games/snake-3d/Snake3D.js +1 -1
- package/lib/module/games/snake-3d/Snake3DScene.js +1 -1
- package/lib/module/games/snakes-and-ladders/SnakesAndLadders.js +1 -1
- package/lib/module/games/snakes-and-ladders/SnakesAndLaddersScene.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighter.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighterScene.js +1 -1
- package/lib/module/games/spider-solitaire/SpiderSolitaire.js +1 -1
- package/lib/module/games/spider-solitaire/SpiderSolitaireScene.js +1 -1
- package/lib/module/games/stack-tower/StackTower.js +1 -1
- package/lib/module/games/stack-tower/StackTowerScene.js +1 -1
- package/lib/module/games/sudoku/Sudoku.js +1 -1
- package/lib/module/games/sudoku/SudokuScene.js +1 -1
- package/lib/module/games/tangram/Tangram.js +1 -1
- package/lib/module/games/tangram/TangramScene.js +1 -1
- package/lib/module/games/tank-1990/Tank1990.js +1 -1
- package/lib/module/games/tank-1990/Tank1990Scene.js +1 -1
- package/lib/module/games/tic-tac-toe/TicTacToe.js +1 -1
- package/lib/module/games/tic-tac-toe/TicTacToeScene.js +1 -1
- package/lib/module/games/tile-home/TileHome.js +1 -1
- package/lib/module/games/tile-home/TileHomeScene.js +1 -1
- package/lib/module/games/treasure-hunt/TreasureHunt.js +1 -1
- package/lib/module/games/treasure-hunt/TreasureHuntConstants.js +1 -1
- package/lib/module/games/treasure-hunt/TreasureHuntModel.js +1 -1
- package/lib/module/games/treasure-hunt/TreasureHuntScene.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMole.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleScene.js +1 -1
- package/lib/module/helpers/GameSettingsModal.js +1 -1
- package/lib/module/helpers/GameTheme.js +1 -1
- package/package.json +1 -2
- 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 +0 -51
- package/src/assets/models/explorer/source.json +0 -222
- package/src/assets/models/play-with-tua/play-with-tua.glb +0 -0
- package/src/assets/models/play-with-tua/sources.json +0 -141
- 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 +0 -87
- 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 +0 -69
- package/src/games/arrows/ArrowsConstants.ts +0 -107
- package/src/games/arrows/ArrowsGame.ts +0 -735
- package/src/games/arrows/ArrowsScene.ts +0 -395
- package/src/games/balloon-blaster/BalloonBlaster.tsx +0 -75
- package/src/games/balloon-blaster/BalloonBlasterConstants.ts +0 -79
- package/src/games/balloon-blaster/BalloonBlasterGame.ts +0 -287
- package/src/games/balloon-blaster/BalloonBlasterPhysics.ts +0 -95
- package/src/games/balloon-blaster/BalloonBlasterScene.ts +0 -225
- package/src/games/bike-racing/BikeMeshes.ts +0 -273
- package/src/games/bike-racing/BikeRacing.tsx +0 -211
- package/src/games/bike-racing/BikeRacingConstants.ts +0 -103
- package/src/games/bike-racing/BikeRacingGame.ts +0 -557
- package/src/games/bike-racing/BikeRacingScene.ts +0 -119
- package/src/games/block-blast/BlockBlast.tsx +0 -73
- package/src/games/block-blast/BlockBlastConstants.ts +0 -179
- package/src/games/block-blast/BlockBlastGame.ts +0 -471
- package/src/games/block-blast/BlockBlastScene.ts +0 -156
- package/src/games/block-breaker/BlockBreaker.tsx +0 -79
- package/src/games/block-breaker/BlockBreakerConstants.ts +0 -139
- package/src/games/block-breaker/BlockBreakerGame.ts +0 -459
- package/src/games/block-breaker/BlockBreakerScene.ts +0 -257
- package/src/games/bluk/Bluk.tsx +0 -82
- package/src/games/bluk/BlukConstants.ts +0 -121
- package/src/games/bluk/BlukGame.ts +0 -323
- package/src/games/bluk/BlukRules.ts +0 -154
- package/src/games/bluk/BlukScene.ts +0 -514
- package/src/games/bubble-shooter/BubbleShooter.tsx +0 -76
- package/src/games/bubble-shooter/BubbleShooterConstants.ts +0 -103
- package/src/games/bubble-shooter/BubbleShooterGame.ts +0 -459
- package/src/games/bubble-shooter/BubbleShooterScene.ts +0 -158
- package/src/games/candy-crush/CandyCrush.tsx +0 -77
- package/src/games/candy-crush/CandyCrushConstants.ts +0 -94
- package/src/games/candy-crush/CandyCrushGame.ts +0 -477
- package/src/games/candy-crush/CandyCrushScene.ts +0 -209
- package/src/games/car-racing/CarMeshes.ts +0 -440
- package/src/games/car-racing/CarRacing.tsx +0 -211
- package/src/games/car-racing/CarRacingConstants.ts +0 -167
- package/src/games/car-racing/CarRacingFacade.ts +0 -40
- package/src/games/car-racing/CarRacingGame.ts +0 -539
- package/src/games/car-racing/CarRacingScene.ts +0 -1026
- package/src/games/car-racing/CarRacingScenery.ts +0 -265
- package/src/games/chameleon-run/ChameleonRun.tsx +0 -96
- package/src/games/chameleon-run/ChameleonRunBackdrop.ts +0 -186
- package/src/games/chameleon-run/ChameleonRunConstants.ts +0 -47
- package/src/games/chameleon-run/ChameleonRunGame.ts +0 -309
- package/src/games/chameleon-run/ChameleonRunMeshes.ts +0 -305
- package/src/games/chameleon-run/ChameleonRunRules.ts +0 -252
- package/src/games/chameleon-run/ChameleonRunScene.ts +0 -310
- package/src/games/checkers/Checkers.tsx +0 -83
- package/src/games/checkers/CheckersAI.ts +0 -255
- package/src/games/checkers/CheckersConstants.ts +0 -68
- package/src/games/checkers/CheckersGame.ts +0 -322
- package/src/games/checkers/CheckersRules.ts +0 -167
- package/src/games/checkers/CheckersScene.ts +0 -308
- package/src/games/color-switch/ColorSwitch.tsx +0 -75
- package/src/games/color-switch/ColorSwitchConstants.ts +0 -61
- package/src/games/color-switch/ColorSwitchGame.ts +0 -329
- package/src/games/color-switch/ColorSwitchScene.ts +0 -220
- package/src/games/colors-sort/ColorsSort.tsx +0 -82
- package/src/games/colors-sort/ColorsSortConstants.ts +0 -119
- package/src/games/colors-sort/ColorsSortGame.ts +0 -246
- package/src/games/colors-sort/ColorsSortScene.ts +0 -315
- package/src/games/connect-em-all/ConnectEmAll.tsx +0 -70
- package/src/games/connect-em-all/ConnectEmAllConstants.ts +0 -77
- package/src/games/connect-em-all/ConnectEmAllGame.ts +0 -401
- package/src/games/connect-em-all/ConnectEmAllScene.ts +0 -235
- package/src/games/crossy-road/CrossyRoad.tsx +0 -74
- package/src/games/crossy-road/CrossyRoadCamera.ts +0 -59
- package/src/games/crossy-road/CrossyRoadConstants.ts +0 -132
- package/src/games/crossy-road/CrossyRoadGame.ts +0 -293
- package/src/games/crossy-road/CrossyRoadMeshes.ts +0 -195
- package/src/games/crossy-road/CrossyRoadPerson.ts +0 -198
- package/src/games/crossy-road/CrossyRoadRules.ts +0 -99
- package/src/games/crossy-road/CrossyRoadScene.ts +0 -355
- package/src/games/dino-jump/DinoJump.tsx +0 -77
- package/src/games/dino-jump/DinoJumpConstants.ts +0 -80
- package/src/games/dino-jump/DinoJumpGame.ts +0 -344
- package/src/games/dino-jump/DinoJumpScene.ts +0 -686
- package/src/games/dots-and-boxes/DotsAndBoxes.tsx +0 -83
- package/src/games/dots-and-boxes/DotsAndBoxesConstants.ts +0 -77
- package/src/games/dots-and-boxes/DotsAndBoxesGame.ts +0 -271
- package/src/games/dots-and-boxes/DotsAndBoxesScene.ts +0 -249
- package/src/games/falling-sticks/FallingSticks.tsx +0 -72
- package/src/games/falling-sticks/FallingSticksConstants.ts +0 -62
- package/src/games/falling-sticks/FallingSticksGame.ts +0 -220
- package/src/games/falling-sticks/FallingSticksRules.ts +0 -145
- package/src/games/falling-sticks/FallingSticksScene.ts +0 -245
- package/src/games/find-different-number/FindDifferentNumber.tsx +0 -74
- package/src/games/find-different-number/FindDifferentNumberConstants.ts +0 -74
- package/src/games/find-different-number/FindDifferentNumberGame.ts +0 -174
- package/src/games/find-different-number/FindDifferentNumberRules.ts +0 -43
- package/src/games/find-different-number/FindDifferentNumberScene.ts +0 -193
- package/src/games/flappy-bird/FlappyBird.tsx +0 -73
- package/src/games/flappy-bird/FlappyBirdConstants.ts +0 -95
- package/src/games/flappy-bird/FlappyBirdGame.ts +0 -375
- package/src/games/flappy-bird/FlappyBirdScene.ts +0 -630
- package/src/games/fruit-merger/FruitMerger.tsx +0 -73
- package/src/games/fruit-merger/FruitMergerConstants.ts +0 -102
- package/src/games/fruit-merger/FruitMergerGame.ts +0 -285
- package/src/games/fruit-merger/FruitMergerRules.ts +0 -286
- package/src/games/fruit-merger/FruitMergerScene.ts +0 -498
- package/src/games/fruit-ninja/FruitNinja.tsx +0 -129
- package/src/games/fruit-ninja/FruitNinjaConstants.ts +0 -107
- package/src/games/fruit-ninja/FruitNinjaGame.ts +0 -391
- package/src/games/fruit-ninja/FruitNinjaScene.ts +0 -319
- package/src/games/fruit-ninja/FruitNinjaWorld.ts +0 -17
- package/src/games/game-2048/Game2048.tsx +0 -84
- package/src/games/game-2048/Game2048Constants.ts +0 -68
- package/src/games/game-2048/Game2048Game.ts +0 -181
- package/src/games/game-2048/Game2048Rules.ts +0 -101
- package/src/games/game-2048/Game2048Scene.ts +0 -206
- package/src/games/knife-hit/KnifeHit.tsx +0 -78
- package/src/games/knife-hit/KnifeHitConstants.ts +0 -89
- package/src/games/knife-hit/KnifeHitGame.ts +0 -264
- package/src/games/knife-hit/KnifeHitScene.ts +0 -360
- package/src/games/ludo-king/LudoKing.tsx +0 -86
- package/src/games/ludo-king/LudoKingConstants.ts +0 -212
- package/src/games/ludo-king/LudoKingGame.ts +0 -326
- package/src/games/ludo-king/LudoKingRules.ts +0 -143
- package/src/games/ludo-king/LudoKingScene.ts +0 -397
- package/src/games/maze-runner/MazeRunner.tsx +0 -88
- package/src/games/maze-runner/MazeRunnerConstants.ts +0 -65
- package/src/games/maze-runner/MazeRunnerGame.ts +0 -176
- package/src/games/maze-runner/MazeRunnerRules.ts +0 -161
- package/src/games/maze-runner/MazeRunnerScene.ts +0 -245
- package/src/games/memory-match/MemoryMatch.tsx +0 -77
- package/src/games/memory-match/MemoryMatchConstants.ts +0 -105
- package/src/games/memory-match/MemoryMatchGame.ts +0 -222
- package/src/games/memory-match/MemoryMatchRules.ts +0 -38
- package/src/games/memory-match/MemoryMatchScene.ts +0 -268
- package/src/games/mine-sweeper/MineSweeper.tsx +0 -77
- package/src/games/mine-sweeper/MineSweeperConstants.ts +0 -94
- package/src/games/mine-sweeper/MineSweeperGame.ts +0 -234
- package/src/games/mine-sweeper/MineSweeperRules.ts +0 -67
- package/src/games/mine-sweeper/MineSweeperScene.ts +0 -262
- package/src/games/mob-control/MobControl.tsx +0 -73
- package/src/games/mob-control/MobControlConstants.ts +0 -106
- package/src/games/mob-control/MobControlGame.ts +0 -176
- package/src/games/mob-control/MobControlMeshes.ts +0 -85
- package/src/games/mob-control/MobControlRenderer.ts +0 -108
- package/src/games/mob-control/MobControlRules.ts +0 -522
- package/src/games/mob-control/MobControlScene.ts +0 -399
- package/src/games/number-search/NumberSearch.tsx +0 -18
- package/src/games/number-search/NumberSearchNumbers.ts +0 -623
- package/src/games/nuts-and-bolts/NutsAndBolts.tsx +0 -85
- package/src/games/nuts-and-bolts/NutsAndBoltsConstants.ts +0 -75
- package/src/games/nuts-and-bolts/NutsAndBoltsGame.ts +0 -298
- package/src/games/nuts-and-bolts/NutsAndBoltsRules.ts +0 -474
- package/src/games/nuts-and-bolts/NutsAndBoltsScene.ts +0 -498
- package/src/games/pac-man/PacMan.tsx +0 -86
- package/src/games/pac-man/PacManConstants.ts +0 -169
- package/src/games/pac-man/PacManGame.ts +0 -406
- package/src/games/pac-man/PacManRules.ts +0 -255
- package/src/games/pac-man/PacManScene.ts +0 -387
- package/src/games/paper-io/PaperIo.tsx +0 -91
- package/src/games/paper-io/PaperIoConstants.ts +0 -86
- package/src/games/paper-io/PaperIoGame.ts +0 -193
- package/src/games/paper-io/PaperIoMeshes.ts +0 -233
- package/src/games/paper-io/PaperIoRules.ts +0 -315
- package/src/games/paper-io/PaperIoScene.ts +0 -310
- package/src/games/penguin-run/PenguinMeshes.ts +0 -269
- package/src/games/penguin-run/PenguinModel.ts +0 -712
- package/src/games/penguin-run/PenguinRun.tsx +0 -77
- package/src/games/penguin-run/PenguinRunConstants.ts +0 -69
- package/src/games/penguin-run/PenguinRunGame.ts +0 -406
- package/src/games/penguin-run/PenguinRunScene.ts +0 -949
- package/src/games/perfect-circle/PerfectCircle.tsx +0 -74
- package/src/games/perfect-circle/PerfectCircleConstants.ts +0 -52
- package/src/games/perfect-circle/PerfectCircleGame.ts +0 -153
- package/src/games/perfect-circle/PerfectCircleRules.ts +0 -111
- package/src/games/perfect-circle/PerfectCircleScene.ts +0 -176
- package/src/games/pipe-connect/PipeConnect.tsx +0 -69
- package/src/games/pipe-connect/PipeConnectConstants.ts +0 -101
- package/src/games/pipe-connect/PipeConnectGame.ts +0 -179
- package/src/games/pipe-connect/PipeConnectRules.ts +0 -326
- package/src/games/pipe-connect/PipeConnectScene.ts +0 -271
- package/src/games/play-with-tua/PlayWithTua.tsx +0 -123
- package/src/games/play-with-tua/PlayWithTuaConstants.ts +0 -70
- package/src/games/play-with-tua/PlayWithTuaGame.ts +0 -167
- package/src/games/play-with-tua/PlayWithTuaModel.ts +0 -42
- package/src/games/play-with-tua/PlayWithTuaScene.ts +0 -36
- package/src/games/popit-fidget/PopitFidget.tsx +0 -72
- package/src/games/popit-fidget/PopitFidgetConstants.ts +0 -71
- package/src/games/popit-fidget/PopitFidgetGame.ts +0 -148
- package/src/games/popit-fidget/PopitFidgetScene.ts +0 -242
- package/src/games/reversi/Reversi.tsx +0 -94
- package/src/games/reversi/ReversiConstants.ts +0 -67
- package/src/games/reversi/ReversiGame.ts +0 -266
- package/src/games/reversi/ReversiRules.ts +0 -176
- package/src/games/reversi/ReversiScene.ts +0 -240
- package/src/games/search-grid/SearchGrid.tsx +0 -92
- package/src/games/search-grid/SearchGridConstants.ts +0 -178
- package/src/games/search-grid/SearchGridGame.ts +0 -209
- package/src/games/search-grid/SearchGridScene.ts +0 -301
- package/src/games/shared/BackdropCard.tsx +0 -54
- package/src/games/shared/EngineBackdrop.ts +0 -300
- package/src/games/shared/EngineBlasts.ts +0 -136
- package/src/games/shared/EngineBlocks.ts +0 -91
- package/src/games/shared/EngineControlText.ts +0 -17
- package/src/games/shared/EngineDice.ts +0 -250
- package/src/games/shared/EngineFootprint.ts +0 -35
- package/src/games/shared/EngineFruits.ts +0 -1435
- package/src/games/shared/EngineGameLoader.tsx +0 -88
- package/src/games/shared/EngineGameScreen.tsx +0 -325
- package/src/games/shared/EngineGameWidth.ts +0 -3
- package/src/games/shared/EngineGameWidth.web.ts +0 -3
- package/src/games/shared/EngineGlyphs.ts +0 -178
- package/src/games/shared/EngineHud.ts +0 -815
- package/src/games/shared/EngineLoading.ts +0 -477
- package/src/games/shared/EngineMeadow.ts +0 -725
- package/src/games/shared/EngineMeshCache.ts +0 -15
- package/src/games/shared/EngineMeshes.ts +0 -10
- package/src/games/shared/EngineRacingChase.ts +0 -21
- package/src/games/shared/EngineRacingHandling.ts +0 -48
- package/src/games/shared/EngineReadyContext.ts +0 -4
- package/src/games/shared/EngineTilt.ts +0 -44
- package/src/games/shared/EngineTouchSurface.tsx +0 -103
- package/src/games/shared/EngineUtils.ts +0 -52
- package/src/games/shared/GameActivity.ts +0 -13
- package/src/games/shared/GameLoading.tsx +0 -202
- package/src/games/shared/GameLoadingTransition.tsx +0 -61
- package/src/games/shared/ProceduralCacheVersion.ts +0 -2
- package/src/games/shared/useEngineGame.ts +0 -240
- package/src/games/shared/useGameResource.ts +0 -21
- package/src/games/shared/useLiveState.ts +0 -58
- package/src/games/sliding-numbers/SlidingNumbers.tsx +0 -71
- package/src/games/sliding-numbers/SlidingNumbersConstants.ts +0 -65
- package/src/games/sliding-numbers/SlidingNumbersGame.ts +0 -192
- package/src/games/sliding-numbers/SlidingNumbersRules.ts +0 -79
- package/src/games/sliding-numbers/SlidingNumbersScene.ts +0 -193
- package/src/games/snake-3d/Snake3D.tsx +0 -76
- package/src/games/snake-3d/Snake3DConstants.ts +0 -61
- package/src/games/snake-3d/Snake3DGame.ts +0 -192
- package/src/games/snake-3d/Snake3DMotion.ts +0 -22
- package/src/games/snake-3d/Snake3DRules.ts +0 -116
- package/src/games/snake-3d/Snake3DScene.ts +0 -322
- package/src/games/snakes-and-ladders/SnakesAndLadders.tsx +0 -87
- package/src/games/snakes-and-ladders/SnakesAndLaddersConstants.ts +0 -136
- package/src/games/snakes-and-ladders/SnakesAndLaddersGame.ts +0 -310
- package/src/games/snakes-and-ladders/SnakesAndLaddersScene.ts +0 -515
- package/src/games/space-fighter/SpaceFighter.tsx +0 -74
- package/src/games/space-fighter/SpaceFighterConstants.ts +0 -86
- package/src/games/space-fighter/SpaceFighterGame.ts +0 -292
- package/src/games/space-fighter/SpaceFighterScene.ts +0 -550
- package/src/games/spider-solitaire/SpiderSolitaire.tsx +0 -80
- package/src/games/spider-solitaire/SpiderSolitaireConstants.ts +0 -107
- package/src/games/spider-solitaire/SpiderSolitaireGame.ts +0 -387
- package/src/games/spider-solitaire/SpiderSolitaireRules.ts +0 -123
- package/src/games/spider-solitaire/SpiderSolitaireScene.ts +0 -352
- package/src/games/stack-tower/StackTower.tsx +0 -76
- package/src/games/stack-tower/StackTowerConstants.ts +0 -74
- package/src/games/stack-tower/StackTowerGame.ts +0 -236
- package/src/games/stack-tower/StackTowerScene.ts +0 -186
- package/src/games/sudoku/Sudoku.tsx +0 -73
- package/src/games/sudoku/SudokuConstants.ts +0 -127
- package/src/games/sudoku/SudokuGame.ts +0 -250
- package/src/games/sudoku/SudokuRules.ts +0 -125
- package/src/games/sudoku/SudokuScene.ts +0 -304
- package/src/games/tangram/Tangram.tsx +0 -79
- package/src/games/tangram/TangramConstants.ts +0 -64
- package/src/games/tangram/TangramGame.ts +0 -356
- package/src/games/tangram/TangramRules.ts +0 -409
- package/src/games/tangram/TangramScene.ts +0 -203
- package/src/games/tank-1990/Tank1990.tsx +0 -78
- package/src/games/tank-1990/Tank1990Constants.ts +0 -81
- package/src/games/tank-1990/Tank1990Game.ts +0 -331
- package/src/games/tank-1990/Tank1990Rules.ts +0 -390
- package/src/games/tank-1990/Tank1990Scene.ts +0 -434
- package/src/games/tic-tac-toe/TicTacToe.tsx +0 -98
- package/src/games/tic-tac-toe/TicTacToeConstants.ts +0 -69
- package/src/games/tic-tac-toe/TicTacToeGame.ts +0 -200
- package/src/games/tic-tac-toe/TicTacToeRules.ts +0 -103
- package/src/games/tic-tac-toe/TicTacToeScene.ts +0 -245
- package/src/games/tile-home/TileHome.tsx +0 -92
- package/src/games/tile-home/TileHomeConstants.ts +0 -139
- package/src/games/tile-home/TileHomeGame.ts +0 -435
- package/src/games/tile-home/TileHomeScene.ts +0 -154
- package/src/games/treasure-hunt/TreasureHunt.tsx +0 -206
- package/src/games/treasure-hunt/TreasureHuntConstants.ts +0 -266
- package/src/games/treasure-hunt/TreasureHuntControls.ts +0 -280
- package/src/games/treasure-hunt/TreasureHuntGame.ts +0 -402
- package/src/games/treasure-hunt/TreasureHuntMeshes.ts +0 -422
- package/src/games/treasure-hunt/TreasureHuntModel.ts +0 -506
- package/src/games/treasure-hunt/TreasureHuntRules.ts +0 -1210
- package/src/games/treasure-hunt/TreasureHuntScene.ts +0 -586
- package/src/games/whack-a-mole/WhackAMole.tsx +0 -79
- package/src/games/whack-a-mole/WhackAMoleConstants.ts +0 -94
- package/src/games/whack-a-mole/WhackAMoleGame.ts +0 -233
- package/src/games/whack-a-mole/WhackAMoleScene.ts +0 -349
- package/src/games/word-search/WordSearch.tsx +0 -18
- package/src/games/word-search/WordSearchWords.ts +0 -1642
- package/src/helpers/GamePatternData.ts +0 -120
- package/src/helpers/GameSettingsModal.tsx +0 -384
- package/src/helpers/GameTheme.tsx +0 -37
- package/src/helpers/IconPaths.ts +0 -6
- package/src/helpers/index.ts +0 -2
- package/src/index.tsx +0 -60
- package/src/services/GameAssetLoader.ts +0 -111
- package/src/services/GameAssets.ts +0 -149
- package/src/services/GameLoaders.ts +0 -93
- package/src/services/GamesConstants.ts +0 -193
- package/src/services/GamesMetadata.ts +0 -711
- package/src/services/GamesService.ts +0 -116
- package/src/services/HapticsService.ts +0 -48
- package/src/services/ScoringService.ts +0 -19
- package/src/services/SfxSources.ts +0 -81
- package/src/services/SoundsService.ts +0 -582
- package/src/services/ThemeService.ts +0 -281
- package/src/services/UtilsService.ts +0 -134
- package/src/services/index.ts +0 -6
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
// Color Switch's play, with no React: build a game with `createGame`, give it a layout, `start` it and
|
|
2
|
-
// `tick` it every frame. Tap to hop the ball up through spinning rings; it may only cross a ring
|
|
3
|
-
// through the quarter of its own colour. Stars between the rings change its colour. Each ring passed
|
|
4
|
-
// scores 1,000; surviving two minutes wins, touching the wrong colour or dropping off the screen loses.
|
|
5
|
-
//
|
|
6
|
-
// Ported step for step from the original version's UI-thread physics and service (games/color-switch), at
|
|
7
|
-
// the same fixed 60 Hz steps: the ball falls, the camera follows, the rings turn (from one shared
|
|
8
|
-
// tick), crossings and stars are checked, new rings spawn above and old ones are dropped below.
|
|
9
|
-
import { type Camera, World } from '@nayan-ui/engine';
|
|
10
|
-
import type { GameTheme } from '../../services/ThemeService';
|
|
11
|
-
import {
|
|
12
|
-
FORGIVENESS,
|
|
13
|
-
GAME_COLORS,
|
|
14
|
-
GRAVITY,
|
|
15
|
-
JUMP_VELOCITY,
|
|
16
|
-
type Layout,
|
|
17
|
-
MAX_PENDING_MS,
|
|
18
|
-
MAX_VELOCITY,
|
|
19
|
-
POINTS_PER_PASS,
|
|
20
|
-
ROTATION_SPEED,
|
|
21
|
-
SPAWN_MARGIN,
|
|
22
|
-
STEP_MS,
|
|
23
|
-
STEP_TOLERANCE_MS,
|
|
24
|
-
TIME_LIMIT
|
|
25
|
-
} from './ColorSwitchConstants';
|
|
26
|
-
import {
|
|
27
|
-
buildScene,
|
|
28
|
-
frame,
|
|
29
|
-
hop,
|
|
30
|
-
placeBall,
|
|
31
|
-
recolor,
|
|
32
|
-
removeScene,
|
|
33
|
-
resetBall,
|
|
34
|
-
type Scene,
|
|
35
|
-
setSceneTheme,
|
|
36
|
-
shatter,
|
|
37
|
-
syncField,
|
|
38
|
-
turnRing
|
|
39
|
-
} from './ColorSwitchScene';
|
|
40
|
-
|
|
41
|
-
export type Phase = 'ready' | 'playing' | 'over';
|
|
42
|
-
/** jump: a hop; pass: a ring cleared; color: a star caught; crash: the wrong colour, or off the screen. */
|
|
43
|
-
export type GameEvent = 'jump' | 'pass' | 'color' | 'crash';
|
|
44
|
-
|
|
45
|
-
export type Ring = { id: string; y: number; rotationSpeed: number; rotationBase: number; passed: boolean };
|
|
46
|
-
export type Star = { id: string; y: number; colorIndex: number };
|
|
47
|
-
|
|
48
|
-
const WORLD_CAPACITY = 300; // the rings and stars on screen, the ball, the backdrop, and bursts
|
|
49
|
-
const COLORS = GAME_COLORS.length;
|
|
50
|
-
const TWO_PI = Math.PI * 2;
|
|
51
|
-
const QUADRANT = Math.PI / 2;
|
|
52
|
-
|
|
53
|
-
let ids = 0;
|
|
54
|
-
const ring = (y: number): Ring => ({
|
|
55
|
-
id: `r${ids++}`,
|
|
56
|
-
y,
|
|
57
|
-
rotationSpeed: ROTATION_SPEED * (Math.random() < 0.5 ? 1 : -1),
|
|
58
|
-
rotationBase: Math.random() * TWO_PI,
|
|
59
|
-
passed: false
|
|
60
|
-
});
|
|
61
|
-
/** A star of any colour but the ball's. */
|
|
62
|
-
const star = (y: number, ballColor: number): Star => {
|
|
63
|
-
let colorIndex = ballColor;
|
|
64
|
-
while (colorIndex === ballColor) colorIndex = Math.floor(Math.random() * COLORS);
|
|
65
|
-
return { id: `s${ids++}`, y, colorIndex };
|
|
66
|
-
};
|
|
67
|
-
export const ringRotation = (r: Ring, tick: number) => r.rotationBase + r.rotationSpeed * tick;
|
|
68
|
-
const quarterAt = (angle: number, rotation: number) => {
|
|
69
|
-
let a = (angle - rotation) % TWO_PI;
|
|
70
|
-
if (a < 0) a += TWO_PI;
|
|
71
|
-
return Math.floor(a / QUADRANT) % 4;
|
|
72
|
-
};
|
|
73
|
-
/** Whether the ring's colour at an angle is the ball's (forgiving the boundaries a little). */
|
|
74
|
-
const safeAt = (angle: number, rotation: number, color: number) =>
|
|
75
|
-
quarterAt(angle, rotation) === color || quarterAt(angle + FORGIVENESS, rotation) === color || quarterAt(angle - FORGIVENESS, rotation) === color;
|
|
76
|
-
|
|
77
|
-
export function createGame(theme: GameTheme) {
|
|
78
|
-
const world = new World(WORLD_CAPACITY);
|
|
79
|
-
const camera: Camera = { eye: [0, 0, 240], target: [0, 0, 0], fov: 1, ortho: 1 };
|
|
80
|
-
const g = {
|
|
81
|
-
world,
|
|
82
|
-
camera,
|
|
83
|
-
theme,
|
|
84
|
-
layout: null as Layout | null,
|
|
85
|
-
scene: null as Scene | null,
|
|
86
|
-
phase: 'ready' as Phase,
|
|
87
|
-
rings: [] as Ring[],
|
|
88
|
-
stars: [] as Star[],
|
|
89
|
-
ballY: 0,
|
|
90
|
-
velocity: 0,
|
|
91
|
-
/** The ball's burst: play stops and the round ends a moment later. */
|
|
92
|
-
crashed: false,
|
|
93
|
-
color: 0,
|
|
94
|
-
cameraY: 0,
|
|
95
|
-
/** Physics steps taken; every ring's rotation follows from it. */
|
|
96
|
-
tick: 0,
|
|
97
|
-
highestY: Infinity,
|
|
98
|
-
passed: 0,
|
|
99
|
-
/** Score and the countdown live in the engine (Rust), advanced by world.update. */
|
|
100
|
-
get score() {
|
|
101
|
-
return world.scoreboard.score;
|
|
102
|
-
},
|
|
103
|
-
get timeLeft() {
|
|
104
|
-
return world.scoreboard.shownSeconds;
|
|
105
|
-
},
|
|
106
|
-
won: false,
|
|
107
|
-
pending: 0,
|
|
108
|
-
// UI hooks, set by the screen.
|
|
109
|
-
onPhase: (_p: Phase) => {},
|
|
110
|
-
onScore: (_s: number) => {},
|
|
111
|
-
onTime: (_t: number) => {},
|
|
112
|
-
onEvent: (_e: GameEvent) => {}
|
|
113
|
-
};
|
|
114
|
-
world.scoreboard.reset(0, TIME_LIMIT);
|
|
115
|
-
world.scoreboard.handlers = {
|
|
116
|
-
onSecond: (t) => g.onTime(t),
|
|
117
|
-
// Two minutes survived is a win
|
|
118
|
-
onTimeUp: () => g.phase === 'playing' && end(g, true)
|
|
119
|
-
};
|
|
120
|
-
return g;
|
|
121
|
-
}
|
|
122
|
-
export type Game = ReturnType<typeof createGame>;
|
|
123
|
-
|
|
124
|
-
// ── Scene ─────────────────────────────────────────────────────────────
|
|
125
|
-
|
|
126
|
-
/** Lays the field out for the view (first layout, header height, rotation); a fresh preview if nothing's laid out yet. */
|
|
127
|
-
export function setLayout(g: Game, l: Layout) {
|
|
128
|
-
const first = !g.layout;
|
|
129
|
-
if (g.scene) removeScene(g.world, g.scene);
|
|
130
|
-
g.layout = l;
|
|
131
|
-
g.scene = buildScene(g.world, l, g.theme);
|
|
132
|
-
if (first) preview(g);
|
|
133
|
-
else resetBall(g.world, l, g.scene, g.color);
|
|
134
|
-
draw(g);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export function setTheme(g: Game, theme: GameTheme) {
|
|
138
|
-
g.theme = theme;
|
|
139
|
-
if (g.scene) setSceneTheme(g.world, g.scene, theme);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function draw(g: Game) {
|
|
143
|
-
const { layout: l, scene: s } = g;
|
|
144
|
-
if (!l || !s) return;
|
|
145
|
-
syncField(g.world, l, s, g.rings, g.stars);
|
|
146
|
-
for (const r of g.rings) turnRing(g.world, s, r.id, ringRotation(r, g.tick));
|
|
147
|
-
placeBall(g.world, l, s, g.ballY);
|
|
148
|
-
frame(g.world, l, s, g.camera, g.cameraY);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/** The ball and camera where a game starts. */
|
|
152
|
-
function home(g: Game, l: Layout) {
|
|
153
|
-
g.ballY = l.ballStartY;
|
|
154
|
-
g.cameraY = l.ballStartY - l.fieldHeight * 0.65;
|
|
155
|
-
g.pending = 0;
|
|
156
|
-
g.crashed = false;
|
|
157
|
-
g.passed = 0;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/** Three rings waiting above the ball, with stars between them (the idle screen). */
|
|
161
|
-
function preview(g: Game) {
|
|
162
|
-
const l = g.layout;
|
|
163
|
-
if (!l) return;
|
|
164
|
-
home(g, l);
|
|
165
|
-
g.velocity = 0;
|
|
166
|
-
g.color = 0;
|
|
167
|
-
g.rings = [];
|
|
168
|
-
g.stars = [];
|
|
169
|
-
g.highestY = Infinity;
|
|
170
|
-
const first = l.ballStartY - l.gap * 0.8;
|
|
171
|
-
for (let i = 0; i < 3; i++) {
|
|
172
|
-
const y = first - i * l.gap;
|
|
173
|
-
g.rings.push(ring(y));
|
|
174
|
-
g.highestY = Math.min(g.highestY, y);
|
|
175
|
-
if (i > 0) g.stars.push(star(y + l.gap / 2, 0));
|
|
176
|
-
}
|
|
177
|
-
if (g.scene) resetBall(g.world, l, g.scene, 0);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// ── Run ───────────────────────────────────────────────────────────────
|
|
181
|
-
|
|
182
|
-
/** Starts from the preview: a random colour, the waiting rings kept (extended to five), the ball already hopping. */
|
|
183
|
-
export function start(g: Game) {
|
|
184
|
-
const l = g.layout;
|
|
185
|
-
if (g.phase !== 'ready' || !l) return;
|
|
186
|
-
home(g, l);
|
|
187
|
-
g.color = Math.floor(Math.random() * COLORS);
|
|
188
|
-
g.rings = g.rings.map((r) => ({ ...r, passed: false }));
|
|
189
|
-
g.highestY = g.rings.reduce((h, r) => Math.min(h, r.y), Infinity);
|
|
190
|
-
const first = l.ballStartY - l.gap * 0.8;
|
|
191
|
-
for (let i = g.rings.length; i < 5; i++) {
|
|
192
|
-
const y = first - i * l.gap;
|
|
193
|
-
g.rings.push(ring(y));
|
|
194
|
-
g.highestY = Math.min(g.highestY, y);
|
|
195
|
-
if (i > 0 && g.stars.length < i) g.stars.push(star(y + l.gap / 2, g.color));
|
|
196
|
-
}
|
|
197
|
-
g.velocity = JUMP_VELOCITY;
|
|
198
|
-
g.world.scoreboard.reset();
|
|
199
|
-
g.world.scoreboard.startCountdown(TIME_LIMIT);
|
|
200
|
-
g.won = false;
|
|
201
|
-
g.phase = 'playing';
|
|
202
|
-
if (g.scene) resetBall(g.world, l, g.scene, g.color);
|
|
203
|
-
draw(g);
|
|
204
|
-
g.onScore(0);
|
|
205
|
-
g.onTime(TIME_LIMIT);
|
|
206
|
-
g.onPhase('playing');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/** Back to the idle preview (Stop, Play Again). The world, and the GPU view drawing it, are kept. */
|
|
210
|
-
export function reset(g: Game) {
|
|
211
|
-
g.world.scoreboard.reset(0, TIME_LIMIT);
|
|
212
|
-
g.won = false;
|
|
213
|
-
g.phase = 'ready';
|
|
214
|
-
preview(g);
|
|
215
|
-
draw(g);
|
|
216
|
-
g.onScore(0);
|
|
217
|
-
g.onTime(TIME_LIMIT);
|
|
218
|
-
g.onPhase('ready');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
export function dispose(g: Game) {
|
|
222
|
-
g.world.dispose();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
export function tick(g: Game, dt: number) {
|
|
226
|
-
if (g.world.isDisposed) return;
|
|
227
|
-
if (g.phase === 'playing') {
|
|
228
|
-
// Fixed 60 Hz steps; a long frame catches up at most a few
|
|
229
|
-
let pending = Math.min(g.pending + dt * 1000, MAX_PENDING_MS);
|
|
230
|
-
while (g.phase === 'playing' && !g.crashed && pending >= STEP_MS - STEP_TOLERANCE_MS) {
|
|
231
|
-
pending -= STEP_MS;
|
|
232
|
-
step(g);
|
|
233
|
-
}
|
|
234
|
-
g.pending = pending;
|
|
235
|
-
draw(g);
|
|
236
|
-
}
|
|
237
|
-
g.world.update(dt);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
function end(g: Game, won: boolean) {
|
|
241
|
-
g.world.scoreboard.stop();
|
|
242
|
-
g.won = won;
|
|
243
|
-
g.phase = 'over';
|
|
244
|
-
g.onPhase('over');
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/** One 60 Hz tick, in the original loop's order. */
|
|
248
|
-
function step(g: Game) {
|
|
249
|
-
const l = g.layout!;
|
|
250
|
-
g.velocity += GRAVITY;
|
|
251
|
-
const ny = g.ballY + g.velocity;
|
|
252
|
-
g.velocity = Math.max(-MAX_VELOCITY, Math.min(MAX_VELOCITY, g.velocity));
|
|
253
|
-
// The camera rises to keep the ball 65% of the way down, and never follows it back down
|
|
254
|
-
const delta = ny - l.fieldHeight * 0.65 - g.cameraY;
|
|
255
|
-
const camera = delta < 0 ? g.cameraY + delta * 0.12 : g.cameraY;
|
|
256
|
-
g.tick += 1;
|
|
257
|
-
|
|
258
|
-
// Hit the ground (the bottom of the screen): it blasts and the round ends
|
|
259
|
-
const ground = camera + l.fieldHeight - l.top;
|
|
260
|
-
if (ny + l.ballRadius >= ground) {
|
|
261
|
-
g.ballY = ground - l.ballRadius;
|
|
262
|
-
return crash(g);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const outer = l.ringRadius + l.ringThickness / 2;
|
|
266
|
-
const inner = l.ringRadius - l.ringThickness / 2;
|
|
267
|
-
for (const r of g.rings) {
|
|
268
|
-
// Every ring collides, passed or not: falling back down through one is as deadly as jumping up
|
|
269
|
-
const dy = ny - r.y;
|
|
270
|
-
const dist = Math.abs(dy);
|
|
271
|
-
// The ball's edge in the ring's band: only the colour straight above or below it counts
|
|
272
|
-
if (dist + l.ballRadius >= inner && Math.max(0, dist - l.ballRadius) <= outer) {
|
|
273
|
-
if (!safeAt(Math.atan2(dy, 0), ringRotation(r, g.tick), g.color)) return crash(g);
|
|
274
|
-
}
|
|
275
|
-
if (!r.passed && ny < r.y - outer - l.ballRadius * 2) {
|
|
276
|
-
r.passed = true;
|
|
277
|
-
g.passed += 1;
|
|
278
|
-
g.onScore(g.world.scoreboard.add(POINTS_PER_PASS));
|
|
279
|
-
g.onEvent('pass');
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
g.ballY = ny;
|
|
284
|
-
g.cameraY = camera;
|
|
285
|
-
const below = camera + l.fieldHeight + SPAWN_MARGIN;
|
|
286
|
-
|
|
287
|
-
// A star caught changes the ball's colour; stars well below the screen go
|
|
288
|
-
g.stars = g.stars.filter((st) => {
|
|
289
|
-
if (Math.abs(g.ballY - st.y) < l.ballRadius + l.starRadius) {
|
|
290
|
-
g.color = st.colorIndex;
|
|
291
|
-
if (g.scene) recolor(g.world, l, g.scene, st.colorIndex, g.ballY, st.id);
|
|
292
|
-
g.onEvent('color');
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
return st.y < below;
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
// A new ring (and star) above the screen, and rings well below it dropped
|
|
299
|
-
if (g.highestY > camera - SPAWN_MARGIN) {
|
|
300
|
-
const y = g.highestY - l.gap;
|
|
301
|
-
g.rings.push(ring(y));
|
|
302
|
-
g.stars.push(star(y + l.gap / 2, g.color));
|
|
303
|
-
g.highestY = y;
|
|
304
|
-
}
|
|
305
|
-
if (g.rings.some((r) => r.y >= below)) g.rings = g.rings.filter((r) => r.y < below);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/** How long the blast plays before the round ends (and the game-over card covers it). */
|
|
309
|
-
const CRASH_DELAY = 0.7;
|
|
310
|
-
|
|
311
|
-
function crash(g: Game) {
|
|
312
|
-
const { layout: l, scene: s } = g;
|
|
313
|
-
if (g.crashed) return;
|
|
314
|
-
g.crashed = true;
|
|
315
|
-
g.world.scoreboard.stop();
|
|
316
|
-
if (l && s) shatter(g.world, l, s, g.ballY, g.color);
|
|
317
|
-
g.onEvent('crash');
|
|
318
|
-
g.world.after(CRASH_DELAY, () => g.phase === 'playing' && g.crashed && end(g, false));
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// ── The tap ───────────────────────────────────────────────────────────
|
|
322
|
-
|
|
323
|
-
/** A finger down hops the ball up. */
|
|
324
|
-
export function jump(g: Game) {
|
|
325
|
-
if (g.phase !== 'playing' || g.crashed) return;
|
|
326
|
-
g.velocity = JUMP_VELOCITY;
|
|
327
|
-
if (g.layout && g.scene) hop(g.world, g.layout, g.scene);
|
|
328
|
-
g.onEvent('jump');
|
|
329
|
-
}
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
// Everything Color Switch draws: glossy rings (real tori, a quarter in each of the four colors) spinning
|
|
2
|
-
// up the screen, a spinning colour-changer star between each pair, and the bouncing ball, under an
|
|
3
|
-
// orthographic camera looking straight at the field (one world unit per point) that follows the ball
|
|
4
|
-
// up. The ball pops on a hop, a halo bursts from it when it changes colour, and it shatters on a crash.
|
|
5
|
-
// Every ring is one mesh, and so is every star.
|
|
6
|
-
//
|
|
7
|
-
// The field's points (x right, y down, as the rules use) map to the world with y flipped; the camera
|
|
8
|
-
// rises with the rules' camera, the backdrop staying fixed behind.
|
|
9
|
-
import {
|
|
10
|
-
type Camera,
|
|
11
|
-
type Color,
|
|
12
|
-
type Entity,
|
|
13
|
-
extrude,
|
|
14
|
-
merge,
|
|
15
|
-
type Model,
|
|
16
|
-
type MutableQuat,
|
|
17
|
-
Path,
|
|
18
|
-
quat,
|
|
19
|
-
tube,
|
|
20
|
-
type Vec3,
|
|
21
|
-
type World
|
|
22
|
-
} from '@nayan-ui/engine';
|
|
23
|
-
import type { GameTheme } from '../../services/ThemeService';
|
|
24
|
-
import { setBackdropTheme, spawnBackdrop } from '../shared/EngineBackdrop';
|
|
25
|
-
import { popAndBurst } from '../shared/EngineBlasts';
|
|
26
|
-
import { cacheGameAsset, createGameMesh as createShape } from '../shared/EngineMeshes';
|
|
27
|
-
import { toColor } from '../shared/EngineUtils';
|
|
28
|
-
import { GAME_COLORS, type Layout } from './ColorSwitchConstants';
|
|
29
|
-
|
|
30
|
-
const meshes = new Map<string, Model>();
|
|
31
|
-
const cached = (key: string, build: () => Model) => {
|
|
32
|
-
let m = meshes.get(key);
|
|
33
|
-
if (!m) {
|
|
34
|
-
m = cacheGameAsset('color-switch/ColorSwitchScene:' + key, build);
|
|
35
|
-
meshes.set(key, m);
|
|
36
|
-
}
|
|
37
|
-
return m;
|
|
38
|
-
};
|
|
39
|
-
const BACKDROP_DEPTH = 60;
|
|
40
|
-
const EYE_DISTANCE = 240;
|
|
41
|
-
|
|
42
|
-
/** A circle's points from angle `from` to `to` (world radians), radius 1. */
|
|
43
|
-
const arc = (from: number, to: number, n = 14): Vec3[] =>
|
|
44
|
-
Array.from({ length: n + 1 }, (_, i) => {
|
|
45
|
-
const a = from + ((to - from) * i) / n;
|
|
46
|
-
return [Math.cos(a), Math.sin(a), 0] as Vec3;
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* A ring of radius 1 whose tube is `thickness` across: quarter k in GAME_COLORS[k], running clockwise
|
|
51
|
-
* on screen from k x 90 degrees (the screen's angles run clockwise, the world's the other way).
|
|
52
|
-
*/
|
|
53
|
-
const ringMesh = (thickness: number) =>
|
|
54
|
-
cached(`cs-ring:${thickness.toFixed(3)}`, () =>
|
|
55
|
-
createShape(
|
|
56
|
-
merge(
|
|
57
|
-
GAME_COLORS.map((c, k) => ({
|
|
58
|
-
geometry: tube(arc((-k * Math.PI) / 2, (-(k + 1) * Math.PI) / 2), { radius: thickness / 2, sides: 16, smoothness: 3, caps: false }),
|
|
59
|
-
color: toColor(c)
|
|
60
|
-
}))
|
|
61
|
-
),
|
|
62
|
-
{ center: false, shine: 0.65 }
|
|
63
|
-
)
|
|
64
|
-
);
|
|
65
|
-
/** A thin white circle, radius 1, tinted to the ball's new colour as it bursts out. */
|
|
66
|
-
const haloMesh = () =>
|
|
67
|
-
cached('cs-halo', () => createShape(tube(arc(0, Math.PI * 2, 32), { radius: 0.06, sides: 10, smoothness: 2, caps: false }), { center: false }));
|
|
68
|
-
/** A five-pointed star one unit across with some depth. */
|
|
69
|
-
const starMesh = () => cached('cs-star', () => createShape(extrude(new Path().addStar(0, 0, 0.5, 0.22), { depth: 0.3 }), { shine: 0.6 }));
|
|
70
|
-
|
|
71
|
-
// ── Spawning ──────────────────────────────────────────────────────────
|
|
72
|
-
|
|
73
|
-
export type Scene = {
|
|
74
|
-
syncedRings?: object;
|
|
75
|
-
syncedStars?: object;
|
|
76
|
-
ringCount?: number;
|
|
77
|
-
starCount?: number;
|
|
78
|
-
backdrop: Entity;
|
|
79
|
-
ball: Entity;
|
|
80
|
-
halo: Entity;
|
|
81
|
-
rings: Map<string, Entity>;
|
|
82
|
-
stars: Map<string, Entity>;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
/** A field point (y down) in the world. */
|
|
86
|
-
export const toWorld = (l: Layout, x: number, y: number, z = 0): Vec3 => [x - l.width / 2, -y, z];
|
|
87
|
-
export const colorOf = (i: number): Color => toColor(GAME_COLORS[i] ?? GAME_COLORS[0]!);
|
|
88
|
-
|
|
89
|
-
export function buildScene(world: World, l: Layout, theme: GameTheme): Scene {
|
|
90
|
-
const backdrop = spawnBackdrop(world, l.width, l.height, -BACKDROP_DEPTH, theme);
|
|
91
|
-
const ball = world.spawn({ mesh: 'sphere', scale: l.ballRadius * 2, color: colorOf(0), pickable: false });
|
|
92
|
-
const halo = world.spawn({ mesh: haloMesh(), scale: 0, color: [1, 1, 1, 0], pickable: false });
|
|
93
|
-
return { backdrop, ball, halo, rings: new Map(), stars: new Map() };
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export function removeScene(world: World, s: Scene) {
|
|
97
|
-
for (const e of [s.backdrop, s.ball, s.halo, ...Array.from(s.rings.values()), ...Array.from(s.stars.values())]) world.despawn(e);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export function setSceneTheme(world: World, s: Scene, theme: GameTheme) {
|
|
101
|
-
setBackdropTheme(world, s.backdrop, theme);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/** Frames the field with the rules' camera (its top edge's field y), the backdrop kept fixed on screen. */
|
|
105
|
-
export function frame(world: World, l: Layout, s: Scene, camera: Camera, cameraY: number) {
|
|
106
|
-
// A field point shows at view y = top + (y - cameraY): the view's centre is field y (cameraY + height / 2 - top)
|
|
107
|
-
const centre = -(cameraY + l.height / 2 - l.top);
|
|
108
|
-
camera.eye = [0, centre, EYE_DISTANCE];
|
|
109
|
-
camera.target = [0, centre, 0];
|
|
110
|
-
camera.ortho = l.height / 2;
|
|
111
|
-
world.set(s.backdrop, { position: [-l.width / 2, centre + l.height / 2, -BACKDROP_DEPTH] });
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/** Keeps the rings and stars in step with the rules' lists: new ones appear, gone ones go. */
|
|
115
|
-
export function syncField(
|
|
116
|
-
world: World,
|
|
117
|
-
l: Layout,
|
|
118
|
-
s: Scene,
|
|
119
|
-
rings: { id: string; y: number }[],
|
|
120
|
-
stars: { id: string; y: number; colorIndex: number }[]
|
|
121
|
-
) {
|
|
122
|
-
if (s.syncedRings === rings && s.syncedStars === stars && s.ringCount === rings.length && s.starCount === stars.length) return;
|
|
123
|
-
s.syncedRings = rings;
|
|
124
|
-
s.syncedStars = stars;
|
|
125
|
-
s.ringCount = rings.length;
|
|
126
|
-
s.starCount = stars.length;
|
|
127
|
-
const live = new Set<string>();
|
|
128
|
-
for (const r of rings) {
|
|
129
|
-
live.add(r.id);
|
|
130
|
-
if (!s.rings.has(r.id))
|
|
131
|
-
s.rings.set(
|
|
132
|
-
r.id,
|
|
133
|
-
world.spawn({ mesh: ringMesh(l.ringThickness / l.ringRadius), position: toWorld(l, l.width / 2, r.y), scale: l.ringRadius, pickable: false })
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
for (const [id, e] of s.rings)
|
|
137
|
-
if (!live.has(id)) {
|
|
138
|
-
world.despawn(e);
|
|
139
|
-
s.rings.delete(id);
|
|
140
|
-
}
|
|
141
|
-
live.clear();
|
|
142
|
-
for (const st of stars) {
|
|
143
|
-
live.add(st.id);
|
|
144
|
-
if (!s.stars.has(st.id))
|
|
145
|
-
s.stars.set(
|
|
146
|
-
st.id,
|
|
147
|
-
world.spawn({
|
|
148
|
-
mesh: starMesh(),
|
|
149
|
-
position: toWorld(l, l.width / 2, st.y, 4),
|
|
150
|
-
scale: l.starRadius * 2.4,
|
|
151
|
-
color: colorOf(st.colorIndex),
|
|
152
|
-
spin: [0, 2.2, 0],
|
|
153
|
-
pickable: false
|
|
154
|
-
})
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
for (const [id, e] of s.stars)
|
|
158
|
-
if (!live.has(id)) {
|
|
159
|
-
world.despawn(e);
|
|
160
|
-
s.stars.delete(id);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Scratch for the per-frame turn (world.set copies it).
|
|
165
|
-
const TURN: MutableQuat = [0, 0, 0, 1];
|
|
166
|
-
|
|
167
|
-
/** A ring turned to `rotation` (radians, clockwise on screen). */
|
|
168
|
-
export function turnRing(world: World, s: Scene, id: string, rotation: number) {
|
|
169
|
-
const e = s.rings.get(id);
|
|
170
|
-
if (e != null) world.set(e, { rotation: quat.z(-rotation, TURN) });
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export function placeBall(world: World, l: Layout, s: Scene, y: number) {
|
|
174
|
-
world.set(s.ball, { position: toWorld(l, l.width / 2, y, 6) });
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// ── Feedback ──────────────────────────────────────────────────────────
|
|
178
|
-
|
|
179
|
-
/** A little squash on every hop. */
|
|
180
|
-
export function hop(world: World, l: Layout, s: Scene) {
|
|
181
|
-
const d = l.ballRadius * 2;
|
|
182
|
-
world.animate(s.ball, [{ scale: d * 1.14, at: 0.3 }, { scale: d }], { duration: 0.22 });
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/** A star caught: the ball takes its colour with a pop, and a halo of it bursts out and fades. */
|
|
186
|
-
export function recolor(world: World, l: Layout, s: Scene, colorIndex: number, y: number, starId: string | null) {
|
|
187
|
-
const c = colorOf(colorIndex);
|
|
188
|
-
const d = l.ballRadius * 2;
|
|
189
|
-
world.set(s.ball, { color: c });
|
|
190
|
-
world.animate(s.ball, [{ scale: d * 1.3, at: 0.25 }, { scale: d }], { duration: 0.3 });
|
|
191
|
-
world.stopAnimation(s.halo);
|
|
192
|
-
world.set(s.halo, { position: toWorld(l, l.width / 2, y, 5), scale: l.ballRadius, color: [c[0], c[1], c[2], 0.9] });
|
|
193
|
-
world.animate(s.halo, { scale: l.ballRadius * 2.6, color: [c[0], c[1], c[2], 0] }, { duration: 0.42, easing: 'easeOut' });
|
|
194
|
-
if (starId) {
|
|
195
|
-
const star = s.stars.get(starId);
|
|
196
|
-
if (star != null) world.set(star, { scale: 0 });
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/** A crash: the ball bursts into its colour and fades where it was caught. */
|
|
201
|
-
/** The ball's crash, as Block Blast's cleared blocks go: it swells, flashes white and shrinks away in a burst of its colour. */
|
|
202
|
-
export function shatter(world: World, l: Layout, s: Scene, y: number, colorIndex: number) {
|
|
203
|
-
const c = colorOf(colorIndex);
|
|
204
|
-
const size = l.ballRadius * 2;
|
|
205
|
-
world.stopAnimation(s.ball);
|
|
206
|
-
popAndBurst(
|
|
207
|
-
world,
|
|
208
|
-
s.ball,
|
|
209
|
-
{ scale: size, color: c, duration: 0.45 },
|
|
210
|
-
{ position: toWorld(l, l.width / 2, y, 10), size: size * 1.6, color: c, count: 14 }
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/** Back to a whole ball of a colour (a new game or the preview). */
|
|
215
|
-
export function resetBall(world: World, l: Layout, s: Scene, colorIndex: number) {
|
|
216
|
-
world.stopAnimation(s.ball);
|
|
217
|
-
world.stopAnimation(s.halo);
|
|
218
|
-
world.set(s.ball, { scale: l.ballRadius * 2, color: colorOf(colorIndex) });
|
|
219
|
-
world.set(s.halo, { scale: 0 });
|
|
220
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
// Colors Sort's screen, on the Nayan engine: the glass tubes and pucks are one 3D scene (an
|
|
2
|
-
// orthographic camera looking down a little from in front), under Playtura's scoreboard, controls and
|
|
3
|
-
// modals. The rules are in ColorsSortGame.ts, what it draws in ColorsSortScene.ts.
|
|
4
|
-
//
|
|
5
|
-
// One world serves the whole visit: Start, Stop and Play Again reset it in place and a theme change
|
|
6
|
-
// repaints the glass and backdrop, so the GPU view is never rebuilt. Lifts, moves and corks animate in
|
|
7
|
-
// the engine's Rust core; JS hit-tests taps and steps the clock and the world once a frame.
|
|
8
|
-
import { HapticType } from '../../services/HapticsService';
|
|
9
|
-
import { calculateTimeBasedScore } from '../../services/ScoringService';
|
|
10
|
-
import { GAME_SOUNDS } from '../../services/SoundsService';
|
|
11
|
-
import { formatTime, GAME_IDS } from '../../services/UtilsService';
|
|
12
|
-
import { engineGame, EngineGameScreen } from '../shared/EngineGameScreen';
|
|
13
|
-
import { timerColumn } from '../shared/EngineHud';
|
|
14
|
-
import { useEngineGame } from '../shared/useEngineGame';
|
|
15
|
-
import { useLiveState } from '../shared/useLiveState';
|
|
16
|
-
import { getLayout, LIGHT, SCORE_BASE, TIME_LIMIT } from './ColorsSortConstants';
|
|
17
|
-
import { createGame, dispose, type GameEvent, reset, setLayout, setTheme, start, tap, tick } from './ColorsSortGame';
|
|
18
|
-
|
|
19
|
-
const SOUNDS = GAME_SOUNDS.COLORS_SORT;
|
|
20
|
-
|
|
21
|
-
/** Each event's sound and haptic, as the original version played them. */
|
|
22
|
-
const FEEDBACK: Record<GameEvent, { sound: (typeof SOUNDS)[keyof typeof SOUNDS]; haptic: HapticType }> = {
|
|
23
|
-
pick: { sound: SOUNDS.PICK, haptic: HapticType.LIGHT },
|
|
24
|
-
drop: { sound: SOUNDS.DESELECT, haptic: HapticType.LIGHT },
|
|
25
|
-
refuse: { sound: SOUNDS.MISS, haptic: HapticType.LIGHT },
|
|
26
|
-
move: { sound: SOUNDS.MATCH, haptic: HapticType.MEDIUM },
|
|
27
|
-
complete: { sound: SOUNDS.COMPLETE, haptic: HapticType.SUCCESS }
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const timedOutFormatter = () => formatTime(TIME_LIMIT);
|
|
31
|
-
|
|
32
|
-
export const ColorsSort = engineGame(GAME_IDS.COLORS_SORT, (props) => {
|
|
33
|
-
const [timeLeft, setTimeLeft] = useLiveState(TIME_LIMIT);
|
|
34
|
-
|
|
35
|
-
// A win scores by how fast it was sorted; a time-out or cancel scores 0 (a win's sound already
|
|
36
|
-
// played with its last move)
|
|
37
|
-
const { game, theme, screen, gameOver } = useEngineGame(props, {
|
|
38
|
-
gameId: GAME_IDS.COLORS_SORT,
|
|
39
|
-
create: createGame,
|
|
40
|
-
start,
|
|
41
|
-
reset,
|
|
42
|
-
dispose,
|
|
43
|
-
tick,
|
|
44
|
-
setTheme,
|
|
45
|
-
resize: (g, width, height, offset) => {
|
|
46
|
-
const l = getLayout(width, height, offset);
|
|
47
|
-
setLayout(g, l);
|
|
48
|
-
return l.shelves[0]?.width;
|
|
49
|
-
},
|
|
50
|
-
tap,
|
|
51
|
-
outcome: (g) => (g.timedOut ? 'lose' : 'win'),
|
|
52
|
-
reportScore: (g, status) => (status === 'win' ? calculateTimeBasedScore(g.time, TIME_LIMIT, SCORE_BASE) : 0),
|
|
53
|
-
sounds: SOUNDS,
|
|
54
|
-
onStart: (fx) => fx(SOUNDS.START, HapticType.MEDIUM),
|
|
55
|
-
onOver: (fx, status) => {
|
|
56
|
-
if (status !== 'win') fx(SOUNDS.GAME_OVER, HapticType.ERROR);
|
|
57
|
-
},
|
|
58
|
-
wire: (g, fx) => {
|
|
59
|
-
g.onTime = setTimeLeft;
|
|
60
|
-
g.onEvent = (event) => fx(FEEDBACK[event].sound, FEEDBACK[event].haptic);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const timedOut = game.timedOut;
|
|
65
|
-
|
|
66
|
-
return (
|
|
67
|
-
<EngineGameScreen
|
|
68
|
-
{...screen}
|
|
69
|
-
light={LIGHT}
|
|
70
|
-
columns={[timerColumn(timeLeft, theme)]}
|
|
71
|
-
subtext="Sort colors!"
|
|
72
|
-
gameOver={gameOver({
|
|
73
|
-
title: timedOut ? 'TIME UP!' : 'SORTED!',
|
|
74
|
-
message: timedOut ? 'You ran out of time!' : 'All colors sorted!',
|
|
75
|
-
scoreLabel: timedOut ? "Time's Up!" : 'Completion Time',
|
|
76
|
-
score: game.time,
|
|
77
|
-
formatter: timedOut ? timedOutFormatter : formatTime,
|
|
78
|
-
buttonText: 'Sort Again!'
|
|
79
|
-
})}
|
|
80
|
-
/>
|
|
81
|
-
);
|
|
82
|
-
});
|