@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.
Files changed (552) hide show
  1. package/lib/module/games/arrows/Arrows.js +1 -1
  2. package/lib/module/games/arrows/ArrowsScene.js +1 -1
  3. package/lib/module/games/balloon-blaster/BalloonBlaster.js +1 -1
  4. package/lib/module/games/balloon-blaster/BalloonBlasterScene.js +1 -1
  5. package/lib/module/games/bike-racing/BikeMeshes.js +1 -1
  6. package/lib/module/games/bike-racing/BikeRacing.js +1 -1
  7. package/lib/module/games/bike-racing/BikeRacingConstants.js +1 -1
  8. package/lib/module/games/bike-racing/BikeRacingScene.js +1 -1
  9. package/lib/module/games/block-blast/BlockBlast.js +1 -1
  10. package/lib/module/games/block-blast/BlockBlastScene.js +1 -1
  11. package/lib/module/games/block-breaker/BlockBreaker.js +1 -1
  12. package/lib/module/games/block-breaker/BlockBreakerScene.js +1 -1
  13. package/lib/module/games/bluk/Bluk.js +1 -1
  14. package/lib/module/games/bluk/BlukScene.js +1 -1
  15. package/lib/module/games/bubble-shooter/BubbleShooter.js +1 -1
  16. package/lib/module/games/bubble-shooter/BubbleShooterScene.js +1 -1
  17. package/lib/module/games/candy-crush/CandyCrush.js +1 -1
  18. package/lib/module/games/candy-crush/CandyCrushScene.js +1 -1
  19. package/lib/module/games/car-racing/CarMeshes.js +1 -1
  20. package/lib/module/games/car-racing/CarRacing.js +1 -1
  21. package/lib/module/games/car-racing/CarRacingScene.js +1 -1
  22. package/lib/module/games/chameleon-run/ChameleonRun.js +1 -1
  23. package/lib/module/games/chameleon-run/ChameleonRunBackdrop.js +1 -1
  24. package/lib/module/games/chameleon-run/ChameleonRunMeshes.js +1 -1
  25. package/lib/module/games/checkers/Checkers.js +1 -1
  26. package/lib/module/games/checkers/CheckersScene.js +1 -1
  27. package/lib/module/games/color-switch/ColorSwitch.js +1 -1
  28. package/lib/module/games/color-switch/ColorSwitchScene.js +1 -1
  29. package/lib/module/games/colors-sort/ColorsSort.js +1 -1
  30. package/lib/module/games/colors-sort/ColorsSortScene.js +1 -1
  31. package/lib/module/games/connect-em-all/ConnectEmAll.js +1 -1
  32. package/lib/module/games/connect-em-all/ConnectEmAllScene.js +1 -1
  33. package/lib/module/games/crossy-road/CrossyRoad.js +1 -1
  34. package/lib/module/games/crossy-road/CrossyRoadMeshes.js +1 -1
  35. package/lib/module/games/crossy-road/CrossyRoadPerson.js +1 -1
  36. package/lib/module/games/dino-jump/DinoJump.js +1 -1
  37. package/lib/module/games/dino-jump/DinoJumpScene.js +1 -1
  38. package/lib/module/games/dots-and-boxes/DotsAndBoxes.js +1 -1
  39. package/lib/module/games/dots-and-boxes/DotsAndBoxesScene.js +1 -1
  40. package/lib/module/games/falling-sticks/FallingSticks.js +1 -1
  41. package/lib/module/games/falling-sticks/FallingSticksScene.js +1 -1
  42. package/lib/module/games/find-different-number/FindDifferentNumber.js +1 -1
  43. package/lib/module/games/find-different-number/FindDifferentNumberScene.js +1 -1
  44. package/lib/module/games/flappy-bird/FlappyBird.js +1 -1
  45. package/lib/module/games/flappy-bird/FlappyBirdScene.js +1 -1
  46. package/lib/module/games/fruit-merger/FruitMerger.js +1 -1
  47. package/lib/module/games/fruit-merger/FruitMergerScene.js +1 -1
  48. package/lib/module/games/fruit-ninja/FruitNinja.js +1 -1
  49. package/lib/module/games/fruit-ninja/FruitNinjaScene.js +1 -1
  50. package/lib/module/games/fruit-ninja/FruitNinjaWorld.js +1 -1
  51. package/lib/module/games/game-2048/Game2048.js +1 -1
  52. package/lib/module/games/game-2048/Game2048Scene.js +1 -1
  53. package/lib/module/games/knife-hit/KnifeHit.js +1 -1
  54. package/lib/module/games/knife-hit/KnifeHitScene.js +1 -1
  55. package/lib/module/games/ludo-king/LudoKing.js +1 -1
  56. package/lib/module/games/ludo-king/LudoKingScene.js +1 -1
  57. package/lib/module/games/maze-runner/MazeRunner.js +1 -1
  58. package/lib/module/games/maze-runner/MazeRunnerScene.js +1 -1
  59. package/lib/module/games/memory-match/MemoryMatch.js +1 -1
  60. package/lib/module/games/memory-match/MemoryMatchScene.js +1 -1
  61. package/lib/module/games/mine-sweeper/MineSweeper.js +1 -1
  62. package/lib/module/games/mine-sweeper/MineSweeperScene.js +1 -1
  63. package/lib/module/games/mob-control/MobControl.js +1 -1
  64. package/lib/module/games/mob-control/MobControlGame.js +1 -1
  65. package/lib/module/games/mob-control/MobControlMeshes.js +1 -1
  66. package/lib/module/games/mob-control/MobControlRenderer.js +1 -1
  67. package/lib/module/games/mob-control/MobControlRules.js +1 -1
  68. package/lib/module/games/mob-control/MobControlScene.js +1 -1
  69. package/lib/module/games/nuts-and-bolts/NutsAndBolts.js +1 -1
  70. package/lib/module/games/nuts-and-bolts/NutsAndBoltsScene.js +1 -1
  71. package/lib/module/games/pac-man/PacMan.js +1 -1
  72. package/lib/module/games/pac-man/PacManGame.js +1 -1
  73. package/lib/module/games/pac-man/PacManScene.js +1 -1
  74. package/lib/module/games/paper-io/PaperIo.js +1 -1
  75. package/lib/module/games/paper-io/PaperIoMeshes.js +1 -1
  76. package/lib/module/games/paper-io/PaperIoScene.js +1 -1
  77. package/lib/module/games/penguin-run/PenguinMeshes.js +1 -1
  78. package/lib/module/games/penguin-run/PenguinRun.js +1 -1
  79. package/lib/module/games/penguin-run/PenguinRunScene.js +1 -1
  80. package/lib/module/games/perfect-circle/PerfectCircle.js +1 -1
  81. package/lib/module/games/perfect-circle/PerfectCircleScene.js +1 -1
  82. package/lib/module/games/pipe-connect/PipeConnect.js +1 -1
  83. package/lib/module/games/pipe-connect/PipeConnectScene.js +1 -1
  84. package/lib/module/games/play-with-tua/PlayWithTua.js +1 -1
  85. package/lib/module/games/popit-fidget/PopitFidget.js +1 -1
  86. package/lib/module/games/popit-fidget/PopitFidgetScene.js +1 -1
  87. package/lib/module/games/reversi/Reversi.js +1 -1
  88. package/lib/module/games/reversi/ReversiScene.js +1 -1
  89. package/lib/module/games/search-grid/SearchGrid.js +1 -1
  90. package/lib/module/games/search-grid/SearchGridScene.js +1 -1
  91. package/lib/module/games/shared/BackdropCard.js +1 -1
  92. package/lib/module/games/shared/EngineBackdrop.js +1 -1
  93. package/lib/module/games/shared/EngineBlasts.js +1 -1
  94. package/lib/module/games/shared/EngineBlocks.js +1 -1
  95. package/lib/module/games/shared/EngineDice.js +1 -1
  96. package/lib/module/games/shared/EngineFruits.js +1 -1
  97. package/lib/module/games/shared/EngineGameLoader.js +1 -1
  98. package/lib/module/games/shared/EngineGameScreen.js +1 -1
  99. package/lib/module/games/shared/EngineGlyphs.js +1 -1
  100. package/lib/module/games/shared/EngineHud.js +1 -1
  101. package/lib/module/games/shared/EngineMeadow.js +1 -1
  102. package/lib/module/games/shared/EngineTouchSurface.js +1 -1
  103. package/lib/module/games/shared/GameActivity.js +1 -1
  104. package/lib/module/games/shared/GameLoading.js +1 -1
  105. package/lib/module/games/shared/GameLoadingTransition.js +1 -1
  106. package/lib/module/games/sliding-numbers/SlidingNumbers.js +1 -1
  107. package/lib/module/games/sliding-numbers/SlidingNumbersScene.js +1 -1
  108. package/lib/module/games/snake-3d/Snake3D.js +1 -1
  109. package/lib/module/games/snake-3d/Snake3DScene.js +1 -1
  110. package/lib/module/games/snakes-and-ladders/SnakesAndLadders.js +1 -1
  111. package/lib/module/games/snakes-and-ladders/SnakesAndLaddersScene.js +1 -1
  112. package/lib/module/games/space-fighter/SpaceFighter.js +1 -1
  113. package/lib/module/games/space-fighter/SpaceFighterScene.js +1 -1
  114. package/lib/module/games/spider-solitaire/SpiderSolitaire.js +1 -1
  115. package/lib/module/games/spider-solitaire/SpiderSolitaireScene.js +1 -1
  116. package/lib/module/games/stack-tower/StackTower.js +1 -1
  117. package/lib/module/games/stack-tower/StackTowerScene.js +1 -1
  118. package/lib/module/games/sudoku/Sudoku.js +1 -1
  119. package/lib/module/games/sudoku/SudokuScene.js +1 -1
  120. package/lib/module/games/tangram/Tangram.js +1 -1
  121. package/lib/module/games/tangram/TangramScene.js +1 -1
  122. package/lib/module/games/tank-1990/Tank1990.js +1 -1
  123. package/lib/module/games/tank-1990/Tank1990Scene.js +1 -1
  124. package/lib/module/games/tic-tac-toe/TicTacToe.js +1 -1
  125. package/lib/module/games/tic-tac-toe/TicTacToeScene.js +1 -1
  126. package/lib/module/games/tile-home/TileHome.js +1 -1
  127. package/lib/module/games/tile-home/TileHomeScene.js +1 -1
  128. package/lib/module/games/treasure-hunt/TreasureHunt.js +1 -1
  129. package/lib/module/games/treasure-hunt/TreasureHuntConstants.js +1 -1
  130. package/lib/module/games/treasure-hunt/TreasureHuntModel.js +1 -1
  131. package/lib/module/games/treasure-hunt/TreasureHuntScene.js +1 -1
  132. package/lib/module/games/whack-a-mole/WhackAMole.js +1 -1
  133. package/lib/module/games/whack-a-mole/WhackAMoleScene.js +1 -1
  134. package/lib/module/helpers/GameSettingsModal.js +1 -1
  135. package/lib/module/helpers/GameTheme.js +1 -1
  136. package/package.json +1 -2
  137. package/src/assets/fonts/Inter-SemiBold.ttf +0 -0
  138. package/src/assets/models/explorer/explorer.glb +0 -0
  139. package/src/assets/models/explorer/params.json +0 -51
  140. package/src/assets/models/explorer/source.json +0 -222
  141. package/src/assets/models/play-with-tua/play-with-tua.glb +0 -0
  142. package/src/assets/models/play-with-tua/sources.json +0 -141
  143. package/src/assets/sfx/balloon_pop.wav +0 -0
  144. package/src/assets/sfx/blocked.wav +0 -0
  145. package/src/assets/sfx/boing.wav +0 -0
  146. package/src/assets/sfx/bonus.wav +0 -0
  147. package/src/assets/sfx/boom.wav +0 -0
  148. package/src/assets/sfx/bump.wav +0 -0
  149. package/src/assets/sfx/cannon.wav +0 -0
  150. package/src/assets/sfx/capture.wav +0 -0
  151. package/src/assets/sfx/card_flip.wav +0 -0
  152. package/src/assets/sfx/card_place.wav +0 -0
  153. package/src/assets/sfx/catch.wav +0 -0
  154. package/src/assets/sfx/chime.wav +0 -0
  155. package/src/assets/sfx/chomp.wav +0 -0
  156. package/src/assets/sfx/chomp_alt.wav +0 -0
  157. package/src/assets/sfx/clack.wav +0 -0
  158. package/src/assets/sfx/clang.wav +0 -0
  159. package/src/assets/sfx/clash.wav +0 -0
  160. package/src/assets/sfx/click.wav +0 -0
  161. package/src/assets/sfx/coin.wav +0 -0
  162. package/src/assets/sfx/combo.wav +0 -0
  163. package/src/assets/sfx/crash.wav +0 -0
  164. package/src/assets/sfx/crunch.wav +0 -0
  165. package/src/assets/sfx/dance.wav +0 -0
  166. package/src/assets/sfx/deselect.wav +0 -0
  167. package/src/assets/sfx/dice_roll.wav +0 -0
  168. package/src/assets/sfx/die.wav +0 -0
  169. package/src/assets/sfx/draw.wav +0 -0
  170. package/src/assets/sfx/drop.wav +0 -0
  171. package/src/assets/sfx/eat.wav +0 -0
  172. package/src/assets/sfx/engine.wav +0 -0
  173. package/src/assets/sfx/error.wav +0 -0
  174. package/src/assets/sfx/flag.wav +0 -0
  175. package/src/assets/sfx/flap.wav +0 -0
  176. package/src/assets/sfx/flip_disc.wav +0 -0
  177. package/src/assets/sfx/footstep_run.wav +0 -0
  178. package/src/assets/sfx/footstep_walk.wav +0 -0
  179. package/src/assets/sfx/game_over.wav +0 -0
  180. package/src/assets/sfx/gate.wav +0 -0
  181. package/src/assets/sfx/hit.wav +0 -0
  182. package/src/assets/sfx/hop.wav +0 -0
  183. package/src/assets/sfx/hurt.wav +0 -0
  184. package/src/assets/sfx/invalid.wav +0 -0
  185. package/src/assets/sfx/jump.wav +0 -0
  186. package/src/assets/sfx/ladder.wav +0 -0
  187. package/src/assets/sfx/land.wav +0 -0
  188. package/src/assets/sfx/laugh.wav +0 -0
  189. package/src/assets/sfx/lose.wav +0 -0
  190. package/src/assets/sfx/merge.wav +0 -0
  191. package/src/assets/sfx/miss.wav +0 -0
  192. package/src/assets/sfx/nitro.wav +0 -0
  193. package/src/assets/sfx/pew.wav +0 -0
  194. package/src/assets/sfx/place.wav +0 -0
  195. package/src/assets/sfx/pling.wav +0 -0
  196. package/src/assets/sfx/point.wav +0 -0
  197. package/src/assets/sfx/pop.wav +0 -0
  198. package/src/assets/sfx/pop_soft.wav +0 -0
  199. package/src/assets/sfx/power_up.wav +0 -0
  200. package/src/assets/sfx/reveal.wav +0 -0
  201. package/src/assets/sfx/robot.wav +0 -0
  202. package/src/assets/sfx/rotate.wav +0 -0
  203. package/src/assets/sfx/run_steps.wav +0 -0
  204. package/src/assets/sfx/select.wav +0 -0
  205. package/src/assets/sfx/shuffle.wav +0 -0
  206. package/src/assets/sfx/six.wav +0 -0
  207. package/src/assets/sfx/slice.wav +0 -0
  208. package/src/assets/sfx/slide.wav +0 -0
  209. package/src/assets/sfx/snake.wav +0 -0
  210. package/src/assets/sfx/snap.wav +0 -0
  211. package/src/assets/sfx/splash.wav +0 -0
  212. package/src/assets/sfx/star.wav +0 -0
  213. package/src/assets/sfx/start.wav +0 -0
  214. package/src/assets/sfx/swoosh.wav +0 -0
  215. package/src/assets/sfx/tap.wav +0 -0
  216. package/src/assets/sfx/thud.wav +0 -0
  217. package/src/assets/sfx/thunk.wav +0 -0
  218. package/src/assets/sfx/tick.wav +0 -0
  219. package/src/assets/sfx/time_up.wav +0 -0
  220. package/src/assets/sfx/tock.wav +0 -0
  221. package/src/assets/sfx/walk_steps.wav +0 -0
  222. package/src/assets/sfx/warning.wav +0 -0
  223. package/src/assets/sfx/whack.wav +0 -0
  224. package/src/assets/sfx/whoosh.wav +0 -0
  225. package/src/assets/sfx/win.wav +0 -0
  226. package/src/assets/sfx/zap.wav +0 -0
  227. package/src/assets/textures/ad_bolt.png +0 -0
  228. package/src/assets/textures/ad_bubbles.png +0 -0
  229. package/src/assets/textures/ad_chevrons.png +0 -0
  230. package/src/assets/textures/asphalt.png +0 -0
  231. package/src/assets/textures/bark.jpg +0 -0
  232. package/src/assets/textures/explorer-atlas.png +0 -0
  233. package/src/assets/textures/facade.png +0 -0
  234. package/src/assets/textures/grass.png +0 -0
  235. package/src/assets/textures/leaves.png +0 -0
  236. package/src/assets/textures/limestone.jpg +0 -0
  237. package/src/assets/textures/meadow.jpg +0 -0
  238. package/src/assets/textures/nature-sources.json +0 -87
  239. package/src/assets/textures/pine.png +0 -0
  240. package/src/assets/textures/river.jpg +0 -0
  241. package/src/assets/textures/soft_glow.png +0 -0
  242. package/src/games/arrows/Arrows.tsx +0 -69
  243. package/src/games/arrows/ArrowsConstants.ts +0 -107
  244. package/src/games/arrows/ArrowsGame.ts +0 -735
  245. package/src/games/arrows/ArrowsScene.ts +0 -395
  246. package/src/games/balloon-blaster/BalloonBlaster.tsx +0 -75
  247. package/src/games/balloon-blaster/BalloonBlasterConstants.ts +0 -79
  248. package/src/games/balloon-blaster/BalloonBlasterGame.ts +0 -287
  249. package/src/games/balloon-blaster/BalloonBlasterPhysics.ts +0 -95
  250. package/src/games/balloon-blaster/BalloonBlasterScene.ts +0 -225
  251. package/src/games/bike-racing/BikeMeshes.ts +0 -273
  252. package/src/games/bike-racing/BikeRacing.tsx +0 -211
  253. package/src/games/bike-racing/BikeRacingConstants.ts +0 -103
  254. package/src/games/bike-racing/BikeRacingGame.ts +0 -557
  255. package/src/games/bike-racing/BikeRacingScene.ts +0 -119
  256. package/src/games/block-blast/BlockBlast.tsx +0 -73
  257. package/src/games/block-blast/BlockBlastConstants.ts +0 -179
  258. package/src/games/block-blast/BlockBlastGame.ts +0 -471
  259. package/src/games/block-blast/BlockBlastScene.ts +0 -156
  260. package/src/games/block-breaker/BlockBreaker.tsx +0 -79
  261. package/src/games/block-breaker/BlockBreakerConstants.ts +0 -139
  262. package/src/games/block-breaker/BlockBreakerGame.ts +0 -459
  263. package/src/games/block-breaker/BlockBreakerScene.ts +0 -257
  264. package/src/games/bluk/Bluk.tsx +0 -82
  265. package/src/games/bluk/BlukConstants.ts +0 -121
  266. package/src/games/bluk/BlukGame.ts +0 -323
  267. package/src/games/bluk/BlukRules.ts +0 -154
  268. package/src/games/bluk/BlukScene.ts +0 -514
  269. package/src/games/bubble-shooter/BubbleShooter.tsx +0 -76
  270. package/src/games/bubble-shooter/BubbleShooterConstants.ts +0 -103
  271. package/src/games/bubble-shooter/BubbleShooterGame.ts +0 -459
  272. package/src/games/bubble-shooter/BubbleShooterScene.ts +0 -158
  273. package/src/games/candy-crush/CandyCrush.tsx +0 -77
  274. package/src/games/candy-crush/CandyCrushConstants.ts +0 -94
  275. package/src/games/candy-crush/CandyCrushGame.ts +0 -477
  276. package/src/games/candy-crush/CandyCrushScene.ts +0 -209
  277. package/src/games/car-racing/CarMeshes.ts +0 -440
  278. package/src/games/car-racing/CarRacing.tsx +0 -211
  279. package/src/games/car-racing/CarRacingConstants.ts +0 -167
  280. package/src/games/car-racing/CarRacingFacade.ts +0 -40
  281. package/src/games/car-racing/CarRacingGame.ts +0 -539
  282. package/src/games/car-racing/CarRacingScene.ts +0 -1026
  283. package/src/games/car-racing/CarRacingScenery.ts +0 -265
  284. package/src/games/chameleon-run/ChameleonRun.tsx +0 -96
  285. package/src/games/chameleon-run/ChameleonRunBackdrop.ts +0 -186
  286. package/src/games/chameleon-run/ChameleonRunConstants.ts +0 -47
  287. package/src/games/chameleon-run/ChameleonRunGame.ts +0 -309
  288. package/src/games/chameleon-run/ChameleonRunMeshes.ts +0 -305
  289. package/src/games/chameleon-run/ChameleonRunRules.ts +0 -252
  290. package/src/games/chameleon-run/ChameleonRunScene.ts +0 -310
  291. package/src/games/checkers/Checkers.tsx +0 -83
  292. package/src/games/checkers/CheckersAI.ts +0 -255
  293. package/src/games/checkers/CheckersConstants.ts +0 -68
  294. package/src/games/checkers/CheckersGame.ts +0 -322
  295. package/src/games/checkers/CheckersRules.ts +0 -167
  296. package/src/games/checkers/CheckersScene.ts +0 -308
  297. package/src/games/color-switch/ColorSwitch.tsx +0 -75
  298. package/src/games/color-switch/ColorSwitchConstants.ts +0 -61
  299. package/src/games/color-switch/ColorSwitchGame.ts +0 -329
  300. package/src/games/color-switch/ColorSwitchScene.ts +0 -220
  301. package/src/games/colors-sort/ColorsSort.tsx +0 -82
  302. package/src/games/colors-sort/ColorsSortConstants.ts +0 -119
  303. package/src/games/colors-sort/ColorsSortGame.ts +0 -246
  304. package/src/games/colors-sort/ColorsSortScene.ts +0 -315
  305. package/src/games/connect-em-all/ConnectEmAll.tsx +0 -70
  306. package/src/games/connect-em-all/ConnectEmAllConstants.ts +0 -77
  307. package/src/games/connect-em-all/ConnectEmAllGame.ts +0 -401
  308. package/src/games/connect-em-all/ConnectEmAllScene.ts +0 -235
  309. package/src/games/crossy-road/CrossyRoad.tsx +0 -74
  310. package/src/games/crossy-road/CrossyRoadCamera.ts +0 -59
  311. package/src/games/crossy-road/CrossyRoadConstants.ts +0 -132
  312. package/src/games/crossy-road/CrossyRoadGame.ts +0 -293
  313. package/src/games/crossy-road/CrossyRoadMeshes.ts +0 -195
  314. package/src/games/crossy-road/CrossyRoadPerson.ts +0 -198
  315. package/src/games/crossy-road/CrossyRoadRules.ts +0 -99
  316. package/src/games/crossy-road/CrossyRoadScene.ts +0 -355
  317. package/src/games/dino-jump/DinoJump.tsx +0 -77
  318. package/src/games/dino-jump/DinoJumpConstants.ts +0 -80
  319. package/src/games/dino-jump/DinoJumpGame.ts +0 -344
  320. package/src/games/dino-jump/DinoJumpScene.ts +0 -686
  321. package/src/games/dots-and-boxes/DotsAndBoxes.tsx +0 -83
  322. package/src/games/dots-and-boxes/DotsAndBoxesConstants.ts +0 -77
  323. package/src/games/dots-and-boxes/DotsAndBoxesGame.ts +0 -271
  324. package/src/games/dots-and-boxes/DotsAndBoxesScene.ts +0 -249
  325. package/src/games/falling-sticks/FallingSticks.tsx +0 -72
  326. package/src/games/falling-sticks/FallingSticksConstants.ts +0 -62
  327. package/src/games/falling-sticks/FallingSticksGame.ts +0 -220
  328. package/src/games/falling-sticks/FallingSticksRules.ts +0 -145
  329. package/src/games/falling-sticks/FallingSticksScene.ts +0 -245
  330. package/src/games/find-different-number/FindDifferentNumber.tsx +0 -74
  331. package/src/games/find-different-number/FindDifferentNumberConstants.ts +0 -74
  332. package/src/games/find-different-number/FindDifferentNumberGame.ts +0 -174
  333. package/src/games/find-different-number/FindDifferentNumberRules.ts +0 -43
  334. package/src/games/find-different-number/FindDifferentNumberScene.ts +0 -193
  335. package/src/games/flappy-bird/FlappyBird.tsx +0 -73
  336. package/src/games/flappy-bird/FlappyBirdConstants.ts +0 -95
  337. package/src/games/flappy-bird/FlappyBirdGame.ts +0 -375
  338. package/src/games/flappy-bird/FlappyBirdScene.ts +0 -630
  339. package/src/games/fruit-merger/FruitMerger.tsx +0 -73
  340. package/src/games/fruit-merger/FruitMergerConstants.ts +0 -102
  341. package/src/games/fruit-merger/FruitMergerGame.ts +0 -285
  342. package/src/games/fruit-merger/FruitMergerRules.ts +0 -286
  343. package/src/games/fruit-merger/FruitMergerScene.ts +0 -498
  344. package/src/games/fruit-ninja/FruitNinja.tsx +0 -129
  345. package/src/games/fruit-ninja/FruitNinjaConstants.ts +0 -107
  346. package/src/games/fruit-ninja/FruitNinjaGame.ts +0 -391
  347. package/src/games/fruit-ninja/FruitNinjaScene.ts +0 -319
  348. package/src/games/fruit-ninja/FruitNinjaWorld.ts +0 -17
  349. package/src/games/game-2048/Game2048.tsx +0 -84
  350. package/src/games/game-2048/Game2048Constants.ts +0 -68
  351. package/src/games/game-2048/Game2048Game.ts +0 -181
  352. package/src/games/game-2048/Game2048Rules.ts +0 -101
  353. package/src/games/game-2048/Game2048Scene.ts +0 -206
  354. package/src/games/knife-hit/KnifeHit.tsx +0 -78
  355. package/src/games/knife-hit/KnifeHitConstants.ts +0 -89
  356. package/src/games/knife-hit/KnifeHitGame.ts +0 -264
  357. package/src/games/knife-hit/KnifeHitScene.ts +0 -360
  358. package/src/games/ludo-king/LudoKing.tsx +0 -86
  359. package/src/games/ludo-king/LudoKingConstants.ts +0 -212
  360. package/src/games/ludo-king/LudoKingGame.ts +0 -326
  361. package/src/games/ludo-king/LudoKingRules.ts +0 -143
  362. package/src/games/ludo-king/LudoKingScene.ts +0 -397
  363. package/src/games/maze-runner/MazeRunner.tsx +0 -88
  364. package/src/games/maze-runner/MazeRunnerConstants.ts +0 -65
  365. package/src/games/maze-runner/MazeRunnerGame.ts +0 -176
  366. package/src/games/maze-runner/MazeRunnerRules.ts +0 -161
  367. package/src/games/maze-runner/MazeRunnerScene.ts +0 -245
  368. package/src/games/memory-match/MemoryMatch.tsx +0 -77
  369. package/src/games/memory-match/MemoryMatchConstants.ts +0 -105
  370. package/src/games/memory-match/MemoryMatchGame.ts +0 -222
  371. package/src/games/memory-match/MemoryMatchRules.ts +0 -38
  372. package/src/games/memory-match/MemoryMatchScene.ts +0 -268
  373. package/src/games/mine-sweeper/MineSweeper.tsx +0 -77
  374. package/src/games/mine-sweeper/MineSweeperConstants.ts +0 -94
  375. package/src/games/mine-sweeper/MineSweeperGame.ts +0 -234
  376. package/src/games/mine-sweeper/MineSweeperRules.ts +0 -67
  377. package/src/games/mine-sweeper/MineSweeperScene.ts +0 -262
  378. package/src/games/mob-control/MobControl.tsx +0 -73
  379. package/src/games/mob-control/MobControlConstants.ts +0 -106
  380. package/src/games/mob-control/MobControlGame.ts +0 -176
  381. package/src/games/mob-control/MobControlMeshes.ts +0 -85
  382. package/src/games/mob-control/MobControlRenderer.ts +0 -108
  383. package/src/games/mob-control/MobControlRules.ts +0 -522
  384. package/src/games/mob-control/MobControlScene.ts +0 -399
  385. package/src/games/number-search/NumberSearch.tsx +0 -18
  386. package/src/games/number-search/NumberSearchNumbers.ts +0 -623
  387. package/src/games/nuts-and-bolts/NutsAndBolts.tsx +0 -85
  388. package/src/games/nuts-and-bolts/NutsAndBoltsConstants.ts +0 -75
  389. package/src/games/nuts-and-bolts/NutsAndBoltsGame.ts +0 -298
  390. package/src/games/nuts-and-bolts/NutsAndBoltsRules.ts +0 -474
  391. package/src/games/nuts-and-bolts/NutsAndBoltsScene.ts +0 -498
  392. package/src/games/pac-man/PacMan.tsx +0 -86
  393. package/src/games/pac-man/PacManConstants.ts +0 -169
  394. package/src/games/pac-man/PacManGame.ts +0 -406
  395. package/src/games/pac-man/PacManRules.ts +0 -255
  396. package/src/games/pac-man/PacManScene.ts +0 -387
  397. package/src/games/paper-io/PaperIo.tsx +0 -91
  398. package/src/games/paper-io/PaperIoConstants.ts +0 -86
  399. package/src/games/paper-io/PaperIoGame.ts +0 -193
  400. package/src/games/paper-io/PaperIoMeshes.ts +0 -233
  401. package/src/games/paper-io/PaperIoRules.ts +0 -315
  402. package/src/games/paper-io/PaperIoScene.ts +0 -310
  403. package/src/games/penguin-run/PenguinMeshes.ts +0 -269
  404. package/src/games/penguin-run/PenguinModel.ts +0 -712
  405. package/src/games/penguin-run/PenguinRun.tsx +0 -77
  406. package/src/games/penguin-run/PenguinRunConstants.ts +0 -69
  407. package/src/games/penguin-run/PenguinRunGame.ts +0 -406
  408. package/src/games/penguin-run/PenguinRunScene.ts +0 -949
  409. package/src/games/perfect-circle/PerfectCircle.tsx +0 -74
  410. package/src/games/perfect-circle/PerfectCircleConstants.ts +0 -52
  411. package/src/games/perfect-circle/PerfectCircleGame.ts +0 -153
  412. package/src/games/perfect-circle/PerfectCircleRules.ts +0 -111
  413. package/src/games/perfect-circle/PerfectCircleScene.ts +0 -176
  414. package/src/games/pipe-connect/PipeConnect.tsx +0 -69
  415. package/src/games/pipe-connect/PipeConnectConstants.ts +0 -101
  416. package/src/games/pipe-connect/PipeConnectGame.ts +0 -179
  417. package/src/games/pipe-connect/PipeConnectRules.ts +0 -326
  418. package/src/games/pipe-connect/PipeConnectScene.ts +0 -271
  419. package/src/games/play-with-tua/PlayWithTua.tsx +0 -123
  420. package/src/games/play-with-tua/PlayWithTuaConstants.ts +0 -70
  421. package/src/games/play-with-tua/PlayWithTuaGame.ts +0 -167
  422. package/src/games/play-with-tua/PlayWithTuaModel.ts +0 -42
  423. package/src/games/play-with-tua/PlayWithTuaScene.ts +0 -36
  424. package/src/games/popit-fidget/PopitFidget.tsx +0 -72
  425. package/src/games/popit-fidget/PopitFidgetConstants.ts +0 -71
  426. package/src/games/popit-fidget/PopitFidgetGame.ts +0 -148
  427. package/src/games/popit-fidget/PopitFidgetScene.ts +0 -242
  428. package/src/games/reversi/Reversi.tsx +0 -94
  429. package/src/games/reversi/ReversiConstants.ts +0 -67
  430. package/src/games/reversi/ReversiGame.ts +0 -266
  431. package/src/games/reversi/ReversiRules.ts +0 -176
  432. package/src/games/reversi/ReversiScene.ts +0 -240
  433. package/src/games/search-grid/SearchGrid.tsx +0 -92
  434. package/src/games/search-grid/SearchGridConstants.ts +0 -178
  435. package/src/games/search-grid/SearchGridGame.ts +0 -209
  436. package/src/games/search-grid/SearchGridScene.ts +0 -301
  437. package/src/games/shared/BackdropCard.tsx +0 -54
  438. package/src/games/shared/EngineBackdrop.ts +0 -300
  439. package/src/games/shared/EngineBlasts.ts +0 -136
  440. package/src/games/shared/EngineBlocks.ts +0 -91
  441. package/src/games/shared/EngineControlText.ts +0 -17
  442. package/src/games/shared/EngineDice.ts +0 -250
  443. package/src/games/shared/EngineFootprint.ts +0 -35
  444. package/src/games/shared/EngineFruits.ts +0 -1435
  445. package/src/games/shared/EngineGameLoader.tsx +0 -88
  446. package/src/games/shared/EngineGameScreen.tsx +0 -325
  447. package/src/games/shared/EngineGameWidth.ts +0 -3
  448. package/src/games/shared/EngineGameWidth.web.ts +0 -3
  449. package/src/games/shared/EngineGlyphs.ts +0 -178
  450. package/src/games/shared/EngineHud.ts +0 -815
  451. package/src/games/shared/EngineLoading.ts +0 -477
  452. package/src/games/shared/EngineMeadow.ts +0 -725
  453. package/src/games/shared/EngineMeshCache.ts +0 -15
  454. package/src/games/shared/EngineMeshes.ts +0 -10
  455. package/src/games/shared/EngineRacingChase.ts +0 -21
  456. package/src/games/shared/EngineRacingHandling.ts +0 -48
  457. package/src/games/shared/EngineReadyContext.ts +0 -4
  458. package/src/games/shared/EngineTilt.ts +0 -44
  459. package/src/games/shared/EngineTouchSurface.tsx +0 -103
  460. package/src/games/shared/EngineUtils.ts +0 -52
  461. package/src/games/shared/GameActivity.ts +0 -13
  462. package/src/games/shared/GameLoading.tsx +0 -202
  463. package/src/games/shared/GameLoadingTransition.tsx +0 -61
  464. package/src/games/shared/ProceduralCacheVersion.ts +0 -2
  465. package/src/games/shared/useEngineGame.ts +0 -240
  466. package/src/games/shared/useGameResource.ts +0 -21
  467. package/src/games/shared/useLiveState.ts +0 -58
  468. package/src/games/sliding-numbers/SlidingNumbers.tsx +0 -71
  469. package/src/games/sliding-numbers/SlidingNumbersConstants.ts +0 -65
  470. package/src/games/sliding-numbers/SlidingNumbersGame.ts +0 -192
  471. package/src/games/sliding-numbers/SlidingNumbersRules.ts +0 -79
  472. package/src/games/sliding-numbers/SlidingNumbersScene.ts +0 -193
  473. package/src/games/snake-3d/Snake3D.tsx +0 -76
  474. package/src/games/snake-3d/Snake3DConstants.ts +0 -61
  475. package/src/games/snake-3d/Snake3DGame.ts +0 -192
  476. package/src/games/snake-3d/Snake3DMotion.ts +0 -22
  477. package/src/games/snake-3d/Snake3DRules.ts +0 -116
  478. package/src/games/snake-3d/Snake3DScene.ts +0 -322
  479. package/src/games/snakes-and-ladders/SnakesAndLadders.tsx +0 -87
  480. package/src/games/snakes-and-ladders/SnakesAndLaddersConstants.ts +0 -136
  481. package/src/games/snakes-and-ladders/SnakesAndLaddersGame.ts +0 -310
  482. package/src/games/snakes-and-ladders/SnakesAndLaddersScene.ts +0 -515
  483. package/src/games/space-fighter/SpaceFighter.tsx +0 -74
  484. package/src/games/space-fighter/SpaceFighterConstants.ts +0 -86
  485. package/src/games/space-fighter/SpaceFighterGame.ts +0 -292
  486. package/src/games/space-fighter/SpaceFighterScene.ts +0 -550
  487. package/src/games/spider-solitaire/SpiderSolitaire.tsx +0 -80
  488. package/src/games/spider-solitaire/SpiderSolitaireConstants.ts +0 -107
  489. package/src/games/spider-solitaire/SpiderSolitaireGame.ts +0 -387
  490. package/src/games/spider-solitaire/SpiderSolitaireRules.ts +0 -123
  491. package/src/games/spider-solitaire/SpiderSolitaireScene.ts +0 -352
  492. package/src/games/stack-tower/StackTower.tsx +0 -76
  493. package/src/games/stack-tower/StackTowerConstants.ts +0 -74
  494. package/src/games/stack-tower/StackTowerGame.ts +0 -236
  495. package/src/games/stack-tower/StackTowerScene.ts +0 -186
  496. package/src/games/sudoku/Sudoku.tsx +0 -73
  497. package/src/games/sudoku/SudokuConstants.ts +0 -127
  498. package/src/games/sudoku/SudokuGame.ts +0 -250
  499. package/src/games/sudoku/SudokuRules.ts +0 -125
  500. package/src/games/sudoku/SudokuScene.ts +0 -304
  501. package/src/games/tangram/Tangram.tsx +0 -79
  502. package/src/games/tangram/TangramConstants.ts +0 -64
  503. package/src/games/tangram/TangramGame.ts +0 -356
  504. package/src/games/tangram/TangramRules.ts +0 -409
  505. package/src/games/tangram/TangramScene.ts +0 -203
  506. package/src/games/tank-1990/Tank1990.tsx +0 -78
  507. package/src/games/tank-1990/Tank1990Constants.ts +0 -81
  508. package/src/games/tank-1990/Tank1990Game.ts +0 -331
  509. package/src/games/tank-1990/Tank1990Rules.ts +0 -390
  510. package/src/games/tank-1990/Tank1990Scene.ts +0 -434
  511. package/src/games/tic-tac-toe/TicTacToe.tsx +0 -98
  512. package/src/games/tic-tac-toe/TicTacToeConstants.ts +0 -69
  513. package/src/games/tic-tac-toe/TicTacToeGame.ts +0 -200
  514. package/src/games/tic-tac-toe/TicTacToeRules.ts +0 -103
  515. package/src/games/tic-tac-toe/TicTacToeScene.ts +0 -245
  516. package/src/games/tile-home/TileHome.tsx +0 -92
  517. package/src/games/tile-home/TileHomeConstants.ts +0 -139
  518. package/src/games/tile-home/TileHomeGame.ts +0 -435
  519. package/src/games/tile-home/TileHomeScene.ts +0 -154
  520. package/src/games/treasure-hunt/TreasureHunt.tsx +0 -206
  521. package/src/games/treasure-hunt/TreasureHuntConstants.ts +0 -266
  522. package/src/games/treasure-hunt/TreasureHuntControls.ts +0 -280
  523. package/src/games/treasure-hunt/TreasureHuntGame.ts +0 -402
  524. package/src/games/treasure-hunt/TreasureHuntMeshes.ts +0 -422
  525. package/src/games/treasure-hunt/TreasureHuntModel.ts +0 -506
  526. package/src/games/treasure-hunt/TreasureHuntRules.ts +0 -1210
  527. package/src/games/treasure-hunt/TreasureHuntScene.ts +0 -586
  528. package/src/games/whack-a-mole/WhackAMole.tsx +0 -79
  529. package/src/games/whack-a-mole/WhackAMoleConstants.ts +0 -94
  530. package/src/games/whack-a-mole/WhackAMoleGame.ts +0 -233
  531. package/src/games/whack-a-mole/WhackAMoleScene.ts +0 -349
  532. package/src/games/word-search/WordSearch.tsx +0 -18
  533. package/src/games/word-search/WordSearchWords.ts +0 -1642
  534. package/src/helpers/GamePatternData.ts +0 -120
  535. package/src/helpers/GameSettingsModal.tsx +0 -384
  536. package/src/helpers/GameTheme.tsx +0 -37
  537. package/src/helpers/IconPaths.ts +0 -6
  538. package/src/helpers/index.ts +0 -2
  539. package/src/index.tsx +0 -60
  540. package/src/services/GameAssetLoader.ts +0 -111
  541. package/src/services/GameAssets.ts +0 -149
  542. package/src/services/GameLoaders.ts +0 -93
  543. package/src/services/GamesConstants.ts +0 -193
  544. package/src/services/GamesMetadata.ts +0 -711
  545. package/src/services/GamesService.ts +0 -116
  546. package/src/services/HapticsService.ts +0 -48
  547. package/src/services/ScoringService.ts +0 -19
  548. package/src/services/SfxSources.ts +0 -81
  549. package/src/services/SoundsService.ts +0 -582
  550. package/src/services/ThemeService.ts +0 -281
  551. package/src/services/UtilsService.ts +0 -134
  552. package/src/services/index.ts +0 -6
