@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,440 +0,0 @@
|
|
|
1
|
-
// The car and the roadside tree, built in code (as Penguin Run's penguin) rather than loaded from
|
|
2
|
-
// files. The car is a mid-engined supercar: a low wedge nose with LED headlights in dark housings and
|
|
3
|
-
// vents in the bonnet, a cab-forward glasshouse, flanks that pinch at the doors and swell over the
|
|
4
|
-
// wheels, cut-out arches with big low-profile wheels flush inside them, and a long louvred engine deck
|
|
5
|
-
// under an airfoil wing on swan-neck mounts. Model units are metres: it sits on y = 0 facing -z, about
|
|
6
|
-
// 2.4 wide (mirrors) by 1.18 tall by 4.36 long. Three meshes, as any model: the body (white, so each car
|
|
7
|
-
// paints its own color), the glass, and the trim (wheels, lights, carbon, vents, exhausts) in its own colors.
|
|
8
|
-
import {
|
|
9
|
-
block,
|
|
10
|
-
type Color,
|
|
11
|
-
ellipsoid,
|
|
12
|
-
type Geometry,
|
|
13
|
-
lathe,
|
|
14
|
-
loft,
|
|
15
|
-
type LoftSection as Section,
|
|
16
|
-
merge,
|
|
17
|
-
type Model,
|
|
18
|
-
type Quat,
|
|
19
|
-
quat,
|
|
20
|
-
smoothCurve,
|
|
21
|
-
tube,
|
|
22
|
-
type Vec3
|
|
23
|
-
} from '@nayan-ui/engine';
|
|
24
|
-
|
|
25
|
-
type GeometryPart = Parameters<typeof merge>[0][number];
|
|
26
|
-
import type { Footprint } from '../shared/EngineFootprint';
|
|
27
|
-
import { cacheGameAsset, createGameMesh as createShape } from '../shared/EngineMeshes';
|
|
28
|
-
|
|
29
|
-
const TAU = Math.PI * 2;
|
|
30
|
-
const GLASS: Color = [0.05, 0.065, 0.09];
|
|
31
|
-
const TREAD: Color = [0.035, 0.035, 0.04];
|
|
32
|
-
const SIDEWALL: Color = [0.07, 0.07, 0.075];
|
|
33
|
-
const GUNMETAL: Color = [0.14, 0.14, 0.16];
|
|
34
|
-
const SPOKE: Color = [0.72, 0.73, 0.77];
|
|
35
|
-
const DISC: Color = [0.32, 0.32, 0.34];
|
|
36
|
-
const CALIPER: Color = [0.85, 0.08, 0.06];
|
|
37
|
-
const CARBON: Color = [0.055, 0.055, 0.065];
|
|
38
|
-
const BLACK: Color = [0.025, 0.025, 0.03];
|
|
39
|
-
const HEADLIGHT: Color = [0.95, 0.97, 1];
|
|
40
|
-
const DRL: Color = [1.4, 1.4, 1.45];
|
|
41
|
-
const TAIL_LIGHT: Color = [0.8, 0.03, 0.03];
|
|
42
|
-
const TAIL_LED: Color = [1.2, 0.08, 0.06];
|
|
43
|
-
const CHROME: Color = [0.8, 0.81, 0.84];
|
|
44
|
-
|
|
45
|
-
/** Turns a lathe's axis (y) onto x, for wheels. */
|
|
46
|
-
export const AXLE_X: Quat = [0, 0, Math.SQRT1_2, Math.SQRT1_2];
|
|
47
|
-
|
|
48
|
-
export type WheelOptions = {
|
|
49
|
-
/** The rim's radius as a share of the wheel's (a low-profile tyre is around 0.75). Default 0.7. */
|
|
50
|
-
rim?: number;
|
|
51
|
-
/** Spokes. Default 10. */
|
|
52
|
-
spokes?: number;
|
|
53
|
-
/** The rim's and the spokes' colors. Default gunmetal and bright silver. */
|
|
54
|
-
rimColor?: Color;
|
|
55
|
-
spokeColor?: Color;
|
|
56
|
-
/** What shows between the spokes (the brake disc on a car; dark on a bike, as if open). Default disc grey. */
|
|
57
|
-
gapColor?: Color;
|
|
58
|
-
/** A red brake caliper behind the spokes, toward the front (-z) and up, as on a car. Default false. */
|
|
59
|
-
caliper?: boolean;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* A wheel `radius` across and `width` wide around the y axis (turn it with AXLE_X): a tyre with a
|
|
64
|
-
* rounded tread and darker sidewall, around a dished alloy rim with slim spokes over a brake disc.
|
|
65
|
-
* Wheels don't spin in these games, so the caliper is painted where it shows.
|
|
66
|
-
*/
|
|
67
|
-
export function wheel(radius: number, width: number, options: WheelOptions = {}): Geometry {
|
|
68
|
-
const h = width / 2;
|
|
69
|
-
const rim = radius * (options.rim ?? 0.7);
|
|
70
|
-
const spokes = options.spokes ?? 10;
|
|
71
|
-
const rimColor = options.rimColor ?? GUNMETAL;
|
|
72
|
-
const spokeColor = options.spokeColor ?? SPOKE;
|
|
73
|
-
const gapColor = options.gapColor ?? DISC;
|
|
74
|
-
const profile: [number, number][] = [
|
|
75
|
-
[0.001, h * 0.45],
|
|
76
|
-
[rim * 0.18, h * 0.5],
|
|
77
|
-
[rim * 0.92, h * 0.86],
|
|
78
|
-
[rim * 1.02, h * 0.98],
|
|
79
|
-
[rim * 1.04, h],
|
|
80
|
-
[radius * 0.94, h * 0.97],
|
|
81
|
-
[radius * 0.995, h * 0.7],
|
|
82
|
-
[radius * 1.005, 0],
|
|
83
|
-
[radius * 0.995, -h * 0.7],
|
|
84
|
-
[radius * 0.94, -h * 0.97],
|
|
85
|
-
[rim * 1.04, -h],
|
|
86
|
-
[rim * 1.02, -h * 0.98],
|
|
87
|
-
[rim * 0.92, -h * 0.86],
|
|
88
|
-
[rim * 0.18, -h * 0.5],
|
|
89
|
-
[0.001, -h * 0.45]
|
|
90
|
-
];
|
|
91
|
-
return lathe(profile, {
|
|
92
|
-
segments: 48,
|
|
93
|
-
color: ({ u, position: [x, , z] }) => {
|
|
94
|
-
const r = Math.hypot(x, z);
|
|
95
|
-
if (r > radius * 0.97) return TREAD;
|
|
96
|
-
if (r > rim * 1.05) return SIDEWALL;
|
|
97
|
-
if (r > rim * 0.94) return spokeColor; // the rim's polished lip
|
|
98
|
-
if (r < rim * 0.14) return BLACK; // centre lock
|
|
99
|
-
if (r < rim * 0.26) return rimColor;
|
|
100
|
-
if (Math.cos(u * TAU * spokes) > 0.55) return spokeColor;
|
|
101
|
-
if (options.caliper && r > rim * 0.58 && r < rim * 0.86 && x > 0 && z < 0 && Math.atan2(x, -z) > 0.35 && Math.atan2(x, -z) < 1.2)
|
|
102
|
-
return CALIPER;
|
|
103
|
-
return r > rim * 0.42 ? gapColor : rimColor;
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// ── The car ───────────────────────────────────────────────────────────
|
|
109
|
-
|
|
110
|
-
const WHEEL_R = 0.36;
|
|
111
|
-
const FRONT_AXLE = -1.36;
|
|
112
|
-
const REAR_AXLE = 1.38;
|
|
113
|
-
const ARCH_R = WHEEL_R + 0.05;
|
|
114
|
-
const SKIRT = 0.17;
|
|
115
|
-
|
|
116
|
-
/** The body's profiles along its length (z): roof of the lower body, half widths, and the floor. */
|
|
117
|
-
const topLine = smoothCurve([
|
|
118
|
-
[-2.18, 0.48],
|
|
119
|
-
[-2.06, 0.58],
|
|
120
|
-
[-1.75, 0.69],
|
|
121
|
-
[-1.36, 0.8], // over the front wheels
|
|
122
|
-
[-1.05, 0.78], // the scuttle, at the foot of the windscreen
|
|
123
|
-
[-0.3, 0.8],
|
|
124
|
-
[0.55, 0.86],
|
|
125
|
-
[1.38, 0.92], // the rear haunches
|
|
126
|
-
[1.9, 0.92],
|
|
127
|
-
[2.1, 0.86],
|
|
128
|
-
[2.18, 0.78]
|
|
129
|
-
]);
|
|
130
|
-
const halfWidth = smoothCurve([
|
|
131
|
-
[-2.18, 0.84],
|
|
132
|
-
[-2.02, 1.04],
|
|
133
|
-
[-1.6, 1.15],
|
|
134
|
-
[-1.36, 1.17], // front flares
|
|
135
|
-
[-0.95, 1.11],
|
|
136
|
-
[-0.15, 1.06], // the waist at the doors
|
|
137
|
-
[0.6, 1.12],
|
|
138
|
-
[1.1, 1.19],
|
|
139
|
-
[1.4, 1.2], // rear haunches
|
|
140
|
-
[1.85, 1.16],
|
|
141
|
-
[2.18, 1.0]
|
|
142
|
-
]);
|
|
143
|
-
/** The floor: low along the sills, arched over each wheel. */
|
|
144
|
-
const floorAt = (z: number) => {
|
|
145
|
-
let y = smoothCurve([
|
|
146
|
-
[-2.18, 0.24],
|
|
147
|
-
[-1.95, SKIRT],
|
|
148
|
-
[1.95, SKIRT],
|
|
149
|
-
[2.18, 0.3]
|
|
150
|
-
])(z);
|
|
151
|
-
for (const axle of [FRONT_AXLE, REAR_AXLE]) {
|
|
152
|
-
const d = z - axle;
|
|
153
|
-
if (Math.abs(d) < ARCH_R) y = Math.max(y, WHEEL_R + Math.sqrt(ARCH_R * ARCH_R - d * d));
|
|
154
|
-
}
|
|
155
|
-
return y;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
/** Sections, closely spaced around the arches so their curves come out round. */
|
|
159
|
-
function bodySections(): Section[] {
|
|
160
|
-
const zs = new Set<number>();
|
|
161
|
-
for (let z = -2.18; z < 2.18; z += 0.1) zs.add(Math.round(z * 1000) / 1000);
|
|
162
|
-
zs.add(2.18);
|
|
163
|
-
for (const axle of [FRONT_AXLE, REAR_AXLE])
|
|
164
|
-
for (let i = 0; i <= 20; i++) zs.add(Math.round((axle - ARCH_R * Math.cos((i / 20) * Math.PI)) * 1000) / 1000);
|
|
165
|
-
for (const axle of [FRONT_AXLE, REAR_AXLE]) for (const d of [-ARCH_R - 0.015, ARCH_R + 0.015]) zs.add(Math.round((axle + d) * 1000) / 1000);
|
|
166
|
-
return [...zs].sort((a, b) => a - b).map(sectionAt);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/** The body's section at `z`. */
|
|
170
|
-
function sectionAt(z: number): Section {
|
|
171
|
-
const top = topLine(z);
|
|
172
|
-
const bottom = Math.min(floorAt(z), top - 0.06);
|
|
173
|
-
const width = halfWidth(z);
|
|
174
|
-
const nose = Math.max(0, Math.min(1, (z + 2.18) / 0.3));
|
|
175
|
-
return { z, bottom, top, width, topWidth: width * 0.86, square: 3 + 1.8 * nose };
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/** How far out the body's side is at height `y`, `z` along it (its outline there is a superellipse). */
|
|
179
|
-
function surfaceX(z: number, y: number) {
|
|
180
|
-
const { bottom, top, width, topWidth = width, square = 4 } = sectionAt(z);
|
|
181
|
-
const py = Math.max(-1, Math.min(1, (y - (bottom + top) / 2) / ((top - bottom) / 2)));
|
|
182
|
-
const px = (1 - Math.abs(py) ** square) ** (1 / square);
|
|
183
|
-
return px * (py > 0 ? width + (topWidth - width) * py : width);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/** Door mirrors: where each stalk leaves the door (just under its surface) and where its cap sits. */
|
|
187
|
-
const MIRROR_Z = -0.9;
|
|
188
|
-
const MIRROR_BASE_Y = 0.7;
|
|
189
|
-
const mirrorBase = (s: number): Vec3 => [s * (surfaceX(MIRROR_Z, MIRROR_BASE_Y) - 0.02), MIRROR_BASE_Y, MIRROR_Z];
|
|
190
|
-
const mirrorCap = (s: number): Vec3 => [s * (surfaceX(MIRROR_Z, MIRROR_BASE_Y) + 0.15), MIRROR_BASE_Y + 0.08, MIRROR_Z + 0.04];
|
|
191
|
-
|
|
192
|
-
/** The glasshouse, narrowing above a painted shoulder: a steep wrapped windscreen and a fastback onto the deck. */
|
|
193
|
-
const CABIN: Section[] = [
|
|
194
|
-
{ z: -1.06, bottom: 0.55, top: 0.79, width: 0.82, topWidth: 0.78 },
|
|
195
|
-
{ z: -0.72, bottom: 0.55, top: 0.95, width: 0.8, topWidth: 0.62 },
|
|
196
|
-
{ z: -0.3, bottom: 0.55, top: 1.09, width: 0.79, topWidth: 0.55 },
|
|
197
|
-
{ z: 0.05, bottom: 0.55, top: 1.12, width: 0.78, topWidth: 0.53 },
|
|
198
|
-
{ z: 0.45, bottom: 0.55, top: 1.1, width: 0.79, topWidth: 0.55 },
|
|
199
|
-
{ z: 0.95, bottom: 0.6, top: 1.0, width: 0.8, topWidth: 0.62 },
|
|
200
|
-
{ z: 1.4, bottom: 0.7, top: 0.93, width: 0.86, topWidth: 0.8 }
|
|
201
|
-
];
|
|
202
|
-
/** The painted roof panel, flush over the glass. */
|
|
203
|
-
const ROOF: Section[] = [
|
|
204
|
-
{ z: -0.36, bottom: 1.07, top: 1.09, width: 0.44, square: 6 },
|
|
205
|
-
{ z: -0.2, bottom: 1.09, top: 1.13, width: 0.52, square: 6 },
|
|
206
|
-
{ z: 0.42, bottom: 1.09, top: 1.125, width: 0.53, square: 6 },
|
|
207
|
-
{ z: 0.66, bottom: 1.05, top: 1.07, width: 0.46, square: 6 }
|
|
208
|
-
];
|
|
209
|
-
|
|
210
|
-
/** The rear wing: a cambered airfoil across the car (lofted along its span, then turned across). */
|
|
211
|
-
function wingGeometry(span: number, chord: number, thickness: number): Geometry {
|
|
212
|
-
const sections: Section[] = [-1, -0.92, 0, 0.92, 1].map((t) => ({
|
|
213
|
-
z: (t * span) / 2,
|
|
214
|
-
bottom: -thickness / 2,
|
|
215
|
-
top: thickness / 2,
|
|
216
|
-
width: (chord / 2) * (Math.abs(t) > 0.95 ? 0.94 : 1),
|
|
217
|
-
square: 2.6
|
|
218
|
-
}));
|
|
219
|
-
return loft(sections, { around: 20, smoothness: 2, color: CARBON });
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
export type CarMeshes = { body: Model; glass: Model; trim: Model };
|
|
223
|
-
let car: CarMeshes | null = null;
|
|
224
|
-
|
|
225
|
-
/** The car's three meshes, built once per app. */
|
|
226
|
-
export function carMeshes(): CarMeshes {
|
|
227
|
-
return cacheGameAsset('car-racing/CarMeshes:carMeshes', () => carMeshesUncached());
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function carMeshesUncached(): CarMeshes {
|
|
231
|
-
if (car) return car;
|
|
232
|
-
// Paint darkens toward the sills, so the flanks read as curved under any color
|
|
233
|
-
const shell = loft(bodySections(), {
|
|
234
|
-
around: 56,
|
|
235
|
-
smoothness: 2,
|
|
236
|
-
color: ([, y]) => {
|
|
237
|
-
const k = 0.62 + 0.38 * Math.max(0, Math.min(1, (y - 0.18) / 0.34));
|
|
238
|
-
return [k, k, k];
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
const bodyParts: GeometryPart[] = [{ geometry: shell }, { geometry: loft(ROOF, { around: 32, smoothness: 3 }) }];
|
|
242
|
-
// Mirror caps in the body color
|
|
243
|
-
for (const s of [-1, 1]) bodyParts.push({ geometry: ellipsoid([0.09, 0.05, 0.12]), position: mirrorCap(s) });
|
|
244
|
-
const body = createShape(merge(bodyParts), { center: false, shine: 0.9 });
|
|
245
|
-
const glass = createShape(loft(CABIN, { around: 40, smoothness: 4, color: GLASS }), {
|
|
246
|
-
center: false,
|
|
247
|
-
shine: 0.95
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
const parts: GeometryPart[] = [];
|
|
251
|
-
const front = wheel(WHEEL_R, 0.26, { rim: 0.76, spokes: 10, caliper: true });
|
|
252
|
-
const rear = wheel(WHEEL_R, 0.31, { rim: 0.76, spokes: 10, caliper: true });
|
|
253
|
-
const liner = lathe(
|
|
254
|
-
[
|
|
255
|
-
[0.001, 0.01],
|
|
256
|
-
[WHEEL_R + 0.03, 0.01],
|
|
257
|
-
[WHEEL_R + 0.03, -0.01],
|
|
258
|
-
[0.001, -0.01]
|
|
259
|
-
],
|
|
260
|
-
{ segments: 24, color: BLACK }
|
|
261
|
-
);
|
|
262
|
-
const hoodY = (z: number) => topLine(z) + 0.004;
|
|
263
|
-
for (const s of [-1, 1]) {
|
|
264
|
-
parts.push(
|
|
265
|
-
{ geometry: front, position: [s * 0.98, WHEEL_R, FRONT_AXLE], rotation: AXLE_X },
|
|
266
|
-
{ geometry: rear, position: [s * 0.97, WHEEL_R, REAR_AXLE], rotation: AXLE_X },
|
|
267
|
-
// Dark wheel wells behind the wheels
|
|
268
|
-
{ geometry: liner, position: [s * 0.8, WHEEL_R + 0.03, FRONT_AXLE], rotation: AXLE_X },
|
|
269
|
-
{ geometry: liner, position: [s * 0.78, WHEEL_R + 0.03, REAR_AXLE], rotation: AXLE_X },
|
|
270
|
-
// LED headlights in dark housings, a daytime-running-light strip along their top edge
|
|
271
|
-
{
|
|
272
|
-
geometry: ellipsoid([0.3, 0.05, 0.09], BLACK),
|
|
273
|
-
position: [s * 0.64, 0.555, -2.04],
|
|
274
|
-
rotation: quat.y(s * 0.32)
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
geometry: ellipsoid([0.26, 0.034, 0.08], HEADLIGHT),
|
|
278
|
-
position: [s * 0.64, 0.555, -2.06],
|
|
279
|
-
rotation: quat.y(s * 0.32)
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
geometry: block(0.32, 0.012, 0.02, 6, DRL),
|
|
283
|
-
position: [s * 0.62, 0.585, -2.08],
|
|
284
|
-
rotation: quat.y(s * 0.32)
|
|
285
|
-
},
|
|
286
|
-
// Intakes either side of the nose, vents in the bonnet, and vents behind the front wheels
|
|
287
|
-
{
|
|
288
|
-
geometry: block(0.46, 0.14, 0.08, 6, BLACK),
|
|
289
|
-
position: [s * 0.52, 0.34, -2.14],
|
|
290
|
-
rotation: quat.y(s * 0.15)
|
|
291
|
-
},
|
|
292
|
-
{
|
|
293
|
-
geometry: block(0.3, 0.012, 0.16, 6, BLACK),
|
|
294
|
-
position: [s * 0.36, hoodY(-1.58), -1.58],
|
|
295
|
-
rotation: quat.x(-0.27)
|
|
296
|
-
},
|
|
297
|
-
...[0.47, 0.53, 0.59].map((y): GeometryPart => ({
|
|
298
|
-
geometry: block(0.016, 0.022, 0.2, 6, BLACK),
|
|
299
|
-
position: [s * (halfWidth(-0.84) - 0.01), y, -0.84 + (y - 0.53) * 0.4]
|
|
300
|
-
})),
|
|
301
|
-
// Side intakes ahead of the rear wheels, carbon side skirts
|
|
302
|
-
{ geometry: ellipsoid([0.02, 0.08, 0.3], BLACK), position: [s * 1.115, 0.58, 0.72] },
|
|
303
|
-
{ geometry: block(0.06, 0.06, 2.0, 6, CARBON), position: [s * 1.05, 0.2, 0.01] },
|
|
304
|
-
// Carbon mirror stalks to the body-colored caps
|
|
305
|
-
{
|
|
306
|
-
geometry: tube([mirrorBase(s), [s * (surfaceX(MIRROR_Z, MIRROR_BASE_Y) + 0.05), MIRROR_BASE_Y + 0.06, MIRROR_Z + 0.02], mirrorCap(s)], {
|
|
307
|
-
radius: 0.02,
|
|
308
|
-
sides: 8,
|
|
309
|
-
smoothness: 3
|
|
310
|
-
}),
|
|
311
|
-
color: CARBON
|
|
312
|
-
},
|
|
313
|
-
// Wing endplates and swan-neck mounts over the top of the wing
|
|
314
|
-
{ geometry: block(0.012, 0.16, 0.34, 6, CARBON), position: [s * 0.87, 1.07, 1.98] },
|
|
315
|
-
{
|
|
316
|
-
geometry: tube(
|
|
317
|
-
[
|
|
318
|
-
[s * 0.42, 0.93, 2.04],
|
|
319
|
-
[s * 0.42, 1.08, 1.96],
|
|
320
|
-
[s * 0.42, 1.115, 1.99]
|
|
321
|
-
],
|
|
322
|
-
{
|
|
323
|
-
radius: 0.018,
|
|
324
|
-
shape: (a) => 0.45 + 0.55 * Math.abs(Math.cos(a * TAU)),
|
|
325
|
-
sides: 10,
|
|
326
|
-
smoothness: 4
|
|
327
|
-
}
|
|
328
|
-
),
|
|
329
|
-
color: CARBON
|
|
330
|
-
},
|
|
331
|
-
// Tail lights: a slim red LED at each corner, curving down the rear
|
|
332
|
-
{
|
|
333
|
-
geometry: tube(
|
|
334
|
-
[
|
|
335
|
-
[s * 0.62, 0.79, 2.17],
|
|
336
|
-
[s * 0.86, 0.79, 2.15],
|
|
337
|
-
[s * 0.96, 0.72, 2.11],
|
|
338
|
-
[s * 0.94, 0.62, 2.09]
|
|
339
|
-
],
|
|
340
|
-
{ radius: 0.022, sides: 8, smoothness: 4 }
|
|
341
|
-
),
|
|
342
|
-
color: TAIL_LED
|
|
343
|
-
}
|
|
344
|
-
);
|
|
345
|
-
// Quad exhausts, chrome with dark bores
|
|
346
|
-
for (const x of [0.2, 0.34]) {
|
|
347
|
-
parts.push({
|
|
348
|
-
geometry: tube(
|
|
349
|
-
[
|
|
350
|
-
[s * x, 0.3, 2.04],
|
|
351
|
-
[s * x, 0.3, 2.2]
|
|
352
|
-
],
|
|
353
|
-
{ radius: 0.042, sides: 14, smoothness: 1, color: CHROME, capColor: BLACK }
|
|
354
|
-
)
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
parts.push(
|
|
359
|
-
{
|
|
360
|
-
geometry: wingGeometry(1.74, 0.3, 0.035),
|
|
361
|
-
position: [0, 1.1, 1.98],
|
|
362
|
-
rotation: quat.multiply(quat.x(0.08), quat.y(Math.PI / 2))
|
|
363
|
-
}, // the wing
|
|
364
|
-
{ geometry: block(1.85, 0.035, 0.26, 8, CARBON), position: [0, 0.19, -2.04] }, // front splitter
|
|
365
|
-
{ geometry: block(0.5, 0.09, 0.06, 6, BLACK), position: [0, 0.31, -2.18] }, // centre intake
|
|
366
|
-
{ geometry: block(1.24, 0.03, 0.04, 8, TAIL_LIGHT), position: [0, 0.79, 2.18] }, // light bar between the tail lights
|
|
367
|
-
{ geometry: block(1.1, 0.08, 0.03, 6, BLACK), position: [0, 0.5, 2.18] }, // rear mesh panel
|
|
368
|
-
{ geometry: block(1.62, 0.13, 0.26, 6, CARBON), position: [0, 0.24, 2.06] }, // diffuser
|
|
369
|
-
{ geometry: block(1.84, 0.12, 3.5, 4, BLACK), position: [0, 0.22, 0] } // undertray
|
|
370
|
-
);
|
|
371
|
-
// Diffuser fins and engine-cover louvres
|
|
372
|
-
for (let i = -2; i <= 2; i++) parts.push({ geometry: block(0.02, 0.1, 0.22, 4, BLACK), position: [i * 0.28, 0.25, 2.08] });
|
|
373
|
-
for (let i = 0; i < 6; i++)
|
|
374
|
-
parts.push({
|
|
375
|
-
geometry: block(0.9, 0.012, 0.035, 4, BLACK),
|
|
376
|
-
position: [0, 0.93, 1.48 + i * 0.075]
|
|
377
|
-
});
|
|
378
|
-
const trim = createShape(merge(parts), { center: false, shine: 0.4 });
|
|
379
|
-
car = { body, glass, trim };
|
|
380
|
-
return car;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* The car's outline from above, for collisions: the body's own half widths along its length (the
|
|
385
|
-
* mirrors fold in on contact, so they don't count), a couple of centimetres inside the paint.
|
|
386
|
-
*/
|
|
387
|
-
export const CAR_FOOTPRINT: Footprint = {
|
|
388
|
-
length: 4.36,
|
|
389
|
-
halfWidth: (z) => Math.max(0, halfWidth(z) - 0.03)
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
/** Where the car's lamps are (for the night glow over them): the headlights' centres and the tail-light bar. */
|
|
393
|
-
export const CAR_LAMPS = {
|
|
394
|
-
headlights: [-0.64, 0.64].map((x): Vec3 => [x, 0.555, -2.08]),
|
|
395
|
-
headlightSize: [0.46, 0.06, 0.04] as Vec3,
|
|
396
|
-
tail: [0, 0.79, 2.2] as Vec3,
|
|
397
|
-
tailSize: [1.9, 0.04, 0.03] as Vec3
|
|
398
|
-
};
|
|
399
|
-
|
|
400
|
-
// ── The roadside tree ─────────────────────────────────────────────────
|
|
401
|
-
|
|
402
|
-
const BARK: Color = [0.45, 0.3, 0.18];
|
|
403
|
-
const NEEDLES_DARK: Color = [0.25, 0.6, 0.3];
|
|
404
|
-
const NEEDLES: Color = [0.32, 0.7, 0.35];
|
|
405
|
-
|
|
406
|
-
let tree: Model | null = null;
|
|
407
|
-
/** A low-poly pine about 1.2 tall and 1.5 across, its base at the origin: a trunk under three tiers. */
|
|
408
|
-
export function treeMesh(): Model {
|
|
409
|
-
return cacheGameAsset('car-racing/CarMeshes:treeMesh', () => treeMeshUncached());
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
function treeMeshUncached(): Model {
|
|
413
|
-
if (tree) return tree;
|
|
414
|
-
const trunk = lathe(
|
|
415
|
-
[
|
|
416
|
-
[0.001, 0.4],
|
|
417
|
-
[0.07, 0.4],
|
|
418
|
-
[0.09, 0],
|
|
419
|
-
[0.001, 0]
|
|
420
|
-
],
|
|
421
|
-
{ segments: 8, color: BARK }
|
|
422
|
-
);
|
|
423
|
-
const tier = (bottom: number, top: number, radius: number, color: Color): GeometryPart => ({
|
|
424
|
-
geometry: lathe(
|
|
425
|
-
[
|
|
426
|
-
[0.001, top],
|
|
427
|
-
[radius, bottom],
|
|
428
|
-
[0.001, bottom]
|
|
429
|
-
],
|
|
430
|
-
{ segments: 7, color }
|
|
431
|
-
)
|
|
432
|
-
});
|
|
433
|
-
tree = createShape(
|
|
434
|
-
merge([{ geometry: trunk }, tier(0.22, 0.72, 0.75, NEEDLES_DARK), tier(0.5, 0.98, 0.56, NEEDLES), tier(0.76, 1.2, 0.36, NEEDLES_DARK)]),
|
|
435
|
-
{
|
|
436
|
-
center: false
|
|
437
|
-
}
|
|
438
|
-
);
|
|
439
|
-
return tree;
|
|
440
|
-
}
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
// Car Racing's screen, on the Nayan engine (@nayan-ui/engine): loads the assets, builds a run, and draws
|
|
2
|
-
// Playtura's scoreboard, controls and modals over the 3D view. The rules are in CarRacingGame.ts, what
|
|
3
|
-
// it draws in CarRacingScene.ts, tuning and assets in CarRacingConstants.ts.
|
|
4
|
-
//
|
|
5
|
-
// The engine runs the simulation (physics, particles, audio, haptics) in its Rust core; GameView's
|
|
6
|
-
// `onUpdate` advances the shared engine simulation and HUD once per frame.
|
|
7
|
-
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
8
|
-
import { type DragEvent, haptics } from '@nayan-ui/engine';
|
|
9
|
-
import { resolveGameTheme } from '../../services/ThemeService';
|
|
10
|
-
import { GAME_IDS, type GameProps } from '../../services/UtilsService';
|
|
11
|
-
import { engineGame, EngineGameScreen } from '../shared/EngineGameScreen';
|
|
12
|
-
import { livesColumn, scoreColumn, textColumn } from '../shared/EngineHud';
|
|
13
|
-
import { GameLoading } from '../shared/GameLoading';
|
|
14
|
-
import { GameLoadingTransition } from '../shared/GameLoadingTransition';
|
|
15
|
-
import { useGameResource } from '../shared/useGameResource';
|
|
16
|
-
import {
|
|
17
|
-
type Assets,
|
|
18
|
-
AUTOPLAY,
|
|
19
|
-
DAY_LIGHT,
|
|
20
|
-
EDGE,
|
|
21
|
-
getCachedAssets,
|
|
22
|
-
LIVES,
|
|
23
|
-
loadAssets,
|
|
24
|
-
NIGHT_LIGHT,
|
|
25
|
-
NIGHT_SKY,
|
|
26
|
-
SKY,
|
|
27
|
-
STEER_WIDTH,
|
|
28
|
-
TRACK_LENGTH
|
|
29
|
-
} from './CarRacingConstants';
|
|
30
|
-
import { createGame, dispose, type Phase, setAudible, setNight, start, steer, tick } from './CarRacingGame';
|
|
31
|
-
|
|
32
|
-
export { preloadRacing as preloadCarRacing } from './CarRacingConstants';
|
|
33
|
-
|
|
34
|
-
const RESULTS_DELAY = 1200; // ms: the crash (or the finish) is seen before the modal covers it
|
|
35
|
-
|
|
36
|
-
type RunProps = GameProps & { assets: Assets; night: boolean; onRestart: () => void };
|
|
37
|
-
|
|
38
|
-
/** One run, from the start screen to the results. Restarting mounts a new one. */
|
|
39
|
-
const Run = React.memo(
|
|
40
|
-
({
|
|
41
|
-
assets,
|
|
42
|
-
night,
|
|
43
|
-
onRestart,
|
|
44
|
-
settings,
|
|
45
|
-
onSettingsChange,
|
|
46
|
-
onEndGame,
|
|
47
|
-
onReplayGame,
|
|
48
|
-
onShare,
|
|
49
|
-
onShareScreenshot,
|
|
50
|
-
onShowLeaderboard,
|
|
51
|
-
bannerAd
|
|
52
|
-
}: RunProps) => {
|
|
53
|
-
const initialNight = useRef(night);
|
|
54
|
-
const game = useGameResource(
|
|
55
|
-
() => createGame(assets, initialNight.current),
|
|
56
|
-
(value) => () => {
|
|
57
|
-
if (value.phase === 'playing') reportGameEnd('cancel');
|
|
58
|
-
dispose(value);
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
setNight(game, night);
|
|
63
|
-
}, [game, night]);
|
|
64
|
-
const width = useRef(1);
|
|
65
|
-
const [phase, setPhase] = useState<Phase>('ready');
|
|
66
|
-
const [showResults, setShowResults] = useState(false);
|
|
67
|
-
const [score, setScore] = useState(0);
|
|
68
|
-
const [lives, setLives] = useState(LIVES);
|
|
69
|
-
const [left, setLeft] = useState(TRACK_LENGTH);
|
|
70
|
-
// Report each run once: win on crossing the finish line, lose on the last crash, cancel on stop.
|
|
71
|
-
const gameReportedRef = useRef(false);
|
|
72
|
-
const onEndGameRef = useRef(onEndGame);
|
|
73
|
-
onEndGameRef.current = onEndGame;
|
|
74
|
-
const reportGameEnd = useCallback(
|
|
75
|
-
(status: 'win' | 'lose' | 'cancel') => {
|
|
76
|
-
if (!onEndGameRef.current || gameReportedRef.current) return;
|
|
77
|
-
gameReportedRef.current = true;
|
|
78
|
-
onEndGameRef.current({ status, score: game.score.toString() });
|
|
79
|
-
},
|
|
80
|
-
[game]
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
useEffect(() => {
|
|
84
|
-
haptics.enabled = settings.enableHaptics;
|
|
85
|
-
}, [settings.enableHaptics]);
|
|
86
|
-
|
|
87
|
-
useEffect(() => {
|
|
88
|
-
game.onPhase = setPhase;
|
|
89
|
-
game.onLives = setLives;
|
|
90
|
-
game.onDistance = setLeft;
|
|
91
|
-
game.onScore = setScore;
|
|
92
|
-
}, [game]);
|
|
93
|
-
|
|
94
|
-
// Game over detection, in its own effect.
|
|
95
|
-
useEffect(() => {
|
|
96
|
-
if (phase !== 'over') return;
|
|
97
|
-
reportGameEnd(game.lives > 0 ? 'win' : 'lose');
|
|
98
|
-
const t = setTimeout(() => setShowResults(true), RESULTS_DELAY);
|
|
99
|
-
return () => clearTimeout(t);
|
|
100
|
-
}, [phase, game, reportGameEnd]);
|
|
101
|
-
|
|
102
|
-
// Autoplay (EXPO_PUBLIC_AUTOPLAY=1): start by itself and restart after a pause.
|
|
103
|
-
useEffect(() => {
|
|
104
|
-
if (!AUTOPLAY || phase === 'playing') return;
|
|
105
|
-
const t = setTimeout(phase === 'ready' ? () => start(game) : onRestart, phase === 'ready' ? 1500 : 3000);
|
|
106
|
-
return () => clearTimeout(t);
|
|
107
|
-
}, [phase, game, onRestart]);
|
|
108
|
-
|
|
109
|
-
const onAudioChange = useCallback((audible: boolean) => setAudible(game, audible), [game]);
|
|
110
|
-
const onUpdate = useCallback((dt: number) => tick(game, dt), [game]);
|
|
111
|
-
|
|
112
|
-
// Relative steering: wherever the swipe starts, the car moves by how far the finger moves.
|
|
113
|
-
const onDrag = useCallback(({ phase: touch, dx }: DragEvent) => steer(game, touch, dx, (2 * EDGE) / (STEER_WIDTH * width.current)), [game]);
|
|
114
|
-
|
|
115
|
-
const handleStartGame = useCallback(() => {
|
|
116
|
-
gameReportedRef.current = false;
|
|
117
|
-
start(game);
|
|
118
|
-
}, [game]);
|
|
119
|
-
|
|
120
|
-
// Report before resetting, then a fresh run.
|
|
121
|
-
const handleStopGame = useCallback(() => {
|
|
122
|
-
reportGameEnd('cancel');
|
|
123
|
-
onRestart();
|
|
124
|
-
}, [reportGameEnd, onRestart]);
|
|
125
|
-
|
|
126
|
-
const handleResetGame = useCallback(() => {
|
|
127
|
-
onReplayGame?.();
|
|
128
|
-
onRestart();
|
|
129
|
-
}, [onReplayGame, onRestart]);
|
|
130
|
-
|
|
131
|
-
const won = lives > 0;
|
|
132
|
-
return (
|
|
133
|
-
<EngineGameScreen
|
|
134
|
-
onAudioChange={onAudioChange}
|
|
135
|
-
gameId={GAME_IDS.CAR_RACING}
|
|
136
|
-
settings={settings}
|
|
137
|
-
onSettingsChange={onSettingsChange}
|
|
138
|
-
onShare={onShareScreenshot ?? onShare}
|
|
139
|
-
onShowLeaderboard={onShowLeaderboard}
|
|
140
|
-
bannerAd={bannerAd}
|
|
141
|
-
source={game.world}
|
|
142
|
-
feedback={game.hudFeedback}
|
|
143
|
-
camera={game.camera}
|
|
144
|
-
light={night ? NIGHT_LIGHT : DAY_LIGHT}
|
|
145
|
-
background={night ? NIGHT_SKY : SKY}
|
|
146
|
-
fog={0.0075}
|
|
147
|
-
onUpdate={onUpdate}
|
|
148
|
-
onDrag={onDrag}
|
|
149
|
-
onResize={(value) => {
|
|
150
|
-
width.current = value;
|
|
151
|
-
}}
|
|
152
|
-
columns={[scoreColumn(score), livesColumn(lives, LIVES), textColumn('TRACK', `${left} m`)]}
|
|
153
|
-
playing={phase === 'playing'}
|
|
154
|
-
subtext="Dodge traffic to score!"
|
|
155
|
-
onStart={handleStartGame}
|
|
156
|
-
onStop={handleStopGame}
|
|
157
|
-
gameOver={
|
|
158
|
-
showResults
|
|
159
|
-
? {
|
|
160
|
-
title: won ? 'FINISHED!' : 'CRASHED!',
|
|
161
|
-
message: won
|
|
162
|
-
? `You crossed the finish line! Great driving!`
|
|
163
|
-
: `Out of lives ${TRACK_LENGTH - left} m into the ${TRACK_LENGTH} m race.`,
|
|
164
|
-
scoreLabel: 'Final Score',
|
|
165
|
-
score,
|
|
166
|
-
buttonText: 'Race Again!',
|
|
167
|
-
onPlayAgain: handleResetGame,
|
|
168
|
-
onShare: onShareScreenshot
|
|
169
|
-
}
|
|
170
|
-
: null
|
|
171
|
-
}
|
|
172
|
-
/>
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
Run.displayName = 'CarRacingRun';
|
|
178
|
-
|
|
179
|
-
export const CarRacing = engineGame(GAME_IDS.CAR_RACING, (props) => {
|
|
180
|
-
const settings = props.settings;
|
|
181
|
-
const theme = resolveGameTheme(settings.theme);
|
|
182
|
-
const [run, setRun] = useState(0);
|
|
183
|
-
const [assets, setAssets] = useState<Assets | null>(getCachedAssets);
|
|
184
|
-
const [error, setError] = useState<string | null>(null);
|
|
185
|
-
|
|
186
|
-
useEffect(() => {
|
|
187
|
-
if (assets) return;
|
|
188
|
-
let alive = true;
|
|
189
|
-
// Sounds don't hold up the scene: plays before they're decoded are skipped.
|
|
190
|
-
loadAssets()
|
|
191
|
-
.then((a) => alive && setAssets(a))
|
|
192
|
-
.catch((e: Error) => alive && setError(e.message));
|
|
193
|
-
return () => {
|
|
194
|
-
alive = false;
|
|
195
|
-
};
|
|
196
|
-
}, [assets]);
|
|
197
|
-
|
|
198
|
-
const restart = useCallback(() => setRun((r) => r + 1), []);
|
|
199
|
-
|
|
200
|
-
// Host theme changes repaint the existing race without resetting score or positions.
|
|
201
|
-
const night = theme.isDark;
|
|
202
|
-
return (
|
|
203
|
-
<GameLoadingTransition
|
|
204
|
-
ready={!!assets}
|
|
205
|
-
loader={
|
|
206
|
-
<GameLoading gameId={GAME_IDS.CAR_RACING} theme={settings.theme} offset={settings.offset} error={!!error} message={error ?? undefined} />
|
|
207
|
-
}>
|
|
208
|
-
{assets && <Run key={run} {...props} settings={settings} assets={assets} night={night} onRestart={restart} />}
|
|
209
|
-
</GameLoadingTransition>
|
|
210
|
-
);
|
|
211
|
-
});
|