@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,167 +0,0 @@
|
|
|
1
|
-
// Checkers' rules, with no React or engine: the board, moves (captures are forced, multi-jumps chain,
|
|
2
|
-
// a man reaching the far row is crowned and that ends its move), and the robot's pick. Ported from the
|
|
3
|
-
// original store (games/checkers/CheckersStore.ts), so every position plays out as it did.
|
|
4
|
-
import { bestAIMoves } from './CheckersAI';
|
|
5
|
-
|
|
6
|
-
export const BOARD_N = 8;
|
|
7
|
-
export const PIECES_PER_SIDE = 12;
|
|
8
|
-
export const AI_DEPTH = 5;
|
|
9
|
-
|
|
10
|
-
/** You play red (bottom rows, moving up); the robot plays black (top, moving down). */
|
|
11
|
-
export type CheckerPlayer = 'red' | 'black';
|
|
12
|
-
export type Piece = { player: CheckerPlayer; king: boolean };
|
|
13
|
-
export type Cell = Piece | null;
|
|
14
|
-
export type CheckersBoard = Cell[]; // 64 squares, index = row * 8 + col
|
|
15
|
-
/** One hop: where it lands, and the square it jumps (null for a slide). */
|
|
16
|
-
export type Step = { to: number; captured: number | null };
|
|
17
|
-
/** A whole move: a slide, or a full (maybe multi-) jump. */
|
|
18
|
-
export type FullMove = { from: number; steps: Step[] };
|
|
19
|
-
|
|
20
|
-
export const HUMAN: CheckerPlayer = 'red';
|
|
21
|
-
export const AI: CheckerPlayer = 'black';
|
|
22
|
-
|
|
23
|
-
export const rc = (index: number) => ({ row: Math.floor(index / BOARD_N), col: index % BOARD_N });
|
|
24
|
-
export const idx = (row: number, col: number) => row * BOARD_N + col;
|
|
25
|
-
export const inBounds = (row: number, col: number) => row >= 0 && row < BOARD_N && col >= 0 && col < BOARD_N;
|
|
26
|
-
/** Pieces live on the dark squares. */
|
|
27
|
-
export const isPlayable = (row: number, col: number) => (row + col) % 2 === 1;
|
|
28
|
-
|
|
29
|
-
export function createInitialBoard(): CheckersBoard {
|
|
30
|
-
const board: CheckersBoard = new Array(BOARD_N * BOARD_N).fill(null);
|
|
31
|
-
for (let row = 0; row < BOARD_N; row++)
|
|
32
|
-
for (let col = 0; col < BOARD_N; col++) {
|
|
33
|
-
if (!isPlayable(row, col)) continue;
|
|
34
|
-
if (row < 3) board[idx(row, col)] = { player: AI, king: false };
|
|
35
|
-
else if (row > BOARD_N - 4) board[idx(row, col)] = { player: HUMAN, king: false };
|
|
36
|
-
}
|
|
37
|
-
return board;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const KING_DIRS: readonly (readonly [number, number])[] = [
|
|
41
|
-
[-1, -1],
|
|
42
|
-
[-1, 1],
|
|
43
|
-
[1, -1],
|
|
44
|
-
[1, 1]
|
|
45
|
-
];
|
|
46
|
-
const HUMAN_DIRS: readonly (readonly [number, number])[] = [
|
|
47
|
-
[-1, -1],
|
|
48
|
-
[-1, 1]
|
|
49
|
-
];
|
|
50
|
-
const AI_DIRS: readonly (readonly [number, number])[] = [
|
|
51
|
-
[1, -1],
|
|
52
|
-
[1, 1]
|
|
53
|
-
];
|
|
54
|
-
const dirsFor = (player: CheckerPlayer, king: boolean) => (king ? KING_DIRS : player === HUMAN ? HUMAN_DIRS : AI_DIRS);
|
|
55
|
-
|
|
56
|
-
export function singleJumps(board: CheckersBoard, from: number, player: CheckerPlayer, king: boolean): Step[] {
|
|
57
|
-
const { row, col } = rc(from);
|
|
58
|
-
const steps: Step[] = [];
|
|
59
|
-
for (const [dr, dc] of dirsFor(player, king)) {
|
|
60
|
-
const landR = row + dr * 2;
|
|
61
|
-
const landC = col + dc * 2;
|
|
62
|
-
if (!inBounds(landR, landC)) continue;
|
|
63
|
-
const landIdx = idx(landR, landC);
|
|
64
|
-
if (board[landIdx] !== null) continue;
|
|
65
|
-
const midIdx = idx(row + dr, col + dc);
|
|
66
|
-
const mid = board[midIdx];
|
|
67
|
-
if (mid && mid.player !== player) steps.push({ to: landIdx, captured: midIdx });
|
|
68
|
-
}
|
|
69
|
-
return steps;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export function singleSlides(board: CheckersBoard, from: number, player: CheckerPlayer, king: boolean): Step[] {
|
|
73
|
-
const { row, col } = rc(from);
|
|
74
|
-
const steps: Step[] = [];
|
|
75
|
-
for (const [dr, dc] of dirsFor(player, king)) {
|
|
76
|
-
const r = row + dr;
|
|
77
|
-
const c = col + dc;
|
|
78
|
-
if (!inBounds(r, c)) continue;
|
|
79
|
-
const to = idx(r, c);
|
|
80
|
-
if (board[to] === null) steps.push({ to, captured: null });
|
|
81
|
-
}
|
|
82
|
-
return steps;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** One hop on a copy of the board; says whether the mover was crowned. */
|
|
86
|
-
export function applyStep(board: CheckersBoard, from: number, step: Step, player: CheckerPlayer): { board: CheckersBoard; promoted: boolean } {
|
|
87
|
-
const nb = board.slice();
|
|
88
|
-
const p = nb[from]!;
|
|
89
|
-
nb[from] = null;
|
|
90
|
-
if (step.captured !== null) nb[step.captured] = null;
|
|
91
|
-
const { row } = rc(step.to);
|
|
92
|
-
const promotes = !p.king && ((player === HUMAN && row === 0) || (player === AI && row === BOARD_N - 1));
|
|
93
|
-
nb[step.to] = promotes ? { player, king: true } : p;
|
|
94
|
-
return { board: nb, promoted: promotes };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function playerHasCapture(board: CheckersBoard, player: CheckerPlayer): boolean {
|
|
98
|
-
for (let i = 0; i < board.length; i++) {
|
|
99
|
-
const p = board[i];
|
|
100
|
-
if (p && p.player === player && singleJumps(board, i, p.player, p.king).length > 0) return true;
|
|
101
|
-
}
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function captureSequences(board: CheckersBoard, origin: number, cur: number, player: CheckerPlayer, king: boolean, steps: Step[]): FullMove[] {
|
|
106
|
-
const jumps = singleJumps(board, cur, player, king);
|
|
107
|
-
if (jumps.length === 0) return steps.length ? [{ from: origin, steps }] : [];
|
|
108
|
-
const results: FullMove[] = [];
|
|
109
|
-
for (const j of jumps) {
|
|
110
|
-
const applied = applyStep(board, cur, j, player);
|
|
111
|
-
const newSteps = [...steps, j];
|
|
112
|
-
if (applied.promoted) results.push({ from: origin, steps: newSteps });
|
|
113
|
-
else results.push(...captureSequences(applied.board, origin, j.to, player, king, newSteps));
|
|
114
|
-
}
|
|
115
|
-
return results;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/** Every legal whole move for a side (captures forced when there are any). */
|
|
119
|
-
export function generateMoves(board: CheckersBoard, player: CheckerPlayer): FullMove[] {
|
|
120
|
-
const captures: FullMove[] = [];
|
|
121
|
-
for (let i = 0; i < board.length; i++) {
|
|
122
|
-
const p = board[i];
|
|
123
|
-
if (!p || p.player !== player) continue;
|
|
124
|
-
const seqs = captureSequences(board, i, i, player, p.king, []);
|
|
125
|
-
if (seqs.length) captures.push(...seqs);
|
|
126
|
-
}
|
|
127
|
-
if (captures.length) return captures;
|
|
128
|
-
const slides: FullMove[] = [];
|
|
129
|
-
for (let i = 0; i < board.length; i++) {
|
|
130
|
-
const p = board[i];
|
|
131
|
-
if (!p || p.player !== player) continue;
|
|
132
|
-
for (const s of singleSlides(board, i, player, p.king)) slides.push({ from: i, steps: [s] });
|
|
133
|
-
}
|
|
134
|
-
return slides;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export function applyFullMove(board: CheckersBoard, move: FullMove): CheckersBoard {
|
|
138
|
-
const player = board[move.from]!.player;
|
|
139
|
-
let b = board;
|
|
140
|
-
let cur = move.from;
|
|
141
|
-
for (const s of move.steps) {
|
|
142
|
-
b = applyStep(b, cur, s, player).board;
|
|
143
|
-
cur = s.to;
|
|
144
|
-
}
|
|
145
|
-
return b;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/** A piece's single hops when it isn't forced to capture: jumps first, then slides. */
|
|
149
|
-
export const allSteps = (board: CheckersBoard, index: number, player: CheckerPlayer, king: boolean): Step[] => [
|
|
150
|
-
...singleJumps(board, index, player, king),
|
|
151
|
-
...singleSlides(board, index, player, king)
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
export function countPieces(board: CheckersBoard, player: CheckerPlayer): number {
|
|
155
|
-
let n = 0;
|
|
156
|
-
for (const c of board) if (c && c.player === player) n++;
|
|
157
|
-
return n;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/** The robot's move: the only one, or a random one of the best its search finds. */
|
|
161
|
-
export function chooseAIMove(board: CheckersBoard): FullMove | null {
|
|
162
|
-
const moves = generateMoves(board, AI);
|
|
163
|
-
if (moves.length === 0) return null;
|
|
164
|
-
if (moves.length === 1) return moves[0]!;
|
|
165
|
-
const best = bestAIMoves(board, moves, AI_DEPTH);
|
|
166
|
-
return best[Math.floor(Math.random() * best.length)]!;
|
|
167
|
-
}
|
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import { type Color, effects, type Entity, extrude, lathe, merge, type Model, Path, quat, type Vec3, type World } from '@nayan-ui/engine';
|
|
2
|
-
import type { GameTheme } from '../../services/ThemeService';
|
|
3
|
-
import { setBackdropTheme, spawnBackdrop } from '../shared/EngineBackdrop';
|
|
4
|
-
import { cacheGameAsset, createGameMesh as createShape } from '../shared/EngineMeshes';
|
|
5
|
-
import { placeTiltedBackdrop } from '../shared/EngineTilt';
|
|
6
|
-
// Everything Checkers draws: a flat board of 64 squares with a thin outer border, turned checker pieces
|
|
7
|
-
// (a lathe profile: a rounded rim and grooved top) in red and slate, kings as two stacked with a gold
|
|
8
|
-
// crown, and the hints: the picked piece's square glows gold, slides show green dots, jumps red rings.
|
|
9
|
-
// A flat board seen directly from above, with only the checker pieces raised in 3D. Every piece is
|
|
10
|
-
// one entity sharing one mesh; a king carries its crown.
|
|
11
|
-
import { toColor } from '../shared/EngineUtils';
|
|
12
|
-
import { BOARD_BORDER_WIDTH, COLORS, HOP_TIME, type Layout, PIECE_HEIGHT, SLIDE_TIME, squareCentre } from './CheckersConstants';
|
|
13
|
-
import type { CheckersBoard, Piece } from './CheckersRules';
|
|
14
|
-
|
|
15
|
-
const meshes = new Map<string, Model>();
|
|
16
|
-
const cached = (key: string, build: () => Model) => {
|
|
17
|
-
let m = meshes.get(key);
|
|
18
|
-
if (!m) {
|
|
19
|
-
m = cacheGameAsset('checkers/CheckersScene:' + key, build);
|
|
20
|
-
meshes.set(key, m);
|
|
21
|
-
}
|
|
22
|
-
return m;
|
|
23
|
-
};
|
|
24
|
-
const STAND_UP = quat.x(Math.PI / 2);
|
|
25
|
-
const BACKDROP_DEPTH = 30;
|
|
26
|
-
const SURFACE = 0.2; // the flat squares' plane
|
|
27
|
-
const HINTS = 4; // a piece has at most four places to go
|
|
28
|
-
|
|
29
|
-
// ── Meshes (one square across) ────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
/** A checker: a turned disc, rounded at the rim, two grooves on top, standing on z = 0. */
|
|
32
|
-
const pieceMesh = () =>
|
|
33
|
-
cached('ck-piece', () => {
|
|
34
|
-
const h = PIECE_HEIGHT;
|
|
35
|
-
const profile: [number, number][] = [
|
|
36
|
-
[0.001, h],
|
|
37
|
-
[0.14, h],
|
|
38
|
-
[0.155, h - 0.012],
|
|
39
|
-
[0.17, h],
|
|
40
|
-
[0.27, h],
|
|
41
|
-
[0.285, h - 0.014],
|
|
42
|
-
[0.3, h],
|
|
43
|
-
[0.36, h],
|
|
44
|
-
[0.395, h - 0.02],
|
|
45
|
-
[0.41, h * 0.55],
|
|
46
|
-
[0.4, h * 0.18],
|
|
47
|
-
[0.37, 0],
|
|
48
|
-
[0.001, 0]
|
|
49
|
-
];
|
|
50
|
-
const g = lathe(profile, {
|
|
51
|
-
segments: 36,
|
|
52
|
-
// The grooves and the rim a little darker than the face
|
|
53
|
-
color: ({ position: [x, y, z] }) => {
|
|
54
|
-
const r = Math.hypot(x, z);
|
|
55
|
-
const k = y < h - 0.004 ? (r > 0.38 ? 0.78 : 0.88) : 1;
|
|
56
|
-
return [k, k, k, 1];
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
return createShape(merge([{ geometry: g, rotation: STAND_UP }]), { center: false, shine: 0.55 });
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
/** A king's crown: a gold three-pointed crown, standing on top of the stack. */
|
|
63
|
-
const crownMesh = () =>
|
|
64
|
-
cached('ck-crown', () => {
|
|
65
|
-
const p = new Path().addPolygon([
|
|
66
|
-
[-0.2, 0.1],
|
|
67
|
-
[-0.2, -0.06],
|
|
68
|
-
[-0.12, 0.02],
|
|
69
|
-
[-0.06, -0.12],
|
|
70
|
-
[0, 0.0],
|
|
71
|
-
[0.06, -0.12],
|
|
72
|
-
[0.12, 0.02],
|
|
73
|
-
[0.2, -0.06],
|
|
74
|
-
[0.2, 0.1]
|
|
75
|
-
]);
|
|
76
|
-
return createShape(extrude(p, { depth: 0.04 }), { center: false, shine: 0.8 });
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
/** A hint ring (a capture target): flat, lying on a square. */
|
|
80
|
-
const ringMesh = () =>
|
|
81
|
-
cached('ck-ring', () =>
|
|
82
|
-
createShape(extrude(new Path().addCircle(0, 0, 0.4).addCircle(0, 0, 0.33), { depth: 0, fillRule: 'evenodd' }), { center: false })
|
|
83
|
-
);
|
|
84
|
-
const discMesh = () => cached('ck-disc', () => createShape(extrude(new Path().addCircle(0, 0, 0.5), { depth: 0 }), { center: false }));
|
|
85
|
-
const panelMesh = (w: number, radius: number) =>
|
|
86
|
-
cached(`ck-flat-panel:${w}:${radius}`, () => createShape(extrude(new Path().addRoundedRect(-w / 2, -w / 2, w, w, radius), { depth: 0 })));
|
|
87
|
-
|
|
88
|
-
// ── Spawning ──────────────────────────────────────────────────────────
|
|
89
|
-
|
|
90
|
-
type PieceView = { root: Entity; crown: Entity | null };
|
|
91
|
-
export type Scene = {
|
|
92
|
-
backdrop: Entity;
|
|
93
|
-
board: Entity[];
|
|
94
|
-
pieces: Map<number, PieceView>;
|
|
95
|
-
select: Entity;
|
|
96
|
-
dots: Entity[];
|
|
97
|
-
rings: Entity[];
|
|
98
|
-
/** Bursts waiting for their moment (a burst can't be delayed), and the scene's clock. */
|
|
99
|
-
queue: { at: number; run: () => void }[];
|
|
100
|
-
time: number;
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const pieceColor = (p: Piece): Color => toColor(p.player === 'red' ? COLORS.RED : COLORS.BLACK);
|
|
104
|
-
const at = (l: Layout, index: number, z = SURFACE): Vec3 => {
|
|
105
|
-
const [x, y] = squareCentre(l, index);
|
|
106
|
-
return [x, y, z];
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
function spawnBoard(world: World, l: Layout): Entity[] {
|
|
110
|
-
const out: Entity[] = [];
|
|
111
|
-
const add = (o: Parameters<World['spawn']>[0]) => out.push(world.spawn({ pickable: false, ...o }));
|
|
112
|
-
for (let i = 0; i < 64; i++) {
|
|
113
|
-
const dark = (Math.floor(i / 8) + i) % 2 === 1;
|
|
114
|
-
const [x, y] = squareCentre(l, i);
|
|
115
|
-
add({
|
|
116
|
-
mesh: panelMesh(1, 0),
|
|
117
|
-
position: [x, y, SURFACE],
|
|
118
|
-
scale: [l.cell, l.cell, 1],
|
|
119
|
-
color: toColor(dark ? COLORS.DARK_SQ : COLORS.LIGHT_SQ)
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
const edge = BOARD_BORDER_WIDTH;
|
|
123
|
-
const border = toColor(COLORS.BOARD_BORDER);
|
|
124
|
-
for (const side of [-1, 1]) {
|
|
125
|
-
add({ mesh: panelMesh(1, 0), position: [0, (side * (l.size + edge)) / 2, SURFACE], scale: [l.size + edge * 2, edge, 1], color: border });
|
|
126
|
-
add({ mesh: panelMesh(1, 0), position: [(side * (l.size + edge)) / 2, 0, SURFACE], scale: [edge, l.size, 1], color: border });
|
|
127
|
-
}
|
|
128
|
-
return out;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function spawnPiece(world: World, l: Layout, s: Scene, index: number, p: Piece) {
|
|
132
|
-
const root = world.spawn({ mesh: pieceMesh(), position: at(l, index), scale: l.cell, color: pieceColor(p), pickable: false });
|
|
133
|
-
const view: PieceView = { root, crown: null };
|
|
134
|
-
s.pieces.set(index, view);
|
|
135
|
-
if (p.king) crown(world, view, p, false);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/** A king: a second piece stacked on the first, a gold crown on top. */
|
|
139
|
-
function crown(world: World, v: PieceView, p: Piece, animate: boolean) {
|
|
140
|
-
if (v.crown != null) return;
|
|
141
|
-
const stack = world.spawn({ mesh: pieceMesh(), parent: v.root, position: [0, 0, PIECE_HEIGHT * 0.95], color: pieceColor(p), pickable: false });
|
|
142
|
-
world.spawn({
|
|
143
|
-
mesh: crownMesh(),
|
|
144
|
-
parent: stack,
|
|
145
|
-
position: [0, 0.02, PIECE_HEIGHT + 0.025],
|
|
146
|
-
color: toColor(COLORS.GOLD),
|
|
147
|
-
pickable: false
|
|
148
|
-
});
|
|
149
|
-
v.crown = stack;
|
|
150
|
-
if (animate) {
|
|
151
|
-
world.set(stack, { position: [0, 0, PIECE_HEIGHT * 4] });
|
|
152
|
-
world.animate(stack, { position: [0, 0, PIECE_HEIGHT * 0.95] }, { duration: 0.35, delay: SLIDE_TIME, easing: 'bounce' });
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export function buildScene(world: World, l: Layout, theme: GameTheme, board: CheckersBoard): Scene {
|
|
157
|
-
const backdrop = spawnBackdrop(world, l.width, l.height, -BACKDROP_DEPTH, theme);
|
|
158
|
-
placeTiltedBackdrop(world, backdrop, l, BACKDROP_DEPTH);
|
|
159
|
-
const hint = (mesh: Model, color: string, alpha: number) => world.spawn({ mesh, scale: 0, color: toColor(color, alpha), pickable: false });
|
|
160
|
-
const s: Scene = {
|
|
161
|
-
backdrop,
|
|
162
|
-
board: spawnBoard(world, l),
|
|
163
|
-
pieces: new Map(),
|
|
164
|
-
select: world.spawn({ mesh: panelMesh(1, 0), scale: 0, color: toColor(COLORS.SELECT, 0.55), pickable: false }),
|
|
165
|
-
dots: Array.from({ length: HINTS }, () => hint(discMesh(), COLORS.MOVE, 0.9)),
|
|
166
|
-
rings: Array.from({ length: HINTS }, () => hint(ringMesh(), COLORS.CAPTURE, 0.95)),
|
|
167
|
-
queue: [],
|
|
168
|
-
time: 0
|
|
169
|
-
};
|
|
170
|
-
board.forEach((p, i) => p && spawnPiece(world, l, s, i, p));
|
|
171
|
-
return s;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
export function removeScene(world: World, s: Scene) {
|
|
175
|
-
for (const e of [s.backdrop, ...s.board, ...Array.from(s.pieces.values(), (v) => v.root), s.select, ...s.dots, ...s.rings]) world.despawn(e);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function setSceneTheme(world: World, l: Layout, s: Scene, theme: GameTheme) {
|
|
179
|
-
setBackdropTheme(world, s.backdrop, theme);
|
|
180
|
-
for (const e of s.board) world.despawn(e);
|
|
181
|
-
s.board = spawnBoard(world, l);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/** Puts every piece back where the board has it (a new game): the old ones go, fresh ones are set down. */
|
|
185
|
-
export function resetPieces(world: World, l: Layout, s: Scene, board: CheckersBoard) {
|
|
186
|
-
for (const v of s.pieces.values()) world.despawn(v.root);
|
|
187
|
-
s.pieces.clear();
|
|
188
|
-
s.queue = [];
|
|
189
|
-
board.forEach((p, i) => p && spawnPiece(world, l, s, i, p));
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// ── Hints ─────────────────────────────────────────────────────────────
|
|
193
|
-
|
|
194
|
-
/** The picked piece's square glows; where it may go shows a green dot (a slide) or a red ring (a jump). */
|
|
195
|
-
export function showHints(world: World, l: Layout, s: Scene, selected: number, targets: number[], captures: number[]) {
|
|
196
|
-
const updates = world.transforms;
|
|
197
|
-
if (selected >= 0) {
|
|
198
|
-
const [x, y] = squareCentre(l, selected);
|
|
199
|
-
updates.position(s.select, x, y, SURFACE + 0.05);
|
|
200
|
-
updates.scale(s.select, l.cell, l.cell, 1);
|
|
201
|
-
} else updates.scale(s.select, 0);
|
|
202
|
-
let d = 0;
|
|
203
|
-
let r = 0;
|
|
204
|
-
for (const t of targets) {
|
|
205
|
-
const capture = captures.includes(t);
|
|
206
|
-
const e = capture ? s.rings[r++] : s.dots[d++];
|
|
207
|
-
if (e == null) continue;
|
|
208
|
-
const [x, y] = squareCentre(l, t);
|
|
209
|
-
updates.position(e, x, y, SURFACE + 0.12);
|
|
210
|
-
updates.scale(e, capture ? l.cell : l.cell * 0.32);
|
|
211
|
-
}
|
|
212
|
-
for (; d < HINTS; d++) updates.scale(s.dots[d]!, 0);
|
|
213
|
-
for (; r < HINTS; r++) updates.scale(s.rings[r]!, 0);
|
|
214
|
-
updates.flush();
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/** The picked piece lifts a little off the board. */
|
|
218
|
-
export function lift(world: World, l: Layout, s: Scene, index: number, up: boolean) {
|
|
219
|
-
const v = s.pieces.get(index);
|
|
220
|
-
if (v) world.animate(v.root, { position: at(l, index, SURFACE + (up ? l.cell * 0.12 : 0)) }, { duration: 0.12 });
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// ── Moves ─────────────────────────────────────────────────────────────
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* A piece goes from `from` along `path` (its landing squares), sliding or hopping over the pieces it
|
|
227
|
-
* takes (which pop and go as it clears them), and is crowned if it becomes a king. `delay` starts it later.
|
|
228
|
-
*/
|
|
229
|
-
export function movePiece(world: World, l: Layout, s: Scene, from: number, path: number[], captured: number[], king: Piece | null, delay = 0) {
|
|
230
|
-
const v = s.pieces.get(from);
|
|
231
|
-
if (!v) return;
|
|
232
|
-
s.pieces.delete(from);
|
|
233
|
-
const jump = captured.length > 0;
|
|
234
|
-
const per = jump ? HOP_TIME : SLIDE_TIME;
|
|
235
|
-
const keys: { position: Vec3; at: number }[] = [];
|
|
236
|
-
let prev = from;
|
|
237
|
-
path.forEach((to, k) => {
|
|
238
|
-
const [ax, ay] = squareCentre(l, prev);
|
|
239
|
-
const [bx, by] = squareCentre(l, to);
|
|
240
|
-
if (jump) keys.push({ position: [(ax + bx) / 2, (ay + by) / 2, SURFACE + l.cell * 0.55], at: (k + 0.5) / path.length });
|
|
241
|
-
keys.push({ position: [bx, by, SURFACE], at: (k + 1) / path.length });
|
|
242
|
-
prev = to;
|
|
243
|
-
});
|
|
244
|
-
world.stopAnimation(v.root);
|
|
245
|
-
world.animate(v.root, keys, { duration: per * path.length, delay, path: jump ? 'smooth' : 'linear', easing: 'easeInOut' });
|
|
246
|
-
captured.forEach((sq, k) => {
|
|
247
|
-
const c = s.pieces.get(sq);
|
|
248
|
-
if (!c) return;
|
|
249
|
-
s.pieces.delete(sq);
|
|
250
|
-
const when = delay + per * (k + 0.55);
|
|
251
|
-
world.animate(c.root, [{ scale: l.cell * 1.15, at: 0.3 }, { scale: 0.01 }], { duration: 0.22, delay: when, easing: 'easeIn' });
|
|
252
|
-
world.set(c.root, { lifetime: when + 0.3 });
|
|
253
|
-
const [x, y] = squareCentre(l, sq);
|
|
254
|
-
queueBurst(world, l, s, [x, y, SURFACE + l.cell * 0.15], when);
|
|
255
|
-
});
|
|
256
|
-
const dest = path[path.length - 1]!;
|
|
257
|
-
s.pieces.set(dest, v);
|
|
258
|
-
if (king) crown(world, v, king, true);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/** Splinters where a piece is taken, at its moment. */
|
|
262
|
-
function queueBurst(world: World, l: Layout, s: Scene, position: Vec3, delay: number) {
|
|
263
|
-
s.queue.push({
|
|
264
|
-
at: s.time + delay,
|
|
265
|
-
run: () =>
|
|
266
|
-
effects.sparkle(world, {
|
|
267
|
-
position,
|
|
268
|
-
count: 16,
|
|
269
|
-
size: l.cell * 0.07,
|
|
270
|
-
speed: l.cell * 2.5,
|
|
271
|
-
lifetime: 0.55,
|
|
272
|
-
gravity: -l.cell * 4,
|
|
273
|
-
colors: [toColor('#FFFFFF'), toColor(COLORS.GOLD)]
|
|
274
|
-
})
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/** Runs the scene's queued bursts; called once a frame. */
|
|
279
|
-
export function stepScene(s: Scene, dt: number) {
|
|
280
|
-
s.time += dt;
|
|
281
|
-
for (let i = s.queue.length - 1; i >= 0; i--)
|
|
282
|
-
if (s.queue[i]!.at <= s.time) {
|
|
283
|
-
const [q] = s.queue.splice(i, 1);
|
|
284
|
-
q!.run();
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/** The game won: confetti over the board, the red pieces hop. */
|
|
289
|
-
export function celebrate(world: World, l: Layout, s: Scene, board: CheckersBoard) {
|
|
290
|
-
for (const [i, v] of s.pieces) {
|
|
291
|
-
if (board[i]?.player !== 'red') continue;
|
|
292
|
-
const [x, y] = squareCentre(l, i);
|
|
293
|
-
world.animate(v.root, [{ position: [x, y, SURFACE + l.cell * 0.5], at: 0.4 }, { position: [x, y, SURFACE] }], {
|
|
294
|
-
duration: 0.45,
|
|
295
|
-
delay: 0.3 + (Math.floor(i / 8) + (i % 8)) * 0.04,
|
|
296
|
-
easing: 'easeOut'
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
effects.confetti(world, {
|
|
300
|
-
position: [0, 0, l.cell],
|
|
301
|
-
count: 70,
|
|
302
|
-
size: l.cell * 0.12,
|
|
303
|
-
speed: l.size * 1.3,
|
|
304
|
-
lifetime: 1.3,
|
|
305
|
-
gravity: -l.size * 2.4,
|
|
306
|
-
colors: ['#FFD700', '#E53935', '#4CAF50', '#2196F3'].map((c) => toColor(c))
|
|
307
|
-
});
|
|
308
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// Color Switch's screen, on the Nayan engine: the rings, stars and ball are one 3D scene (an
|
|
2
|
-
// orthographic camera following the ball up the field), under Playtura's scoreboard, controls and
|
|
3
|
-
// modals. The play is in ColorSwitchGame.ts, what it draws in ColorSwitchScene.ts.
|
|
4
|
-
//
|
|
5
|
-
// One world serves the whole visit: Start, Stop and Play Again reset it in place, so the GPU view is
|
|
6
|
-
// never rebuilt. JS steps the ball and the rings (a few numbers) and the world once a frame; hops,
|
|
7
|
-
// colour changes and the crash animate in the engine's Rust core.
|
|
8
|
-
import { HapticType } from '../../services/HapticsService';
|
|
9
|
-
import { GAME_SOUNDS } from '../../services/SoundsService';
|
|
10
|
-
import { GAME_IDS } from '../../services/UtilsService';
|
|
11
|
-
import { engineGame, EngineGameScreen } from '../shared/EngineGameScreen';
|
|
12
|
-
import { scoreColumn, timerColumn } from '../shared/EngineHud';
|
|
13
|
-
import { useEngineGame } from '../shared/useEngineGame';
|
|
14
|
-
import { useLiveState } from '../shared/useLiveState';
|
|
15
|
-
import { getLayout, LIGHT, TIME_LIMIT } from './ColorSwitchConstants';
|
|
16
|
-
import { createGame, dispose, type GameEvent, jump, reset, setLayout, setTheme, start, tick } from './ColorSwitchGame';
|
|
17
|
-
|
|
18
|
-
const SOUNDS = GAME_SOUNDS.COLOR_SWITCH;
|
|
19
|
-
|
|
20
|
-
/** Each event's sound and haptic, as the original version played them. */
|
|
21
|
-
const FEEDBACK: Record<GameEvent, { sound: (typeof SOUNDS)[keyof typeof SOUNDS]; haptic: HapticType }> = {
|
|
22
|
-
jump: { sound: SOUNDS.JUMP, haptic: HapticType.LIGHT },
|
|
23
|
-
pass: { sound: SOUNDS.PASS, haptic: HapticType.MEDIUM },
|
|
24
|
-
color: { sound: SOUNDS.COLOR_CHANGE, haptic: HapticType.SUCCESS },
|
|
25
|
-
crash: { sound: SOUNDS.GAME_OVER, haptic: HapticType.ERROR }
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const ColorSwitch = engineGame(GAME_IDS.COLOR_SWITCH, (props) => {
|
|
29
|
-
const [score, setScore] = useLiveState(0);
|
|
30
|
-
const [time, setTime] = useLiveState(TIME_LIMIT);
|
|
31
|
-
|
|
32
|
-
// A win after two minutes, a loss on a crash
|
|
33
|
-
const { theme, status, screen, gameOver } = useEngineGame(props, {
|
|
34
|
-
gameId: GAME_IDS.COLOR_SWITCH,
|
|
35
|
-
create: createGame,
|
|
36
|
-
start,
|
|
37
|
-
reset,
|
|
38
|
-
dispose,
|
|
39
|
-
tick,
|
|
40
|
-
setTheme,
|
|
41
|
-
resize: (g, width, height, offset) => setLayout(g, getLayout(width, height, offset)),
|
|
42
|
-
// Hops on touch-down, as the original game did
|
|
43
|
-
drag: (g, e) => {
|
|
44
|
-
if (e.phase === 'start') jump(g);
|
|
45
|
-
},
|
|
46
|
-
sounds: SOUNDS,
|
|
47
|
-
onStart: (fx) => fx(SOUNDS.START, HapticType.SUCCESS),
|
|
48
|
-
onStop: (fx) => fx(null, HapticType.MEDIUM),
|
|
49
|
-
// A win's sound and haptic (a crash's played as it happened)
|
|
50
|
-
onOver: (fx, s) => {
|
|
51
|
-
if (s === 'win') fx(GAME_SOUNDS.WELL_DONE, HapticType.SUCCESS);
|
|
52
|
-
},
|
|
53
|
-
wire: (g, fx) => {
|
|
54
|
-
g.onScore = setScore;
|
|
55
|
-
g.onTime = setTime;
|
|
56
|
-
g.onEvent = (event) => fx(FEEDBACK[event].sound, FEEDBACK[event].haptic);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<EngineGameScreen
|
|
62
|
-
{...screen}
|
|
63
|
-
light={LIGHT}
|
|
64
|
-
columns={[scoreColumn(score), timerColumn(time, theme, 0)]}
|
|
65
|
-
subtext="Tap to jump through!"
|
|
66
|
-
gameOver={gameOver({
|
|
67
|
-
title: status === 'win' ? 'YOU WON!' : 'GAME OVER',
|
|
68
|
-
message: status === 'win' ? 'You survived 2 minutes!' : 'Wrong color!',
|
|
69
|
-
scoreLabel: 'Final Score',
|
|
70
|
-
score,
|
|
71
|
-
buttonText: 'Switch Again!'
|
|
72
|
-
})}
|
|
73
|
-
/>
|
|
74
|
-
);
|
|
75
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
// Color Switch's rules, physics, timings and layout. Rules, physics (per 60 Hz tick, in points) and
|
|
2
|
-
// scoring match the original version (games/color-switch), so scores and feel carry over.
|
|
3
|
-
import { frontLight } from '../shared/EngineUtils';
|
|
4
|
-
|
|
5
|
-
// ── Rules ─────────────────────────────────────────────────────────────
|
|
6
|
-
|
|
7
|
-
/** The four colors, one per quarter of every ring (quarter k from k x 90 degrees, clockwise on screen). */
|
|
8
|
-
export const GAME_COLORS = ['#FF6B6B', '#FFE66D', '#4ECDC4', '#A855F7'] as const;
|
|
9
|
-
export const TIME_LIMIT = 120; // seconds; surviving them wins
|
|
10
|
-
export const POINTS_PER_PASS = 1000;
|
|
11
|
-
|
|
12
|
-
// ── Physics (per 60 Hz tick) ──────────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
export const STEP_MS = 1000 / 60;
|
|
15
|
-
export const STEP_TOLERANCE_MS = 2;
|
|
16
|
-
export const MAX_PENDING_MS = 50;
|
|
17
|
-
export const GRAVITY = 0.2;
|
|
18
|
-
export const JUMP_VELOCITY = -4.5;
|
|
19
|
-
export const MAX_VELOCITY = 12;
|
|
20
|
-
export const ROTATION_SPEED = 0.017; // every ring keeps this speed for the entire run
|
|
21
|
-
export const FORGIVENESS = Math.PI / 15; // a ring's colour boundaries forgive this much either side
|
|
22
|
-
export const SPAWN_MARGIN = 100;
|
|
23
|
-
|
|
24
|
-
// ── The scene ─────────────────────────────────────────────────────────
|
|
25
|
-
|
|
26
|
-
/** Lit from the upper left; faces toward the camera (+z) keep their exact color. */
|
|
27
|
-
export const LIGHT = frontLight([-0.45, 0.55, 1], 0.45);
|
|
28
|
-
|
|
29
|
-
// ── Layout (view points; the field's y runs down and the camera follows the ball up it) ──
|
|
30
|
-
|
|
31
|
-
const TABLET_WIDTH = 640;
|
|
32
|
-
|
|
33
|
-
export type Layout = {
|
|
34
|
-
width: number;
|
|
35
|
-
height: number;
|
|
36
|
-
/** The field's top edge in the view (the original canvas sat centred under the header, as tall as the window). */
|
|
37
|
-
top: number;
|
|
38
|
-
fieldHeight: number;
|
|
39
|
-
ballRadius: number;
|
|
40
|
-
ringRadius: number;
|
|
41
|
-
ringThickness: number;
|
|
42
|
-
gap: number;
|
|
43
|
-
starRadius: number;
|
|
44
|
-
ballStartY: number;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
export function getLayout(width: number, height: number, offset: number): Layout {
|
|
48
|
-
const tablet = width > TABLET_WIDTH;
|
|
49
|
-
return {
|
|
50
|
-
width,
|
|
51
|
-
height,
|
|
52
|
-
top: offset / 2,
|
|
53
|
-
fieldHeight: height,
|
|
54
|
-
ballRadius: tablet ? 14 : 11,
|
|
55
|
-
ringRadius: tablet ? 150 : 120,
|
|
56
|
-
ringThickness: tablet ? 16 : 13,
|
|
57
|
-
gap: tablet ? 550 : 450,
|
|
58
|
-
starRadius: tablet ? 10 : 8,
|
|
59
|
-
ballStartY: height * 0.9
|
|
60
|
-
};
|
|
61
|
-
}
|