@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,94 +0,0 @@
|
|
|
1
|
-
// Whack a Mole's rules, timings and layout. Rules, timings and scoring match the original version
|
|
2
|
-
// (games/whack-a-mole), so scores carry over.
|
|
3
|
-
import { getScoreBoardTop } from '../shared/EngineHud';
|
|
4
|
-
import { makeView, type MeadowOptions, rayThrough, type View3D } from '../shared/EngineMeadow';
|
|
5
|
-
import { gameWidthFor } from '../shared/EngineUtils';
|
|
6
|
-
|
|
7
|
-
// ── Rules ─────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
export const GRID = 3; // holes a side
|
|
10
|
-
export const HOLES = GRID * GRID;
|
|
11
|
-
export const TIME_LIMIT = 120; // seconds; surviving them is the end of every game (always a win)
|
|
12
|
-
export const POINTS_PER_MOLE = 500;
|
|
13
|
-
export const TIME_WARNING = 10; // seconds left when the warning sounds
|
|
14
|
-
|
|
15
|
-
// ── Timings (seconds, as the original version) ────────────────────────────
|
|
16
|
-
|
|
17
|
-
export const FIRST_SPAWN = 1;
|
|
18
|
-
export const SPAWN_MAX = 1.5;
|
|
19
|
-
export const SPAWN_MIN = 1.05; // 30% faster than the longest gap
|
|
20
|
-
export const MOLE_UP_TIME = 2; // a mole stays up this long, then ducks back (a miss)
|
|
21
|
-
|
|
22
|
-
// ── The scene (metres) ────────────────────────────────────────────────
|
|
23
|
-
|
|
24
|
-
export const EYE_HEIGHT = 1.6;
|
|
25
|
-
/** Rows are further apart in depth than columns across, so the perspective doesn't squash them together. */
|
|
26
|
-
export const ROW_SPACING = 1.6; // x the column spacing
|
|
27
|
-
export const HOLE_RADIUS = 0.36; // x the column spacing
|
|
28
|
-
export const MOLE_HEIGHT = 0.62; // x the column spacing: how far a mole rises out of its hole
|
|
29
|
-
|
|
30
|
-
// ── Layout ────────────────────────────────────────────────────────────
|
|
31
|
-
|
|
32
|
-
const SCOREBOARD_HEIGHT = 82;
|
|
33
|
-
const CONTROLS_HEIGHT = 175; // room under the near row: the holes sit well clear of the controls
|
|
34
|
-
const SKY_BELOW_SCOREBOARD = 45; // points of sky and treeline showing under the scoreboard
|
|
35
|
-
const SIDE_MARGIN = 14;
|
|
36
|
-
const MAX_FAR_Z = 5.3; // metres: the far row's rims stay in front of the meadow's rocks and bushes (6 m on)
|
|
37
|
-
|
|
38
|
-
export type Layout = {
|
|
39
|
-
width: number;
|
|
40
|
-
height: number;
|
|
41
|
-
view: View3D;
|
|
42
|
-
/** Metres between neighbouring holes across; rows are `ROW_SPACING` times that apart. */
|
|
43
|
-
spacing: number;
|
|
44
|
-
/** Metres from the eye to the near row. */
|
|
45
|
-
nearZ: number;
|
|
46
|
-
/** Each hole's centre on the ground, row 0 (furthest) first, left to right. */
|
|
47
|
-
holes: [number, number, number][];
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* The camera at eye height looking across a lawn: the horizon a little under the scoreboard (sky,
|
|
52
|
-
* hills and the treeline above it), the near row's rims just above the controls, the grid as wide as
|
|
53
|
-
* fits the screen.
|
|
54
|
-
*/
|
|
55
|
-
export function getLayout(width: number, height: number, offset: number): Layout {
|
|
56
|
-
const horizonY = getScoreBoardTop(offset) + SCOREBOARD_HEIGHT + SKY_BELOW_SCOREBOARD;
|
|
57
|
-
const view = makeView(width, height, { eyeHeight: EYE_HEIGHT, horizon: horizonY / height, playDepth: 3 });
|
|
58
|
-
// Where the bottom of the near row's rims meets the ground
|
|
59
|
-
const ray = rayThrough(view, width / 2, height - CONTROLS_HEIGHT);
|
|
60
|
-
const bottomZ = -(EYE_HEIGHT / -ray[1]) * ray[2]; // metres ahead
|
|
61
|
-
// The near row spans at most the game width (the view less 30, at most 500)
|
|
62
|
-
const edge = Math.min(width - SIDE_MARGIN, width / 2 + gameWidthFor(width) / 2);
|
|
63
|
-
// The widest spacing that keeps the near row's outer rims on screen
|
|
64
|
-
let lo = 0.05;
|
|
65
|
-
let hi = 3;
|
|
66
|
-
for (let i = 0; i < 40; i++) {
|
|
67
|
-
const s = (lo + hi) / 2;
|
|
68
|
-
const [x] = toScreen(view, [s * (1 + HOLE_RADIUS), 0, -(bottomZ + s * HOLE_RADIUS)]);
|
|
69
|
-
if (x > edge) hi = s;
|
|
70
|
-
else lo = s;
|
|
71
|
-
}
|
|
72
|
-
// ...and in front of the meadow's rocks and bushes
|
|
73
|
-
const spacing = Math.min(lo, (MAX_FAR_Z - bottomZ) / (HOLE_RADIUS * 2 + (GRID - 1) * ROW_SPACING));
|
|
74
|
-
const nearZ = bottomZ + spacing * HOLE_RADIUS;
|
|
75
|
-
const holes: [number, number, number][] = [];
|
|
76
|
-
for (let row = 0; row < GRID; row++)
|
|
77
|
-
for (let col = 0; col < GRID; col++) holes.push([(col - 1) * spacing, 0, -(nearZ + (GRID - 1 - row) * spacing * ROW_SPACING)]);
|
|
78
|
-
return { width, height, view, spacing, nearZ, holes };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Where a world point appears in the view (screen points). */
|
|
82
|
-
export function toScreen(v: View3D, p: readonly [number, number, number]): [number, number] {
|
|
83
|
-
const d = [p[0] - v.eye[0], p[1] - v.eye[1], p[2] - v.eye[2]] as const;
|
|
84
|
-
const depth = d[0] * v.forward[0] + d[1] * v.forward[1] + d[2] * v.forward[2];
|
|
85
|
-
const up = d[0] * v.up[0] + d[1] * v.up[1] + d[2] * v.up[2];
|
|
86
|
-
const k = v.height / 2 / (v.tanHalf * Math.max(depth, 1e-3));
|
|
87
|
-
return [v.width / 2 + d[0] * k, v.height / 2 - up * k];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** The meadow around the lawn: the sun and clouds in the strip of sky above the horizon. */
|
|
91
|
-
export function meadowFor(l: Layout): MeadowOptions {
|
|
92
|
-
const horizon = l.view.horizon;
|
|
93
|
-
return { sun: [0.82, horizon * 0.55], clouds: [0.02, horizon * 0.8], hotAirBalloons: 1 };
|
|
94
|
-
}
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
// Whack a Mole's rules, with no React: build a game with `createGame`, give it a layout, `start` it and
|
|
2
|
-
// `tick` it every frame. Moles pop up in random free holes (the first after a second, then every
|
|
3
|
-
// 1.05 to 1.5 seconds) and duck back after two; tap one to whack it for 500 points. When the two
|
|
4
|
-
// minutes run out the game ends, always a win, with whatever was scored.
|
|
5
|
-
//
|
|
6
|
-
// Every timer (the clock, spawns, each mole's two seconds) runs on the game's own clock, advanced by
|
|
7
|
-
// `tick`: a stop or reset drops what's pending, so nothing lands in the next game, and it all pauses
|
|
8
|
-
// with the view.
|
|
9
|
-
import { type Camera, World } from '@nayan-ui/engine';
|
|
10
|
-
import type { GameTheme } from '../../services/ThemeService';
|
|
11
|
-
import { cameraFor } from '../shared/EngineMeadow';
|
|
12
|
-
import {
|
|
13
|
-
FIRST_SPAWN,
|
|
14
|
-
HOLES,
|
|
15
|
-
type Layout,
|
|
16
|
-
MOLE_UP_TIME,
|
|
17
|
-
POINTS_PER_MOLE,
|
|
18
|
-
SPAWN_MAX,
|
|
19
|
-
SPAWN_MIN,
|
|
20
|
-
TIME_LIMIT,
|
|
21
|
-
TIME_WARNING,
|
|
22
|
-
toScreen
|
|
23
|
-
} from './WhackAMoleConstants';
|
|
24
|
-
import { bonk, buildScene, duck, hideAll, hitEffect, missEffect, moleTop, popUp, removeScene, type Scene, thud } from './WhackAMoleScene';
|
|
25
|
-
|
|
26
|
-
export type Phase = 'ready' | 'playing' | 'over';
|
|
27
|
-
export type GameEvent = 'spawn' | 'hit' | 'miss' | 'empty' | 'warning';
|
|
28
|
-
|
|
29
|
-
const WORLD_CAPACITY = 1000; // the meadow (~350), the lawn's props (~110), holes and moles, bursts
|
|
30
|
-
const MAX_STEP = 0.1;
|
|
31
|
-
|
|
32
|
-
export function createGame(theme: GameTheme) {
|
|
33
|
-
const world = new World(WORLD_CAPACITY);
|
|
34
|
-
// Placed for the view on the first layout; GameView reads this object every frame
|
|
35
|
-
const camera: Camera = { eye: [0, 1.6, 0], target: [0, 1, -3], fov: 0.9 };
|
|
36
|
-
const g = {
|
|
37
|
-
world,
|
|
38
|
-
camera,
|
|
39
|
-
theme,
|
|
40
|
-
layout: null as Layout | null,
|
|
41
|
-
hitLayout: null as Layout | null,
|
|
42
|
-
hitZones: [] as { rim: [number, number]; up: [number, number]; down: [number, number]; reach: number }[],
|
|
43
|
-
scene: null as Scene | null,
|
|
44
|
-
phase: 'ready' as Phase,
|
|
45
|
-
/** Score and the countdown live in the engine (Rust), advanced by world.update. */
|
|
46
|
-
get score() {
|
|
47
|
-
return world.scoreboard.score;
|
|
48
|
-
},
|
|
49
|
-
get timeLeft() {
|
|
50
|
-
return world.scoreboard.shownSeconds;
|
|
51
|
-
},
|
|
52
|
-
/** Which holes have a mole up, and when each one ducks back (game clock). */
|
|
53
|
-
up: new Array<boolean>(HOLES).fill(false),
|
|
54
|
-
hideAt: new Array<number>(HOLES).fill(0),
|
|
55
|
-
nextSpawn: 0,
|
|
56
|
-
/** Seconds on the game's clock, for spawns and each mole's time up. */
|
|
57
|
-
clock: 0,
|
|
58
|
-
// UI hooks, set by the screen.
|
|
59
|
-
onPhase: (_p: Phase) => {},
|
|
60
|
-
onScore: (_s: number) => {},
|
|
61
|
-
onTime: (_t: number) => {},
|
|
62
|
-
onEvent: (_e: GameEvent) => {}
|
|
63
|
-
};
|
|
64
|
-
world.scoreboard.reset(0, TIME_LIMIT);
|
|
65
|
-
world.scoreboard.handlers = {
|
|
66
|
-
onScore: (s) => g.onScore(s),
|
|
67
|
-
onSecond: (t) => {
|
|
68
|
-
g.onTime(t);
|
|
69
|
-
if (t === TIME_WARNING && g.phase === 'playing') g.onEvent('warning');
|
|
70
|
-
},
|
|
71
|
-
onTimeUp: () => g.phase === 'playing' && end(g)
|
|
72
|
-
};
|
|
73
|
-
return g;
|
|
74
|
-
}
|
|
75
|
-
export type Game = ReturnType<typeof createGame>;
|
|
76
|
-
|
|
77
|
-
// ── Scene ─────────────────────────────────────────────────────────────
|
|
78
|
-
|
|
79
|
-
/** Lays the world out for the view (first layout, header height, rotation): rebuilt from the game's state. */
|
|
80
|
-
export function setLayout(g: Game, l: Layout) {
|
|
81
|
-
if (g.scene) removeScene(g.world, g.scene);
|
|
82
|
-
g.layout = l;
|
|
83
|
-
const cam = cameraFor(l.view);
|
|
84
|
-
g.camera.eye = cam.eye;
|
|
85
|
-
g.camera.target = cam.target;
|
|
86
|
-
g.camera.fov = cam.fov;
|
|
87
|
-
g.scene = buildScene(g.world, l, g.theme);
|
|
88
|
-
g.up.forEach((up, i) => up && g.scene && g.world.set(g.scene.moles[i]!, { position: [l.holes[i]![0], 0, l.holes[i]![2]] }));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** A new theme: day or night (the screen swaps the light); the game carries on. */
|
|
92
|
-
export function setTheme(g: Game, theme: GameTheme) {
|
|
93
|
-
if (theme === g.theme) return;
|
|
94
|
-
g.theme = theme;
|
|
95
|
-
if (g.layout && !g.world.isDisposed) setLayout(g, g.layout);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// ── Run ───────────────────────────────────────────────────────────────
|
|
99
|
-
|
|
100
|
-
export function start(g: Game) {
|
|
101
|
-
if (g.phase !== 'ready') return;
|
|
102
|
-
g.phase = 'playing';
|
|
103
|
-
g.nextSpawn = g.clock + FIRST_SPAWN;
|
|
104
|
-
g.world.scoreboard.startCountdown(TIME_LIMIT);
|
|
105
|
-
g.onPhase('playing');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** Back to a fresh, unstarted game (Stop, Play Again). The world, and the GPU view drawing it, are kept. */
|
|
109
|
-
export function reset(g: Game) {
|
|
110
|
-
g.world.cancelTimers();
|
|
111
|
-
clearMoles(g);
|
|
112
|
-
g.world.scoreboard.reset(0, TIME_LIMIT);
|
|
113
|
-
g.phase = 'ready';
|
|
114
|
-
g.onScore(0);
|
|
115
|
-
g.onTime(TIME_LIMIT);
|
|
116
|
-
g.onPhase('ready');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export function dispose(g: Game) {
|
|
120
|
-
g.world.dispose();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function clearMoles(g: Game) {
|
|
124
|
-
g.up.fill(false);
|
|
125
|
-
if (g.layout && g.scene) hideAll(g.world, g.layout, g.scene);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function tick(g: Game, dt: number) {
|
|
129
|
-
if (g.world.isDisposed) return;
|
|
130
|
-
g.clock += Math.min(dt, MAX_STEP);
|
|
131
|
-
if (g.phase === 'playing') {
|
|
132
|
-
// Moles that weren't hit in time duck back
|
|
133
|
-
for (let i = 0; g.phase === 'playing' && i < HOLES; i++) {
|
|
134
|
-
if (g.up[i] && g.clock >= g.hideAt[i]!) {
|
|
135
|
-
g.up[i] = false;
|
|
136
|
-
if (g.layout && g.scene) duck(g.world, g.layout, g.scene, i);
|
|
137
|
-
g.onEvent('miss');
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (g.phase === 'playing' && g.clock >= g.nextSpawn) {
|
|
141
|
-
spawn(g);
|
|
142
|
-
g.nextSpawn = g.clock + SPAWN_MIN + Math.random() * (SPAWN_MAX - SPAWN_MIN);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
g.world.update(dt);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/** A mole up in a random free hole. */
|
|
149
|
-
function spawn(g: Game) {
|
|
150
|
-
const free: number[] = [];
|
|
151
|
-
for (let i = 0; i < HOLES; i++) if (!g.up[i]) free.push(i);
|
|
152
|
-
if (!free.length) return;
|
|
153
|
-
const hole = free[Math.floor(Math.random() * free.length)]!;
|
|
154
|
-
g.up[hole] = true;
|
|
155
|
-
g.hideAt[hole] = g.clock + MOLE_UP_TIME;
|
|
156
|
-
if (g.layout && g.scene) popUp(g.world, g.layout, g.scene, hole);
|
|
157
|
-
g.onEvent('spawn');
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function end(g: Game) {
|
|
161
|
-
g.world.cancelTimers();
|
|
162
|
-
g.world.scoreboard.stop();
|
|
163
|
-
clearMoles(g);
|
|
164
|
-
g.phase = 'over';
|
|
165
|
-
g.onPhase('over');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// ── Taps ──────────────────────────────────────────────────────────────
|
|
169
|
-
|
|
170
|
-
/** Distance from point p to the segment a..b. */
|
|
171
|
-
function toSegment(p: [number, number], a: [number, number], b: [number, number]) {
|
|
172
|
-
const dx = b[0] - a[0];
|
|
173
|
-
const dy = b[1] - a[1];
|
|
174
|
-
const t = dx || dy ? Math.max(0, Math.min(1, ((p[0] - a[0]) * dx + (p[1] - a[1]) * dy) / (dx * dx + dy * dy))) : 0;
|
|
175
|
-
return Math.hypot(p[0] - (a[0] + dx * t), p[1] - (a[1] + dy * t));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* The hole a view point is over: its rim, or the mole standing in it. Each hole's zone reaches half way
|
|
180
|
-
* to its neighbours in its row (the far row's are smaller, as it looks), and the nearest one wins.
|
|
181
|
-
*/
|
|
182
|
-
export function holeAt(g: Game, x: number, y: number): number | null {
|
|
183
|
-
const l = g.layout;
|
|
184
|
-
if (!l) return null;
|
|
185
|
-
if (g.hitLayout !== l) {
|
|
186
|
-
const top = moleTop(l);
|
|
187
|
-
g.hitZones = l.holes.map((hole) => {
|
|
188
|
-
const rim = toScreen(l.view, hole);
|
|
189
|
-
return {
|
|
190
|
-
rim,
|
|
191
|
-
reach: Math.abs(toScreen(l.view, [hole[0] + l.spacing, 0, hole[2]])[0] - rim[0]) * 0.5,
|
|
192
|
-
up: toScreen(l.view, [hole[0], top, hole[2]]),
|
|
193
|
-
down: toScreen(l.view, [hole[0], l.spacing * 0.15, hole[2]])
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
g.hitLayout = l;
|
|
197
|
-
}
|
|
198
|
-
let best: number | null = null;
|
|
199
|
-
let bestScore = 1;
|
|
200
|
-
const point: [number, number] = [x, y];
|
|
201
|
-
g.hitZones.forEach(({ rim, up, down, reach }, i) => {
|
|
202
|
-
const head = g.up[i] ? up : down;
|
|
203
|
-
const score = toSegment(point, rim, head) / reach;
|
|
204
|
-
if (score < bestScore) {
|
|
205
|
-
best = i;
|
|
206
|
-
bestScore = score;
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
return best;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/** A tap: a hit lands on the hole under it at once, whacking the mole if one's up. */
|
|
213
|
-
export function tap(g: Game, x: number, y: number) {
|
|
214
|
-
if (g.phase !== 'playing') return;
|
|
215
|
-
const hole = holeAt(g, x, y);
|
|
216
|
-
if (hole == null) return;
|
|
217
|
-
const { layout: l, scene: s } = g;
|
|
218
|
-
if (!g.up[hole]) {
|
|
219
|
-
g.onEvent('empty');
|
|
220
|
-
if (l) {
|
|
221
|
-
thud(g.world, l, hole);
|
|
222
|
-
missEffect(g.world, l, hole);
|
|
223
|
-
}
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
g.up[hole] = false;
|
|
227
|
-
g.world.scoreboard.add(POINTS_PER_MOLE);
|
|
228
|
-
g.onEvent('hit');
|
|
229
|
-
if (l && s) {
|
|
230
|
-
bonk(g.world, l, s, hole);
|
|
231
|
-
hitEffect(g.world, l, hole);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
@@ -1,349 +0,0 @@
|
|
|
1
|
-
// Everything Whack a Mole draws, in the shared 3D meadow (shared/EngineMeadow): a lawn of nine dirt
|
|
2
|
-
// mounds round dark holes, a mole in each that springs up and ducks back, and a flash of impact
|
|
3
|
-
// streaks and dust wherever you tap. The world is y-up and in metres; the holes and moles are sized by the
|
|
4
|
-
// layout's spacing. Each kind of thing is one shared mesh (one instanced draw): mesh ids are app-wide
|
|
5
|
-
// and limited, so each is built once.
|
|
6
|
-
import {
|
|
7
|
-
type Color,
|
|
8
|
-
effects,
|
|
9
|
-
type Entity,
|
|
10
|
-
type GeometryPart,
|
|
11
|
-
lathe,
|
|
12
|
-
merge,
|
|
13
|
-
type Model,
|
|
14
|
-
quat,
|
|
15
|
-
shapeGeometry,
|
|
16
|
-
tube,
|
|
17
|
-
type Vec3,
|
|
18
|
-
type World
|
|
19
|
-
} from '@nayan-ui/engine';
|
|
20
|
-
import type { GameTheme } from '../../services/ThemeService';
|
|
21
|
-
import { flowerMesh, noise, random, rockMesh, sceneryTint, spawnWorld, tuftMesh } from '../shared/EngineMeadow';
|
|
22
|
-
import { cacheGameAsset, createGameMesh as createShape } from '../shared/EngineMeshes';
|
|
23
|
-
import { toColor } from '../shared/EngineUtils';
|
|
24
|
-
import { HOLE_RADIUS, type Layout, meadowFor, MOLE_HEIGHT } from './WhackAMoleConstants';
|
|
25
|
-
|
|
26
|
-
// ── Helpers ───────────────────────────────────────────────────────────
|
|
27
|
-
|
|
28
|
-
const meshes = new Map<string, Model>();
|
|
29
|
-
const cached = (key: string, build: () => Model) => {
|
|
30
|
-
let m = meshes.get(key);
|
|
31
|
-
if (!m) {
|
|
32
|
-
m = cacheGameAsset('whack-a-mole/WhackAMoleScene:' + key, build);
|
|
33
|
-
meshes.set(key, m);
|
|
34
|
-
}
|
|
35
|
-
return m;
|
|
36
|
-
};
|
|
37
|
-
type RGB = [number, number, number];
|
|
38
|
-
const rgb = (css: string): RGB => {
|
|
39
|
-
const [r, g, b] = toColor(css);
|
|
40
|
-
return [r, g, b];
|
|
41
|
-
};
|
|
42
|
-
const mix = (a: RGB, b: RGB, t: number): RGB => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
|
|
43
|
-
const shade = (c: RGB, k: number): RGB => [c[0] * k, c[1] * k, c[2] * k];
|
|
44
|
-
const smooth = (a: number, b: number, x: number) => {
|
|
45
|
-
const t = Math.min(1, Math.max(0, (x - a) / (b - a)));
|
|
46
|
-
return t * t * (3 - 2 * t);
|
|
47
|
-
};
|
|
48
|
-
const sphere = () => shapeGeometry('sphere');
|
|
49
|
-
const tinted = (c: Color, t: Color): Color => [c[0] * t[0], c[1] * t[1], c[2] * t[2], c[3] ?? 1];
|
|
50
|
-
|
|
51
|
-
// ── Meshes (unit sizes; entities scale them by the layout's spacing) ──
|
|
52
|
-
|
|
53
|
-
/** A hole: a dark throat in a raised ring of loose soil, `HOLE_RADIUS` across at the rim, on the ground. */
|
|
54
|
-
const moundMesh = () =>
|
|
55
|
-
cached('wam-mound', () => {
|
|
56
|
-
const soil = rgb('#7A4E2D');
|
|
57
|
-
const dry = rgb('#A27449');
|
|
58
|
-
const deep = rgb('#140B05');
|
|
59
|
-
const r = HOLE_RADIUS;
|
|
60
|
-
return createShape(
|
|
61
|
-
lathe(
|
|
62
|
-
[
|
|
63
|
-
[r * 1.75, 0],
|
|
64
|
-
[r * 1.45, r * 0.12],
|
|
65
|
-
[r * 1.12, r * 0.3],
|
|
66
|
-
[r * 0.95, r * 0.32],
|
|
67
|
-
[r * 0.8, r * 0.16],
|
|
68
|
-
[r * 0.66, r * 0.03],
|
|
69
|
-
[0.001, r * 0.015]
|
|
70
|
-
],
|
|
71
|
-
{
|
|
72
|
-
segments: 40,
|
|
73
|
-
displace: (u, v) => (v < 0.6 ? 0.012 * Math.sin(u * Math.PI * 2 * 9) * Math.sin(v * Math.PI) : 0),
|
|
74
|
-
color: ({ position: p }) => {
|
|
75
|
-
const radius = Math.hypot(p[0], p[2]) / r;
|
|
76
|
-
const lumps = 0.82 + 0.36 * noise(p[0] * 40 + 5, p[2] * 40);
|
|
77
|
-
const c = mix(shade(soil, 0.65), dry, smooth(0.9, 1.15, radius) * (1 - smooth(1.3, 1.75, radius) * 0.6));
|
|
78
|
-
return shade(mix(deep, c, smooth(0.62, 0.92, radius)), lumps);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
),
|
|
82
|
-
{ center: false, shine: 0.05 }
|
|
83
|
-
);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
/** A mole, about one unit tall and standing on the origin, facing the camera (+z): furry, pink-nosed, blinking out. */
|
|
87
|
-
const moleMesh = () =>
|
|
88
|
-
cached('wam-mole', () => {
|
|
89
|
-
const fur = rgb('#7B5134');
|
|
90
|
-
const furDark = rgb('#4E3220');
|
|
91
|
-
const muzzle = rgb('#E8B48A');
|
|
92
|
-
const pink = rgb('#FF6F91');
|
|
93
|
-
const paw = rgb('#F2A99B');
|
|
94
|
-
const body = lathe(
|
|
95
|
-
[
|
|
96
|
-
[0.33, -0.45],
|
|
97
|
-
[0.36, 0.05],
|
|
98
|
-
[0.35, 0.4],
|
|
99
|
-
[0.3, 0.66],
|
|
100
|
-
[0.2, 0.84],
|
|
101
|
-
[0.001, 0.93]
|
|
102
|
-
],
|
|
103
|
-
{
|
|
104
|
-
segments: 32,
|
|
105
|
-
color: ({ position: p, normal: n }) => {
|
|
106
|
-
// A paler belly toward the front, fur streaks all over
|
|
107
|
-
const front = smooth(0.35, 0.85, n[2]) * (1 - smooth(0.35, 0.6, p[1]));
|
|
108
|
-
const c = mix(mix(furDark, fur, smooth(-0.3, 0.6, p[1])), muzzle, front * 0.65);
|
|
109
|
-
return shade(c, 0.85 + 0.3 * noise(p[0] * 30 + p[1] * 8, p[2] * 30 + p[1] * 70));
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
);
|
|
113
|
-
const pair = (part: GeometryPart): GeometryPart[] => [part, { ...part, position: [-part.position![0], part.position![1], part.position![2]] }];
|
|
114
|
-
const whiskers: GeometryPart[] = [];
|
|
115
|
-
for (const side of [1, -1])
|
|
116
|
-
for (const [dy, dz] of [
|
|
117
|
-
[0.02, 0.04],
|
|
118
|
-
[-0.02, 0.0],
|
|
119
|
-
[-0.06, -0.03]
|
|
120
|
-
] as [number, number][])
|
|
121
|
-
whiskers.push({
|
|
122
|
-
geometry: tube(
|
|
123
|
-
[
|
|
124
|
-
[side * 0.1, 0.62 + dy, 0.36],
|
|
125
|
-
[side * 0.24, 0.63 + dy * 1.6, 0.34 + dz],
|
|
126
|
-
[side * 0.36, 0.62 + dy * 2.4, 0.3 + dz]
|
|
127
|
-
],
|
|
128
|
-
{ radius: 0.006, sides: 4, smoothness: 4, color: [0.15, 0.1, 0.08] }
|
|
129
|
-
)
|
|
130
|
-
});
|
|
131
|
-
return createShape(
|
|
132
|
-
merge([
|
|
133
|
-
{ geometry: body },
|
|
134
|
-
// Snout, nose, teeth
|
|
135
|
-
{ geometry: sphere(), position: [0, 0.6, 0.27], scale: [0.25, 0.19, 0.22], color: [...muzzle, 1] },
|
|
136
|
-
{ geometry: sphere(), position: [0, 0.65, 0.38], scale: [0.11, 0.085, 0.09], color: [...pink, 1] },
|
|
137
|
-
{ geometry: sphere(), position: [0.02, 0.675, 0.42], scale: 0.025, color: [1, 1, 1, 1] },
|
|
138
|
-
...pair({ geometry: shapeGeometry('roundedBox'), position: [0.025, 0.52, 0.355], scale: [0.04, 0.06, 0.02], color: [1, 1, 0.96, 1] }),
|
|
139
|
-
// Glossy black eyes with a glint, little ears, rosy cheeks
|
|
140
|
-
...pair({ geometry: sphere(), position: [0.11, 0.77, 0.25], scale: 0.075, color: [0.04, 0.03, 0.03, 1] }),
|
|
141
|
-
...pair({ geometry: sphere(), position: [0.095, 0.79, 0.285], scale: 0.022, color: [1, 1, 1, 1] }),
|
|
142
|
-
...pair({ geometry: sphere(), position: [0.23, 0.84, 0.0], scale: [0.11, 0.09, 0.05], color: [...furDark, 1] }),
|
|
143
|
-
...pair({ geometry: sphere(), position: [0.2, 0.6, 0.2], scale: [0.11, 0.08, 0.06], color: [...mix(muzzle, pink, 0.35), 1] }),
|
|
144
|
-
// Paws gripping the rim
|
|
145
|
-
...pair({ geometry: sphere(), position: [0.2, 0.2, 0.3], scale: [0.17, 0.09, 0.15], color: [...paw, 1] }),
|
|
146
|
-
...whiskers
|
|
147
|
-
]),
|
|
148
|
-
{ center: false, shine: 0.22 }
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// ── Spawning ──────────────────────────────────────────────────────────
|
|
153
|
-
|
|
154
|
-
export type Scene = {
|
|
155
|
-
scenery: Entity[];
|
|
156
|
-
mounds: Entity[];
|
|
157
|
-
moles: Entity[];
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
const moleScale = (l: Layout) => (MOLE_HEIGHT * l.spacing) / 0.93;
|
|
161
|
-
/** A mole's place: up out of its hole, or hidden below the ground. */
|
|
162
|
-
export const molePosition = (l: Layout, hole: number, up: boolean): Vec3 => {
|
|
163
|
-
const [x, , z] = l.holes[hole]!;
|
|
164
|
-
return [x, up ? 0 : -moleScale(l) * 1.05, z];
|
|
165
|
-
};
|
|
166
|
-
/** The top of a mole that's up, for hit-testing and the hit's burst. */
|
|
167
|
-
export const moleTop = (l: Layout) => moleScale(l) * 0.9;
|
|
168
|
-
|
|
169
|
-
export function buildScene(world: World, l: Layout, theme: GameTheme): Scene {
|
|
170
|
-
const tint = sceneryTint(theme);
|
|
171
|
-
const scenery = spawnWorld(world, l.view, theme, { ...meadowFor(l), foreground: false });
|
|
172
|
-
// The lawn's own tufts, flowers and pebbles, kept off the holes
|
|
173
|
-
const rand = random(11);
|
|
174
|
-
const s = l.spacing;
|
|
175
|
-
const near = -l.holes[l.holes.length - 1]![2];
|
|
176
|
-
const far = -l.holes[0]![2];
|
|
177
|
-
const clear = (x: number, z: number) => l.holes.every(([hx, , hz]) => Math.hypot(x - hx, z - hz) > s * HOLE_RADIUS * 2);
|
|
178
|
-
const place = (mesh: Model, size: number | Vec3, color: Color, count: number, from: number, to: number) => {
|
|
179
|
-
for (let i = 0, tries = 0; i < count && tries < count * 8; tries++) {
|
|
180
|
-
const z = -(from + rand() * (to - from));
|
|
181
|
-
const x = (rand() * 2 - 1) * (-z * 0.62 + 0.4);
|
|
182
|
-
if (!clear(x, z)) continue;
|
|
183
|
-
scenery.push(
|
|
184
|
-
world.spawn({ mesh, position: [x, 0, z], scale: size, rotation: quat.y(rand() * 6.3), color: tinted(color, tint), pickable: false })
|
|
185
|
-
);
|
|
186
|
-
i++;
|
|
187
|
-
}
|
|
188
|
-
};
|
|
189
|
-
place(tuftMesh(), 0.9, [1, 1, 1, 1], 70, near - s, far + s * 1.4);
|
|
190
|
-
const petals = ['#FF6B9D', '#FFFFFF', '#FFD54F', '#B784FF', '#6FA8FF'].map((c) => toColor(c));
|
|
191
|
-
for (let i = 0; i < 5; i++) place(flowerMesh(), 0.8, petals[i]!, 5, near - s * 0.5, far + s * 1.4);
|
|
192
|
-
place(rockMesh(), [0.07, 0.05, 0.06], [0.85, 0.8, 0.75, 1], 14, near - s * 0.5, far + s);
|
|
193
|
-
|
|
194
|
-
const mounds = l.holes.map(([x, , z]) =>
|
|
195
|
-
world.spawn({
|
|
196
|
-
mesh: moundMesh(),
|
|
197
|
-
position: [x, 0, z],
|
|
198
|
-
scale: s,
|
|
199
|
-
rotation: quat.y(rand() * 6.3),
|
|
200
|
-
color: tinted([1, 1, 1, 1], tint),
|
|
201
|
-
pickable: false
|
|
202
|
-
})
|
|
203
|
-
);
|
|
204
|
-
const moles = l.holes.map((_, i) =>
|
|
205
|
-
world.spawn({ mesh: moleMesh(), position: molePosition(l, i, false), scale: moleScale(l), color: tinted([1, 1, 1, 1], tint), pickable: false })
|
|
206
|
-
);
|
|
207
|
-
return { scenery, mounds, moles };
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export function removeScene(world: World, s: Scene) {
|
|
211
|
-
for (const e of [...s.scenery, ...s.mounds, ...s.moles]) world.despawn(e);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// ── Motion ────────────────────────────────────────────────────────────
|
|
215
|
-
|
|
216
|
-
/** A mole springs up out of its hole and looks about. */
|
|
217
|
-
export function popUp(world: World, l: Layout, s: Scene, hole: number) {
|
|
218
|
-
const mole = s.moles[hole]!;
|
|
219
|
-
world.stopAnimation(mole);
|
|
220
|
-
world.set(mole, { position: molePosition(l, hole, false), scale: moleScale(l), rotation: quat.y(0) });
|
|
221
|
-
world.animate(mole, { position: molePosition(l, hole, true) }, { spring: { stiffness: 200, damping: 15 } });
|
|
222
|
-
world.animate(mole, [{ rotation: quat.y(0.35), at: 0.3 }, { rotation: quat.y(-0.35), at: 0.8 }, { rotation: quat.y(0) }], {
|
|
223
|
-
duration: 1.6,
|
|
224
|
-
delay: 0.25,
|
|
225
|
-
easing: 'easeInOut'
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/** A mole that wasn't hit ducks back down. */
|
|
230
|
-
export function duck(world: World, l: Layout, s: Scene, hole: number) {
|
|
231
|
-
const mole = s.moles[hole]!;
|
|
232
|
-
world.stopAnimation(mole);
|
|
233
|
-
world.animate(mole, { position: molePosition(l, hole, false) }, { duration: 0.22, easing: 'easeIn' });
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/** A whacked mole squashes flat, sees stars and sinks away. */
|
|
237
|
-
export function bonk(world: World, l: Layout, s: Scene, hole: number) {
|
|
238
|
-
const mole = s.moles[hole]!;
|
|
239
|
-
const size = moleScale(l);
|
|
240
|
-
world.stopAnimation(mole);
|
|
241
|
-
world.animate(mole, [{ scale: [size * 1.25, size * 0.55, size * 1.25], at: 0.25 }, { scale: [size * 1.1, size * 0.7, size * 1.1] }], {
|
|
242
|
-
duration: 0.18
|
|
243
|
-
});
|
|
244
|
-
world.animate(mole, { position: molePosition(l, hole, false) }, { duration: 0.28, delay: 0.14, easing: 'easeIn' });
|
|
245
|
-
world.animate(mole, { scale: size }, { duration: 0.01, delay: 0.45 });
|
|
246
|
-
const [x, , z] = l.holes[hole]!;
|
|
247
|
-
effects.sparkle(world, {
|
|
248
|
-
position: [x, moleTop(l) * 0.75, z],
|
|
249
|
-
count: 14,
|
|
250
|
-
size: l.spacing * 0.06,
|
|
251
|
-
speed: l.spacing * 2.2,
|
|
252
|
-
direction: [0, 1, 0],
|
|
253
|
-
spread: 1.1,
|
|
254
|
-
lifetime: 0.55,
|
|
255
|
-
gravity: -l.spacing * 4,
|
|
256
|
-
colors: [toColor('#FFD700'), toColor('#FFF59D'), toColor('#FFA500')]
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/** Dirt kicked up where a tap hits an empty hole. */
|
|
261
|
-
export function thud(world: World, l: Layout, hole: number) {
|
|
262
|
-
const [x, , z] = l.holes[hole]!;
|
|
263
|
-
effects.shatter(world, {
|
|
264
|
-
position: [x, l.spacing * 0.05, z],
|
|
265
|
-
count: 8,
|
|
266
|
-
mesh: 'sphere',
|
|
267
|
-
size: l.spacing * 0.05,
|
|
268
|
-
speed: l.spacing * 1.6,
|
|
269
|
-
direction: [0, 1, 0],
|
|
270
|
-
spread: 1.2,
|
|
271
|
-
lifetime: 0.45,
|
|
272
|
-
gravity: -l.spacing * 6,
|
|
273
|
-
colors: [toColor('#7A4E2D'), toColor('#A27449')],
|
|
274
|
-
flash: false
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// ── The hit ───────────────────────────────────────────────────────────
|
|
279
|
-
|
|
280
|
-
const STREAK: Color = [2.2, 1.85, 0.7, 0.95]; // above 1: self-lit
|
|
281
|
-
const FLASH: Color = [2.4, 2.1, 1.2, 0.8];
|
|
282
|
-
const DUST: Color = [0.86, 0.74, 0.56, 0.6];
|
|
283
|
-
|
|
284
|
-
/** A soft puff of dust kicked out round a hole, low and wide. */
|
|
285
|
-
function dust(world: World, l: Layout, hole: number, amount: number) {
|
|
286
|
-
const [x, , z] = l.holes[hole]!;
|
|
287
|
-
const s = l.spacing;
|
|
288
|
-
effects.dust(world, {
|
|
289
|
-
position: [x, s * 0.05, z],
|
|
290
|
-
count: Math.round(10 * amount),
|
|
291
|
-
size: s * 0.22 * amount,
|
|
292
|
-
speed: s * 2.2 * amount,
|
|
293
|
-
direction: [0, 1, 0],
|
|
294
|
-
spread: 1.45,
|
|
295
|
-
lifetime: 0.5,
|
|
296
|
-
color: DUST,
|
|
297
|
-
endSize: 2.2
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* A whack: a hot flash flares behind the mole's head, eight impact streaks shoot out from it, comic
|
|
303
|
-
* style, and dust puffs out round the hole (the mole squashes and sees stars in `bonk`).
|
|
304
|
-
*/
|
|
305
|
-
export function hitEffect(world: World, l: Layout, hole: number) {
|
|
306
|
-
const [x, , z] = l.holes[hole]!;
|
|
307
|
-
const s = l.spacing;
|
|
308
|
-
const at: Vec3 = [x, moleTop(l) * 0.8, z + s * 0.2];
|
|
309
|
-
effects.flash(world, { position: at, color: FLASH, size: s * 0.5, lifetime: 0.16, endSize: 2.4 });
|
|
310
|
-
const spokes = 8;
|
|
311
|
-
const twist = Math.random() * Math.PI;
|
|
312
|
-
for (let i = 0; i < spokes; i++) {
|
|
313
|
-
const a = twist + (i / spokes) * Math.PI * 2;
|
|
314
|
-
const [cx, cy] = [Math.cos(a), Math.sin(a)];
|
|
315
|
-
const from = s * 0.32;
|
|
316
|
-
const to = s * (0.75 + (i % 2) * 0.2);
|
|
317
|
-
const streak = world.spawn({
|
|
318
|
-
mesh: 'cube',
|
|
319
|
-
position: [at[0] + cx * from, at[1] + cy * from, at[2]],
|
|
320
|
-
rotation: quat.z(a),
|
|
321
|
-
scale: [s * 0.2, s * 0.05, s * 0.02],
|
|
322
|
-
color: STREAK,
|
|
323
|
-
pickable: false
|
|
324
|
-
});
|
|
325
|
-
world
|
|
326
|
-
.animate(
|
|
327
|
-
streak,
|
|
328
|
-
{ position: [at[0] + cx * to, at[1] + cy * to, at[2]], scale: [s * 0.04, s * 0.012, s * 0.02], color: [STREAK[0], STREAK[1], STREAK[2], 0] },
|
|
329
|
-
{ duration: 0.26, easing: 'easeOut' }
|
|
330
|
-
)
|
|
331
|
-
.then(() => {
|
|
332
|
-
if (world.has(streak)) world.despawn(streak);
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
dust(world, l, hole, 1);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/** A miss: a smaller puff of dust with the dirt. */
|
|
339
|
-
export function missEffect(world: World, l: Layout, hole: number) {
|
|
340
|
-
dust(world, l, hole, 0.6);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/** Every mole back underground (a reset or the end of a game). */
|
|
344
|
-
export function hideAll(world: World, l: Layout, s: Scene) {
|
|
345
|
-
s.moles.forEach((m, i) => {
|
|
346
|
-
world.stopAnimation(m);
|
|
347
|
-
world.set(m, { position: molePosition(l, i, false), scale: moleScale(l), rotation: quat.y(0) });
|
|
348
|
-
});
|
|
349
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// Word Search, on the Nayan engine: eight words hidden in a 10 x 10 grid of 3D letter tiles. The board,
|
|
2
|
-
// rules and screen are shared with Number Search (search-grid/); this is what's Word Search's own.
|
|
3
|
-
import { GAME_SOUNDS } from '../../services/SoundsService';
|
|
4
|
-
import { GAME_IDS } from '../../services/UtilsService';
|
|
5
|
-
import { createSearchGame } from '../search-grid/SearchGrid';
|
|
6
|
-
import { WORDS } from './WordSearchWords';
|
|
7
|
-
|
|
8
|
-
export const WordSearch = createSearchGame({
|
|
9
|
-
gameId: GAME_IDS.WORD_SEARCH,
|
|
10
|
-
list: WORDS,
|
|
11
|
-
alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
|
12
|
-
sounds: GAME_SOUNDS.WORD_SEARCH,
|
|
13
|
-
winTitle: 'ALL WORDS FOUND!',
|
|
14
|
-
winMessage: 'Great word hunting!',
|
|
15
|
-
startSubtext: 'Find hidden words!',
|
|
16
|
-
variant: 'word',
|
|
17
|
-
displayName: 'WordSearch'
|
|
18
|
-
});
|