@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,79 +0,0 @@
|
|
|
1
|
-
// Block Breaker's screen, on the Nayan engine: the board, bricks, paddle, balls and power-ups are one
|
|
2
|
-
// 3D scene (an orthographic camera over glossy blocks), under Playtura's scoreboard, controls and
|
|
3
|
-
// modals. The rules and physics are in BlockBreakerGame.ts, what it draws in BlockBreakerScene.ts.
|
|
4
|
-
//
|
|
5
|
-
// One world serves the whole visit: Start, Stop and Play Again build a new wall in place and a theme
|
|
6
|
-
// change repaints it, so the GPU view is never rebuilt. The wall's build-in, breaks, paddle squash and
|
|
7
|
-
// power-up glow animate in the engine's Rust core; JS steps the balls and steps the world once a frame.
|
|
8
|
-
import { HapticType } from '../../services/HapticsService';
|
|
9
|
-
import { GAME_SOUNDS } from '../../services/SoundsService';
|
|
10
|
-
import { GAME_IDS } from '../../services/UtilsService';
|
|
11
|
-
import { engineGame, EngineGameScreen } from '../shared/EngineGameScreen';
|
|
12
|
-
import { livesColumn, scoreColumn, timerColumn } from '../shared/EngineHud';
|
|
13
|
-
import { useEngineGame } from '../shared/useEngineGame';
|
|
14
|
-
import { useLiveState } from '../shared/useLiveState';
|
|
15
|
-
import { getLayout, LIGHT, LIVES, TIME_LIMIT } from './BlockBreakerConstants';
|
|
16
|
-
import { createGame, dispose, dragMove, dragStart, reset, setLayout, setTheme, start, tick } from './BlockBreakerGame';
|
|
17
|
-
|
|
18
|
-
const SOUNDS = GAME_SOUNDS.BLOCK_BREAKER;
|
|
19
|
-
|
|
20
|
-
export const BlockBreaker = engineGame(GAME_IDS.BLOCK_BREAKER, (props) => {
|
|
21
|
-
const [score, setScore] = useLiveState(0);
|
|
22
|
-
const [lives, setLives] = useLiveState(LIVES);
|
|
23
|
-
const [timeLeft, setTimeLeft] = useLiveState(TIME_LIMIT);
|
|
24
|
-
|
|
25
|
-
// Win on a cleared wall, lose on no lives or time up
|
|
26
|
-
const { theme, status, screen, gameOver } = useEngineGame(props, {
|
|
27
|
-
gameId: GAME_IDS.BLOCK_BREAKER,
|
|
28
|
-
create: createGame,
|
|
29
|
-
start,
|
|
30
|
-
reset,
|
|
31
|
-
dispose,
|
|
32
|
-
tick,
|
|
33
|
-
setTheme,
|
|
34
|
-
resize: (g, width, height, offset) => {
|
|
35
|
-
const l = getLayout(width, height, offset);
|
|
36
|
-
setLayout(g, l);
|
|
37
|
-
return l.boardWidth;
|
|
38
|
-
},
|
|
39
|
-
// Drag anywhere to slide the paddle by the same distance
|
|
40
|
-
drag: (g, { phase, dx }) => {
|
|
41
|
-
if (phase === 'start') dragStart(g);
|
|
42
|
-
else if (phase === 'move') dragMove(g, dx);
|
|
43
|
-
},
|
|
44
|
-
sounds: SOUNDS,
|
|
45
|
-
onStart: (fx) => fx(SOUNDS.START, HapticType.SUCCESS),
|
|
46
|
-
onStop: (fx) => fx(null, HapticType.MEDIUM),
|
|
47
|
-
wire: (g, fx) => {
|
|
48
|
-
g.onScore = setScore;
|
|
49
|
-
g.onLives = setLives;
|
|
50
|
-
g.onTime = setTimeLeft;
|
|
51
|
-
g.onWall = () => fx(SOUNDS.WALL, HapticType.LIGHT);
|
|
52
|
-
g.onPaddle = () => fx(SOUNDS.PADDLE, HapticType.LIGHT);
|
|
53
|
-
g.onBrickHit = () => fx(SOUNDS.HIT, HapticType.LIGHT);
|
|
54
|
-
g.onBrickBreak = () => fx(SOUNDS.DESTROY, HapticType.MEDIUM);
|
|
55
|
-
g.onCombo = () => fx(SOUNDS.COMBO, HapticType.MEDIUM);
|
|
56
|
-
g.onPowerUp = () => fx(SOUNDS.POWER_UP, HapticType.SUCCESS);
|
|
57
|
-
g.onLaunch = () => fx(SOUNDS.LAUNCH, HapticType.LIGHT);
|
|
58
|
-
g.onLoseLife = () => fx(SOUNDS.LOSE_LIFE, HapticType.ERROR);
|
|
59
|
-
g.onWin = () => fx(SOUNDS.WIN, HapticType.SUCCESS);
|
|
60
|
-
g.onLose = () => fx(SOUNDS.GAME_OVER, HapticType.ERROR);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<EngineGameScreen
|
|
66
|
-
{...screen}
|
|
67
|
-
light={LIGHT}
|
|
68
|
-
columns={[scoreColumn(score), livesColumn(lives, LIVES), timerColumn(timeLeft, theme)]}
|
|
69
|
-
subtext="Break all bricks!"
|
|
70
|
-
gameOver={gameOver({
|
|
71
|
-
title: status === 'win' ? 'YOU WON!' : 'GAME OVER',
|
|
72
|
-
message: status === 'win' ? 'All bricks destroyed!' : 'Great breaking!',
|
|
73
|
-
scoreLabel: 'Final Score',
|
|
74
|
-
score,
|
|
75
|
-
buttonText: 'Break Again!'
|
|
76
|
-
})}
|
|
77
|
-
/>
|
|
78
|
-
);
|
|
79
|
-
});
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
// Block Breaker's rules, physics, timings, colors and layout. Rules, scoring, physics and layout match
|
|
2
|
-
// the original version (games/block-breaker), so scores and feel carry over.
|
|
3
|
-
import { isTablet } from '../../services/UtilsService';
|
|
4
|
-
import { getSceneInputInsets } from '../shared/EngineHud';
|
|
5
|
-
import { frontLight, gameWidthFor } from '../shared/EngineUtils';
|
|
6
|
-
|
|
7
|
-
// ── Rules ─────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
export const BRICK_COLS = 8;
|
|
10
|
-
export const BRICK_ROWS = 5;
|
|
11
|
-
export const LIVES = 3;
|
|
12
|
-
export const TIME_LIMIT = 300; // seconds
|
|
13
|
-
export const POINTS_PER_BRICK = 200;
|
|
14
|
-
export const POINTS_PER_COMBO = 150; // added per brick in the current combo (bricks since the paddle)
|
|
15
|
-
export const COMBO_CALLOUT = 3; // a combo this long or more cheers
|
|
16
|
-
|
|
17
|
-
export enum PowerUpType {
|
|
18
|
-
WIDE_PADDLE = 'wide_paddle',
|
|
19
|
-
MULTI_BALL = 'multi_ball',
|
|
20
|
-
EXTRA_LIFE = 'extra_life'
|
|
21
|
-
}
|
|
22
|
-
export const POWER_UP_TYPES = [PowerUpType.WIDE_PADDLE, PowerUpType.MULTI_BALL, PowerUpType.EXTRA_LIFE] as const;
|
|
23
|
-
export const POWER_UP_CHANCE = 0.15;
|
|
24
|
-
export const MAX_BALLS = 5;
|
|
25
|
-
export const WIDE_FACTOR = 1.3; // each wide paddle widens by this...
|
|
26
|
-
export const WIDE_MAX = 1.5; // ...up to this much of the normal width
|
|
27
|
-
export const WIDE_TIME = 10; // seconds, then the paddle goes back to normal
|
|
28
|
-
|
|
29
|
-
// ── Physics (points per 60 fps frame, as the original version) ───────────
|
|
30
|
-
|
|
31
|
-
export const FRAME_TIME = 1 / 60;
|
|
32
|
-
export const MAX_FRAMES = 2; // a long frame moves at most this many frames' worth
|
|
33
|
-
export const BALL_SPEED = isTablet ? 5 : 4;
|
|
34
|
-
export const BALL_RADIUS = isTablet ? 8 : 7;
|
|
35
|
-
export const LAUNCH_SPREAD = Math.PI / 3; // a new ball leaves within ±30° of straight up
|
|
36
|
-
export const PADDLE_BOUNCE = Math.PI / 3; // the paddle's edge sends the ball out at 60°
|
|
37
|
-
export const POWER_UP_SPEED = 2;
|
|
38
|
-
export const POWER_UP_SIZE = isTablet ? 18 : 14;
|
|
39
|
-
export const RELAUNCH_DELAY = 0.5; // seconds after a lost ball
|
|
40
|
-
|
|
41
|
-
// ── Feel (seconds) ────────────────────────────────────────────────────
|
|
42
|
-
|
|
43
|
-
export const PADDLE_WIDTH_TIME = 0.22;
|
|
44
|
-
export const BUMP_TIME = 0.06; // the paddle squashes when something lands on it...
|
|
45
|
-
export const BUMP_SPRING = { damping: 8, stiffness: 320 }; // ...and springs back
|
|
46
|
-
export const BALL_SPAWN_SPRING = { damping: 10, stiffness: 300 };
|
|
47
|
-
export const BRICK_DROP = 18; // a new wall's bricks drop this far into place...
|
|
48
|
-
export const BRICK_INTRO_SPRING = { damping: 11, stiffness: 190 }; // ...with a little bounce,
|
|
49
|
-
export const BRICK_ROW_STAGGER = 0.07; // row by row
|
|
50
|
-
export const BRICK_COL_STAGGER = 0.018;
|
|
51
|
-
export const PULSE_TIME = 0.52; // a power-up's glow breathes
|
|
52
|
-
// Ball trail: three fading dots behind it, at multiples of its velocity
|
|
53
|
-
export const TRAIL = [
|
|
54
|
-
{ k: 1.6, r: 0.8, o: 0.32 },
|
|
55
|
-
{ k: 3.2, r: 0.62, o: 0.18 },
|
|
56
|
-
{ k: 4.8, r: 0.45, o: 0.08 }
|
|
57
|
-
] as const;
|
|
58
|
-
|
|
59
|
-
// ── Look ──────────────────────────────────────────────────────────────
|
|
60
|
-
|
|
61
|
-
export const LIGHT = frontLight([-0.3, 0.7, 1], 0.5);
|
|
62
|
-
|
|
63
|
-
export const BRICK_COLORS = ['#FF3B3B', '#FFD700', '#32CD32', '#4DA6FF', '#BF5AF2', '#FF9500'] as const;
|
|
64
|
-
export const POWER_UP_COLORS: Record<PowerUpType, string> = {
|
|
65
|
-
[PowerUpType.WIDE_PADDLE]: '#00FF88',
|
|
66
|
-
[PowerUpType.MULTI_BALL]: '#FF6B9D',
|
|
67
|
-
[PowerUpType.EXTRA_LIFE]: '#FFD700'
|
|
68
|
-
};
|
|
69
|
-
export const PADDLE_COLOR = '#ffffff';
|
|
70
|
-
export const BALL_COLOR = '#e0e0e0';
|
|
71
|
-
export const TRAIL_COLOR = '#ffffff';
|
|
72
|
-
export const CLASSIC_BOARD = 'rgba(255, 255, 255, 0.25)';
|
|
73
|
-
export const CLASSIC_BORDER = 'rgba(255, 255, 255, 0.5)';
|
|
74
|
-
export const CLASSIC_RADIUS = 16;
|
|
75
|
-
export const THEMED_RADIUS = 8;
|
|
76
|
-
|
|
77
|
-
// ── Layout (points; same arithmetic as the original version) ──────────────
|
|
78
|
-
|
|
79
|
-
const BRICK_PADDING = 3;
|
|
80
|
-
const GRID_TOP = 5;
|
|
81
|
-
|
|
82
|
-
export type Layout = {
|
|
83
|
-
/** The GameView's size. */
|
|
84
|
-
width: number;
|
|
85
|
-
height: number;
|
|
86
|
-
/** The board: as wide as the game area, a fixed height, centred below the header. */
|
|
87
|
-
boardLeft: number;
|
|
88
|
-
boardTop: number;
|
|
89
|
-
boardWidth: number;
|
|
90
|
-
boardHeight: number;
|
|
91
|
-
// Everything below is in board points, from its top-left.
|
|
92
|
-
brickWidth: number;
|
|
93
|
-
brickHeight: number;
|
|
94
|
-
/** The first brick's left edge and the top row's top. */
|
|
95
|
-
bricksLeft: number;
|
|
96
|
-
bricksTop: number;
|
|
97
|
-
/** One brick to the next. */
|
|
98
|
-
brickStepX: number;
|
|
99
|
-
brickStepY: number;
|
|
100
|
-
paddleWidth: number;
|
|
101
|
-
paddleHeight: number;
|
|
102
|
-
paddleTop: number;
|
|
103
|
-
/** Where the ball's centre stays between (side walls), and where a ball counts as lost. */
|
|
104
|
-
minX: number;
|
|
105
|
-
maxX: number;
|
|
106
|
-
lostY: number;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
export function getLayout(width: number, height: number, offset: number): Layout {
|
|
110
|
-
const boardWidth = gameWidthFor(width);
|
|
111
|
-
const insets = getSceneInputInsets(offset);
|
|
112
|
-
const top = insets.top + 4;
|
|
113
|
-
const room = Math.max(1, height - top - insets.bottom - 10);
|
|
114
|
-
const boardHeight = Math.min(isTablet ? 650 : 500, room);
|
|
115
|
-
const brickWidth = Math.floor((boardWidth - BRICK_PADDING * (BRICK_COLS + 1)) / BRICK_COLS);
|
|
116
|
-
const brickHeight = isTablet ? 22 : 18;
|
|
117
|
-
const paddleHeight = isTablet ? 14 : 12;
|
|
118
|
-
const paddleY = boardHeight - (isTablet ? 30 : 20);
|
|
119
|
-
return {
|
|
120
|
-
width,
|
|
121
|
-
height,
|
|
122
|
-
boardLeft: (width - boardWidth) / 2,
|
|
123
|
-
boardTop: top + (room - boardHeight) / 2,
|
|
124
|
-
boardWidth,
|
|
125
|
-
boardHeight,
|
|
126
|
-
brickWidth,
|
|
127
|
-
brickHeight,
|
|
128
|
-
bricksLeft: (boardWidth - (BRICK_COLS * brickWidth + (BRICK_COLS - 1) * BRICK_PADDING)) / 2,
|
|
129
|
-
bricksTop: GRID_TOP,
|
|
130
|
-
brickStepX: brickWidth + BRICK_PADDING,
|
|
131
|
-
brickStepY: brickHeight + BRICK_PADDING,
|
|
132
|
-
paddleWidth: isTablet ? 100 : 80,
|
|
133
|
-
paddleHeight,
|
|
134
|
-
paddleTop: paddleY - paddleHeight / 2,
|
|
135
|
-
minX: BALL_RADIUS,
|
|
136
|
-
maxX: boardWidth - BALL_RADIUS,
|
|
137
|
-
lostY: boardHeight - BALL_RADIUS
|
|
138
|
-
};
|
|
139
|
-
}
|
|
@@ -1,459 +0,0 @@
|
|
|
1
|
-
// Block Breaker's rules and physics, with no React: build a run with `createGame`, give it a layout,
|
|
2
|
-
// `start` it and `tick` it every frame. Drag to slide the paddle and keep the ball in play; every brick
|
|
3
|
-
// it breaks scores 200, plus 150 for each brick already broken since it last touched the paddle.
|
|
4
|
-
// Broken bricks sometimes drop a power-up: a wider paddle for 10s, two extra balls, or an extra life.
|
|
5
|
-
// Break every brick to win; lose all three lives, or run out of time, and it's over. The physics is the
|
|
6
|
-
// original version's: moves are per 60 fps frame, scaled by the frame's length.
|
|
7
|
-
import { type Camera, type Entity, World } from '@nayan-ui/engine';
|
|
8
|
-
import type { GameTheme } from '../../services/ThemeService';
|
|
9
|
-
import { introPlayed } from '../shared/EngineUtils';
|
|
10
|
-
import {
|
|
11
|
-
BALL_RADIUS,
|
|
12
|
-
BALL_SPEED,
|
|
13
|
-
BRICK_COL_STAGGER,
|
|
14
|
-
BRICK_COLS,
|
|
15
|
-
BRICK_ROW_STAGGER,
|
|
16
|
-
BRICK_ROWS,
|
|
17
|
-
COMBO_CALLOUT,
|
|
18
|
-
FRAME_TIME,
|
|
19
|
-
LAUNCH_SPREAD,
|
|
20
|
-
type Layout,
|
|
21
|
-
LIVES,
|
|
22
|
-
MAX_BALLS,
|
|
23
|
-
MAX_FRAMES,
|
|
24
|
-
PADDLE_BOUNCE,
|
|
25
|
-
POINTS_PER_BRICK,
|
|
26
|
-
POINTS_PER_COMBO,
|
|
27
|
-
POWER_UP_CHANCE,
|
|
28
|
-
POWER_UP_SPEED,
|
|
29
|
-
POWER_UP_TYPES,
|
|
30
|
-
PowerUpType,
|
|
31
|
-
RELAUNCH_DELAY,
|
|
32
|
-
TIME_LIMIT,
|
|
33
|
-
WIDE_FACTOR,
|
|
34
|
-
WIDE_MAX,
|
|
35
|
-
WIDE_TIME
|
|
36
|
-
} from './BlockBreakerConstants';
|
|
37
|
-
import {
|
|
38
|
-
type BallView,
|
|
39
|
-
breakBrick,
|
|
40
|
-
buildScenery,
|
|
41
|
-
bumpPaddle,
|
|
42
|
-
colorBall,
|
|
43
|
-
hitBrick,
|
|
44
|
-
type Paddle,
|
|
45
|
-
pieceColors,
|
|
46
|
-
placeBall,
|
|
47
|
-
placePaddle,
|
|
48
|
-
placePowerUp,
|
|
49
|
-
removeBall,
|
|
50
|
-
removeScenery,
|
|
51
|
-
type Scenery,
|
|
52
|
-
setPaddleWidth,
|
|
53
|
-
setSceneryTheme,
|
|
54
|
-
spawnBall,
|
|
55
|
-
spawnBrick,
|
|
56
|
-
spawnPaddle,
|
|
57
|
-
spawnPowerUp
|
|
58
|
-
} from './BlockBreakerScene';
|
|
59
|
-
|
|
60
|
-
export type Phase = 'ready' | 'playing' | 'over';
|
|
61
|
-
|
|
62
|
-
type Brick = { row: number; col: number; hits: number; entity: Entity | null };
|
|
63
|
-
type Ball = { x: number; y: number; vx: number; vy: number; view: BallView | null };
|
|
64
|
-
type PowerUp = { type: PowerUpType; x: number; y: number; entity: Entity | null };
|
|
65
|
-
|
|
66
|
-
const WORLD_CAPACITY = 500; // 40 bricks, 5 balls x 4, power-ups, paddle, scenery, bursts
|
|
67
|
-
|
|
68
|
-
const newBricks = (): Brick[] =>
|
|
69
|
-
Array.from({ length: BRICK_ROWS * BRICK_COLS }, (_, i) => ({ row: Math.floor(i / BRICK_COLS), col: i % BRICK_COLS, hits: 1, entity: null }));
|
|
70
|
-
|
|
71
|
-
export function createGame(theme: GameTheme) {
|
|
72
|
-
const world = new World(WORLD_CAPACITY);
|
|
73
|
-
const camera: Camera = { eye: [0, 0, 400], target: [0, 0, 0], fov: 1, ortho: 1 };
|
|
74
|
-
const g = {
|
|
75
|
-
world,
|
|
76
|
-
camera,
|
|
77
|
-
theme,
|
|
78
|
-
colors: pieceColors(theme),
|
|
79
|
-
layout: null as Layout | null,
|
|
80
|
-
scenery: null as Scenery | null,
|
|
81
|
-
phase: 'ready' as Phase,
|
|
82
|
-
/** Score, lives and the countdown live in the engine (Rust), advanced by world.update. */
|
|
83
|
-
get score() {
|
|
84
|
-
return world.scoreboard.score;
|
|
85
|
-
},
|
|
86
|
-
get lives() {
|
|
87
|
-
return world.scoreboard.lives;
|
|
88
|
-
},
|
|
89
|
-
get timeLeft() {
|
|
90
|
-
return world.scoreboard.shownSeconds;
|
|
91
|
-
},
|
|
92
|
-
won: false,
|
|
93
|
-
/** Game clock, seconds: drives the delayed steps (they pause with the frame loop). */
|
|
94
|
-
time: 0,
|
|
95
|
-
bricks: newBricks(),
|
|
96
|
-
balls: [] as Ball[],
|
|
97
|
-
powerUps: [] as PowerUp[],
|
|
98
|
-
/** Bricks broken since the ball last touched the paddle. */
|
|
99
|
-
combo: 0,
|
|
100
|
-
paddle: null as Paddle | null,
|
|
101
|
-
/** Paddle centre (board points), the width it collides with, and where a drag started. */
|
|
102
|
-
paddleX: 0,
|
|
103
|
-
paddleWidth: 0,
|
|
104
|
-
dragFrom: 0,
|
|
105
|
-
/** The next wall to appear builds in. */
|
|
106
|
-
intro: true,
|
|
107
|
-
/** Game seconds the current intro has been playing (-1 until its board spawns). */
|
|
108
|
-
introAge: -1,
|
|
109
|
-
// UI hooks, set by the screen.
|
|
110
|
-
onPhase: (_p: Phase) => {},
|
|
111
|
-
onScore: (_s: number) => {},
|
|
112
|
-
onLives: (_n: number) => {},
|
|
113
|
-
onTime: (_t: number) => {},
|
|
114
|
-
onWall: () => {},
|
|
115
|
-
onPaddle: () => {},
|
|
116
|
-
onBrickHit: () => {},
|
|
117
|
-
onBrickBreak: () => {},
|
|
118
|
-
onCombo: () => {},
|
|
119
|
-
onPowerUp: () => {},
|
|
120
|
-
onLaunch: () => {},
|
|
121
|
-
onLoseLife: () => {},
|
|
122
|
-
onWin: () => {},
|
|
123
|
-
onLose: () => {}
|
|
124
|
-
};
|
|
125
|
-
world.scoreboard.reset(LIVES, TIME_LIMIT);
|
|
126
|
-
world.scoreboard.handlers = {
|
|
127
|
-
onSecond: (t) => g.onTime(t),
|
|
128
|
-
onTimeUp: () => g.phase === 'playing' && end(g, false)
|
|
129
|
-
};
|
|
130
|
-
return g;
|
|
131
|
-
}
|
|
132
|
-
export type Game = ReturnType<typeof createGame>;
|
|
133
|
-
|
|
134
|
-
const after = (g: Game, seconds: number, run: () => void) => g.world.after(seconds, run);
|
|
135
|
-
const brickX = (l: Layout, b: Brick) => l.bricksLeft + b.col * l.brickStepX;
|
|
136
|
-
const brickY = (l: Layout, b: Brick) => l.bricksTop + b.row * l.brickStepY;
|
|
137
|
-
|
|
138
|
-
// ── Scene ─────────────────────────────────────────────────────────────
|
|
139
|
-
|
|
140
|
-
/** Lays the scene out for the view (first layout, header height, rotation): rebuilt from the run's state. */
|
|
141
|
-
export function setLayout(g: Game, l: Layout) {
|
|
142
|
-
const w = g.world;
|
|
143
|
-
const old = g.layout;
|
|
144
|
-
if (g.scenery) removeScenery(w, g.scenery);
|
|
145
|
-
if (g.paddle) w.despawn(g.paddle.root);
|
|
146
|
-
clearPieces(g);
|
|
147
|
-
for (const b of g.bricks) if (b.entity != null) w.despawn(b.entity);
|
|
148
|
-
g.layout = l;
|
|
149
|
-
g.camera.ortho = l.height / 2;
|
|
150
|
-
g.scenery = buildScenery(w, l, g.theme);
|
|
151
|
-
// Keep the paddle where it was across the board (its width only changes with a power-up)
|
|
152
|
-
g.paddleX = old ? (g.paddleX / old.boardWidth) * l.boardWidth : l.boardWidth / 2;
|
|
153
|
-
if (!old || g.paddleWidth === 0) g.paddleWidth = l.paddleWidth;
|
|
154
|
-
g.paddle = spawnPaddle(w, l, g.paddleX, g.paddleWidth, g.colors.paddle);
|
|
155
|
-
spawnBricks(g);
|
|
156
|
-
// Mid-run, the cleared ball comes back on the paddle, as after a lost life (without costing one)
|
|
157
|
-
if (old && g.phase === 'playing') after(g, RELAUNCH_DELAY, () => relaunch(g));
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/** A new theme: the background and board are repainted and the ball and paddle recolored. */
|
|
161
|
-
export function setTheme(g: Game, theme: GameTheme) {
|
|
162
|
-
g.theme = theme;
|
|
163
|
-
g.colors = pieceColors(theme);
|
|
164
|
-
if (!g.layout || !g.scenery || g.world.isDisposed) return;
|
|
165
|
-
setSceneryTheme(g.world, g.layout, g.scenery, theme);
|
|
166
|
-
if (g.paddle) g.world.set(g.paddle.body, { color: g.colors.paddle });
|
|
167
|
-
for (const b of g.balls) if (b.view) colorBall(g.world, b.view, g.colors);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/** Spawns the standing bricks; a new wall builds in row by row. */
|
|
171
|
-
function spawnBricks(g: Game) {
|
|
172
|
-
const l = g.layout;
|
|
173
|
-
if (!l) return;
|
|
174
|
-
const intro = g.intro;
|
|
175
|
-
if (intro) g.introAge = 0;
|
|
176
|
-
for (const b of g.bricks) {
|
|
177
|
-
if (b.hits <= 0) continue;
|
|
178
|
-
b.entity = spawnBrick(g.world, l, brickX(l, b), brickY(l, b), b.row, intro ? b.row * BRICK_ROW_STAGGER + b.col * BRICK_COL_STAGGER : null);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/** Removes every ball and power-up (Stop, Play Again, a new layout). */
|
|
183
|
-
function clearPieces(g: Game) {
|
|
184
|
-
for (const b of g.balls) if (b.view) removeBall(g.world, b.view);
|
|
185
|
-
for (const p of g.powerUps) if (p.entity != null) g.world.despawn(p.entity);
|
|
186
|
-
g.balls = [];
|
|
187
|
-
g.powerUps = [];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// ── Run ───────────────────────────────────────────────────────────────
|
|
191
|
-
|
|
192
|
-
/** A ball leaving the paddle within ±30° of straight up. */
|
|
193
|
-
function launch(g: Game, x: number) {
|
|
194
|
-
const l = g.layout;
|
|
195
|
-
if (!l) return;
|
|
196
|
-
const angle = (Math.random() - 0.5) * LAUNCH_SPREAD;
|
|
197
|
-
const y = l.paddleTop - BALL_RADIUS - 2;
|
|
198
|
-
g.balls.push({ x, y, vx: Math.sin(angle) * BALL_SPEED, vy: -Math.abs(Math.cos(angle) * BALL_SPEED), view: spawnBall(g.world, l, x, y, g.colors) });
|
|
199
|
-
g.combo = 0;
|
|
200
|
-
g.onLaunch();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/** After a lost ball: the next one appears on the paddle wherever it is now. */
|
|
204
|
-
function relaunch(g: Game) {
|
|
205
|
-
if (g.phase === 'playing' && !g.balls.length) launch(g, g.paddleX);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export function start(g: Game) {
|
|
209
|
-
const l = g.layout;
|
|
210
|
-
if (g.phase !== 'ready' || !l) return;
|
|
211
|
-
if (!g.bricks.some((b) => b.hits > 0)) newWall(g);
|
|
212
|
-
// The paddle goes back to the centre first, so the ball launches from there
|
|
213
|
-
g.paddleX = l.boardWidth / 2;
|
|
214
|
-
g.paddleWidth = l.paddleWidth;
|
|
215
|
-
if (g.paddle) {
|
|
216
|
-
placePaddle(g.world, l, g.paddle, g.paddleX);
|
|
217
|
-
setPaddleWidth(g.world, l, g.paddle, g.paddleWidth, false);
|
|
218
|
-
}
|
|
219
|
-
g.phase = 'playing';
|
|
220
|
-
g.world.scoreboard.startCountdown(TIME_LIMIT);
|
|
221
|
-
g.onPhase('playing');
|
|
222
|
-
launch(g, g.paddleX);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function newWall(g: Game) {
|
|
226
|
-
for (const b of g.bricks) if (b.entity != null) g.world.despawn(b.entity);
|
|
227
|
-
g.bricks = newBricks();
|
|
228
|
-
g.intro = true;
|
|
229
|
-
spawnBricks(g);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/** A new wall, lives and timer (Stop, Play Again). The world, and the GPU view drawing it, are kept. */
|
|
233
|
-
export function reset(g: Game) {
|
|
234
|
-
g.world.cancelTimers(); // a pending relaunch or wide-paddle expiry can't reach the next game
|
|
235
|
-
clearPieces(g);
|
|
236
|
-
newWall(g);
|
|
237
|
-
const l = g.layout;
|
|
238
|
-
if (l && g.paddle) {
|
|
239
|
-
g.paddleX = l.boardWidth / 2;
|
|
240
|
-
g.paddleWidth = l.paddleWidth;
|
|
241
|
-
placePaddle(g.world, l, g.paddle, g.paddleX);
|
|
242
|
-
setPaddleWidth(g.world, l, g.paddle, g.paddleWidth, false);
|
|
243
|
-
}
|
|
244
|
-
g.combo = 0;
|
|
245
|
-
g.world.scoreboard.reset(LIVES, TIME_LIMIT);
|
|
246
|
-
g.won = false;
|
|
247
|
-
g.phase = 'ready';
|
|
248
|
-
g.onScore(0);
|
|
249
|
-
g.onLives(LIVES);
|
|
250
|
-
g.onTime(TIME_LIMIT);
|
|
251
|
-
g.onPhase('ready');
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
export function dispose(g: Game) {
|
|
255
|
-
g.world.cancelTimers();
|
|
256
|
-
g.world.dispose();
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/** The run ends: balls and power-ups freeze where they are, under the game-over card. */
|
|
260
|
-
function end(g: Game, won: boolean) {
|
|
261
|
-
g.world.scoreboard.stop();
|
|
262
|
-
g.world.cancelTimers();
|
|
263
|
-
g.won = won;
|
|
264
|
-
g.phase = 'over';
|
|
265
|
-
if (won) g.onWin();
|
|
266
|
-
else g.onLose();
|
|
267
|
-
g.onPhase('over');
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export function tick(g: Game, dt: number) {
|
|
271
|
-
if (g.world.isDisposed) return;
|
|
272
|
-
introPlayed(g, dt);
|
|
273
|
-
g.time += dt;
|
|
274
|
-
// While waiting for a relaunch nothing moves, power-ups included, as before
|
|
275
|
-
if (g.phase === 'playing' && g.balls.length) step(g, Math.min(dt / FRAME_TIME, MAX_FRAMES));
|
|
276
|
-
g.world.update(dt);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// ── Touch ─────────────────────────────────────────────────────────────
|
|
280
|
-
|
|
281
|
-
export function dragStart(g: Game) {
|
|
282
|
-
g.dragFrom = g.paddleX;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/** Slides the paddle by the drag's distance, kept inside the board. */
|
|
286
|
-
export function dragMove(g: Game, dx: number) {
|
|
287
|
-
const l = g.layout;
|
|
288
|
-
if (!l || !g.paddle || g.phase !== 'playing') return;
|
|
289
|
-
const half = g.paddleWidth / 2;
|
|
290
|
-
g.paddleX = Math.max(half, Math.min(l.boardWidth - half, g.dragFrom + dx));
|
|
291
|
-
placePaddle(g.world, l, g.paddle, g.paddleX);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// ── Physics ───────────────────────────────────────────────────────────
|
|
295
|
-
|
|
296
|
-
/** One step of `dt` 60 fps frames: balls, bricks, power-ups, in the original version's order and maths. */
|
|
297
|
-
function step(g: Game, dt: number) {
|
|
298
|
-
const l = g.layout!;
|
|
299
|
-
const w = g.world;
|
|
300
|
-
const half = g.paddleWidth / 2;
|
|
301
|
-
const px = g.paddleX;
|
|
302
|
-
let wallHits = 0;
|
|
303
|
-
let paddleHits = 0;
|
|
304
|
-
let combos = 0;
|
|
305
|
-
let broke = false;
|
|
306
|
-
let hit = false;
|
|
307
|
-
let points = 0;
|
|
308
|
-
let lost = false;
|
|
309
|
-
|
|
310
|
-
const kept = g.balls;
|
|
311
|
-
let ballCount = 0;
|
|
312
|
-
for (const ball of g.balls) {
|
|
313
|
-
let x = ball.x + ball.vx * dt;
|
|
314
|
-
let y = ball.y + ball.vy * dt;
|
|
315
|
-
let { vx, vy } = ball;
|
|
316
|
-
|
|
317
|
-
// Side and top walls
|
|
318
|
-
let wall = false;
|
|
319
|
-
if (x <= l.minX) {
|
|
320
|
-
x = l.minX;
|
|
321
|
-
vx = Math.abs(vx);
|
|
322
|
-
wall = true;
|
|
323
|
-
} else if (x >= l.maxX) {
|
|
324
|
-
x = l.maxX;
|
|
325
|
-
vx = -Math.abs(vx);
|
|
326
|
-
wall = true;
|
|
327
|
-
}
|
|
328
|
-
if (y - BALL_RADIUS <= 0) {
|
|
329
|
-
y = BALL_RADIUS;
|
|
330
|
-
vy = Math.abs(vy);
|
|
331
|
-
wall = true;
|
|
332
|
-
}
|
|
333
|
-
if (wall) wallHits++;
|
|
334
|
-
|
|
335
|
-
// Past the paddle: lost
|
|
336
|
-
if (y + BALL_RADIUS > l.lostY) {
|
|
337
|
-
lost = true;
|
|
338
|
-
if (ball.view) removeBall(w, ball.view);
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// The paddle sends it back out at an angle set by where it landed
|
|
343
|
-
if (
|
|
344
|
-
vy > 0 &&
|
|
345
|
-
y + BALL_RADIUS >= l.paddleTop &&
|
|
346
|
-
y + BALL_RADIUS <= l.paddleTop + l.paddleHeight + 5 &&
|
|
347
|
-
x >= px - half - BALL_RADIUS &&
|
|
348
|
-
x <= px + half + BALL_RADIUS
|
|
349
|
-
) {
|
|
350
|
-
const angle = ((x - px) / half) * PADDLE_BOUNCE;
|
|
351
|
-
const speed = Math.hypot(vx, vy);
|
|
352
|
-
vx = Math.sin(angle) * speed;
|
|
353
|
-
vy = -Math.abs(Math.cos(angle) * speed);
|
|
354
|
-
y = l.paddleTop - BALL_RADIUS - 1;
|
|
355
|
-
paddleHits++;
|
|
356
|
-
if (g.paddle) bumpPaddle(w, g.paddle, 1);
|
|
357
|
-
g.combo = 0;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// At most one brick a frame per ball; it bounces off the side it overlaps least
|
|
361
|
-
for (const brick of g.bricks) {
|
|
362
|
-
if (brick.hits <= 0) continue;
|
|
363
|
-
const bx = brickX(l, brick);
|
|
364
|
-
const by = brickY(l, brick);
|
|
365
|
-
if (x + BALL_RADIUS <= bx || x - BALL_RADIUS >= bx + l.brickWidth || y + BALL_RADIUS <= by || y - BALL_RADIUS >= by + l.brickHeight) continue;
|
|
366
|
-
const overlapX = Math.min(x + BALL_RADIUS - bx, bx + l.brickWidth - (x - BALL_RADIUS));
|
|
367
|
-
const overlapY = Math.min(y + BALL_RADIUS - by, by + l.brickHeight - (y - BALL_RADIUS));
|
|
368
|
-
if (overlapX < overlapY) vx = -vx;
|
|
369
|
-
else vy = -vy;
|
|
370
|
-
|
|
371
|
-
brick.hits -= 1;
|
|
372
|
-
if (brick.hits <= 0) {
|
|
373
|
-
if (brick.entity != null) breakBrick(w, l, brick.entity, bx, by, brick.row);
|
|
374
|
-
brick.entity = null;
|
|
375
|
-
broke = true;
|
|
376
|
-
g.combo++;
|
|
377
|
-
if (g.combo >= COMBO_CALLOUT) combos++;
|
|
378
|
-
if (Math.random() < POWER_UP_CHANCE) {
|
|
379
|
-
const type = POWER_UP_TYPES[Math.floor(Math.random() * POWER_UP_TYPES.length)]!;
|
|
380
|
-
const cx = bx + l.brickWidth / 2;
|
|
381
|
-
const cy = by + l.brickHeight / 2;
|
|
382
|
-
g.powerUps.push({ type, x: cx, y: cy, entity: spawnPowerUp(w, l, type, cx, cy) });
|
|
383
|
-
}
|
|
384
|
-
} else {
|
|
385
|
-
if (brick.entity != null) hitBrick(w, brick.entity);
|
|
386
|
-
hit = true;
|
|
387
|
-
}
|
|
388
|
-
points += POINTS_PER_BRICK + g.combo * POINTS_PER_COMBO;
|
|
389
|
-
break;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
ball.x = x;
|
|
393
|
-
ball.y = y;
|
|
394
|
-
ball.vx = vx;
|
|
395
|
-
ball.vy = vy;
|
|
396
|
-
if (ball.view) placeBall(w, l, ball.view, x, y, vx, vy);
|
|
397
|
-
kept[ballCount++] = ball;
|
|
398
|
-
}
|
|
399
|
-
kept.length = ballCount;
|
|
400
|
-
|
|
401
|
-
// Power-ups fall and are caught by this frame's paddle
|
|
402
|
-
const collected: PowerUpType[] = [];
|
|
403
|
-
g.powerUps = g.powerUps.filter((p) => {
|
|
404
|
-
p.y += POWER_UP_SPEED * dt;
|
|
405
|
-
const caught = p.y >= l.paddleTop && p.y <= l.paddleTop + l.paddleHeight + 10 && p.x >= px - half - 10 && p.x <= px + half + 10;
|
|
406
|
-
if (caught) collected.push(p.type);
|
|
407
|
-
if (caught || p.y > l.boardHeight) {
|
|
408
|
-
if (p.entity != null) w.despawn(p.entity);
|
|
409
|
-
return false;
|
|
410
|
-
}
|
|
411
|
-
if (p.entity != null) placePowerUp(w, l, p.entity, p.x, p.y);
|
|
412
|
-
return true;
|
|
413
|
-
});
|
|
414
|
-
for (const type of collected) collect(g, type);
|
|
415
|
-
|
|
416
|
-
// Sounds and score, in the order the original version raised them
|
|
417
|
-
for (let i = 0; i < wallHits; i++) g.onWall();
|
|
418
|
-
for (let i = 0; i < paddleHits; i++) g.onPaddle();
|
|
419
|
-
for (let i = 0; i < combos; i++) g.onCombo();
|
|
420
|
-
if (points > 0) {
|
|
421
|
-
g.onScore(g.world.scoreboard.add(points));
|
|
422
|
-
}
|
|
423
|
-
if (broke) g.onBrickBreak();
|
|
424
|
-
else if (hit) g.onBrickHit();
|
|
425
|
-
for (let i = 0; i < collected.length; i++) g.onPowerUp();
|
|
426
|
-
|
|
427
|
-
if (lost && !g.balls.length) {
|
|
428
|
-
g.onLives(g.world.scoreboard.addLives(-1));
|
|
429
|
-
g.onLoseLife();
|
|
430
|
-
if (g.lives <= 0) {
|
|
431
|
-
end(g, false);
|
|
432
|
-
return;
|
|
433
|
-
}
|
|
434
|
-
after(g, RELAUNCH_DELAY, () => relaunch(g));
|
|
435
|
-
}
|
|
436
|
-
if (!g.bricks.some((b) => b.hits > 0)) end(g, true);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
function collect(g: Game, type: PowerUpType) {
|
|
440
|
-
const l = g.layout!;
|
|
441
|
-
if (type === PowerUpType.WIDE_PADDLE) {
|
|
442
|
-
g.paddleWidth = Math.min(l.paddleWidth * WIDE_MAX, g.paddleWidth * WIDE_FACTOR);
|
|
443
|
-
if (g.paddle) setPaddleWidth(g.world, l, g.paddle, g.paddleWidth, true);
|
|
444
|
-
after(g, WIDE_TIME, () => {
|
|
445
|
-
g.paddleWidth = l.paddleWidth;
|
|
446
|
-
if (g.paddle && g.layout === l) setPaddleWidth(g.world, l, g.paddle, g.paddleWidth, true);
|
|
447
|
-
});
|
|
448
|
-
} else if (type === PowerUpType.MULTI_BALL) {
|
|
449
|
-
const base = g.balls[0];
|
|
450
|
-
if (base && g.balls.length < MAX_BALLS) {
|
|
451
|
-
const speed = Math.hypot(base.vx, base.vy) * 0.7;
|
|
452
|
-
for (const vx of [-speed, speed]) g.balls.push({ x: base.x, y: base.y, vx, vy: -speed, view: spawnBall(g.world, l, base.x, base.y, g.colors) });
|
|
453
|
-
}
|
|
454
|
-
} else {
|
|
455
|
-
g.world.scoreboard.setLives(Math.min(g.lives + 1, LIVES));
|
|
456
|
-
g.onLives(g.lives);
|
|
457
|
-
}
|
|
458
|
-
if (g.paddle) bumpPaddle(g.world, g.paddle, 1.4);
|
|
459
|
-
}
|