@@ -1,630 +0,0 @@
1
- // Everything Flappy Bird flies through, in front of its 3D meadow (EngineMeadow). Positions come in
2
- // screen points (y down) and land on the play plane ahead of the camera, where the original game drew them;
3
- // sizes are scaled to metres there. The bird is a chubby 3D bird (egg body, belly, cheek, eye, beak,
4
- // crest, tail, feet) with two flapping wings, a blinking eyelid and a squash on every flap; pipes are glossy green tubes with lipped caps; the walls are
5
- // laid brick by brick over mortar. Each is a root turned to face the camera, so its parts are placed in
6
- // screen-like local axes. Every part is a shared mesh: mesh ids are app-wide and limited.
7
- import {
8
- type Color,
9
- effects,
10
- type Entity,
11
- extrude,
12
- type Geometry,
13
- lathe,
14
- merge,
15
- type Model,
16
- type MutableQuat,
17
- Path,
18
- quat,
19
- recolor,
20
- shapeGeometry,
21
- type TransformBatch,
22
- tube,
23
- type Vec3,
24
- type World
25
- } from '@nayan-ui/engine';
26
- import { at, facing, pointSize, type View3D } from '../shared/EngineMeadow';
27
- import { cacheGameAsset, createGameMesh as createShape } from '../shared/EngineMeshes';
28
- import { toColor } from '../shared/EngineUtils';
29
- import { BIRD_SIZE, BRICK_HEIGHT, BRICK_WIDTH, type Layout, PIPE_WIDTH } from './FlappyBirdConstants';
30
-
31
- // ── Meshes ────────────────────────────────────────────────────────────
32
-
33
- const meshes = new Map<string, Model>();
34
- const cached = (key: string, build: () => Model) => {
35
- let m = meshes.get(key);
36
- if (!m) {
37
- m = cacheGameAsset('flappy-bird/FlappyBirdScene:' + key, build);
38
- meshes.set(key, m);
39
- }
40
- return m;
41
- };
42
- type RGB = [number, number, number];
43
- const rgb = (css: string): RGB => {
44
- const [r, g, b] = toColor(css);
45
- return [r, g, b];
46
- };
47
- const mix = (a: RGB, b: RGB, t: number): RGB => [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
48
- const sphere = () => shapeGeometry('sphere');
49
- /** A cone along +x (the beak), from a lathe around y turned a quarter. */
50
- const beakPart = (length: number, radius: number, color: RGB, position: Vec3, tilt: number) => ({
51
- geometry: lathe(
52
- [
53
- [radius, 0],
54
- [radius * 0.6, length * 0.5],
55
- [0.001, length]
56
- ],
57
- { segments: 12, color }
58
- ),
59
- position,
60
- rotation: quat.multiply(quat.z(tilt), quat.z(-Math.PI / 2))
61
- });
62
-
63
- const clamp01 = (x: number) => Math.max(0, Math.min(1, x));
64
- const smoothstep = (x: number) => {
65
- const t = clamp01(x);
66
- return t * t * (3 - 2 * t);
67
- };
68
- const BODY_TOP = rgb('#FFE14D');
69
- const BODY_BOTTOM = rgb('#FFAA1F');
70
- const BELLY = rgb('#FFF4CC');
71
- const BLUSH = rgb('#FF8C9A');
72
- const FEATHER = rgb('#F08A12');
73
-
74
- /** A tapered feather along `points`, flattened into a blade. */
75
- const feather = (points: Vec3[], radius: number, color: RGB) =>
76
- tube(points, {
77
- radius: (t) => radius * Math.max(0.08, 1 - t * 0.85),
78
- shape: (a) => 0.35 + 0.65 * Math.abs(Math.cos(a * Math.PI * 2)),
79
- sides: 8,
80
- smoothness: 5,
81
- color: [...color, 1] as Color
82
- });
83
-
84
- /**
85
- * The bird's body (without its wings, eyelid or squash), one unit long, facing +x (right), its front
86
- * toward +z (the camera): a chubby egg, yellow fading to orange below, a cream belly and pink cheek,
87
- * a big eye, a two-part beak, curling crest feathers, a fanned tail and tucked feet.
88
- */
89
- const birdMesh = () =>
90
- cached('fb-bird', () => {
91
- // The egg: round at the head (+x), a little narrower at the tail
92
- const profile: [number, number][] = Array.from({ length: 17 }, (_, i) => {
93
- const t = i / 16;
94
- return [Math.max(0.001, 0.47 * Math.sin(Math.PI * t) ** 0.75 * (1 - 0.16 * t)), 0.5 - t];
95
- });
96
- const egg = merge([{ geometry: lathe(profile, { segments: 28 }), rotation: quat.z(-Math.PI / 2), scale: [1, 0.92, 0.86] }]);
97
- const body = recolor(egg, ({ position: [x, y, z] }) => {
98
- let c = mix(BODY_BOTTOM, BODY_TOP, clamp01(0.5 + y * 1.3 + x * 0.25));
99
- // Cream belly on the front and underside
100
- c = mix(c, BELLY, smoothstep((0.06 - y) * 4) * smoothstep(z * 3 + 0.3) * smoothstep((x + 0.32) * 3) * 0.95);
101
- // A pink cheek under the eye
102
- c = mix(c, BLUSH, smoothstep(1 - Math.hypot(x - 0.2, y + 0.06, z - 0.33) / 0.11) * 0.8);
103
- return [...c, 1] as Color;
104
- });
105
- return createShape(
106
- merge([
107
- { geometry: body },
108
- // Eye: white, a black pupil looking ahead, a glint
109
- { geometry: sphere(), position: [0.22, 0.15, 0.26], scale: 0.32, color: [1, 1, 1] },
110
- { geometry: sphere(), position: [0.3, 0.16, 0.38], scale: 0.15, color: rgb('#151515') },
111
- { geometry: sphere(), position: [0.33, 0.2, 0.445], scale: 0.05, color: [1, 1, 1] },
112
- // Beak: upper and lower halves
113
- beakPart(0.3, 0.1, rgb('#FF7B3A'), [0.4, 0.0, 0.06], 0.12),
114
- beakPart(0.24, 0.08, rgb('#D9531A'), [0.39, -0.07, 0.06], -0.2),
115
- // Crest: three curling feathers
116
- {
117
- geometry: feather(
118
- [
119
- [0.02, 0.36, 0],
120
- [0.0, 0.52, 0],
121
- [-0.1, 0.6, 0]
122
- ],
123
- 0.07,
124
- rgb('#FF9500')
125
- )
126
- },
127
- {
128
- geometry: feather(
129
- [
130
- [0.1, 0.36, 0.02],
131
- [0.12, 0.5, 0.02],
132
- [0.06, 0.6, 0.02]
133
- ],
134
- 0.06,
135
- rgb('#FFB300')
136
- )
137
- },
138
- {
139
- geometry: feather(
140
- [
141
- [-0.06, 0.34, -0.02],
142
- [-0.14, 0.46, -0.02],
143
- [-0.24, 0.5, -0.02]
144
- ],
145
- 0.055,
146
- FEATHER
147
- )
148
- },
149
- // Tail: three broad, round-tipped feathers fanned back
150
- ...[0.2, 0.02, -0.16].map((tilt, i) => ({
151
- geometry: tube(
152
- [
153
- [-0.34, 0.02, 0],
154
- [-0.52, 0.04 + tilt * 0.6, 0],
155
- [-0.68, 0.06 + tilt, 0]
156
- ],
157
- {
158
- radius: (t) => 0.13 * (0.55 + 0.45 * Math.sin(Math.PI * (0.25 + t * 0.6))),
159
- shape: (a) => 0.45 + 0.55 * Math.abs(Math.cos(a * Math.PI * 2)),
160
- sides: 10,
161
- smoothness: 5,
162
- color: [...mix(FEATHER, rgb('#C2600A'), i * 0.35), 1] as Color
163
- }
164
- )
165
- })),
166
- // Feet tucked under
167
- ...[0.12, -0.12].map((z) => ({
168
- geometry: feather(
169
- [
170
- [0.02, -0.36, z],
171
- [-0.08, -0.46, z],
172
- [-0.2, -0.48, z]
173
- ],
174
- 0.035,
175
- rgb('#FF7B3A')
176
- )
177
- }))
178
- ]),
179
- { center: false, shine: 0.35 }
180
- );
181
- });
182
-
183
- /** A wing, pivoting at its root (the origin) and reaching back (-x): a rounded feather paddle with a scalloped trailing edge. */
184
- const wingMesh = (far: boolean) =>
185
- cached(`fb-wing:${far}`, () => {
186
- // Points in world-up y (the path's y runs down)
187
- const pts: [number, number][] = [
188
- [0.06, 0.06],
189
- [-0.12, 0.14],
190
- [-0.34, 0.12],
191
- [-0.56, 0.02],
192
- [-0.5, -0.04],
193
- [-0.55, -0.09],
194
- [-0.44, -0.11],
195
- [-0.47, -0.17],
196
- [-0.34, -0.17],
197
- [-0.12, -0.12],
198
- [0.06, -0.05]
199
- ];
200
- const path = new Path().moveTo(pts[0]![0], -pts[0]![1]);
201
- for (const [x, y] of pts.slice(1)) path.lineTo(x, -y);
202
- path.close();
203
- const [root, tip] = far ? [rgb('#B86A08'), rgb('#D9901F')] : [rgb('#F59E0B'), rgb('#FFD35C')];
204
- return createShape(
205
- recolor(extrude(path, { depth: 0.07 }), ({ position: [x] }) => [...mix(root, tip, clamp01(-x / 0.55)), 1] as Color),
206
- { center: false, shine: 0.25 }
207
- );
208
- });
209
-
210
- /** The eyelid: a ball in the body's color over the eye, shown only while blinking. */
211
- const lidMesh = () => cached('fb-lid', () => createShape(merge([{ geometry: sphere(), color: BODY_TOP }]), { shine: 0.35 }));
212
-
213
- /** A unit pipe body: an open tube one unit across and tall, centred, with vertical shading baked in. */
214
- const pipeMesh = () =>
215
- cached('fb-pipe', () =>
216
- createShape(
217
- lathe(
218
- [
219
- [0.5, -0.5],
220
- [0.5, 0.5]
221
- ],
222
- { segments: 24, color: rgb('#4CA840') }
223
- ),
224
- { center: false, shine: 0.55 }
225
- )
226
- );
227
- /** The cap: a wider, short lipped ring, closed at the end facing the gap (+y), one unit tall, centred. */
228
- const capMesh = () =>
229
- cached('fb-cap', () =>
230
- createShape(
231
- merge([
232
- {
233
- geometry: lathe(
234
- [
235
- [0.001, 0.5],
236
- [0.5, 0.5],
237
- [0.52, 0.42],
238
- [0.52, -0.42],
239
- [0.5, -0.5]
240
- ],
241
- { segments: 24, color: rgb('#3A8A2A') }
242
- )
243
- },
244
- // A dark opening, so the pipe reads as hollow
245
- { geometry: sphere(), position: [0, 0.5, 0], scale: [0.78, 0.02, 0.78], color: rgb('#123d10') }
246
- ]),
247
- { center: false, shine: 0.6 }
248
- )
249
- );
250
-
251
- /** Bricks along a row repeat their shades every this many, so the scrolling walls can wrap seamlessly. */
252
- const SHADE_PERIOD = 12;
253
- /** A brick's shade, from its row and its column (wrapped to the period): the same brick always looks the same. */
254
- function brickShade(row: number, col: number): RGB {
255
- const c = ((col % SHADE_PERIOD) + SHADE_PERIOD) % SHADE_PERIOD;
256
- const n = Math.sin(row * 127.1 + c * 311.7) * 43758.5453;
257
- const t = n - Math.floor(n);
258
- const base = rgb('#9E5428');
259
- return t < 0.5 ? mix(rgb('#6E3412'), base, t * 2) : mix(base, rgb('#B8693A'), (t - 0.5) * 2);
260
- }
261
-
262
- /**
263
- * A wall block in its own frame: x across (centred), y running into the wall away from the play area,
264
- * z toward the camera (the back face at 0, the front at `thickness`). `w` and `h` are screen points at
265
- * `k` metres per point. A stone coping runs along the edge facing the play area; above it, bricks in
266
- * running bond, each a slightly different shade, face the front over a mortar core.
267
- */
268
- function wallGeometry(w: number, h: number, k: number, thickness: number): Geometry {
269
- const bw = BRICK_WIDTH * k;
270
- const bh = BRICK_HEIGHT * k;
271
- const width = w * k;
272
- const height = h * k;
273
- const coping = COPING * k;
274
- const relief = bh * 0.35; // how far a brick stands proud of the mortar
275
- const mortar = 0.12 * bh;
276
- const parts: { geometry: Geometry; position: Vec3; scale: Vec3; color: RGB }[] = [];
277
- const box = (x0: number, x1: number, y0: number, y1: number, z0: number, z1: number, color: RGB) =>
278
- parts.push({
279
- geometry: shapeGeometry('cube'),
280
- position: [(x0 + x1) / 2, (y0 + y1) / 2, (z0 + z1) / 2],
281
- scale: [x1 - x0, y1 - y0, z1 - z0],
282
- color
283
- });
284
- // The mortar core, the full depth of the wall (it hides the pipes' ends inside it)
285
- box(-width / 2, width / 2, coping, height, 0, thickness, rgb('#3a1d0c'));
286
- // The coping: a pale stone ledge, overhanging the face a little
287
- box(-width / 2, width / 2, 0, coping, -0.01, thickness + relief + 0.025, rgb('#c8b896'));
288
- box(-width / 2, width / 2, coping * 0.78, coping, thickness + relief + 0.005, thickness + relief + 0.03, rgb('#a9987a'));
289
- const rows = Math.ceil((height - coping) / bh);
290
- for (let r = 0; r < rows; r++) {
291
- const y0 = coping + r * bh;
292
- const y1 = Math.min(height, y0 + bh);
293
- const shift = r % 2 ? bw / 2 : 0;
294
- for (let c = 0, x = -width / 2 - shift; x < width / 2; c++, x += bw) {
295
- // Clip the end bricks to the wall's edges (they're off screen)
296
- const x0 = Math.max(x, -width / 2);
297
- const x1 = Math.min(x + bw, width / 2);
298
- if (x1 - x0 <= mortar || y1 - y0 <= mortar) continue;
299
- box(x0 + mortar / 2, x1 - mortar / 2, y0 + mortar / 2, y1 - mortar / 2, thickness - 0.01, thickness + relief, brickShade(r, c));
300
- }
301
- }
302
- return merge(parts);
303
- }
304
-
305
- // ── Placement ─────────────────────────────────────────────────────────
306
-
307
- /** Local offset (metres) of screen point (x, y) from the root's screen point, in the root's facing axes. */
308
- const local = (k: number, dx: number, dy: number, dz = 0): Vec3 => [dx * k, -dy * k, dz];
309
-
310
- // ── Walls ─────────────────────────────────────────────────────────────
311
-
312
- const CAP_HEIGHT = 26;
313
- const CAP_OVER = 5;
314
- const COPING = 12; // points
315
- /** Points the walls reach past the screen's edge (the perspective shows a little more of a near face). */
316
- const WALL_MARGIN = 160;
317
- /** Points the pipes run on into the walls, so where they meet is inside the brickwork. */
318
- const PIPE_INTO_WALL = 220;
319
-
320
- /** The bottom wall's depth: its back face just behind the pipes, its front just ahead, so a pipe passes through it. */
321
- const wallDepth = (v: View3D) => {
322
- const pipeRadius = ((PIPE_WIDTH + CAP_OVER * 2 * (PIPE_WIDTH / 60)) / 2) * pointSize(v);
323
- return { back: v.playDepth + pipeRadius + 0.04, thickness: pipeRadius * 2 + 0.08, front: v.playDepth - pipeRadius - 0.04 };
324
- };
325
-
326
- /**
327
- * A prism: the convex outline `profile` ((z, y) points, z toward the camera) swept along x from `x0` to
328
- * `x1`, with flat faces turned outward. For shapes the cubes can't make: the top wall's sloped underside.
329
- */
330
- function prism(profile: [number, number][], x0: number, x1: number, color: RGB): Geometry {
331
- const vertices: number[] = [];
332
- const indices: number[] = [];
333
- const cz = profile.reduce((a, p) => a + p[0], 0) / profile.length;
334
- const cy = profile.reduce((a, p) => a + p[1], 0) / profile.length;
335
- const centre: Vec3 = [(x0 + x1) / 2, cy, cz];
336
- const face = (pts: Vec3[]) => {
337
- const [a, b, c] = pts as [Vec3, Vec3, Vec3];
338
- const u: Vec3 = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];
339
- const w: Vec3 = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];
340
- let n: Vec3 = [u[1] * w[2] - u[2] * w[1], u[2] * w[0] - u[0] * w[2], u[0] * w[1] - u[1] * w[0]];
341
- const mid = pts.reduce<Vec3>((m, p) => [m[0] + p[0] / pts.length, m[1] + p[1] / pts.length, m[2] + p[2] / pts.length], [0, 0, 0]);
342
- if (n[0] * (mid[0] - centre[0]) + n[1] * (mid[1] - centre[1]) + n[2] * (mid[2] - centre[2]) < 0) {
343
- pts = [...pts].reverse();
344
- n = [-n[0], -n[1], -n[2]];
345
- }
346
- const len = Math.hypot(n[0], n[1], n[2]) || 1;
347
- const first = vertices.length / 11;
348
- for (const p of pts) vertices.push(p[0], p[1], p[2], n[0] / len, n[1] / len, n[2] / len, color[0], color[1], color[2], 0, 0);
349
- for (let i = 1; i + 1 < pts.length; i++) indices.push(first, first + i, first + i + 1);
350
- };
351
- face(profile.map(([z, y]) => [x0, y, z] as Vec3));
352
- face(profile.map(([z, y]) => [x1, y, z] as Vec3));
353
- profile.forEach(([z, y], i) => {
354
- const [z2, y2] = profile[(i + 1) % profile.length]!;
355
- face([
356
- [x0, y, z],
357
- [x1, y, z],
358
- [x1, y2, z2],
359
- [x0, y2, z2]
360
- ]);
361
- });
362
- return { vertices: new Float32Array(vertices), indices: new Uint32Array(indices) };
363
- }
364
-
365
- /**
366
- * The top wall, in its own frame (x across, y up, z toward the camera, the origin on its front edge).
367
- * The camera looks up at it, so a flat underside would show as a dark band below the bricks. Instead
368
- * the underside rises toward the back along the camera's line of sight through the edge (`slope`
369
- * metres up per metre back), so it's never seen: the stone coping's front comes right down to the line
370
- * and the pipes run straight up into it, as they rise out of the bottom wall's ledge.
371
- */
372
- function topWallGeometry(w: number, h: number, k: number, slope: number): Geometry {
373
- const bw = BRICK_WIDTH * k;
374
- const bh = BRICK_HEIGHT * k;
375
- const width = w * k;
376
- const height = h * k;
377
- const coping = COPING * k;
378
- const relief = bh * 0.35;
379
- const lip = relief + 0.025; // the coping stands this far proud of the core, the bricks a little less
380
- const depth = 0.25;
381
- const mortar = 0.12 * bh;
382
- const s = slope * 1.05; // a hair steeper than the sight line, so the underside is always hidden
383
- const x0 = -width / 2;
384
- const x1 = width / 2;
385
- const parts: { geometry: Geometry; position?: Vec3; scale?: Vec3; color?: RGB }[] = [
386
- // The mortar core behind the bricks
387
- {
388
- geometry: prism(
389
- [
390
- [-lip, s * lip],
391
- [-lip, height],
392
- [-depth, height],
393
- [-depth, s * depth]
394
- ],
395
- x0,
396
- x1,
397
- rgb('#3a1d0c')
398
- )
399
- },
400
- // The stone coping along the edge, with a darker drip line on its face
401
- {
402
- geometry: prism(
403
- [
404
- [0, 0],
405
- [0, coping],
406
- [-lip, coping],
407
- [-lip, s * lip]
408
- ],
409
- x0,
410
- x1,
411
- rgb('#c8b896')
412
- )
413
- },
414
- { geometry: shapeGeometry('cube'), position: [0, coping * 0.11, 0.004], scale: [width, coping * 0.22, 0.008], color: rgb('#a9987a') }
415
- ];
416
- const rows = Math.ceil((height - coping) / bh);
417
- for (let r = 0; r < rows; r++) {
418
- const y0 = coping + r * bh;
419
- const y1 = Math.min(height, y0 + bh);
420
- const shift = r % 2 ? bw / 2 : 0;
421
- for (let c = 0, x = x0 - shift; x < x1; c++, x += bw) {
422
- const bx0 = Math.max(x, x0);
423
- const bx1 = Math.min(x + bw, x1);
424
- if (bx1 - bx0 <= mortar || y1 - y0 <= mortar) continue;
425
- parts.push({
426
- geometry: shapeGeometry('cube'),
427
- position: [(bx0 + bx1) / 2, (y0 + y1) / 2, -lip + relief / 2],
428
- scale: [bx1 - bx0 - mortar, y1 - y0 - mortar, relief + 0.01],
429
- color: brickShade(r + 7, c)
430
- });
431
- }
432
- }
433
- return merge(parts);
434
- }
435
-
436
- export type Walls = { top: Entity; bottom: Entity };
437
-
438
- export function spawnWalls(world: World, v: View3D, l: Layout): Walls {
439
- const { back, front, thickness } = wallDepth(v);
440
- const kb = pointSize(v, back);
441
- const kf = pointSize(v, front);
442
- // How steeply the sight line through the top wall's edge climbs, per metre away from the camera
443
- const slope = ((l.height / 2 - l.topWall) / (l.height / 2)) * v.tanHalf;
444
- // Wide enough to cover the screen at any point of a wrap: the screen, one shade period, and a margin
445
- const width = l.width + SHADE_PERIOD * BRICK_WIDTH + BRICK_WIDTH * 4;
446
- const top = cached(`fb-top-wall:${Math.round(l.width)}x${Math.round(l.topWall)}:${kf.toFixed(6)}:${slope.toFixed(5)}`, () =>
447
- createShape(topWallGeometry(width, l.topWall + WALL_MARGIN, kf, slope), { center: false, shine: 0.05 })
448
- );
449
- const bottomHeight = l.height - l.bottomWallTop;
450
- const bottom = cached(`fb-wall:${Math.round(l.width)}x${Math.round(bottomHeight)}:${kb.toFixed(6)}:${thickness.toFixed(4)}`, () =>
451
- createShape(wallGeometry(width, bottomHeight + WALL_MARGIN, kb, thickness), { center: false, shine: 0.05 })
452
- );
453
- const walls = {
454
- top: world.spawn({ mesh: top, color: [1, 1, 1, 1], pickable: false }),
455
- // The bottom wall is the block turned over: it runs down from its line, its ledge facing up
456
- bottom: world.spawn({ mesh: bottom, color: [1, 1, 1, 1], pickable: false })
457
- };
458
- placeWalls(world, v, l, walls, 0);
459
- return walls;
460
- }
461
-
462
- /**
463
- * Scrolls the walls with the pipes. They move at the pipes' speed in the world (the pipes pass through
464
- * them, so they stay put against the bricks), which on screen is a touch slower for the deeper bottom
465
- * wall: real parallax. Each wraps by a whole shade period, where its bricks look exactly the same.
466
- */
467
- export function placeWalls(world: World, v: View3D, l: Layout, walls: Walls, scroll: number) {
468
- const { back, front } = wallDepth(v);
469
- const travelled = scroll * pointSize(v); // metres the pipes have moved
470
- const place = (wall: Entity, line: number, depth: number, turn: number) => {
471
- const period = SHADE_PERIOD * BRICK_WIDTH * pointSize(v, depth);
472
- const centre = at(v, l.width / 2 + (SHADE_PERIOD * BRICK_WIDTH) / 2, line, depth);
473
- world.set(wall, { position: [centre[0] - (travelled % period), centre[1], centre[2]], rotation: facing(v, turn) });
474
- };
475
- // The top wall's front edge, the bottom wall's back edge, sit on their collision lines
476
- place(walls.top, l.topWall, front, 0);
477
- place(walls.bottom, l.bottomWallTop, back, Math.PI);
478
- }
479
-
480
- // ── Pipes ─────────────────────────────────────────────────────────────
481
-
482
- /** A pair of pipes: the top one comes out of the top wall down to the gap, the bottom one up out of the bottom wall. */
483
- export function spawnPipe(world: World, v: View3D, l: Layout, x: number, gapTop: number, gapBottom: number): Entity {
484
- const k = pointSize(v);
485
- const s = PIPE_WIDTH / 60;
486
- const capH = CAP_HEIGHT * s;
487
- const capW = PIPE_WIDTH + CAP_OVER * 2 * s;
488
- const cx = x + PIPE_WIDTH / 2;
489
- const root = world.spawn({ mesh: 'none', position: at(v, cx, 0), rotation: facing(v), pickable: false });
490
- const add = (mesh: Model, y: number, height: number, width: number, flip = false) =>
491
- world.spawn({
492
- mesh,
493
- parent: root,
494
- position: local(k, 0, y),
495
- scale: [width * k, height * k, width * k],
496
- ...(flip ? { rotation: quat.z(Math.PI) } : {}),
497
- color: [1, 1, 1, 1],
498
- pickable: false
499
- });
500
- const topEnd = Math.max(l.topWall, Math.min(gapTop, l.bottomWallTop));
501
- const bottomStart = Math.max(l.topWall, Math.min(gapBottom, l.bottomWallTop));
502
- const topStart = l.topWall - PIPE_INTO_WALL;
503
- const bottomEnd = l.bottomWallTop + PIPE_INTO_WALL;
504
- if (topEnd - l.topWall > 0.5) {
505
- add(pipeMesh(), (topStart + topEnd) / 2, topEnd - topStart, PIPE_WIDTH);
506
- add(capMesh(), topEnd - capH / 2, capH, capW, true); // its open end faces down into the gap
507
- }
508
- if (l.bottomWallTop - bottomStart > 0.5) {
509
- add(pipeMesh(), (bottomStart + bottomEnd) / 2, bottomEnd - bottomStart, PIPE_WIDTH);
510
- add(capMesh(), bottomStart + capH / 2, capH, capW);
511
- }
512
- return root;
513
- }
514
-
515
- export function placePipe(world: World, v: View3D, root: Entity, x: number, updates?: TransformBatch) {
516
- const position = at(v, x + PIPE_WIDTH / 2, 0);
517
- if (updates) updates.position(root, position[0], position[1], position[2]);
518
- else world.set(root, { position });
519
- }
520
-
521
- // ── The bird ──────────────────────────────────────────────────────────
522
-
523
- export type BirdView = { root: Entity; body: Entity; wing: Entity; farWing: Entity; lid: Entity; size: number };
524
-
525
- /** Where the eye sits on the body, and its size (body units). */
526
- const EYE: Vec3 = [0.22, 0.15, 0.27];
527
- const EYE_SIZE = 0.34;
528
-
529
- /** The bird, its body centred on screen point (x, y). In the ready state it hovers, bobbing gently. */
530
- export function spawnBird(world: World, v: View3D, x: number, y: number): BirdView {
531
- const size = BIRD_SIZE * pointSize(v);
532
- const root = world.spawn({ mesh: 'none', position: at(v, x, y), rotation: facing(v), pickable: false });
533
- // The far wing behind the body (it peeks out on the upstroke), the near one in front
534
- const farWing = world.spawn({
535
- mesh: wingMesh(true),
536
- parent: root,
537
- position: [-size * 0.04, size * 0.04, -size * 0.3],
538
- scale: size,
539
- color: [1, 1, 1, 1],
540
- pickable: false
541
- });
542
- const body = world.spawn({ mesh: birdMesh(), parent: root, scale: size, color: [1, 1, 1, 1], pickable: false });
543
- const lid = world.spawn({
544
- mesh: lidMesh(),
545
- parent: root,
546
- position: [EYE[0] * size, EYE[1] * size, EYE[2] * size],
547
- scale: 0,
548
- color: [1, 1, 1, 1],
549
- pickable: false
550
- });
551
- const wing = world.spawn({
552
- mesh: wingMesh(false),
553
- parent: root,
554
- position: [-size * 0.02, -size * 0.04, size * 0.38],
555
- scale: size,
556
- color: [1, 1, 1, 1],
557
- pickable: false
558
- });
559
- return { root, body, wing, farWing, lid, size };
560
- }
561
-
562
- const NEAR_WING_TILT = quat.x(-0.25);
563
- const FAR_WING_TILT = quat.x(0.25);
564
- const wingTurn: MutableQuat = [0, 0, 0, 1];
565
-
566
- /** Moves the bird: leaning by `tilt`, the wings lifted by `lift` (radians: up positive), the far one a beat behind. */
567
- export function placeBird(world: World, v: View3D, b: BirdView, x: number, y: number, tilt: number, lift: number, farLift = lift) {
568
- world.set(b.root, { position: at(v, x, y), rotation: facing(v, -tilt) });
569
- world.set(b.wing, { rotation: quat.multiply(NEAR_WING_TILT, quat.z(-lift, wingTurn), wingTurn) });
570
- world.set(b.farWing, { rotation: quat.multiply(FAR_WING_TILT, quat.z(-farLift, wingTurn), wingTurn) });
571
- }
572
-
573
- /** The squash and stretch of a flap: the body stretches up as it pushes off, then settles. */
574
- export function flapPop(world: World, b: BirdView) {
575
- const s = b.size;
576
- world.stopAnimation(b.body);
577
- world.animate(b.body, [{ scale: [s * 0.86, s * 1.16, s], at: 0.3 }, { scale: [s * 1.05, s * 0.96, s], at: 0.65 }, { scale: s }], {
578
- duration: 0.26,
579
- easing: 'easeOut'
580
- });
581
- }
582
-
583
- /** A blink: the lid closes over the eye and opens again. */
584
- export function blink(world: World, b: BirdView) {
585
- const s = b.size * EYE_SIZE;
586
- world.animate(b.lid, [{ scale: [s, s, s], at: 0.4 }, { scale: [s, s, s], at: 0.6 }, { scale: 0 }], { duration: 0.16, easing: 'linear' });
587
- }
588
-
589
- /** Knocked silly by a crash: a shake, eyes half shut, wings drooping. */
590
- export function dazeBird(world: World, b: BirdView) {
591
- const s = b.size * EYE_SIZE;
592
- world.stopAnimation(b.lid);
593
- world.set(b.lid, { scale: [s, s * 0.55, s], position: [EYE[0] * b.size, (EYE[1] + 0.06) * b.size, EYE[2] * b.size] });
594
- world.animate(b.root, { shake: b.size * 0.12 }, { duration: 0.35 });
595
- }
596
-
597
- /** Back to normal after a crash (a new run). */
598
- export function wakeBird(world: World, b: BirdView) {
599
- world.stopAnimation(b.lid);
600
- world.set(b.lid, { scale: 0, position: [EYE[0] * b.size, EYE[1] * b.size, EYE[2] * b.size] });
601
- }
602
-
603
- /** A gentle hover while waiting to start (none while flying). */
604
- export function hoverBird(world: World, b: BirdView, on: boolean, v: View3D) {
605
- const amplitude = BIRD_SIZE * pointSize(v) * 0.12;
606
- world.set(b.root, { bob: on ? { amplitude: [0, amplitude, 0], speed: 3.2 } : null });
607
- }
608
-
609
- // ── The crash ─────────────────────────────────────────────────────────
610
-
611
- const FEATHERS: Color[] = ['#FFD700', '#FF8C00', '#FFE850', '#FFFFFF', '#A0522D'].map((c) => toColor(c));
612
-
613
- /** Feathers fly and a puff of dust where the bird hit. */
614
- export function crashBurst(world: World, v: View3D, x: number, y: number) {
615
- const k = pointSize(v);
616
- const size = BIRD_SIZE * k;
617
- const where = at(v, x, y, v.playDepth - size * 0.6);
618
- effects.shatter(world, {
619
- position: where,
620
- count: 16,
621
- mesh: 'sphere',
622
- size: size * 0.12,
623
- speed: size * 7,
624
- lifetime: 0.7,
625
- gravity: -size * 18,
626
- colors: FEATHERS,
627
- dust: false
628
- });
629
- effects.dust(world, { position: where, count: 5, size: size * 0.9, speed: size * 2, lifetime: 0.5, color: [1, 1, 1, 0.75] });
630
- }