@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,300 +0,0 @@
|
|
|
1
|
-
import { type Entity, type Geometry, type Model, type World } from '@nayan-ui/engine';
|
|
2
|
-
import { type GamePattern, gamePattern, PATTERN_GRID_COLOR, type PatternGradient, type PatternShape } from '../../helpers/GamePatternData';
|
|
3
|
-
import type { GameTheme } from '../../services/ThemeService';
|
|
4
|
-
// The Playtura game background (theme color plus the rainbow pattern), built by the Nayan engine with
|
|
5
|
-
// no original. The pattern (helpers/GamePatternData) is turned into one opaque mesh whose vertex colors are
|
|
6
|
-
// what the original pattern composites to at each point: the gradients on a fine grid, the shapes and grid
|
|
7
|
-
// lines layered on top with the layers under them baked in. One draw call, nothing to blend each frame.
|
|
8
|
-
// Shared by the engine games' scenes and the modal cards (BackdropCard).
|
|
9
|
-
import { getScreenDimensions } from '../../services/UtilsService';
|
|
10
|
-
import { cacheGameAsset, createGameMesh as createShape } from './EngineMeshes';
|
|
11
|
-
import { frontLight, toColor } from './EngineUtils';
|
|
12
|
-
|
|
13
|
-
type RGBA = [number, number, number, number];
|
|
14
|
-
|
|
15
|
-
/** Any front light works: these flat meshes face the camera, which it lights at exactly 1. */
|
|
16
|
-
export const BACKDROP_LIGHT = frontLight([0, 0, 1], 1);
|
|
17
|
-
|
|
18
|
-
const GRID_STEP = 16; // points between gradient samples (stops are ~100pt apart)
|
|
19
|
-
const SEGMENTS = 40; // around a circle
|
|
20
|
-
const CORNER_SEGMENTS = 6;
|
|
21
|
-
const LAYER_GAP = 0.05; // depth between layers, toward the camera
|
|
22
|
-
|
|
23
|
-
// ── Compositing (original's: stops interpolated unpremultiplied, layers source-over, group opacity) ──
|
|
24
|
-
|
|
25
|
-
function gradientAt(g: PatternGradient, stops: RGBA[], x: number, y: number): RGBA {
|
|
26
|
-
const dx = g.end[0] - g.start[0];
|
|
27
|
-
const dy = g.end[1] - g.start[1];
|
|
28
|
-
const t = Math.max(0, Math.min(1, ((x - g.start[0]) * dx + (y - g.start[1]) * dy) / (dx * dx + dy * dy)));
|
|
29
|
-
const p = t * (stops.length - 1);
|
|
30
|
-
const i = Math.min(stops.length - 2, Math.floor(p));
|
|
31
|
-
const f = p - i;
|
|
32
|
-
const a = stops[i]!;
|
|
33
|
-
const b = stops[i + 1]!;
|
|
34
|
-
return [a[0] + (b[0] - a[0]) * f, a[1] + (b[1] - a[1]) * f, a[2] + (b[2] - a[2]) * f, a[3] + (b[3] - a[3]) * f];
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function contains(s: PatternShape, x: number, y: number) {
|
|
38
|
-
switch (s.kind) {
|
|
39
|
-
case 'circle':
|
|
40
|
-
return (x - s.cx) ** 2 + (y - s.cy) ** 2 <= s.r * s.r;
|
|
41
|
-
case 'rrect':
|
|
42
|
-
return x >= s.x && x <= s.x + s.w && y >= s.y && y <= s.y + s.h;
|
|
43
|
-
default:
|
|
44
|
-
return Math.abs(x - s.cx) + Math.abs(y - s.cy) <= s.size / 2;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** Composites a pattern point: the gradients, then the shapes up to `layers` (index), then `top` if given. */
|
|
49
|
-
class Compositor {
|
|
50
|
-
private readonly stops: RGBA[][];
|
|
51
|
-
private readonly colors: RGBA[];
|
|
52
|
-
private readonly gridColor = toColor(PATTERN_GRID_COLOR) as RGBA;
|
|
53
|
-
private readonly bg: RGBA;
|
|
54
|
-
|
|
55
|
-
constructor(
|
|
56
|
-
private readonly pattern: GamePattern,
|
|
57
|
-
background: string,
|
|
58
|
-
private readonly opacity: number
|
|
59
|
-
) {
|
|
60
|
-
this.stops = pattern.gradients.map((g) => g.colors.map((c) => toColor(c) as RGBA));
|
|
61
|
-
this.colors = pattern.shapes.map((s) => toColor(s.color) as RGBA);
|
|
62
|
-
this.bg = toColor(background) as RGBA;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Final RGB at (x, y) with shapes [0, shapes) under it, plus shape `self` (or the grid) on top. */
|
|
66
|
-
at(x: number, y: number, shapes: number, self: number | 'grid' | null): [number, number, number] {
|
|
67
|
-
// Premultiplied accumulation of the pattern group
|
|
68
|
-
let r = 0;
|
|
69
|
-
let g = 0;
|
|
70
|
-
let b = 0;
|
|
71
|
-
let a = 0;
|
|
72
|
-
const over = (c: RGBA) => {
|
|
73
|
-
const k = 1 - c[3];
|
|
74
|
-
r = c[0] * c[3] + r * k;
|
|
75
|
-
g = c[1] * c[3] + g * k;
|
|
76
|
-
b = c[2] * c[3] + b * k;
|
|
77
|
-
a = c[3] + a * k;
|
|
78
|
-
};
|
|
79
|
-
this.pattern.gradients.forEach((grad, i) => over(gradientAt(grad, this.stops[i]!, x, y)));
|
|
80
|
-
for (let i = 0; i < shapes; i++) if (contains(this.pattern.shapes[i]!, x, y)) over(this.colors[i]!);
|
|
81
|
-
if (typeof self === 'number') over(this.colors[self]!);
|
|
82
|
-
else if (self === 'grid') over(this.gridColor);
|
|
83
|
-
// The group at the theme's pattern opacity over the background color
|
|
84
|
-
const o = this.opacity;
|
|
85
|
-
return [r * o + this.bg[0] * (1 - a * o), g * o + this.bg[1] * (1 - a * o), b * o + this.bg[2] * (1 - a * o)];
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// ── Mesh ──────────────────────────────────────────────────────────────
|
|
90
|
-
|
|
91
|
-
class MeshBuilder {
|
|
92
|
-
vertices: number[] = [];
|
|
93
|
-
indices: number[] = [];
|
|
94
|
-
/** A vertex at pattern point (x, y) (y down), depth z. */
|
|
95
|
-
vertex(x: number, y: number, z: number, [r, g, b]: [number, number, number]) {
|
|
96
|
-
this.vertices.push(x, -y, z, 0, 0, 1, r, g, b, 0, 0);
|
|
97
|
-
return this.vertices.length / 11 - 1;
|
|
98
|
-
}
|
|
99
|
-
/** A quad from its corners, counter-clockwise seen from the camera (y up). */
|
|
100
|
-
quad(a: number, b: number, c: number, d: number) {
|
|
101
|
-
this.indices.push(a, b, c, a, c, d);
|
|
102
|
-
}
|
|
103
|
-
geometry(): Geometry {
|
|
104
|
-
return { vertices: new Float32Array(this.vertices), indices: new Uint32Array(this.indices) };
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** A shape's outline in pattern points (y down), counter-clockwise with y up (as the camera sees it). */
|
|
109
|
-
function outline(s: PatternShape): [number, number][] {
|
|
110
|
-
if (s.kind === 'circle') {
|
|
111
|
-
return Array.from({ length: SEGMENTS }, (_, k) => {
|
|
112
|
-
const t = (-k / SEGMENTS) * Math.PI * 2;
|
|
113
|
-
return [s.cx + Math.cos(t) * s.r, s.cy + Math.sin(t) * s.r] as [number, number];
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
if (s.kind === 'diamond') {
|
|
117
|
-
const h = s.size / 2;
|
|
118
|
-
return [
|
|
119
|
-
[s.cx + h, s.cy],
|
|
120
|
-
[s.cx, s.cy - h],
|
|
121
|
-
[s.cx - h, s.cy],
|
|
122
|
-
[s.cx, s.cy + h]
|
|
123
|
-
];
|
|
124
|
-
}
|
|
125
|
-
const r = Math.min(s.r, s.w / 2, s.h / 2);
|
|
126
|
-
// Corner centres (y down) with each arc's start angle, counter-clockwise with y up: bottom-right,
|
|
127
|
-
// top-right, top-left, bottom-left. Each arc turns a quarter; y down flips the sine.
|
|
128
|
-
const corners: [number, number, number][] = [
|
|
129
|
-
[s.x + s.w - r, s.y + s.h - r, -Math.PI / 2],
|
|
130
|
-
[s.x + s.w - r, s.y + r, 0],
|
|
131
|
-
[s.x + r, s.y + r, Math.PI / 2],
|
|
132
|
-
[s.x + r, s.y + s.h - r, Math.PI]
|
|
133
|
-
];
|
|
134
|
-
const points: [number, number][] = [];
|
|
135
|
-
for (const [cx, cy, from] of corners) {
|
|
136
|
-
for (let k = 0; k <= CORNER_SEGMENTS; k++) {
|
|
137
|
-
const t = from + (k / CORNER_SEGMENTS) * (Math.PI / 2);
|
|
138
|
-
points.push([cx + Math.cos(t) * r, cy - Math.sin(t) * r]);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return points;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
function centreOf(s: PatternShape): [number, number] {
|
|
145
|
-
return s.kind === 'rrect' ? [s.x + s.w / 2, s.y + s.h / 2] : [s.cx, s.cy];
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function buildGeometry(pattern: GamePattern, background: string, opacity: number, withGrid = true): Geometry {
|
|
149
|
-
const m = new MeshBuilder();
|
|
150
|
-
const c = new Compositor(pattern, background, opacity);
|
|
151
|
-
const { width, height, shapes } = pattern;
|
|
152
|
-
const grid = withGrid ? pattern.grid : [];
|
|
153
|
-
|
|
154
|
-
// The gradients on a grid
|
|
155
|
-
const nx = Math.ceil(width / GRID_STEP);
|
|
156
|
-
const ny = Math.ceil(height / GRID_STEP);
|
|
157
|
-
const first = m.vertices.length / 11;
|
|
158
|
-
for (let j = 0; j <= ny; j++) {
|
|
159
|
-
const y = Math.min(height, j * GRID_STEP);
|
|
160
|
-
for (let i = 0; i <= nx; i++) {
|
|
161
|
-
const x = Math.min(width, i * GRID_STEP);
|
|
162
|
-
m.vertex(x, y, 0, c.at(x, y, 0, null));
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
const at = (i: number, j: number) => first + j * (nx + 1) + i;
|
|
166
|
-
for (let j = 0; j < ny; j++) for (let i = 0; i < nx; i++) m.quad(at(i, j + 1), at(i + 1, j + 1), at(i + 1, j), at(i, j));
|
|
167
|
-
|
|
168
|
-
// Each shape as a fan, above the ones before it
|
|
169
|
-
shapes.forEach((s, k) => {
|
|
170
|
-
const z = (k + 1) * LAYER_GAP;
|
|
171
|
-
const [cx, cy] = centreOf(s);
|
|
172
|
-
const centre = m.vertex(cx, cy, z, c.at(cx, cy, k, k));
|
|
173
|
-
const ring = outline(s).map(([x, y]) => m.vertex(x, y, z, c.at(x, y, k, k)));
|
|
174
|
-
ring.forEach((v, i) => m.indices.push(centre, v, ring[(i + 1) % ring.length]!));
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// The grid lines, split along their length so the colors under them follow
|
|
178
|
-
const z = (shapes.length + 1) * LAYER_GAP;
|
|
179
|
-
for (const line of grid) {
|
|
180
|
-
const long = Math.max(line.w, line.h);
|
|
181
|
-
const steps = Math.max(1, Math.ceil(long / GRID_STEP));
|
|
182
|
-
const vertical = line.h > line.w;
|
|
183
|
-
let prev: [number, number] | null = null;
|
|
184
|
-
for (let s = 0; s <= steps; s++) {
|
|
185
|
-
const t = Math.min(long, s * GRID_STEP);
|
|
186
|
-
// The two edge points across the line at distance t along it
|
|
187
|
-
const p: [number, number, number, number] = vertical
|
|
188
|
-
? [line.x, line.y + t, line.x + line.w, line.y + t]
|
|
189
|
-
: [line.x + t, line.y, line.x + t, line.y + line.h];
|
|
190
|
-
const a = m.vertex(p[0], p[1], z, c.at(p[0], p[1], shapes.length, 'grid'));
|
|
191
|
-
const b = m.vertex(p[2], p[3], z, c.at(p[2], p[3], shapes.length, 'grid'));
|
|
192
|
-
if (prev) {
|
|
193
|
-
// Vertical: prev is above (smaller y). Horizontal: prev is to the left.
|
|
194
|
-
if (vertical) m.quad(a, b, prev[1], prev[0]);
|
|
195
|
-
else m.quad(prev[1], b, a, prev[0]);
|
|
196
|
-
}
|
|
197
|
-
prev = [a, b];
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
return m.geometry();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// One mesh per theme and window size: mesh ids are app-wide and limited, and they last for the app.
|
|
204
|
-
const meshes = new Map<string, Model>();
|
|
205
|
-
|
|
206
|
-
/** The background mesh in pattern space: x right, y up from the window's top-left (y runs to -height). */
|
|
207
|
-
export function backdropMesh(theme: GameTheme): Model {
|
|
208
|
-
const { width, height } = getScreenDimensions();
|
|
209
|
-
const key = `${theme.BACKGROUND}:${theme.PATTERN_OPACITY}:${Math.round(width)}x${Math.round(height)}`;
|
|
210
|
-
let mesh = meshes.get(key);
|
|
211
|
-
if (!mesh) {
|
|
212
|
-
mesh = cacheGameAsset(`backdrop:${key}`, () =>
|
|
213
|
-
createShape(buildGeometry(gamePattern(width, height), theme.BACKGROUND, theme.PATTERN_OPACITY), { center: false })
|
|
214
|
-
);
|
|
215
|
-
meshes.set(key, mesh);
|
|
216
|
-
}
|
|
217
|
-
return mesh;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
const FLOATS = 11;
|
|
221
|
-
|
|
222
|
-
/** Keeps the parts of `geometry` inside a convex polygon (x, y as stored, counter-clockwise), interpolating every vertex attribute. */
|
|
223
|
-
function clipGeometry({ vertices, indices }: Geometry, poly: [number, number][]): Geometry {
|
|
224
|
-
type V = number[];
|
|
225
|
-
const out: number[] = [];
|
|
226
|
-
const outIdx: number[] = [];
|
|
227
|
-
const read = (i: number): V => Array.from(vertices.subarray(i * FLOATS, i * FLOATS + FLOATS));
|
|
228
|
-
for (let t = 0; t < indices.length; t += 3) {
|
|
229
|
-
let shape: V[] = [read(indices[t]!), read(indices[t + 1]!), read(indices[t + 2]!)];
|
|
230
|
-
for (let e = 0; e < poly.length && shape.length > 0; e++) {
|
|
231
|
-
const [ax, ay] = poly[e]!;
|
|
232
|
-
const [bx, by] = poly[(e + 1) % poly.length]!;
|
|
233
|
-
const side = (v: V) => (bx - ax) * (v[1]! - ay) - (by - ay) * (v[0]! - ax);
|
|
234
|
-
const next: V[] = [];
|
|
235
|
-
for (let i = 0; i < shape.length; i++) {
|
|
236
|
-
const p = shape[i]!;
|
|
237
|
-
const q = shape[(i + 1) % shape.length]!;
|
|
238
|
-
const sp = side(p);
|
|
239
|
-
const sq = side(q);
|
|
240
|
-
if (sp >= 0) next.push(p);
|
|
241
|
-
if (sp >= 0 !== sq >= 0) {
|
|
242
|
-
const f = sp / (sp - sq);
|
|
243
|
-
next.push(p.map((x, k) => x + (q[k]! - x) * f));
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
shape = next;
|
|
247
|
-
}
|
|
248
|
-
if (shape.length < 3) continue;
|
|
249
|
-
const base = out.length / FLOATS;
|
|
250
|
-
for (const v of shape) out.push(...v);
|
|
251
|
-
for (let i = 1; i + 1 < shape.length; i++) outIdx.push(base, base + i, base + i + 1);
|
|
252
|
-
}
|
|
253
|
-
return { vertices: new Float32Array(out), indices: new Uint32Array(outIdx) };
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* A modal card's background: the window pattern's top-left `width` x `height` (its gradients and
|
|
258
|
-
* shapes, without the grid lines), cut to a rounded rectangle of corner `radius`. Same space as
|
|
259
|
-
* `backdropMesh` (from the top-left, y up).
|
|
260
|
-
*/
|
|
261
|
-
export function cardBackdropMesh(theme: GameTheme, width: number, height: number, radius: number): Model {
|
|
262
|
-
const win = getScreenDimensions();
|
|
263
|
-
const [w, h] = [Math.round(width), Math.round(height)];
|
|
264
|
-
const key = `card-nogrid:${theme.BACKGROUND}:${theme.PATTERN_OPACITY}:${Math.round(win.width)}x${Math.round(win.height)}:${w}x${h}:${radius}`;
|
|
265
|
-
let mesh = meshes.get(key);
|
|
266
|
-
if (!mesh) {
|
|
267
|
-
const r = Math.min(radius, w / 2, h / 2);
|
|
268
|
-
// The rounded rectangle, counter-clockwise with y up (stored y = -pattern y)
|
|
269
|
-
const poly: [number, number][] = [];
|
|
270
|
-
const corners: [number, number, number][] = [
|
|
271
|
-
[w - r, -h + r, -Math.PI / 2],
|
|
272
|
-
[w - r, -r, 0],
|
|
273
|
-
[r, -r, Math.PI / 2],
|
|
274
|
-
[r, -h + r, Math.PI]
|
|
275
|
-
];
|
|
276
|
-
for (const [cx, cy, from] of corners) {
|
|
277
|
-
for (let k = 0; k <= CORNER_SEGMENTS; k++) {
|
|
278
|
-
const t = from + (k / CORNER_SEGMENTS) * (Math.PI / 2);
|
|
279
|
-
poly.push([cx + Math.cos(t) * r, cy + Math.sin(t) * r]);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
const full = buildGeometry(gamePattern(win.width, win.height), theme.BACKGROUND, theme.PATTERN_OPACITY, false);
|
|
283
|
-
mesh = createShape(clipGeometry(full, poly), { center: false });
|
|
284
|
-
meshes.set(key, mesh);
|
|
285
|
-
}
|
|
286
|
-
return mesh;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* The background behind a centred, one-unit-per-point scene `width` x `height` (the view's size), at
|
|
291
|
-
* depth `z`: the pattern starts at the view's top-left, as the original screens draw it.
|
|
292
|
-
*/
|
|
293
|
-
export function spawnBackdrop(world: World, width: number, height: number, z: number, theme: GameTheme): Entity {
|
|
294
|
-
return world.spawn({ mesh: backdropMesh(theme), position: [-width / 2, height / 2, z], color: [1, 1, 1, 1], pickable: false });
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/** Repaints a backdrop for a new theme. */
|
|
298
|
-
export function setBackdropTheme(world: World, backdrop: Entity, theme: GameTheme) {
|
|
299
|
-
world.set(backdrop, { mesh: backdropMesh(theme) });
|
|
300
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
// Game blasts that need meshes from the games' asset cache: the cleared-piece pop's glow disc and
|
|
2
|
-
// the baton catch. The particle effects themselves (confetti, sparkle, shatter, splash, sparks,
|
|
3
|
-
// explosion, dust, flash) and the swell-and-shrink pop live in the engine as `effects`.
|
|
4
|
-
import { type Color, effects, type Entity, extrude, type Model, Path, type PopOptions, type Quat, type Vec3, type World } from '@nayan-ui/engine';
|
|
5
|
-
import { cacheGameAsset, createGameMesh as createShape } from './EngineMeshes';
|
|
6
|
-
|
|
7
|
-
export type PopBurstOptions = {
|
|
8
|
-
/** Where the beads fly out from (a little in front of the piece reads best). */
|
|
9
|
-
position: Vec3;
|
|
10
|
-
/** The piece's size across, which the burst scales with. */
|
|
11
|
-
size: number;
|
|
12
|
-
/** The piece's color. */
|
|
13
|
-
color: Color;
|
|
14
|
-
/** Depth of the glow (behind the piece, in front of the board). Default the burst's own depth. */
|
|
15
|
-
glowZ?: number;
|
|
16
|
-
/** Beads and glints, about. Default 8. */
|
|
17
|
-
count?: number;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
const WHITE: Color = [1, 1, 1, 1];
|
|
21
|
-
const fade = (c: Color): [number, number, number, number] => [c[0], c[1], c[2], 0];
|
|
22
|
-
|
|
23
|
-
let disc: Model | null = null;
|
|
24
|
-
/** A flat disc one unit across, facing +z. */
|
|
25
|
-
const discMesh = () =>
|
|
26
|
-
cacheGameAsset('shared/EngineBlasts:discMesh', () => (disc ??= createShape(extrude(new Path().addCircle(0, 0, 0.5), { depth: 0 }))));
|
|
27
|
-
|
|
28
|
-
/** Bright beads and glints in the piece's color and white, over a glow that swells and fades behind it. */
|
|
29
|
-
export function popBurst(world: World, o: PopBurstOptions) {
|
|
30
|
-
const [r, g, b] = o.color;
|
|
31
|
-
effects.sparkle(world, {
|
|
32
|
-
position: o.position,
|
|
33
|
-
count: o.count ?? 8,
|
|
34
|
-
size: o.size * 0.2,
|
|
35
|
-
speed: o.size * 6,
|
|
36
|
-
lifetime: 0.45,
|
|
37
|
-
colors: [o.color, WHITE],
|
|
38
|
-
flash: false
|
|
39
|
-
});
|
|
40
|
-
const glow = world.spawn({
|
|
41
|
-
mesh: discMesh(),
|
|
42
|
-
position: [o.position[0], o.position[1], o.glowZ ?? o.position[2]],
|
|
43
|
-
scale: o.size * 0.85,
|
|
44
|
-
color: [r, g, b, 0.6],
|
|
45
|
-
pickable: false
|
|
46
|
-
});
|
|
47
|
-
world.animate(glow, { scale: o.size * 2.8, color: [r, g, b, 0] }, { duration: 0.28 }).then(() => {
|
|
48
|
-
if (world.has(glow)) world.despawn(glow);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** Both: the piece pops away and bursts as it swells. Resolves when it's gone (despawning it is the caller's). */
|
|
53
|
-
export function popAndBurst(world: World, entity: Entity, pop: PopOptions, burst: PopBurstOptions): Promise<void> {
|
|
54
|
-
const delay = pop.delay ?? 0;
|
|
55
|
-
const duration = pop.duration ?? effects.POP_TIME;
|
|
56
|
-
if (delay > 0) world.after(delay + duration * 0.12, () => popBurst(world, burst));
|
|
57
|
-
else popBurst(world, burst);
|
|
58
|
-
return effects.pop(world, entity, pop);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
let stickChip: Model | null = null;
|
|
62
|
-
let catchRing: Model | null = null;
|
|
63
|
-
const stickChipMesh = () =>
|
|
64
|
-
cacheGameAsset(
|
|
65
|
-
'shared/EngineBlasts:stickChipMesh',
|
|
66
|
-
() => (stickChip ??= createShape(extrude(new Path().addRoundedRect(-0.5, -0.09, 1, 0.18, 0.07), { depth: 0.16 }), { shine: 0.25 }))
|
|
67
|
-
);
|
|
68
|
-
const catchRingMesh = () =>
|
|
69
|
-
cacheGameAsset(
|
|
70
|
-
'shared/EngineBlasts:catchRingMesh',
|
|
71
|
-
() => (catchRing ??= createShape(extrude(new Path().addCircle(0, 0, 0.5).addCircle(0, 0, 0.465), { depth: 0, fillRule: 'evenodd' })))
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
/** A baton catch: a full-body pop, expanding ring, colorful splinters and two tip sprays. */
|
|
75
|
-
export function stickBlast(world: World, entity: Entity, o: { position: Vec3; rotation: Quat; scale: Vec3; color: Color }): Promise<void> {
|
|
76
|
-
const [length, width] = o.scale;
|
|
77
|
-
const [x, y, z, w] = o.rotation;
|
|
78
|
-
const axis: Vec3 = [1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y)];
|
|
79
|
-
const normal: Vec3 = [2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y)];
|
|
80
|
-
const at = (along: number, lift = 0): Vec3 => [
|
|
81
|
-
o.position[0] + axis[0] * length * along + normal[0] * lift,
|
|
82
|
-
o.position[1] + axis[1] * length * along + normal[1] * lift,
|
|
83
|
-
o.position[2] + axis[2] * length * along + normal[2] * lift
|
|
84
|
-
];
|
|
85
|
-
const done = popAndBurst(
|
|
86
|
-
world,
|
|
87
|
-
entity,
|
|
88
|
-
{ scale: o.scale, color: o.color, duration: 0.32 },
|
|
89
|
-
{
|
|
90
|
-
position: at(0, width * 0.6),
|
|
91
|
-
size: Math.max(width * 1.6, length * 0.24),
|
|
92
|
-
color: o.color,
|
|
93
|
-
count: 14
|
|
94
|
-
}
|
|
95
|
-
);
|
|
96
|
-
stickChip = stickChipMesh();
|
|
97
|
-
effects.shatter(world, {
|
|
98
|
-
position: at(0, width * 0.4),
|
|
99
|
-
mesh: stickChip,
|
|
100
|
-
count: 7,
|
|
101
|
-
size: length * 0.16,
|
|
102
|
-
speed: length * 2,
|
|
103
|
-
lifetime: 0.5,
|
|
104
|
-
gravity: -length * 4,
|
|
105
|
-
colors: [o.color, effects.pale(o.color, 0.4, 1)],
|
|
106
|
-
flash: false,
|
|
107
|
-
dust: false
|
|
108
|
-
});
|
|
109
|
-
for (const side of [-1, 1])
|
|
110
|
-
effects.sparks(world, {
|
|
111
|
-
position: at(side * 0.32, width * 0.5),
|
|
112
|
-
count: 4,
|
|
113
|
-
size: width * 0.18,
|
|
114
|
-
speed: length * 2.5,
|
|
115
|
-
lifetime: 0.35,
|
|
116
|
-
gravity: -length * 1.5,
|
|
117
|
-
direction: [axis[0] * side, axis[1] * side, axis[2] * side],
|
|
118
|
-
spread: 0.9,
|
|
119
|
-
colors: [o.color, WHITE],
|
|
120
|
-
flash: false
|
|
121
|
-
});
|
|
122
|
-
catchRing = catchRingMesh();
|
|
123
|
-
const color = effects.pale(o.color, 0.45, 0.9);
|
|
124
|
-
const ring = world.spawn({ mesh: catchRing, position: at(0, width * 0.8), rotation: o.rotation, scale: width * 1.8, color, pickable: false });
|
|
125
|
-
world.animate(ring, { scale: length * 1.1, color: fade(color) }, { duration: 0.32, easing: 'easeOut' }).then(() => {
|
|
126
|
-
if (world.has(ring)) world.despawn(ring);
|
|
127
|
-
});
|
|
128
|
-
return done;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/** Reusable assets; the game loader advances one builder per frame. */
|
|
132
|
-
export function* warmAssets(): Iterable<() => unknown> {
|
|
133
|
-
yield discMesh;
|
|
134
|
-
yield stickChipMesh;
|
|
135
|
-
yield catchRingMesh;
|
|
136
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
// The raised block every board game's pieces are made of (Block Blast's blocks, Candy Crush's candies,
|
|
2
|
-
// Block Breaker's bricks, the number tiles): glossy and bevelled, face toward the camera (+z), with a
|
|
3
|
-
// soft shadow on the board down and to the right of it (away from the games' top-left light). The
|
|
4
|
-
// shadow is the block's child, so it moves, scales and pops with it; color changes leave it alone.
|
|
5
|
-
import { type Color, type Entity, extrude, loft, type Model, Path, type Vec3, type World } from '@nayan-ui/engine';
|
|
6
|
-
import { cacheGameAsset, createGameMesh as createShape } from './EngineMeshes';
|
|
7
|
-
|
|
8
|
-
// One mesh per width : height ratio (rounded), one unit high: mesh ids are app-wide and limited.
|
|
9
|
-
const ASPECT_STEP = 0.25;
|
|
10
|
-
const blocks = new Map<string, Model>();
|
|
11
|
-
/**
|
|
12
|
-
* A block `aspect` units wide, one high and one deep: straight sides, then a chamfer up to a slightly
|
|
13
|
-
* smaller face, so its edges catch the light. The chamfer is the same width on every side.
|
|
14
|
-
*/
|
|
15
|
-
function blockMesh(aspect: number, gloss: boolean): Model {
|
|
16
|
-
return cacheGameAsset('shared/EngineBlocks:blockMesh' + JSON.stringify([aspect, gloss]), () => blockMeshUncached(aspect, gloss));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function blockMeshUncached(aspect: number, gloss: boolean): Model {
|
|
20
|
-
const key = `${aspect}:${gloss}`;
|
|
21
|
-
let mesh = blocks.get(key);
|
|
22
|
-
if (!mesh) {
|
|
23
|
-
const w = aspect / 2;
|
|
24
|
-
mesh = createShape(
|
|
25
|
-
loft(
|
|
26
|
-
[
|
|
27
|
-
{ z: -0.5, bottom: -0.5, top: 0.5, width: w, square: 7 },
|
|
28
|
-
{ z: 0.2, bottom: -0.5, top: 0.5, width: w, square: 7 },
|
|
29
|
-
{ z: 0.4, bottom: -0.465, top: 0.465, width: w - 0.035, square: 6.5 },
|
|
30
|
-
{ z: 0.5, bottom: -0.39, top: 0.39, width: w - 0.11, square: 5.5 }
|
|
31
|
-
],
|
|
32
|
-
{ around: 40, smoothness: 2 }
|
|
33
|
-
),
|
|
34
|
-
{ center: false, shine: gloss ? 0.6 : 0 }
|
|
35
|
-
);
|
|
36
|
-
blocks.set(key, mesh);
|
|
37
|
-
}
|
|
38
|
-
return mesh;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
let shadow: Model | null = null;
|
|
42
|
-
/** A soft square one unit across, facing the camera: a block's shadow on the board. */
|
|
43
|
-
const shadowMesh = () => (shadow ??= createShape(extrude(new Path().addRoundedRect(-0.5, -0.5, 1, 1, 0.16), { depth: 0 })));
|
|
44
|
-
/** Down and to the right of its block, just behind it, in the block's own units. */
|
|
45
|
-
const SHADOW_AT: Vec3 = [0.08, -0.11, -0.52];
|
|
46
|
-
const SHADOW_SIZE = 1.04;
|
|
47
|
-
const SHADOW: Color = [0, 0, 0, 0.3];
|
|
48
|
-
|
|
49
|
-
const aspectOf = (size: Vec3) => Math.max(ASPECT_STEP, Math.round(size[0] / size[1] / ASPECT_STEP) * ASPECT_STEP);
|
|
50
|
-
|
|
51
|
-
/** The scale that makes a block `size` (width, height, depth): for animating one back to full size (pops, grow-ins). */
|
|
52
|
-
export const raisedBlockScale = (size: Vec3): Vec3 => [size[0] / aspectOf(size), size[1], size[2]];
|
|
53
|
-
|
|
54
|
-
export type BlockOptions = {
|
|
55
|
-
/** The block's centre. */
|
|
56
|
-
position: Vec3;
|
|
57
|
-
/** Width, height and depth. */
|
|
58
|
-
size: Vec3;
|
|
59
|
-
color: Color;
|
|
60
|
-
parent?: Entity;
|
|
61
|
-
/** The block's scale as a fraction of `size` (0 to grow it in). Default 1. */
|
|
62
|
-
grow?: number;
|
|
63
|
-
/** A glossy finish (else matte). Default true. */
|
|
64
|
-
gloss?: boolean;
|
|
65
|
-
/** Its soft shadow on the board. Default true. */
|
|
66
|
-
shadow?: boolean;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
/** A block and its shadow; the block is returned (scale, move, tint and despawn it as one). */
|
|
70
|
-
export function spawnRaisedBlock(world: World, { position, size, color, parent, grow = 1, gloss = true, shadow = true }: BlockOptions): Entity {
|
|
71
|
-
const aspect = aspectOf(size);
|
|
72
|
-
const full = raisedBlockScale(size);
|
|
73
|
-
const block = world.spawn({
|
|
74
|
-
mesh: blockMesh(aspect, gloss),
|
|
75
|
-
parent,
|
|
76
|
-
position,
|
|
77
|
-
scale: [full[0] * grow, full[1] * grow, full[2] * grow],
|
|
78
|
-
color,
|
|
79
|
-
pickable: false
|
|
80
|
-
});
|
|
81
|
-
if (shadow)
|
|
82
|
-
world.spawn({
|
|
83
|
-
mesh: shadowMesh(),
|
|
84
|
-
parent: block,
|
|
85
|
-
position: SHADOW_AT,
|
|
86
|
-
scale: [aspect * SHADOW_SIZE, SHADOW_SIZE, 1],
|
|
87
|
-
color: SHADOW,
|
|
88
|
-
pickable: false
|
|
89
|
-
});
|
|
90
|
-
return block;
|
|
91
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/** Fit a short control subtitle into its measured inner width without splitting Unicode code points. */
|
|
2
|
-
export function fitControlSubtitle(text: string, maxWidth: number, measure: (value: string) => number): string {
|
|
3
|
-
const words = text.trim().split(/\s+/).filter(Boolean);
|
|
4
|
-
const label = words.slice(0, 4).join(' ') + (words.length > 4 ? '…' : '');
|
|
5
|
-
if (!label || maxWidth <= 0) return '';
|
|
6
|
-
if (measure(label) <= maxWidth) return label;
|
|
7
|
-
if (measure('…') > maxWidth) return '';
|
|
8
|
-
const chars = Array.from(label.replace(/…$/, ''));
|
|
9
|
-
let lo = 0;
|
|
10
|
-
let hi = chars.length;
|
|
11
|
-
while (lo < hi) {
|
|
12
|
-
const mid = Math.ceil((lo + hi) / 2);
|
|
13
|
-
if (measure(chars.slice(0, mid).join('').trimEnd() + '…') <= maxWidth) lo = mid;
|
|
14
|
-
else hi = mid - 1;
|
|
15
|
-
}
|
|
16
|
-
return chars.slice(0, lo).join('').trimEnd() + '…';
|
|
17
|
-
}
|