react-native-games 1.3.0 → 1.5.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 (195) hide show
  1. package/lib/module/games/balloon-blaster/BalloonBlaster.js +1 -1
  2. package/lib/module/games/balloon-blaster/BalloonBlasterConstants.js +1 -1
  3. package/lib/module/games/balloon-blaster/BalloonBlasterService.js +1 -1
  4. package/lib/module/games/balloon-blaster/BalloonBlasterStore.js +1 -1
  5. package/lib/module/games/balloon-blaster/components/BalloonComponent.js +1 -1
  6. package/lib/module/games/balloon-blaster/components/GameArea.js +1 -1
  7. package/lib/module/games/balloon-blaster/components/GameBackground.js +1 -1
  8. package/lib/module/games/balloon-blaster/components/ScoreBoard.js +1 -1
  9. package/lib/module/games/balloon-blaster/components/index.js +1 -1
  10. package/lib/module/games/bike-racing/BikeRacing.js +1 -1
  11. package/lib/module/games/bike-racing/BikeRacingConstants.js +1 -1
  12. package/lib/module/games/bike-racing/BikeRacingService.js +1 -1
  13. package/lib/module/games/bike-racing/BikeRacingStore.js +1 -1
  14. package/lib/module/games/bike-racing/components/BikeComponent.js +1 -1
  15. package/lib/module/games/bike-racing/components/GameBackground.js +1 -1
  16. package/lib/module/games/bike-racing/components/ScoreBoard.js +1 -1
  17. package/lib/module/games/bike-racing/components/index.js +1 -1
  18. package/lib/module/games/bike-racing/index.js +1 -1
  19. package/lib/module/games/block-blast/BlockBlast.js +1 -1
  20. package/lib/module/games/block-blast/BlockBlastConstants.js +1 -1
  21. package/lib/module/games/block-blast/BlockBlastService.js +1 -1
  22. package/lib/module/games/block-blast/BlockBlastStore.js +1 -1
  23. package/lib/module/games/block-blast/components/BlockPieceComponent.js +1 -1
  24. package/lib/module/games/block-blast/components/GameArea.js +1 -1
  25. package/lib/module/games/block-blast/components/GameBackground.js +1 -1
  26. package/lib/module/games/block-blast/components/GridComponent.js +1 -1
  27. package/lib/module/games/block-blast/components/ScoreBoard.js +1 -1
  28. package/lib/module/games/block-blast/components/index.js +1 -1
  29. package/lib/module/games/block-blast/index.js +1 -1
  30. package/lib/module/games/bubble-shooter/BubbleShooter.js +1 -1
  31. package/lib/module/games/bubble-shooter/BubbleShooterConstants.js +1 -1
  32. package/lib/module/games/bubble-shooter/BubbleShooterService.js +1 -1
  33. package/lib/module/games/bubble-shooter/BubbleShooterStore.js +1 -1
  34. package/lib/module/games/bubble-shooter/components/GameArea.js +1 -1
  35. package/lib/module/games/bubble-shooter/components/GameBackground.js +1 -1
  36. package/lib/module/games/bubble-shooter/components/ScoreBoard.js +1 -1
  37. package/lib/module/games/bubble-shooter/components/index.js +1 -1
  38. package/lib/module/games/bubble-shooter/index.js +1 -1
  39. package/lib/module/games/candy-crush/CandyCrush.js +1 -1
  40. package/lib/module/games/candy-crush/CandyCrushConstants.js +1 -1
  41. package/lib/module/games/candy-crush/CandyCrushService.js +1 -1
  42. package/lib/module/games/candy-crush/CandyCrushStore.js +1 -1
  43. package/lib/module/games/candy-crush/components/CandyItem.js +1 -1
  44. package/lib/module/games/candy-crush/components/GameBackground.js +1 -1
  45. package/lib/module/games/candy-crush/components/GameGrid.js +1 -1
  46. package/lib/module/games/candy-crush/components/ScoreBoard.js +1 -1
  47. package/lib/module/games/candy-crush/components/index.js +1 -1
  48. package/lib/module/games/candy-crush/index.js +1 -1
  49. package/lib/module/games/car-racing/CarRacing.js +1 -1
  50. package/lib/module/games/car-racing/CarRacingConstants.js +1 -1
  51. package/lib/module/games/car-racing/CarRacingService.js +1 -1
  52. package/lib/module/games/car-racing/CarRacingStore.js +1 -1
  53. package/lib/module/games/car-racing/components/CarComponent.js +1 -1
  54. package/lib/module/games/car-racing/components/GameBackground.js +1 -1
  55. package/lib/module/games/car-racing/components/ScoreBoard.js +1 -1
  56. package/lib/module/games/car-racing/components/index.js +1 -1
  57. package/lib/module/games/colors-sort/ColorsSort.js +1 -1
  58. package/lib/module/games/colors-sort/ColorsSortConstants.js +1 -1
  59. package/lib/module/games/colors-sort/ColorsSortService.js +1 -1
  60. package/lib/module/games/colors-sort/ColorsSortStore.js +1 -1
  61. package/lib/module/games/colors-sort/components/ColorContainer.js +1 -1
  62. package/lib/module/games/colors-sort/components/GameBackground.js +1 -1
  63. package/lib/module/games/colors-sort/components/ScoreBoard.js +1 -1
  64. package/lib/module/games/colors-sort/components/index.js +1 -1
  65. package/lib/module/games/dino-jump/DinoJump.js +1 -1
  66. package/lib/module/games/dino-jump/DinoJumpConstants.js +1 -1
  67. package/lib/module/games/dino-jump/DinoJumpService.js +1 -1
  68. package/lib/module/games/dino-jump/DinoJumpStore.js +1 -1
  69. package/lib/module/games/dino-jump/components/DinoSprite.js +1 -1
  70. package/lib/module/games/dino-jump/components/GameArea.js +1 -1
  71. package/lib/module/games/dino-jump/components/GameBackground.js +1 -1
  72. package/lib/module/games/dino-jump/components/ObstacleSprite.js +1 -1
  73. package/lib/module/games/dino-jump/components/ScoreBoard.js +1 -1
  74. package/lib/module/games/dino-jump/components/StarSprite.js +1 -1
  75. package/lib/module/games/dino-jump/components/index.js +1 -1
  76. package/lib/module/games/flappy-bird/FlappyBird.js +1 -1
  77. package/lib/module/games/flappy-bird/FlappyBirdConstants.js +1 -1
  78. package/lib/module/games/flappy-bird/FlappyBirdStore.js +1 -1
  79. package/lib/module/games/flappy-bird/components/Bird.js +1 -1
  80. package/lib/module/games/flappy-bird/components/GameArea.js +1 -1
  81. package/lib/module/games/flappy-bird/components/GameBackground.js +1 -1
  82. package/lib/module/games/flappy-bird/components/Pipes.js +1 -1
  83. package/lib/module/games/flappy-bird/components/ScoreBoard.js +1 -1
  84. package/lib/module/games/flappy-bird/components/index.js +1 -1
  85. package/lib/module/games/fruit-merger/FruitMerger.js +1 -1
  86. package/lib/module/games/fruit-merger/FruitMergerConstants.js +1 -1
  87. package/lib/module/games/fruit-merger/FruitMergerService.js +1 -1
  88. package/lib/module/games/fruit-merger/FruitMergerStore.js +1 -1
  89. package/lib/module/games/fruit-merger/components/FruitItem.js +1 -1
  90. package/lib/module/games/fruit-merger/components/GameArea.js +1 -1
  91. package/lib/module/games/fruit-merger/components/GameBackground.js +1 -1
  92. package/lib/module/games/fruit-merger/components/ScoreBoard.js +1 -1
  93. package/lib/module/games/fruit-merger/components/index.js +1 -1
  94. package/lib/module/games/fruit-ninja/FruitNinja.js +1 -1
  95. package/lib/module/games/fruit-ninja/FruitNinjaConstants.js +1 -1
  96. package/lib/module/games/fruit-ninja/FruitNinjaService.js +1 -1
  97. package/lib/module/games/fruit-ninja/FruitNinjaStore.js +1 -1
  98. package/lib/module/games/fruit-ninja/components/FruitComponent.js +1 -1
  99. package/lib/module/games/fruit-ninja/components/GameArea.js +1 -1
  100. package/lib/module/games/fruit-ninja/components/GameBackground.js +1 -1
  101. package/lib/module/games/fruit-ninja/components/ScoreBoard.js +1 -1
  102. package/lib/module/games/fruit-ninja/components/index.js +1 -1
  103. package/lib/module/games/game-2048/Game2048.js +1 -1
  104. package/lib/module/games/game-2048/Game2048Constants.js +1 -1
  105. package/lib/module/games/game-2048/Game2048Service.js +1 -1
  106. package/lib/module/games/game-2048/Game2048Store.js +1 -1
  107. package/lib/module/games/game-2048/components/GameBackground.js +1 -1
  108. package/lib/module/games/game-2048/components/GameGrid.js +1 -1
  109. package/lib/module/games/game-2048/components/GameTile.js +1 -1
  110. package/lib/module/games/game-2048/components/ScoreBoard.js +1 -1
  111. package/lib/module/games/game-2048/components/index.js +1 -1
  112. package/lib/module/games/maze-runner/MazeRunner.js +1 -1
  113. package/lib/module/games/maze-runner/MazeRunnerConstants.js +1 -1
  114. package/lib/module/games/maze-runner/MazeRunnerService.js +1 -1
  115. package/lib/module/games/maze-runner/components/EnhancedBallComponent.js +1 -1
  116. package/lib/module/games/maze-runner/components/EnhancedGameArea.js +1 -1
  117. package/lib/module/games/maze-runner/components/GameBackground.js +1 -1
  118. package/lib/module/games/maze-runner/components/ScoreBoard.js +1 -1
  119. package/lib/module/games/maze-runner/components/SkiaPipeComponent.js +1 -1
  120. package/lib/module/games/maze-runner/components/StaticGameBackground.js +1 -1
  121. package/lib/module/games/maze-runner/components/WallComponent.js +1 -1
  122. package/lib/module/games/maze-runner/components/index.js +1 -1
  123. package/lib/module/games/perfect-circle/PerfectCircle.js +1 -1
  124. package/lib/module/games/perfect-circle/PerfectCircleConstants.js +1 -1
  125. package/lib/module/games/perfect-circle/PerfectCircleService.js +1 -1
  126. package/lib/module/games/perfect-circle/PerfectCircleStore.js +1 -1
  127. package/lib/module/games/perfect-circle/components/DrawingCanvas.js +1 -1
  128. package/lib/module/games/perfect-circle/components/GameBackground.js +1 -1
  129. package/lib/module/games/perfect-circle/components/ScoreBoard.js +1 -1
  130. package/lib/module/games/perfect-circle/index.js +1 -1
  131. package/lib/module/games/popit-fidget/PopitFidget.js +1 -1
  132. package/lib/module/games/popit-fidget/PopitFidgetConstants.js +1 -1
  133. package/lib/module/games/popit-fidget/PopitFidgetService.js +1 -1
  134. package/lib/module/games/popit-fidget/PopitFidgetStore.js +1 -1
  135. package/lib/module/games/popit-fidget/components/BubbleComponent.js +1 -1
  136. package/lib/module/games/popit-fidget/components/FidgetGrid.js +1 -1
  137. package/lib/module/games/popit-fidget/components/GameBackground.js +1 -1
  138. package/lib/module/games/popit-fidget/components/ScoreBoard.js +1 -1
  139. package/lib/module/games/popit-fidget/components/index.js +1 -1
  140. package/lib/module/games/sliding-numbers/SlidingNumbers.js +1 -1
  141. package/lib/module/games/sliding-numbers/SlidingNumbersConstants.js +1 -1
  142. package/lib/module/games/sliding-numbers/SlidingNumbersService.js +1 -1
  143. package/lib/module/games/sliding-numbers/SlidingNumbersStore.js +1 -1
  144. package/lib/module/games/sliding-numbers/components/GameBackground.js +1 -1
  145. package/lib/module/games/sliding-numbers/components/NumbersGrid.js +1 -1
  146. package/lib/module/games/sliding-numbers/components/NumbersTile.js +1 -1
  147. package/lib/module/games/sliding-numbers/components/ScoreBoard.js +1 -1
  148. package/lib/module/games/sliding-numbers/components/index.js +1 -1
  149. package/lib/module/games/snake/Snake.js +1 -1
  150. package/lib/module/games/snake/SnakeConstants.js +1 -1
  151. package/lib/module/games/snake/SnakeService.js +1 -1
  152. package/lib/module/games/snake/SnakeStore.js +1 -1
  153. package/lib/module/games/snake/components/GameBackground.js +1 -1
  154. package/lib/module/games/snake/components/GameGrid.js +1 -1
  155. package/lib/module/games/snake/components/ScoreBoard.js +1 -1
  156. package/lib/module/games/snake/components/index.js +1 -1
  157. package/lib/module/games/snake/index.js +1 -1
  158. package/lib/module/games/space-fighter/SpaceFighter.js +1 -1
  159. package/lib/module/games/space-fighter/SpaceFighterConstants.js +1 -1
  160. package/lib/module/games/space-fighter/SpaceFighterService.js +1 -1
  161. package/lib/module/games/space-fighter/SpaceFighterStore.js +1 -1
  162. package/lib/module/games/space-fighter/components/AsteroidComponent.js +1 -1
  163. package/lib/module/games/space-fighter/components/GameArea.js +1 -1
  164. package/lib/module/games/space-fighter/components/GameBackground.js +1 -1
  165. package/lib/module/games/space-fighter/components/ScoreBoard.js +1 -1
  166. package/lib/module/games/space-fighter/components/Spacecraft3D.js +1 -1
  167. package/lib/module/games/space-fighter/components/SpacecraftPath.js +1 -1
  168. package/lib/module/games/space-fighter/components/index.js +1 -1
  169. package/lib/module/games/whack-a-mole/WhackAMole.js +1 -1
  170. package/lib/module/games/whack-a-mole/WhackAMoleConstants.js +1 -1
  171. package/lib/module/games/whack-a-mole/WhackAMoleService.js +1 -1
  172. package/lib/module/games/whack-a-mole/WhackAMoleStore.js +1 -1
  173. package/lib/module/games/whack-a-mole/components/GameBackground.js +1 -1
  174. package/lib/module/games/whack-a-mole/components/GameGrid.js +1 -1
  175. package/lib/module/games/whack-a-mole/components/GameHole.js +1 -1
  176. package/lib/module/games/whack-a-mole/components/MoleCharacter.js +1 -1
  177. package/lib/module/games/whack-a-mole/components/ScoreBoard.js +1 -1
  178. package/lib/module/games/whack-a-mole/components/index.js +1 -1
  179. package/lib/module/helpers/AnimationFrame.js +1 -1
  180. package/lib/module/helpers/AnimationTracker.js +1 -1
  181. package/lib/module/helpers/ErrorHandler.js +1 -1
  182. package/lib/module/helpers/GameControlButton.js +1 -1
  183. package/lib/module/helpers/GameOverModal.js +1 -1
  184. package/lib/module/helpers/GameSettingsModal.js +1 -1
  185. package/lib/module/helpers/ParticleBlast.js +1 -1
  186. package/lib/module/helpers/ScoreBoardContainer.js +1 -1
  187. package/lib/module/helpers/index.js +1 -1
  188. package/lib/module/index.js +1 -1
  189. package/lib/module/services/GamesConstants.js +1 -1
  190. package/lib/module/services/GamesService.js +1 -1
  191. package/lib/module/services/HapticsService.js +1 -1
  192. package/lib/module/services/ScoringService.js +1 -1
  193. package/lib/module/services/SoundsService.js +1 -1
  194. package/lib/module/services/UtilsService.js +1 -1
  195. package/package.json +5 -2
@@ -1 +1 @@
1
- "use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{immerMiddleware}from "../../services/UtilsService.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{PIECE_COLORS}from "./ColorsSortConstants.js";const shuffleArray = array =>{const shuffled = [...array];for(let i = shuffled.length - 1;i > 0;i--){const j = Math.floor(Math.random()*(i + 1));const temp = shuffled[i];shuffled[i] = shuffled[j];shuffled[j] = temp;}return shuffled;};export const useColorsSortStore = create()(subscribeWithSelector(immerMiddleware((set,get)=>({isPlaying:false,isGameOver:false,isPaused:false,containers:[],selectedContainerId:null,time:0,timerInterval:null,initializeGame:difficulty =>{let numColors;let piecesPerColor;let numContainers;let maxCapacity;switch(difficulty){case 'easy':numColors = 3;piecesPerColor = 3;maxCapacity = 4;numContainers = 4;break;case 'medium':numColors = 4;piecesPerColor = 3;maxCapacity = 4;numContainers = 5;break;case 'hard':numColors = 5;piecesPerColor = 4;maxCapacity = 5;numContainers = 6;break;default:numColors = 4;piecesPerColor = 3;maxCapacity = 4;numContainers = 5;}const selectedColors = PIECE_COLORS.slice(0,numColors);let allPieces = [];selectedColors.forEach((color,colorIndex)=>{for(let i = 0;i < piecesPerColor;i++){allPieces.push({id:`piece-${colorIndex}-${i}`,color});}});allPieces = shuffleArray(allPieces);const containers = [];for(let i = 0;i < numContainers;i++){const container ={id:`container-${i}`,pieces:i < numColors ? allPieces.splice(0,piecesPerColor):[],maxCapacity,x:0,y:0};containers.push(container);}set(state =>{state.containers = containers;state.selectedContainerId = null;state.time = 0;state.isPlaying = false;state.isGameOver = false;});},startGame:()=>{const state = get();if(state.timerInterval){clearInterval(state.timerInterval);}const interval = setInterval(()=>{get().incrementTime();},1000);set(draftState =>{draftState.isPlaying = true;draftState.isGameOver = false;draftState.isPaused = false;draftState.time = 0;draftState.timerInterval = interval;});},stopGame:()=>{const state = get();if(state.timerInterval){clearInterval(state.timerInterval);}state.initializeGame(state.difficulty);},resetGame:()=>{const state = get();if(state.timerInterval){clearInterval(state.timerInterval);}set(draftState =>{draftState.isPlaying = false;draftState.isGameOver = false;draftState.isPaused = false;draftState.selectedContainerId = null;draftState.time = 0;draftState.timerInterval = null;});},pauseGame:()=>{const state = get();if(state.timerInterval){clearInterval(state.timerInterval);}set(draftState =>{draftState.isPaused = true;draftState.timerInterval = null;});},resumeGame:()=>{const interval = setInterval(()=>{get().incrementTime();},1000);set(draftState =>{draftState.isPaused = false;draftState.timerInterval = interval;});},selectContainer:(containerId,settings)=>{const state = get();const container = state.containers.find(c => c.id === containerId);if(!container)return;if(state.selectedContainerId === null){if(container.pieces.length === 0){playSound(GAME_SOUNDS.COLORS_SORT.MISS,settings.enableSounds);playHaptic(HapticType.LIGHT,settings.enableHaptics);return;}set(draftState =>{draftState.selectedContainerId = containerId;});playSound(GAME_SOUNDS.COLORS_SORT.MATCH,settings.enableSounds);playHaptic(HapticType.LIGHT,settings.enableHaptics);}else if(state.selectedContainerId === containerId){set(draftState =>{draftState.selectedContainerId = null;});playSound(GAME_SOUNDS.COLORS_SORT.MISS,settings.enableSounds);playHaptic(HapticType.LIGHT,settings.enableHaptics);}else{get().movePiece(state.selectedContainerId,containerId,settings);}},canMovePiece:(fromContainerId,toContainerId)=>{const state = get();const fromContainer = state.containers.find(c => c.id === fromContainerId);const toContainer = state.containers.find(c => c.id === toContainerId);if(!fromContainer || !toContainer)return false;if(fromContainer.pieces.length === 0)return false;if(toContainer.pieces.length >= toContainer.maxCapacity)return false;return true;},movePiece:(fromContainerId,toContainerId,settings)=>{const canMove = get().canMovePiece(fromContainerId,toContainerId);if(!canMove){set(state =>{state.selectedContainerId = null;});playSound(GAME_SOUNDS.COLORS_SORT.MISS,settings.enableSounds);playHaptic(HapticType.LIGHT,settings.enableHaptics);return;}set(state =>{const fromContainer = state.containers.find(c => c.id === fromContainerId);const toContainer = state.containers.find(c => c.id === toContainerId);if(fromContainer && toContainer && fromContainer.pieces.length > 0){const piece = fromContainer.pieces.pop();if(piece){toContainer.pieces.push(piece);}}state.selectedContainerId = null;});setTimeout(()=>{const hasWon = get().checkWinCondition();if(hasWon){set(state =>{state.isGameOver = true;state.isPlaying = false;if(state.timerInterval){clearInterval(state.timerInterval);state.timerInterval = null;}});playSound(GAME_SOUNDS.COLORS_SORT.COMPLETE,settings.enableSounds);playHaptic(HapticType.SUCCESS,settings.enableHaptics);}},0);playSound(GAME_SOUNDS.COLORS_SORT.MATCH,settings.enableSounds);playHaptic(HapticType.MEDIUM,settings.enableHaptics);},checkWinCondition:()=>{const state = get();const colorPieces = new Map();for(const container of state.containers){if(container.pieces.length === 0)continue;const targetColor = container.pieces[0]?.color;const allSameColor = container.pieces.every(piece => piece.color === targetColor);if(!allSameColor)return false;const currentCount = colorPieces.get(targetColor)|| 0;colorPieces.set(targetColor,currentCount + container.pieces.length);}for(const container of state.containers){if(container.pieces.length === 0)continue;const targetColor = container.pieces[0]?.color;const totalPiecesOfColor = colorPieces.get(targetColor)|| 0;const isContainerValid = container.pieces.length === container.maxCapacity || container.pieces.length === totalPiecesOfColor;if(!isContainerValid)return false;}return true;},incrementTime:()=>{set(state =>{state.time += 1;});}}))));export const useIsPlaying =()=> useColorsSortStore(state => state.isPlaying);export const useIsGameOver =()=> useColorsSortStore(state => state.isGameOver);export const useIsPaused =()=> useColorsSortStore(state => state.isPaused);export const useTime =()=> useColorsSortStore(state => state.time);export const useContainers =()=> useColorsSortStore(state => state.containers);export const useSelectedContainerId =()=> useColorsSortStore(state => state.selectedContainerId);
1
+ "use strict";import{create as e}from"zustand";import{subscribeWithSelector as t}from"zustand/middleware";import{immerMiddleware as o}from"../../services/UtilsService.js";import{playSound as r,GAME_SOUNDS as s}from"../../services/SoundsService.js";import{playHaptic as n,HapticType as c}from"../../services/HapticsService.js";import{PIECE_COLORS as i}from"./ColorsSortConstants.js";const l=e=>{const t=[...e];for(let e=t.length-1;e>0;e--){const o=Math.floor(Math.random()*(e+1)),r=t[e];t[e]=t[o],t[o]=r}return t};export const useColorsSortStore=e()(t(o((e,t)=>({isPlaying:!1,isGameOver:!1,isPaused:!1,containers:[],selectedContainerId:null,time:0,timerInterval:null,initializeGame:t=>{let o,r,s,n;switch(t){case"easy":o=3,r=3,n=4,s=4;break;case"medium":default:o=4,r=3,n=4,s=5;break;case"hard":o=5,r=4,n=5,s=6}const c=i.slice(0,o);let a=[];c.forEach((e,t)=>{for(let o=0;r>o;o++)a.push({id:`piece-${t}-${o}`,color:e})}),a=l(a);const u=[];for(let e=0;s>e;e++){const t={id:"container-"+e,pieces:o>e?a.splice(0,r):[],maxCapacity:n,x:0,y:0};u.push(t)}e(e=>{e.containers=u,e.selectedContainerId=null,e.time=0,e.isPlaying=!1,e.isGameOver=!1})},startGame:()=>{const o=t();o.timerInterval&&clearInterval(o.timerInterval);const r=setInterval(()=>{t().incrementTime()},1e3);e(e=>{e.isPlaying=!0,e.isGameOver=!1,e.isPaused=!1,e.time=0,e.timerInterval=r})},stopGame:()=>{const e=t();e.timerInterval&&clearInterval(e.timerInterval),e.initializeGame(e.difficulty)},resetGame:()=>{const o=t();o.timerInterval&&clearInterval(o.timerInterval),e(e=>{e.isPlaying=!1,e.isGameOver=!1,e.isPaused=!1,e.selectedContainerId=null,e.time=0,e.timerInterval=null})},pauseGame:()=>{const o=t();o.timerInterval&&clearInterval(o.timerInterval),e(e=>{e.isPaused=!0,e.timerInterval=null})},resumeGame:()=>{const o=setInterval(()=>{t().incrementTime()},1e3);e(e=>{e.isPaused=!1,e.timerInterval=o})},selectContainer:(o,i)=>{const l=t(),a=l.containers.find(e=>e.id===o);if(a)if(null===l.selectedContainerId){if(0===a.pieces.length)return r(s.COLORS_SORT.MISS,i.enableSounds),void n(c.LIGHT,i.enableHaptics);e(e=>{e.selectedContainerId=o}),r(s.COLORS_SORT.MATCH,i.enableSounds),n(c.LIGHT,i.enableHaptics)}else l.selectedContainerId===o?(e(e=>{e.selectedContainerId=null}),r(s.COLORS_SORT.MISS,i.enableSounds),n(c.LIGHT,i.enableHaptics)):t().movePiece(l.selectedContainerId,o,i)},canMovePiece:(e,o)=>{const r=t(),s=r.containers.find(t=>t.id===e),n=r.containers.find(e=>e.id===o);return!(!s||!n)&&0!==s.pieces.length&&n.pieces.length<n.maxCapacity},movePiece:(o,i,l)=>{if(!t().canMovePiece(o,i))return e(e=>{e.selectedContainerId=null}),r(s.COLORS_SORT.MISS,l.enableSounds),void n(c.LIGHT,l.enableHaptics);e(e=>{const t=e.containers.find(e=>e.id===o),r=e.containers.find(e=>e.id===i);if(t&&r&&t.pieces.length>0){const e=t.pieces.pop();e&&r.pieces.push(e)}e.selectedContainerId=null}),setTimeout(()=>{t().checkWinCondition()&&(e(e=>{e.isGameOver=!0,e.isPlaying=!1,e.timerInterval&&(clearInterval(e.timerInterval),e.timerInterval=null)}),r(s.COLORS_SORT.COMPLETE,l.enableSounds),n(c.SUCCESS,l.enableHaptics))},0),r(s.COLORS_SORT.MATCH,l.enableSounds),n(c.MEDIUM,l.enableHaptics)},checkWinCondition:()=>{const e=t(),o=new Map;for(const t of e.containers){if(0===t.pieces.length)continue;const e=t.pieces[0]?.color;if(!t.pieces.every(t=>t.color===e))return!1;const r=o.get(e)||0;o.set(e,r+t.pieces.length)}for(const t of e.containers){if(0===t.pieces.length)continue;const e=t.pieces[0]?.color,r=o.get(e)||0;if(t.pieces.length!==t.maxCapacity&&t.pieces.length!==r)return!1}return!0},incrementTime:()=>{e(e=>{e.time+=1})}}))));export const useIsPlaying=()=>useColorsSortStore(e=>e.isPlaying);export const useIsGameOver=()=>useColorsSortStore(e=>e.isGameOver);export const useIsPaused=()=>useColorsSortStore(e=>e.isPaused);export const useTime=()=>useColorsSortStore(e=>e.time);export const useContainers=()=>useColorsSortStore(e=>e.containers);export const useSelectedContainerId=()=>useColorsSortStore(e=>e.selectedContainerId);
@@ -1 +1 @@
1
- "use strict";import React,{useMemo}from 'react';import{TouchableOpacity,View,StyleSheet}from 'react-native';import Animated,{useAnimatedStyle,withTiming}from 'react-native-reanimated';import{COLORS_SORT_COLORS,COLORS_SORT_GAME_CONFIG}from "../ColorsSortConstants.js";import{getPieceHeight}from "../ColorsSortService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const AnimatedPiece = React.memo(({piece,isTopPiece,isSelected,marginTop,size,height})=>{const pieceAnimatedStyle = useAnimatedStyle(()=>({transform:[{translateY:withTiming(isSelected && isTopPiece ? -15:0,{duration:200})}]}),[isSelected,isTopPiece]);return _jsx(Animated.View,{style:[{marginTop},isTopPiece && pieceAnimatedStyle],children:_jsxs(View,{style:[styles.piece,{backgroundColor:piece.color,width:size,height}],children:[_jsx(View,{style:styles.pieceShine}),_jsx(View,{style:styles.pieceDepth})]})});});AnimatedPiece.displayName = 'AnimatedPiece';export const ColorContainer = React.memo(({container,isSelected,onPress,difficulty})=>{const{PIECE_SIZE,PIECE_SPACING}= COLORS_SORT_GAME_CONFIG;const pieceHeight = useMemo(()=> getPieceHeight(difficulty,PIECE_SIZE),[difficulty,PIECE_SIZE]);const containerStyle = useMemo(()=> [styles.container,{borderWidth:isSelected ? 3:2,borderColor:isSelected ? COLORS_SORT_COLORS.BUTTON_PRIMARY:COLORS_SORT_COLORS.BASE_DARK}],[isSelected]);return _jsx(TouchableOpacity,{onPress:onPress,activeOpacity:0.7,children:_jsx(View,{style:containerStyle,children:_jsx(View,{style:styles.pieceStack,children:[...container.pieces].reverse().map((piece,index)=> _jsx(AnimatedPiece,{piece:piece,isTopPiece:index === 0,isSelected:isSelected,marginTop:index === 0 ? 0:PIECE_SPACING,size:70,height:pieceHeight},piece.id))})})});});ColorContainer.displayName = 'ColorContainer';const styles = StyleSheet.create({container:{alignItems:'center',justifyContent:'flex-end',width:80,height:225,borderRadius:15,backgroundColor:'rgba(192,192,192,0.6)',paddingHorizontal:5,paddingTop:10,paddingBottom:5,shadowColor:'#000',shadowOffset:{width:0,height:4},shadowOpacity:0.3,shadowRadius:5,elevation:5},pieceStack:{alignItems:'center',justifyContent:'flex-end',flex:1},piece:{borderRadius:10,borderLeftWidth:2,borderRightWidth:2,borderBottomWidth:2,borderTopWidth:0,borderColor:'rgba(0,0,0,0.3)',overflow:'hidden',shadowColor:'#000',shadowOffset:{width:0,height:3},shadowOpacity:0.4,shadowRadius:4,elevation:5},pieceShine:{position:'absolute',top:2,left:2,right:'50%',height:'30%',backgroundColor:'rgba(255,255,255,0.3)',borderRadius:6},pieceDepth:{position:'absolute',bottom:0,left:0,right:0,height:4,backgroundColor:'rgba(0,0,0,0.2)'}});
1
+ "use strict";import e,{useMemo as o}from"react";import{TouchableOpacity as t,View as r,StyleSheet as i}from"react-native";import n,{useAnimatedStyle as s,withTiming as a}from"react-native-reanimated";import{COLORS_SORT_COLORS as d,COLORS_SORT_GAME_CONFIG as h}from"../ColorsSortConstants.js";import{getPieceHeight as c}from"../ColorsSortService.js";import{jsx as l,jsxs as p}from"react/jsx-runtime";const g=e.memo(({piece:e,isTopPiece:o,isSelected:t,marginTop:i,size:d,height:h})=>{const c=s(()=>({transform:[{translateY:a(t&&o?-15:0,{duration:200})}]}),[t,o]);return l(n.View,{style:[{marginTop:i},o&&c],children:p(r,{style:[m.piece,{backgroundColor:e.color,width:d,height:h}],children:[l(r,{style:m.pieceShine}),l(r,{style:m.pieceDepth})]})})});g.displayName="AnimatedPiece";export const ColorContainer=e.memo(({container:e,isSelected:i,onPress:n,difficulty:s})=>{const{PIECE_SIZE:a,PIECE_SPACING:p}=h,f=o(()=>c(s,a),[s,a]),C=o(()=>[m.container,{borderWidth:i?3:2,borderColor:i?d.BUTTON_PRIMARY:d.BASE_DARK}],[i]);return l(t,{onPress:n,activeOpacity:.7,children:l(r,{style:C,children:l(r,{style:m.pieceStack,children:[...e.pieces].reverse().map((e,o)=>l(g,{piece:e,isTopPiece:0===o,isSelected:i,marginTop:0===o?0:p,size:70,height:f},e.id))})})})});ColorContainer.displayName="ColorContainer";const m=i.create({container:{alignItems:"center",justifyContent:"flex-end",width:80,height:225,borderRadius:15,backgroundColor:"rgba(192, 192, 192, 0.6)",paddingHorizontal:5,paddingTop:10,paddingBottom:5,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.3,shadowRadius:5,elevation:5},pieceStack:{alignItems:"center",justifyContent:"flex-end",flex:1},piece:{borderRadius:10,borderLeftWidth:2,borderRightWidth:2,borderBottomWidth:2,borderTopWidth:0,borderColor:"rgba(0, 0, 0, 0.3)",overflow:"hidden",shadowColor:"#000",shadowOffset:{width:0,height:3},shadowOpacity:.4,shadowRadius:4,elevation:5},pieceShine:{position:"absolute",top:2,left:2,right:"50%",height:"30%",backgroundColor:"rgba(255, 255, 255, 0.3)",borderRadius:6},pieceDepth:{position:"absolute",bottom:0,left:0,right:0,height:4,backgroundColor:"rgba(0, 0, 0, 0.2)"}});
@@ -1 +1 @@
1
- "use strict";import React,{useMemo}from 'react';import{View,Dimensions}from 'react-native';import{Canvas,LinearGradient,Rect,vec,Circle,RoundedRect}from '@shopify/react-native-skia';import{generateFloatingBlocks,getDecorativeBlocks,getDecorativeCircles,getGradientColors}from "../ColorsSortService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');export const GameBackground = React.memo(({children})=>{const floatingBlocks = useMemo(()=> generateFloatingBlocks(),[]);const decorativeBlocks = useMemo(()=> getDecorativeBlocks(),[]);const decorativeCircles = useMemo(()=> getDecorativeCircles(),[]);const gradients = useMemo(()=> getGradientColors(),[]);const renderFloatingBlocks = useMemo(()=>{return floatingBlocks.map(block =>{if(block.type === 'square'){return _jsx(RoundedRect,{x:block.x,y:block.y,width:block.size,height:block.size,r:block.size * 0.2,color:block.color},block.key);}else if(block.type === 'rect'){return _jsx(RoundedRect,{x:block.x,y:block.y,width:block.size * 0.6,height:block.size,r:block.size * 0.15,color:block.color},block.key);}else if(block.type === 'wide'){return _jsx(RoundedRect,{x:block.x,y:block.y,width:block.size * 1.2,height:block.size * 0.8,r:block.size * 0.1,color:block.color},block.key);}else{return _jsx(Circle,{cx:block.x + block.size / 2,cy:block.y + block.size / 2,r:block.size / 2,color:block.color},block.key);}});},[floatingBlocks]);return _jsxs(View,{style:{flex:1},children:[_jsxs(Canvas,{style:{position:'absolute',top:0,left:0,right:0,bottom:0,width,height},children:[_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(width,height),colors:gradients.main})}),_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(width / 2,height / 2),colors:gradients.overlay})}),_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(width,0),end:vec(0,height),colors:gradients.diagonal})}),renderFloatingBlocks,decorativeBlocks.map(block => _jsx(RoundedRect,{x:block.x,y:block.y,width:block.size,height:block.size,r:block.r,color:block.color},block.key)),decorativeCircles.map(circle => _jsx(Circle,{cx:circle.cx,cy:circle.cy,r:circle.r,color:circle.color},circle.key)),Array.from({length:Math.floor(width / 60)},(_,i)=> _jsx(Rect,{x:i * 60,y:0,width:1,height:height,color:"rgba(255,255,255,0.05)"},`grid-v-${i}`)),Array.from({length:Math.floor(height / 60)},(_,i)=> _jsx(Rect,{x:0,y:i * 60,width:width,height:1,color:"rgba(255,255,255,0.05)"},`grid-h-${i}`))]}),children]});});GameBackground.displayName = 'GameBackground';
1
+ "use strict";import r,{useMemo as t}from"react";import{View as o,Dimensions as i}from"react-native";import{Canvas as h,LinearGradient as e,Rect as c,vec as d,Circle as a,RoundedRect as s}from"@shopify/react-native-skia";import{generateFloatingBlocks as l,getDecorativeBlocks as n,getDecorativeCircles as g,getGradientColors as x}from"../ColorsSortService.js";import{jsx as y,jsxs as m}from"react/jsx-runtime";const{width:w,height:p}=i.get("window");export const GameBackground=r.memo(({children:r})=>{const i=t(()=>l(),[]),f=t(()=>n(),[]),u=t(()=>g(),[]),b=t(()=>x(),[]),j=t(()=>i.map(r=>"square"===r.type?y(s,{x:r.x,y:r.y,width:r.size,height:r.size,r:.2*r.size,color:r.color},r.key):"rect"===r.type?y(s,{x:r.x,y:r.y,width:.6*r.size,height:r.size,r:.15*r.size,color:r.color},r.key):"wide"===r.type?y(s,{x:r.x,y:r.y,width:1.2*r.size,height:.8*r.size,r:.1*r.size,color:r.color},r.key):y(a,{cx:r.x+r.size/2,cy:r.y+r.size/2,r:r.size/2,color:r.color},r.key)),[i]);return m(o,{style:{flex:1},children:[m(h,{style:{position:"absolute",top:0,left:0,right:0,bottom:0,width:w,height:p},children:[y(c,{x:0,y:0,width:w,height:p,children:y(e,{start:d(0,0),end:d(w,p),colors:b.main})}),y(c,{x:0,y:0,width:w,height:p,children:y(e,{start:d(0,0),end:d(w/2,p/2),colors:b.overlay})}),y(c,{x:0,y:0,width:w,height:p,children:y(e,{start:d(w,0),end:d(0,p),colors:b.diagonal})}),j,f.map(r=>y(s,{x:r.x,y:r.y,width:r.size,height:r.size,r:r.r,color:r.color},r.key)),u.map(r=>y(a,{cx:r.cx,cy:r.cy,r:r.r,color:r.color},r.key)),Array.from({length:Math.floor(w/60)},(r,t)=>y(c,{x:60*t,y:0,width:1,height:p,color:"rgba(255, 255, 255, 0.05)"},"grid-v-"+t)),Array.from({length:Math.floor(p/60)},(r,t)=>y(c,{x:0,y:60*t,width:w,height:1,color:"rgba(255, 255, 255, 0.05)"},"grid-h-"+t))]}),r]})});GameBackground.displayName="GameBackground";
@@ -1 +1 @@
1
- "use strict";import React,{useMemo}from 'react';import{View,Text,StyleSheet}from 'react-native';import{useTime}from "../ColorsSortStore.js";import{COLORS_SORT_COLORS}from "../ColorsSortConstants.js";import{formatTime}from "../ColorsSortService.js";import{ScoreBoardContainer}from "../../../helpers/index.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const ScoreBoard = React.memo(({offset = 0})=>{const time = useTime();const formattedTime = useMemo(()=> formatTime(time),[time]);return _jsx(ScoreBoardContainer,{offset:offset,backgroundColor:COLORS_SORT_COLORS.SCORE_BACKGROUND,borderColor:COLORS_SORT_COLORS.SCORE_BORDER,children:_jsx(View,{style:styles.scoreBoard,children:_jsxs(View,{style:styles.scoreItem,children:[_jsx(Text,{style:styles.scoreLabel,children:"TIME"}),_jsx(Text,{style:styles.scoreValue,children:formattedTime})]})})});});const styles = StyleSheet.create({scoreBoard:{flexDirection:'row',justifyContent:'space-around',alignItems:'center'},scoreItem:{alignItems:'center',flex:1},scoreLabel:{fontSize:16,fontWeight:'700',color:COLORS_SORT_COLORS.SCORE_TEXT,marginBottom:4,letterSpacing:1,textShadowColor:'rgba(0,0,0,0.5)',textShadowOffset:{width:1,height:1},textShadowRadius:2},scoreValue:{fontSize:25,fontWeight:'900',color:COLORS_SORT_COLORS.SCORE_TEXT,textShadowColor:'rgba(0,0,0,0.8)',textShadowOffset:{width:1,height:1},textShadowRadius:2}});ScoreBoard.displayName = 'ScoreBoard';
1
+ "use strict";import o,{useMemo as t}from"react";import{View as r,Text as e,StyleSheet as s}from"react-native";import{useTime as i}from"../ColorsSortStore.js";import{COLORS_SORT_COLORS as a}from"../ColorsSortConstants.js";import{formatTime as n}from"../ColorsSortService.js";import{ScoreBoardContainer as c}from"../../../helpers/index.js";import{jsx as l,jsxs as d}from"react/jsx-runtime";export const ScoreBoard=o.memo(({offset:o=0})=>{const s=i(),h=t(()=>n(s),[s]);return l(c,{offset:o,backgroundColor:a.SCORE_BACKGROUND,borderColor:a.SCORE_BORDER,children:l(r,{style:f.scoreBoard,children:d(r,{style:f.scoreItem,children:[l(e,{style:f.scoreLabel,children:"TIME"}),l(e,{style:f.scoreValue,children:h})]})})})});const f=s.create({scoreBoard:{flexDirection:"row",justifyContent:"space-around",alignItems:"center"},scoreItem:{alignItems:"center",flex:1},scoreLabel:{fontSize:16,fontWeight:"700",color:a.SCORE_TEXT,marginBottom:4,letterSpacing:1,textShadowColor:"rgba(0, 0, 0, 0.5)",textShadowOffset:{width:1,height:1},textShadowRadius:2},scoreValue:{fontSize:25,fontWeight:"900",color:a.SCORE_TEXT,textShadowColor:"rgba(0, 0, 0, 0.8)",textShadowOffset:{width:1,height:1},textShadowRadius:2}});ScoreBoard.displayName="ScoreBoard";
@@ -1 +1 @@
1
- "use strict";export * from "./ColorContainer.js";export * from "./ScoreBoard.js";export * from "./GameBackground.js";
1
+ "use strict";export*from"./ColorContainer.js";export*from"./ScoreBoard.js";export*from"./GameBackground.js";
@@ -1 +1 @@
1
- "use strict";import React,{useEffect,useMemo,useCallback,useRef}from 'react';import{View,StyleSheet}from 'react-native';import{GestureHandlerRootView}from 'react-native-gesture-handler';import{useDinoJumpStore,useIsPlaying,useIsGameOver,useScore,useLives}from "./DinoJumpStore.js";import{DinoJumpService}from "./DinoJumpService.js";import{GameBackground,GameArea,ScoreBoard}from "./components/index.js";import{GameControlButton,GameOverModal,ParticleBlast}from "../../helpers/index.js";import{GameSettingsModal}from "../../helpers/index.js";import{GAME_IDS,DEFAULT_GAME_SETTINGS}from "../../services/UtilsService.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const DinoJump = React.memo(({settings = DEFAULT_GAME_SETTINGS,onSettingsChange,onEndGame})=>{const isPlaying = useIsPlaying();const isGameOver = useIsGameOver();const score = useScore();const lives = useLives();const gameReportedRef = useRef(false);const reportGameEnd = useCallback(status =>{if(onEndGame && !gameReportedRef.current){onEndGame({status,score:score.toString()});gameReportedRef.current = true;}},[onEndGame,score]);const setOffset = useDinoJumpStore(state => state.setOffset);const initializeGame = useDinoJumpStore(state => state.initializeGame);const startGame = useDinoJumpStore(state => state.startGame);const stopGame = useDinoJumpStore(state => state.stopGame);const resetGame = useDinoJumpStore(state => state.resetGame);const offset = settings?.offset ?? 0;useEffect(()=>{setOffset(offset);},[offset,setOffset]);const decrementTime = useDinoJumpStore(state => state.decrementTime);const updateDinosaur = useDinoJumpStore(state => state.updateDinosaur);const updateObstacles = useDinoJumpStore(state => state.updateObstacles);const updateClouds = useDinoJumpStore(state => state.updateClouds);const updateStars = useDinoJumpStore(state => state.updateStars);const updateGround = useDinoJumpStore(state => state.updateGround);const updateScore = useDinoJumpStore(state => state.updateScore);const updateSpeed = useDinoJumpStore(state => state.updateSpeed);const addObstacle = useDinoJumpStore(state => state.addObstacle);const addCloud = useDinoJumpStore(state => state.addCloud);const addStar = useDinoJumpStore(state => state.addStar);const checkCollisionsAction = useDinoJumpStore(state => state.checkCollisions);const collisionBlasts = useDinoJumpStore(state => state.collisionBlasts);const removeCollisionBlast = useDinoJumpStore(state => state.removeCollisionBlast);const settingsRef = useRef(settings);settingsRef.current = settings;const checkCollisions = useCallback(()=> checkCollisionsAction(settingsRef.current),[checkCollisionsAction]);const difficulty = settings.difficulty;const gameService = useMemo(()=> new DinoJumpService(),[]);useEffect(()=>{initializeGame(difficulty);},[difficulty,initializeGame]);useEffect(()=>{if(isPlaying){gameService.startTimer(()=>{decrementTime();});}else{gameService.stopTimer();}return()=>{gameService.stopTimer();};},[isPlaying,gameService,decrementTime]);useEffect(()=>{gameService.stopPhysicsLoop();gameService.stopObstacleSpawning();gameService.stopCloudSpawning();if(isPlaying && !isGameOver){const startTimeout = setTimeout(()=>{try{gameService.startPhysicsLoop(updateDinosaur,updateObstacles,updateClouds,updateStars,updateGround,updateScore,updateSpeed,checkCollisions,stopGame);gameService.startObstacleSpawning(addObstacle,difficulty,()=> offset);gameService.startCloudSpawning(addCloud);gameService.startStarSpawning(addStar,()=> offset);}catch(error){console.error('Failed to start game loops:',error);stopGame();}},50);return()=>{clearTimeout(startTimeout);gameService.stopPhysicsLoop();gameService.stopObstacleSpawning();gameService.stopCloudSpawning();};}return()=>{gameService.stopPhysicsLoop();gameService.stopObstacleSpawning();gameService.stopCloudSpawning();};},[isPlaying,isGameOver,gameService,updateDinosaur,updateObstacles,updateClouds,updateStars,updateGround,updateScore,updateSpeed,checkCollisions,stopGame,addObstacle,addCloud,addStar,difficulty]);useEffect(()=>{if(isGameOver && !gameReportedRef.current){const status = lives > 0 ? 'win':'lose';reportGameEnd(status);}if(!isGameOver){gameReportedRef.current = false;}},[isGameOver,lives,reportGameEnd]);useEffect(()=>{return()=>{gameService.cleanup();};},[gameService]);const handleStartGame = useCallback(()=>{gameReportedRef.current = false;startGame();playSound(GAME_SOUNDS.DINO_JUMP.START,settingsRef.current.enableSounds);playHaptic(HapticType.MEDIUM,settingsRef.current.enableHaptics);},[startGame]);const handleStopGame = useCallback(()=>{reportGameEnd('cancel');stopGame();},[stopGame,reportGameEnd]);const handleResetGame = useCallback(()=>{resetGame();initializeGame(difficulty);playHaptic(HapticType.LIGHT,settingsRef.current.enableHaptics);},[resetGame,initializeGame,difficulty]);const gameControlButtonProps = useMemo(()=>({isPlaying,gameOver:isGameOver,onStartGame:handleStartGame,onStopGame:handleStopGame,startButtonText:"START RUNNING",stopButtonText:"STOP GAME",startButtonSubtext:"Tap to jump over cacti!",stopButtonSubtext:"End current game",startButtonColor:"#FF6347",stopButtonColor:"#dc2626",startButtonBorderColor:"#FF4500",stopButtonBorderColor:"#f87171"}),[isPlaying,isGameOver,handleStartGame,handleStopGame]);const gameOverModalProps = useMemo(()=>({isVisible:isGameOver,score,onPlayAgain:handleResetGame,buttonText:"Run Again!",primaryColor:"rgba(255,99,71,0.5)",borderColor:"rgba(255,99,71,0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#FF6347"}),[isGameOver,score,handleResetGame]);const gameSettingsModalProps = useMemo(()=>({gameId:GAME_IDS.DINO_JUMP,settings,onSettingsChange}),[settings,onSettingsChange]);return _jsx(View,{style:styles.container,children:_jsx(GestureHandlerRootView,{children:_jsxs(GameBackground,{offset:offset,children:[_jsx(GameArea,{settings:settings}),collisionBlasts.map(blast => _jsx(ParticleBlast,{x:blast.x,y:blast.y,particleCount:15,colors:['#FF6B35','#FFA500','#FFD700','#FF8C42','#32CD32'],duration:800,onComplete:()=> removeCollisionBlast(blast.id)},blast.id)),_jsx(ScoreBoard,{offset:offset}),_jsx(GameControlButton,{...gameControlButtonProps}),_jsx(GameOverModal,{...gameOverModalProps}),_jsx(GameSettingsModal,{...gameSettingsModalProps})]})})});});const styles = StyleSheet.create({container:{flex:1}});DinoJump.displayName = 'DinoJump';
1
+ "use strict";import t,{useEffect as o,useMemo as r,useCallback as e,useRef as n}from"react";import{View as s,StyleSheet as i}from"react-native";import{GestureHandlerRootView as m}from"react-native-gesture-handler";import{useDinoJumpStore as a,useIsPlaying as c,useIsGameOver as u,useScore as p,useLives as f}from"./DinoJumpStore.js";import{DinoJumpService as l}from"./DinoJumpService.js";import{GameBackground as d,GameArea as g,ScoreBoard as x}from"./components/index.js";import{GameControlButton as C,GameOverModal as F,ParticleBlast as S}from"../../helpers/index.js";import{GameSettingsModal as j}from"../../helpers/index.js";import{GAME_IDS as B,DEFAULT_GAME_SETTINGS as v}from"../../services/UtilsService.js";import{playSound as b,GAME_SOUNDS as T}from"../../services/SoundsService.js";import{playHaptic as h,HapticType as D}from"../../services/HapticsService.js";import{jsx as y,jsxs as A}from"react/jsx-runtime";export const DinoJump=t.memo(({settings:t=v,onSettingsChange:i,onEndGame:J})=>{const E=c(),N=u(),P=p(),R=f(),w=n(!1),I=e(t=>{J&&!w.current&&(J({status:t,score:P.toString()}),w.current=!0)},[J,P]),O=a(t=>t.setOffset),U=a(t=>t.initializeGame),H=a(t=>t.startGame),M=a(t=>t.stopGame),V=a(t=>t.resetGame),k=t?.offset??0;o(()=>{O(k)},[k,O]);const q=a(t=>t.decrementTime),z=a(t=>t.updateDinosaur),K=a(t=>t.updateObstacles),L=a(t=>t.updateClouds),Q=a(t=>t.updateStars),W=a(t=>t.updateGround),X=a(t=>t.updateScore),Y=a(t=>t.updateSpeed),Z=a(t=>t.addObstacle),$=a(t=>t.addCloud),_=a(t=>t.addStar),tt=a(t=>t.checkCollisions),ot=a(t=>t.collisionBlasts),rt=a(t=>t.removeCollisionBlast),et=n(t);et.current=t;const nt=e(()=>tt(et.current),[tt]),st=t.difficulty,it=r(()=>new l,[]);o(()=>{U(st)},[st,U]),o(()=>(E?it.startTimer(()=>{q()}):it.stopTimer(),()=>{it.stopTimer()}),[E,it,q]),o(()=>{if(it.stopPhysicsLoop(),it.stopObstacleSpawning(),it.stopCloudSpawning(),E&&!N){const t=setTimeout(()=>{try{it.startPhysicsLoop(z,K,L,Q,W,X,Y,nt,M),it.startObstacleSpawning(Z,st,()=>k),it.startCloudSpawning($),it.startStarSpawning(_,()=>k)}catch(t){M()}},50);return()=>{clearTimeout(t),it.stopPhysicsLoop(),it.stopObstacleSpawning(),it.stopCloudSpawning()}}return()=>{it.stopPhysicsLoop(),it.stopObstacleSpawning(),it.stopCloudSpawning()}},[E,N,it,z,K,L,Q,W,X,Y,nt,M,Z,$,_,st]),o(()=>{N&&!w.current&&I(R>0?"win":"lose"),N||(w.current=!1)},[N,R,I]),o(()=>()=>{it.cleanup()},[it]);const mt=e(()=>{w.current=!1,H(),b(T.DINO_JUMP.START,et.current.enableSounds),h(D.MEDIUM,et.current.enableHaptics)},[H]),at=e(()=>{I("cancel"),M()},[M,I]),ct=e(()=>{V(),U(st),h(D.LIGHT,et.current.enableHaptics)},[V,U,st]),ut=r(()=>({isPlaying:E,gameOver:N,onStartGame:mt,onStopGame:at,startButtonText:"START RUNNING",stopButtonText:"STOP GAME",startButtonSubtext:"Tap to jump over cacti!",stopButtonSubtext:"End current game",startButtonColor:"#FF6347",stopButtonColor:"#dc2626",startButtonBorderColor:"#FF4500",stopButtonBorderColor:"#f87171"}),[E,N,mt,at]),pt=r(()=>({isVisible:N,score:P,onPlayAgain:ct,buttonText:"Run Again!",primaryColor:"rgba(255, 99, 71, 0.5)",borderColor:"rgba(255, 99, 71, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#FF6347"}),[N,P,ct]),ft=r(()=>({gameId:B.DINO_JUMP,settings:t,onSettingsChange:i}),[t,i]);return y(s,{style:G.container,children:y(m,{children:A(d,{offset:k,children:[y(g,{settings:t}),ot.map(t=>y(S,{x:t.x,y:t.y,particleCount:15,colors:["#FF6B35","#FFA500","#FFD700","#FF8C42","#32CD32"],duration:800,onComplete:()=>rt(t.id)},t.id)),y(x,{offset:k}),y(C,{...ut}),y(F,{...pt}),y(j,{...ft})]})})})});const G=i.create({container:{flex:1}});DinoJump.displayName="DinoJump";
@@ -1 +1 @@
1
- "use strict";import{Dimensions}from 'react-native';const{width,height}= Dimensions.get('window');export const DINO_JUMP_CONSTANTS ={gravity:1.0,jumpForce:-20,gameSpeed:{easy:4,medium:6,hard:8},baseScore:{easy:1,medium:1,hard:1},scoreMultiplier:{easy:1,medium:1.5,hard:2},speedIncreaseRate:0.001,maxSpeed:12,timeLimit:{easy:120,medium:180,hard:300}};export const DINO_JUMP_GAME_CONFIG ={SCREEN_WIDTH:width,SCREEN_HEIGHT:height,GROUND_HEIGHT:150,DINOSAUR_WIDTH:55,DINOSAUR_HEIGHT:58,DINOSAUR_X:80,OBSTACLE_WIDTH:20,OBSTACLE_HEIGHT:40,OBSTACLE_SPAWN_DISTANCE:600,GAME_DURATION:120,PHYSICS_FRAME_RATE:60,OBSTACLE_SPAWN_INTERVAL:2000,JUMP_DURATION:600,GROUND_SCROLL_SPEED:4};export const getGroundHeight =(offset = 0)=>{return offset > 0 ? 150:250;};export const getGroundY =(offset = 0)=>{return height - getGroundHeight(offset);};export const DINO_JUMP_ANIMATION_CONFIG ={DINO_JUMP:{damping:15,stiffness:300,mass:1},OBSTACLE_MOVE:{duration:3000},COLLISION_FEEDBACK:{duration:200,intensity:0.1}};export const DINO_JUMP_COLORS ={SKY_TOP:'#FF9A9E',SKY_BOTTOM:'#FECFEF',GROUND:'#FFD93D',GROUND_LINE:'#FF6B6B',DINOSAUR_PRIMARY:'#4ECDC4',DINOSAUR_SECONDARY:'#45B7D1',DINOSAUR_OUTLINE:'#2C3E50',OBSTACLE_PRIMARY:'#2ECC71',OBSTACLE_SECONDARY:'#27AE60',OBSTACLE_OUTLINE:'#1E8449',SCORE_TEXT:'#2C3E50',GAME_OVER_OVERLAY:'rgba(231,76,60,0.8)',BUTTON_PRIMARY:'#E74C3C',BUTTON_SECONDARY:'#C0392B',TEXT_PRIMARY:'#FFFFFF',TEXT_SECONDARY:'#ECF0F1',CLOUD_COLOR:'#FFFFFF',CLOUD_SHADOW:'rgba(52,152,219,0.2)'};export const DINOSAUR_STATES ={RUNNING:'running',JUMPING:'jumping',DUCKING:'ducking',DEAD:'dead'};export const OBSTACLE_TYPES ={CACTUS_SMALL:'cactus_small',CACTUS_LARGE:'cactus_large',BIRD:'bird'};export const DINO_JUMP_THEME ={backgroundColor:'rgba(0,0,0,0.7)',headerBackgroundColor:'#FF6347',headerTextColor:'#ffffff',sectionBackgroundColor:'rgba(255,99,71,0.15)',sectionTitleColor:'#FF6347',buttonSelectedColor:'#FF6347',buttonUnselectedColor:'rgba(255,255,255,0.2)',buttonSelectedTextColor:'#ffffff',buttonUnselectedTextColor:'rgba(255,255,255,0.7)',switchTrackColorFalse:'rgba(255,99,71,0.3)',switchTrackColorTrue:'#FF6347',switchThumbColor:'#ffffff',infoTextColor:'rgba(255,255,255,0.9)'};export const DINO_JUMP_DIFFICULTY_DESCRIPTIONS ={easy:'Slow speed,easy obstacles,perfect for beginners',medium:'Medium speed,moderate challenge with mixed obstacles',hard:'Fast speed,frequent obstacles,expert level challenge'};
1
+ "use strict";import{Dimensions as e}from"react-native";const{width:t,height:o}=e.get("window");export const DINO_JUMP_CONSTANTS={gravity:1,jumpForce:-20,gameSpeed:{easy:4,medium:6,hard:8},baseScore:{easy:1,medium:1,hard:1},scoreMultiplier:{easy:1,medium:1.5,hard:2},speedIncreaseRate:.001,maxSpeed:12,timeLimit:{easy:120,medium:180,hard:300}};export const DINO_JUMP_GAME_CONFIG={SCREEN_WIDTH:t,SCREEN_HEIGHT:o,GROUND_HEIGHT:150,DINOSAUR_WIDTH:55,DINOSAUR_HEIGHT:58,DINOSAUR_X:80,OBSTACLE_WIDTH:20,OBSTACLE_HEIGHT:40,OBSTACLE_SPAWN_DISTANCE:600,GAME_DURATION:120,PHYSICS_FRAME_RATE:60,OBSTACLE_SPAWN_INTERVAL:2e3,JUMP_DURATION:600,GROUND_SCROLL_SPEED:4};export const getGroundHeight=(e=0)=>e>0?150:250;export const getGroundY=(e=0)=>o-getGroundHeight(e);export const DINO_JUMP_ANIMATION_CONFIG={DINO_JUMP:{damping:15,stiffness:300,mass:1},OBSTACLE_MOVE:{duration:3e3},COLLISION_FEEDBACK:{duration:200,intensity:.1}};export const DINO_JUMP_COLORS={SKY_TOP:"#FF9A9E",SKY_BOTTOM:"#FECFEF",GROUND:"#FFD93D",GROUND_LINE:"#FF6B6B",DINOSAUR_PRIMARY:"#4ECDC4",DINOSAUR_SECONDARY:"#45B7D1",DINOSAUR_OUTLINE:"#2C3E50",OBSTACLE_PRIMARY:"#2ECC71",OBSTACLE_SECONDARY:"#27AE60",OBSTACLE_OUTLINE:"#1E8449",SCORE_TEXT:"#2C3E50",GAME_OVER_OVERLAY:"rgba(231, 76, 60, 0.8)",BUTTON_PRIMARY:"#E74C3C",BUTTON_SECONDARY:"#C0392B",TEXT_PRIMARY:"#FFFFFF",TEXT_SECONDARY:"#ECF0F1",CLOUD_COLOR:"#FFFFFF",CLOUD_SHADOW:"rgba(52, 152, 219, 0.2)"};export const DINOSAUR_STATES={RUNNING:"running",JUMPING:"jumping",DUCKING:"ducking",DEAD:"dead"};export const OBSTACLE_TYPES={CACTUS_SMALL:"cactus_small",CACTUS_LARGE:"cactus_large",BIRD:"bird"};export const DINO_JUMP_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#FF6347",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(255, 99, 71, 0.15)",sectionTitleColor:"#FF6347",buttonSelectedColor:"#FF6347",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(255, 99, 71, 0.3)",switchTrackColorTrue:"#FF6347",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const DINO_JUMP_DIFFICULTY_DESCRIPTIONS={easy:"Slow speed, easy obstacles, perfect for beginners",medium:"Medium speed, moderate challenge with mixed obstacles",hard:"Fast speed, frequent obstacles, expert level challenge"};
@@ -1 +1 @@
1
- "use strict";import{DINO_JUMP_CONSTANTS,DINO_JUMP_GAME_CONFIG,getGroundY}from "./DinoJumpConstants.js";export class DinoJumpService{gameTimer = null;physicsAnimationId = null;obstacleTimer = null;cloudTimer = null;starTimer = null;lastFrameTime = 0;obstacleId = 0;cloudId = 0;starId = 0;isPhysicsRunning = false;constructor(){this.lastFrameTime = performance.now();}getDifficultySettings(difficulty){return{speed:DINO_JUMP_CONSTANTS.gameSpeed[difficulty],baseScore:DINO_JUMP_CONSTANTS.baseScore[difficulty],scoreMultiplier:DINO_JUMP_CONSTANTS.scoreMultiplier[difficulty],obstacleSpawnRate:difficulty === 'easy' ? 3000:difficulty === 'medium' ? 2000:1500};}startTimer(decrementTimeCallback){this.stopTimer();this.gameTimer = setInterval(()=>{decrementTimeCallback();},1000);}stopTimer(){if(this.gameTimer){clearInterval(this.gameTimer);this.gameTimer = null;}}startPhysicsLoop(updateDinosaur,updateObstacles,updateClouds,updateStars,updateGround,updateScore,updateSpeed,checkCollisions,stopGame){this.stopPhysicsLoop();this.isPhysicsRunning = true;this.lastFrameTime = performance.now();const physicsLoop = currentTime =>{if(!this.isPhysicsRunning)return;const deltaTime = Math.min((currentTime - this.lastFrameTime)/ 1000,0.016);this.lastFrameTime = currentTime;try{updateDinosaur(deltaTime);updateObstacles(deltaTime);updateClouds(deltaTime);updateStars(deltaTime);updateGround(deltaTime);updateScore(1);updateSpeed();checkCollisions();if(this.isPhysicsRunning){this.physicsAnimationId = requestAnimationFrame(physicsLoop);}}catch(error){console.error('Physics loop error:',error);this.stopPhysicsLoop();stopGame();}};this.physicsAnimationId = requestAnimationFrame(physicsLoop);}stopPhysicsLoop(){this.isPhysicsRunning = false;if(this.physicsAnimationId){cancelAnimationFrame(this.physicsAnimationId);this.physicsAnimationId = null;}}startObstacleSpawning(addObstacle,difficulty,getOffset){this.stopObstacleSpawning();const settings = this.getDifficultySettings(difficulty);const spawnObstacle =()=>{const offset = getOffset();const obstacle = this.createRandomObstacle(offset);addObstacle(obstacle);const nextSpawnTime = settings.obstacleSpawnRate + Math.random()* 1000;this.obstacleTimer = setTimeout(spawnObstacle,nextSpawnTime);};this.obstacleTimer = setTimeout(spawnObstacle,2000);}stopObstacleSpawning(){if(this.obstacleTimer){clearTimeout(this.obstacleTimer);this.obstacleTimer = null;}}startCloudSpawning(addCloud){this.stopCloudSpawning();const spawnCloud =()=>{const cloud = this.createRandomCloud();addCloud(cloud);const nextSpawnTime = 5000 + Math.random()* 5000;this.cloudTimer = setTimeout(spawnCloud,nextSpawnTime);};this.cloudTimer = setTimeout(spawnCloud,3000);}stopCloudSpawning(){if(this.cloudTimer){clearTimeout(this.cloudTimer);this.cloudTimer = null;}}startStarSpawning(addStar,getOffset){this.stopStarSpawning();const spawnStar =()=>{const offset = getOffset();const star = this.createRandomStar(offset);addStar(star);const nextSpawnTime = 8000 + Math.random()* 7000;this.starTimer = setTimeout(spawnStar,nextSpawnTime);};this.starTimer = setTimeout(spawnStar,10000);}stopStarSpawning(){if(this.starTimer){clearTimeout(this.starTimer);this.starTimer = null;}}createRandomObstacle(offset = 0){const types = ['cactus_small','cactus_large'];const type = types[Math.floor(Math.random()* types.length)];let width,height,y;const groundY = getGroundY(offset);switch(type){case 'cactus_small':width = 22;height = 45;y = groundY - height - 22;break;case 'cactus_large':width = 32;height = 65;y = groundY - height - 22;break;}return{id:`obstacle_${this.obstacleId++}`,type,x:DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,y,width,height,speed:5};}createRandomCloud(){return{id:`cloud_${this.cloudId++}`,x:DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,y:50 + Math.random()* 80,width:46 + Math.random()* 30,height:14 + Math.random()* 10,speed:1 + Math.random()* 2};}createRandomStar(offset = 0){const groundY = getGroundY(offset);const width = 45;const height = 45;return{id:`star_${this.starId++}`,x:DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,y:groundY - height - 5,width,height,speed:5};}formatTime(timeInSeconds){const minutes = Math.floor(timeInSeconds / 60);const seconds = timeInSeconds % 60;return `${minutes}:${seconds.toString().padStart(2,'0')}`;}calculateFinalScore(score,timeElapsed,difficulty){const settings = this.getDifficultySettings(difficulty);const timeBonus = Math.max(0,300 - timeElapsed)* settings.scoreMultiplier;return score + timeBonus;}isNewHighScore(currentScore,previousHighScore){return currentScore > previousHighScore;}generateGroundPattern(){const pattern = [];for(let i = 0;i < 20;i++){pattern.push(Math.random()* 3);}return pattern;}cleanup(){this.stopTimer();this.stopPhysicsLoop();this.stopObstacleSpawning();this.stopCloudSpawning();this.stopStarSpawning();}reset(){this.cleanup();this.obstacleId = 0;this.cloudId = 0;this.starId = 0;this.lastFrameTime = performance.now();}}
1
+ "use strict";import{DINO_JUMP_CONSTANTS as t,DINO_JUMP_GAME_CONFIG as s,getGroundY as e}from"./DinoJumpConstants.js";export class DinoJumpService{gameTimer=null;physicsAnimationId=null;obstacleTimer=null;cloudTimer=null;starTimer=null;lastFrameTime=0;obstacleId=0;cloudId=0;starId=0;isPhysicsRunning=!1;constructor(){this.lastFrameTime=performance.now()}getDifficultySettings(s){return{speed:t.gameSpeed[s],baseScore:t.baseScore[s],scoreMultiplier:t.scoreMultiplier[s],obstacleSpawnRate:"easy"===s?3e3:"medium"===s?2e3:1500}}startTimer(t){this.stopTimer(),this.gameTimer=setInterval(()=>{t()},1e3)}stopTimer(){this.gameTimer&&(clearInterval(this.gameTimer),this.gameTimer=null)}startPhysicsLoop(t,s,e,i,a,h,n,r,o){this.stopPhysicsLoop(),this.isPhysicsRunning=!0,this.lastFrameTime=performance.now();const c=l=>{if(!this.isPhysicsRunning)return;const u=Math.min((l-this.lastFrameTime)/1e3,.016);this.lastFrameTime=l;try{t(u),s(u),e(u),i(u),a(u),h(1),n(),r(),this.isPhysicsRunning&&(this.physicsAnimationId=requestAnimationFrame(c))}catch(t){this.stopPhysicsLoop(),o()}};this.physicsAnimationId=requestAnimationFrame(c)}stopPhysicsLoop(){this.isPhysicsRunning=!1,this.physicsAnimationId&&(cancelAnimationFrame(this.physicsAnimationId),this.physicsAnimationId=null)}startObstacleSpawning(t,s,e){this.stopObstacleSpawning();const i=this.getDifficultySettings(s),a=()=>{const s=e(),h=this.createRandomObstacle(s);t(h);const n=i.obstacleSpawnRate+1e3*Math.random();this.obstacleTimer=setTimeout(a,n)};this.obstacleTimer=setTimeout(a,2e3)}stopObstacleSpawning(){this.obstacleTimer&&(clearTimeout(this.obstacleTimer),this.obstacleTimer=null)}startCloudSpawning(t){this.stopCloudSpawning();const s=()=>{const e=this.createRandomCloud();t(e);const i=5e3+5e3*Math.random();this.cloudTimer=setTimeout(s,i)};this.cloudTimer=setTimeout(s,3e3)}stopCloudSpawning(){this.cloudTimer&&(clearTimeout(this.cloudTimer),this.cloudTimer=null)}startStarSpawning(t,s){this.stopStarSpawning();const e=()=>{const i=s(),a=this.createRandomStar(i);t(a);const h=8e3+7e3*Math.random();this.starTimer=setTimeout(e,h)};this.starTimer=setTimeout(e,1e4)}stopStarSpawning(){this.starTimer&&(clearTimeout(this.starTimer),this.starTimer=null)}createRandomObstacle(t=0){const i=["cactus_small","cactus_large"],a=i[Math.floor(Math.random()*i.length)];let h,n,r;const o=e(t);switch(a){case"cactus_small":h=22,n=45,r=o-n-22;break;case"cactus_large":h=32,n=65,r=o-n-22}return{id:"obstacle_"+this.obstacleId++,type:a,x:s.SCREEN_WIDTH+50,y:r,width:h,height:n,speed:5}}createRandomCloud(){return{id:"cloud_"+this.cloudId++,x:s.SCREEN_WIDTH+50,y:50+80*Math.random(),width:46+30*Math.random(),height:14+10*Math.random(),speed:1+2*Math.random()}}createRandomStar(t=0){const i=e(t);return{id:"star_"+this.starId++,x:s.SCREEN_WIDTH+50,y:i-45-5,width:45,height:45,speed:5}}formatTime(t){return`${Math.floor(t/60)}:${(""+t%60).padStart(2,"0")}`}calculateFinalScore(t,s,e){const i=this.getDifficultySettings(e);return t+Math.max(0,300-s)*i.scoreMultiplier}isNewHighScore(t,s){return t>s}generateGroundPattern(){const t=[];for(let s=0;20>s;s++)t.push(3*Math.random());return t}cleanup(){this.stopTimer(),this.stopPhysicsLoop(),this.stopObstacleSpawning(),this.stopCloudSpawning(),this.stopStarSpawning()}reset(){this.cleanup(),this.obstacleId=0,this.cloudId=0,this.starId=0,this.lastFrameTime=performance.now()}}
@@ -1 +1 @@
1
- "use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{immerMiddleware}from "../../services/UtilsService.js";import{DINO_JUMP_CONSTANTS,DINO_JUMP_GAME_CONFIG,getGroundY}from "./DinoJumpConstants.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";export const useDinoJumpStore = create()(subscribeWithSelector(immerMiddleware((set,get)=>({isPlaying:false,isGameOver:false,isPaused:false,dinosaurY:47,dinosaurVelocityY:0,dinosaurState:'running',isJumping:false,isDucking:false,obstacles:[],clouds:[],stars:[],collisionBlasts:[],score:0,distance:0,speed:3,timeLeft:300,timeElapsed:0,startTime:null,lives:3,groundOffset:0,offset:0,setOffset:offset =>{set(state =>{state.offset = offset;});},startGame:()=>{const currentState = get();if(currentState.isPlaying)return;set(state =>{state.isPlaying = true;state.isGameOver = false;state.isPaused = false;state.startTime = Date.now();state.dinosaurState = 'running';});},stopGame:()=>{const state = get();state.resetGame();},resetGame:()=>{set(state =>{state.isPlaying = false;state.isGameOver = false;state.isPaused = false;state.dinosaurY = 47;state.dinosaurVelocityY = 0;state.dinosaurState = 'running';state.isJumping = false;state.isDucking = false;state.obstacles = [];state.clouds = [];state.score = 0;state.distance = 0;state.speed = 3;state.timeLeft = 300;state.timeElapsed = 0;state.startTime = null;state.lives = 3;state.groundOffset = 0;});},pauseGame:()=>{set(state =>{state.isPaused = true;});},resumeGame:()=>{set(state =>{state.isPaused = false;});},jump:()=>{try{const state = get();if(!state || !state.isPlaying || state.isGameOver || state.isPaused || state.isJumping){return;}set(state =>{state.isJumping = true;state.dinosaurVelocityY = DINO_JUMP_CONSTANTS.jumpForce;state.dinosaurState = 'jumping';});}catch(error){console.error('Jump action error:',error);}},updateDinosaur:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{if(state.isJumping){state.dinosaurVelocityY += DINO_JUMP_CONSTANTS.gravity;state.dinosaurY += state.dinosaurVelocityY;if(state.dinosaurY >= 47){state.dinosaurY = 47;state.dinosaurVelocityY = 0;state.isJumping = false;state.dinosaurState = 'running';}}});},addObstacle:obstacle =>{set(state =>{if(state.obstacles.length < 8){state.obstacles.push(obstacle);}});},removeObstacle:id =>{set(state =>{state.obstacles = state.obstacles.filter(obstacle => obstacle.id !== id);});},updateObstacles:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.obstacles.forEach(obstacle =>{obstacle.x -= obstacle.speed;});state.obstacles = state.obstacles.filter(obstacle => obstacle.x > -obstacle.width);});},addCloud:cloud =>{set(state =>{state.clouds.push(cloud);});},addStar:star =>{set(state =>{state.stars.push(star);});},updateStars:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.stars.forEach(star =>{star.x -= star.speed;});state.stars = state.stars.filter(star => star.x > -star.width);});},updateClouds:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.clouds.forEach(cloud =>{cloud.x -= cloud.speed;});state.clouds = state.clouds.filter(cloud => cloud.x > -cloud.width);});},removeCollisionBlast:id =>{set(state =>{state.collisionBlasts = state.collisionBlasts.filter(blast => blast.id !== id);});},checkCollisions:settings =>{const state = get();const dinosaurX = DINO_JUMP_GAME_CONFIG.DINOSAUR_X;const dinosaurWidth = DINO_JUMP_GAME_CONFIG.DINOSAUR_WIDTH;const dinosaurHeight = state.isDucking ? 30:DINO_JUMP_GAME_CONFIG.DINOSAUR_HEIGHT;const groundY = getGroundY(state.offset);const dinosaurScreenY = groundY - dinosaurHeight - 2 -(47 - state.dinosaurY);for(const star of state.stars){if(dinosaurX < star.x + star.width && dinosaurX + dinosaurWidth > star.x && dinosaurScreenY < star.y + star.height && dinosaurScreenY + dinosaurHeight > star.y){set(state =>{state.lives = Math.min(state.lives + 1,5);state.score += 50;state.stars = state.stars.filter(s => s.id !== star.id);});playSound(GAME_SOUNDS.DINO_JUMP.COLLECT,settings.enableSounds);playHaptic(HapticType.SUCCESS,settings.enableHaptics);}}for(const obstacle of state.obstacles){if(dinosaurX < obstacle.x + obstacle.width && dinosaurX + dinosaurWidth > obstacle.x && dinosaurScreenY < obstacle.y + obstacle.height && dinosaurScreenY + dinosaurHeight > obstacle.y){set(state =>{state.lives -= 1;const collisionX = obstacle.x + obstacle.width / 2;const collisionY = obstacle.y + obstacle.height / 2;state.collisionBlasts.push({id:`blast_${Date.now()}`,x:collisionX,y:collisionY});state.obstacles = state.obstacles.filter(obs => obs.id !== obstacle.id);if(state.lives <= 0){state.isGameOver = true;state.isPlaying = false;state.dinosaurState = 'dead';playSound(GAME_SOUNDS.DINO_JUMP.GAME_OVER,settings.enableSounds);playHaptic(HapticType.ERROR,settings.enableHaptics);}else{playSound(GAME_SOUNDS.DINO_JUMP.HIT,settings.enableSounds);playHaptic(HapticType.HEAVY,settings.enableHaptics);}});return true;}}return false;},updateScore:points =>{set(state =>{state.score += points;state.distance += 1;});},updateSpeed:()=>{set(state =>{const speedIncrease = Math.floor(state.distance / 100)* 0.5;state.speed = Math.min(3 + speedIncrease,10);});},updateGround:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.groundOffset += state.speed;if(state.groundOffset >= 100){state.groundOffset = 0;}});},decrementTime:()=>{set(state =>{if(state.timeLeft > 0){state.timeLeft--;if(state.startTime){state.timeElapsed = Math.floor((Date.now()- state.startTime)/ 1000);}}else{state.isPlaying = false;state.isGameOver = true;state.startTime = null;}});},initializeGame:difficulty =>{set(state =>{const speeds ={easy:3,medium:5,hard:7};state.speed = speeds[difficulty];const timeLimits = DINO_JUMP_CONSTANTS.timeLimit;const timeLimit = timeLimits[difficulty];state.isPlaying = false;state.isGameOver = false;state.isPaused = false;state.dinosaurY = 47;state.dinosaurVelocityY = 0;state.dinosaurState = 'running';state.isJumping = false;state.isDucking = false;state.obstacles = [];state.clouds = [];state.score = 0;state.distance = 0;state.timeLeft = timeLimit;state.timeElapsed = 0;state.startTime = null;state.groundOffset = 0;});}}))));export const useIsPlaying =()=> useDinoJumpStore(state => state.isPlaying);export const useIsGameOver =()=> useDinoJumpStore(state => state.isGameOver);export const useIsPaused =()=> useDinoJumpStore(state => state.isPaused);export const useDinosaurY =()=> useDinoJumpStore(state => state.dinosaurY);export const useDinosaurVelocityY =()=> useDinoJumpStore(state => state.dinosaurVelocityY);export const useDinosaurStateValue =()=> useDinoJumpStore(state => state.dinosaurState);export const useIsJumping =()=> useDinoJumpStore(state => state.isJumping);export const useIsDucking =()=> useDinoJumpStore(state => state.isDucking);export const useScore =()=> useDinoJumpStore(state => state.score);export const useTimeLeft =()=> useDinoJumpStore(state => state.timeLeft);export const useLives =()=> useDinoJumpStore(state => state.lives);export const useObstacles =()=> useDinoJumpStore(state => state.obstacles);export const useClouds =()=> useDinoJumpStore(state => state.clouds);export const useGroundOffset =()=> useDinoJumpStore(state => state.groundOffset);export const useStars =()=> useDinoJumpStore(state => state.stars);
1
+ "use strict";import{create as e}from"zustand";import{subscribeWithSelector as s}from"zustand/middleware";import{immerMiddleware as t}from"../../services/UtilsService.js";import{DINO_JUMP_CONSTANTS as o,DINO_JUMP_GAME_CONFIG as u,getGroundY as n}from"./DinoJumpConstants.js";import{playSound as r,GAME_SOUNDS as i}from"../../services/SoundsService.js";import{playHaptic as a,HapticType as c}from"../../services/HapticsService.js";export const useDinoJumpStore=e()(s(t((e,s)=>({isPlaying:!1,isGameOver:!1,isPaused:!1,dinosaurY:47,dinosaurVelocityY:0,dinosaurState:"running",isJumping:!1,isDucking:!1,obstacles:[],clouds:[],stars:[],collisionBlasts:[],score:0,distance:0,speed:3,timeLeft:300,timeElapsed:0,startTime:null,lives:3,groundOffset:0,offset:0,setOffset:s=>{e(e=>{e.offset=s})},startGame:()=>{s().isPlaying||e(e=>{e.isPlaying=!0,e.isGameOver=!1,e.isPaused=!1,e.startTime=Date.now(),e.dinosaurState="running"})},stopGame:()=>{s().resetGame()},resetGame:()=>{e(e=>{e.isPlaying=!1,e.isGameOver=!1,e.isPaused=!1,e.dinosaurY=47,e.dinosaurVelocityY=0,e.dinosaurState="running",e.isJumping=!1,e.isDucking=!1,e.obstacles=[],e.clouds=[],e.score=0,e.distance=0,e.speed=3,e.timeLeft=300,e.timeElapsed=0,e.startTime=null,e.lives=3,e.groundOffset=0})},pauseGame:()=>{e(e=>{e.isPaused=!0})},resumeGame:()=>{e(e=>{e.isPaused=!1})},jump:()=>{try{const t=s();if(!t||!t.isPlaying||t.isGameOver||t.isPaused||t.isJumping)return;e(e=>{e.isJumping=!0,e.dinosaurVelocityY=o.jumpForce,e.dinosaurState="jumping"})}catch(e){}},updateDinosaur:t=>{const u=s();u.isPlaying&&!u.isGameOver&&e(e=>{e.isJumping&&(e.dinosaurVelocityY+=o.gravity,e.dinosaurY+=e.dinosaurVelocityY,47>e.dinosaurY||(e.dinosaurY=47,e.dinosaurVelocityY=0,e.isJumping=!1,e.dinosaurState="running"))})},addObstacle:s=>{e(e=>{8>e.obstacles.length&&e.obstacles.push(s)})},removeObstacle:s=>{e(e=>{e.obstacles=e.obstacles.filter(e=>e.id!==s)})},updateObstacles:t=>{const o=s();o.isPlaying&&!o.isGameOver&&e(e=>{e.obstacles.forEach(e=>{e.x-=e.speed}),e.obstacles=e.obstacles.filter(e=>e.x>-e.width)})},addCloud:s=>{e(e=>{e.clouds.push(s)})},addStar:s=>{e(e=>{e.stars.push(s)})},updateStars:t=>{const o=s();o.isPlaying&&!o.isGameOver&&e(e=>{e.stars.forEach(e=>{e.x-=e.speed}),e.stars=e.stars.filter(e=>e.x>-e.width)})},updateClouds:t=>{const o=s();o.isPlaying&&!o.isGameOver&&e(e=>{e.clouds.forEach(e=>{e.x-=e.speed}),e.clouds=e.clouds.filter(e=>e.x>-e.width)})},removeCollisionBlast:s=>{e(e=>{e.collisionBlasts=e.collisionBlasts.filter(e=>e.id!==s)})},checkCollisions:t=>{const o=s(),p=u.DINOSAUR_X,m=u.DINOSAUR_WIDTH,d=o.isDucking?30:u.DINOSAUR_HEIGHT,l=n(o.offset)-d-2-(47-o.dinosaurY);for(const s of o.stars)p<s.x+s.width&&p+m>s.x&&l<s.y+s.height&&l+d>s.y&&(e(e=>{e.lives=Math.min(e.lives+1,5),e.score+=50,e.stars=e.stars.filter(e=>e.id!==s.id)}),r(i.DINO_JUMP.COLLECT,t.enableSounds),a(c.SUCCESS,t.enableHaptics));for(const s of o.obstacles)if(p<s.x+s.width&&p+m>s.x&&l<s.y+s.height&&l+d>s.y)return e(e=>{e.lives-=1;const o=s.x+s.width/2,u=s.y+s.height/2;e.collisionBlasts.push({id:"blast_"+Date.now(),x:o,y:u}),e.obstacles=e.obstacles.filter(e=>e.id!==s.id),e.lives>0?(r(i.DINO_JUMP.HIT,t.enableSounds),a(c.HEAVY,t.enableHaptics)):(e.isGameOver=!0,e.isPlaying=!1,e.dinosaurState="dead",r(i.DINO_JUMP.GAME_OVER,t.enableSounds),a(c.ERROR,t.enableHaptics))}),!0;return!1},updateScore:s=>{e(e=>{e.score+=s,e.distance+=1})},updateSpeed:()=>{e(e=>{const s=.5*Math.floor(e.distance/100);e.speed=Math.min(3+s,10)})},updateGround:t=>{const o=s();o.isPlaying&&!o.isGameOver&&e(e=>{e.groundOffset+=e.speed,100>e.groundOffset||(e.groundOffset=0)})},decrementTime:()=>{e(e=>{e.timeLeft>0?(e.timeLeft--,e.startTime&&(e.timeElapsed=Math.floor((Date.now()-e.startTime)/1e3))):(e.isPlaying=!1,e.isGameOver=!0,e.startTime=null)})},initializeGame:s=>{e(e=>{e.speed={easy:3,medium:5,hard:7}[s];const t=o.timeLimit[s];e.isPlaying=!1,e.isGameOver=!1,e.isPaused=!1,e.dinosaurY=47,e.dinosaurVelocityY=0,e.dinosaurState="running",e.isJumping=!1,e.isDucking=!1,e.obstacles=[],e.clouds=[],e.score=0,e.distance=0,e.timeLeft=t,e.timeElapsed=0,e.startTime=null,e.groundOffset=0})}}))));export const useIsPlaying=()=>useDinoJumpStore(e=>e.isPlaying);export const useIsGameOver=()=>useDinoJumpStore(e=>e.isGameOver);export const useIsPaused=()=>useDinoJumpStore(e=>e.isPaused);export const useDinosaurY=()=>useDinoJumpStore(e=>e.dinosaurY);export const useDinosaurVelocityY=()=>useDinoJumpStore(e=>e.dinosaurVelocityY);export const useDinosaurStateValue=()=>useDinoJumpStore(e=>e.dinosaurState);export const useIsJumping=()=>useDinoJumpStore(e=>e.isJumping);export const useIsDucking=()=>useDinoJumpStore(e=>e.isDucking);export const useScore=()=>useDinoJumpStore(e=>e.score);export const useTimeLeft=()=>useDinoJumpStore(e=>e.timeLeft);export const useLives=()=>useDinoJumpStore(e=>e.lives);export const useObstacles=()=>useDinoJumpStore(e=>e.obstacles);export const useClouds=()=>useDinoJumpStore(e=>e.clouds);export const useGroundOffset=()=>useDinoJumpStore(e=>e.groundOffset);export const useStars=()=>useDinoJumpStore(e=>e.stars);
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{StyleSheet}from 'react-native';import Animated,{useAnimatedStyle,useSharedValue}from 'react-native-reanimated';import{Canvas,Group,RoundedRect,Circle,LinearGradient,vec}from '@shopify/react-native-skia';import{useDinosaurY,useDinosaurStateValue,useIsPlaying,useDinoJumpStore}from "../DinoJumpStore.js";import{DINO_JUMP_GAME_CONFIG,getGroundY}from "../DinoJumpConstants.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from "react/jsx-runtime";export const DinoSprite = React.memo(()=>{const dinosaurY = useDinosaurY();const dinosaurState = useDinosaurStateValue();const isPlaying = useIsPlaying();const offset = useDinoJumpStore(state => state.offset);const animatedY = React.useRef(useSharedValue(47)).current;const animatedScale = React.useRef(useSharedValue(1)).current;const [legAnimation,setLegAnimation] = React.useState(0);const [bodyBob,setBodyBob] = React.useState(0);if(typeof dinosaurY !== 'number' || isNaN(dinosaurY)){return null;}React.useEffect(()=>{animatedY.value = dinosaurY;},[dinosaurY,animatedY]);React.useEffect(()=>{if(isPlaying && dinosaurState === 'running'){const interval = setInterval(()=>{setLegAnimation(prev => prev === 0 ? 1:0);setBodyBob(prev => prev === 0 ? -1.5:0);},150);return()=> clearInterval(interval);}setLegAnimation(0);setBodyBob(0);return undefined;},[isPlaying,dinosaurState]);React.useEffect(()=>{animatedScale.value = 1;},[dinosaurState,animatedScale]);const animatedStyle = useAnimatedStyle(()=>({transform:[{translateY:-(47 - animatedY.value)},{scale:animatedScale.value}]}));const renderDinosaur = React.useMemo(()=>{const{DINOSAUR_WIDTH,DINOSAUR_HEIGHT}= DINO_JUMP_GAME_CONFIG;const isDead = dinosaurState === 'dead';const legOffset = legAnimation === 0 ? 0:6;const bob = bodyBob;const scale = 1.25;const originalHeight = 47;return _jsx(Canvas,{style:{width:DINOSAUR_WIDTH + 20,height:DINOSAUR_HEIGHT + 20},children:_jsxs(Group,{transform:[{scale}],children:[_jsxs(Group,{transform:[{translateY:bob}],children:[_jsx(RoundedRect,{x:0,y:18,width:16,height:10,r:5,children:_jsx(LinearGradient,{start:vec(0,18),end:vec(16,28),colors:['#FF6B35','#FF8C42','#FFA500']})}),_jsx(RoundedRect,{x:0,y:22,width:8,height:6,r:3,children:_jsx(LinearGradient,{start:vec(0,22),end:vec(8,28),colors:['#FF8C42','#FFA500']})})]}),_jsxs(Group,{transform:[{translateY:bob}],children:[_jsx(RoundedRect,{x:12,y:12,width:26,height:26,r:8,children:_jsx(LinearGradient,{start:vec(12,12),end:vec(38,38),colors:['#FF6B35','#FF8C42','#FFA500','#FF6B35']})}),_jsx(RoundedRect,{x:16,y:14,width:12,height:12,r:6,opacity:0.4,children:_jsx(LinearGradient,{start:vec(16,14),end:vec(28,26),colors:['#FFFFFF','transparent']})}),_jsx(RoundedRect,{x:18,y:24,width:16,height:12,r:6,opacity:0.7,children:_jsx(LinearGradient,{start:vec(18,24),end:vec(34,36),colors:['#FFD93D','#FFC93D']})})]}),_jsxs(Group,{children:[_jsx(RoundedRect,{x:16,y:originalHeight - 10 + legOffset,width:5,height:12 - legOffset,r:2.5,children:_jsx(LinearGradient,{start:vec(16,originalHeight - 10),end:vec(21,originalHeight + 2),colors:['#FF6B35','#FF8C42']})}),_jsx(RoundedRect,{x:14,y:originalHeight + 2,width:8,height:4,r:2,children:_jsx(LinearGradient,{start:vec(14,originalHeight + 2),end:vec(22,originalHeight + 6),colors:['#FFA500','#FF8C42']})})]}),_jsxs(Group,{children:[_jsx(RoundedRect,{x:26,y:originalHeight - 10 - legOffset,width:5,height:12 + legOffset,r:2.5,children:_jsx(LinearGradient,{start:vec(26,originalHeight - 10),end:vec(31,originalHeight + 2),colors:['#FF6B35','#FF8C42']})}),_jsx(RoundedRect,{x:24,y:originalHeight + 2,width:8,height:4,r:2,children:_jsx(LinearGradient,{start:vec(24,originalHeight + 2),end:vec(32,originalHeight + 6),colors:['#FFA500','#FF8C42']})})]}),_jsxs(Group,{transform:[{translateY:bob}],children:[_jsx(RoundedRect,{x:32,y:8,width:8,height:12,r:4,children:_jsx(LinearGradient,{start:vec(32,8),end:vec(40,20),colors:['#FF6B35','#FF8C42']})}),_jsx(RoundedRect,{x:36,y:4,width:18,height:16,r:8,children:_jsx(LinearGradient,{start:vec(36,4),end:vec(54,20),colors:['#FF6B35','#FF8C42','#FFA500']})}),_jsx(RoundedRect,{x:40,y:6,width:8,height:6,r:4,opacity:0.5,children:_jsx(LinearGradient,{start:vec(40,6),end:vec(48,12),colors:['#FFFFFF','transparent']})}),_jsx(RoundedRect,{x:50,y:10,width:8,height:8,r:4,children:_jsx(LinearGradient,{start:vec(50,10),end:vec(58,18),colors:['#FFA500','#FF8C42']})}),_jsx(Circle,{cx:54,cy:14,r:1.5,color:"#8B4513",opacity:0.6}),_jsx(Circle,{cx:46,cy:10,r:3,color:"#000000"}),isDead ? _jsxs(_Fragment,{children:[_jsx(Circle,{cx:45,cy:9,r:1,color:"#FF0000"}),_jsx(Circle,{cx:47,cy:11,r:1,color:"#FF0000"}),_jsx(Circle,{cx:47,cy:9,r:1,color:"#FF0000"}),_jsx(Circle,{cx:45,cy:11,r:1,color:"#FF0000"})]}):_jsx(_Fragment,{children:_jsx(Circle,{cx:46.5,cy:9.5,r:1,color:"#FFFFFF",opacity:0.8})}),_jsxs(Group,{children:[_jsx(RoundedRect,{x:28,y:20,width:3,height:8,r:1.5,children:_jsx(LinearGradient,{start:vec(28,20),end:vec(31,28),colors:['#FF6B35','#FF8C42']})}),_jsx(Circle,{cx:29.5,cy:28,r:1.5,children:_jsx(LinearGradient,{start:vec(28,27),end:vec(31,29),colors:['#FFA500','#FF8C42']})})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:20,cy:12,r:2.5,color:"#32CD32",opacity:0.8}),_jsx(Circle,{cx:26,cy:10,r:3,color:"#32CD32",opacity:0.8}),_jsx(Circle,{cx:32,cy:10,r:2.5,color:"#32CD32",opacity:0.8})]})]})]})});},[dinosaurState,legAnimation,bodyBob]);const groundY = getGroundY(offset);const dinosaurTop = groundY -(DINO_JUMP_GAME_CONFIG.DINOSAUR_HEIGHT + 20)- 2;return _jsx(Animated.View,{style:[styles.container,animatedStyle,{top:dinosaurTop}],children:renderDinosaur});});const styles = StyleSheet.create({container:{position:'absolute',width:DINO_JUMP_GAME_CONFIG.DINOSAUR_WIDTH + 20,height:DINO_JUMP_GAME_CONFIG.DINOSAUR_HEIGHT + 20,left:DINO_JUMP_GAME_CONFIG.DINOSAUR_X - 10},canvas:{flex:1}});DinoSprite.displayName = 'DinoSprite';
1
+ "use strict";import r from"react";import{StyleSheet as t}from"react-native";import e,{useAnimatedStyle as c,useSharedValue as o}from"react-native-reanimated";import{Canvas as i,Group as n,RoundedRect as F,Circle as h,LinearGradient as s,vec as l}from"@shopify/react-native-skia";import{useDinosaurY as a,useDinosaurStateValue as d,useIsPlaying as y,useDinoJumpStore as x}from"../DinoJumpStore.js";import{DINO_JUMP_GAME_CONFIG as p,getGroundY as m}from"../DinoJumpConstants.js";import{jsx as f,jsxs as g,Fragment as C}from"react/jsx-runtime";export const DinoSprite=r.memo(()=>{const t=a(),D=d(),u=y(),A=x(r=>r.offset),B=r.useRef(o(47)).current,v=r.useRef(o(1)).current,[I,S]=r.useState(0),[j,N]=r.useState(0);if("number"!=typeof t||isNaN(t))return null;r.useEffect(()=>{B.value=t},[t,B]),r.useEffect(()=>{if(u&&"running"===D){const r=setInterval(()=>{S(r=>0===r?1:0),N(r=>0===r?-1.5:0)},150);return()=>clearInterval(r)}S(0),N(0)},[u,D]),r.useEffect(()=>{v.value=1},[D,v]);const Y=c(()=>({transform:[{translateY:-(47-B.value)},{scale:v.value}]})),H=r.useMemo(()=>{const{DINOSAUR_WIDTH:r,DINOSAUR_HEIGHT:t}=p,e="dead"===D,c=0===I?0:6,o=j;return f(i,{style:{width:r+20,height:t+20},children:g(n,{transform:[{scale:1.25}],children:[g(n,{transform:[{translateY:o}],children:[f(F,{x:0,y:18,width:16,height:10,r:5,children:f(s,{start:l(0,18),end:l(16,28),colors:["#FF6B35","#FF8C42","#FFA500"]})}),f(F,{x:0,y:22,width:8,height:6,r:3,children:f(s,{start:l(0,22),end:l(8,28),colors:["#FF8C42","#FFA500"]})})]}),g(n,{transform:[{translateY:o}],children:[f(F,{x:12,y:12,width:26,height:26,r:8,children:f(s,{start:l(12,12),end:l(38,38),colors:["#FF6B35","#FF8C42","#FFA500","#FF6B35"]})}),f(F,{x:16,y:14,width:12,height:12,r:6,opacity:.4,children:f(s,{start:l(16,14),end:l(28,26),colors:["#FFFFFF","transparent"]})}),f(F,{x:18,y:24,width:16,height:12,r:6,opacity:.7,children:f(s,{start:l(18,24),end:l(34,36),colors:["#FFD93D","#FFC93D"]})})]}),g(n,{children:[f(F,{x:16,y:37+c,width:5,height:12-c,r:2.5,children:f(s,{start:l(16,37),end:l(21,49),colors:["#FF6B35","#FF8C42"]})}),f(F,{x:14,y:49,width:8,height:4,r:2,children:f(s,{start:l(14,49),end:l(22,53),colors:["#FFA500","#FF8C42"]})})]}),g(n,{children:[f(F,{x:26,y:37-c,width:5,height:12+c,r:2.5,children:f(s,{start:l(26,37),end:l(31,49),colors:["#FF6B35","#FF8C42"]})}),f(F,{x:24,y:49,width:8,height:4,r:2,children:f(s,{start:l(24,49),end:l(32,53),colors:["#FFA500","#FF8C42"]})})]}),g(n,{transform:[{translateY:o}],children:[f(F,{x:32,y:8,width:8,height:12,r:4,children:f(s,{start:l(32,8),end:l(40,20),colors:["#FF6B35","#FF8C42"]})}),f(F,{x:36,y:4,width:18,height:16,r:8,children:f(s,{start:l(36,4),end:l(54,20),colors:["#FF6B35","#FF8C42","#FFA500"]})}),f(F,{x:40,y:6,width:8,height:6,r:4,opacity:.5,children:f(s,{start:l(40,6),end:l(48,12),colors:["#FFFFFF","transparent"]})}),f(F,{x:50,y:10,width:8,height:8,r:4,children:f(s,{start:l(50,10),end:l(58,18),colors:["#FFA500","#FF8C42"]})}),f(h,{cx:54,cy:14,r:1.5,color:"#8B4513",opacity:.6}),f(h,{cx:46,cy:10,r:3,color:"#000000"}),e?g(C,{children:[f(h,{cx:45,cy:9,r:1,color:"#FF0000"}),f(h,{cx:47,cy:11,r:1,color:"#FF0000"}),f(h,{cx:47,cy:9,r:1,color:"#FF0000"}),f(h,{cx:45,cy:11,r:1,color:"#FF0000"})]}):f(C,{children:f(h,{cx:46.5,cy:9.5,r:1,color:"#FFFFFF",opacity:.8})}),g(n,{children:[f(F,{x:28,y:20,width:3,height:8,r:1.5,children:f(s,{start:l(28,20),end:l(31,28),colors:["#FF6B35","#FF8C42"]})}),f(h,{cx:29.5,cy:28,r:1.5,children:f(s,{start:l(28,27),end:l(31,29),colors:["#FFA500","#FF8C42"]})})]}),g(n,{children:[f(h,{cx:20,cy:12,r:2.5,color:"#32CD32",opacity:.8}),f(h,{cx:26,cy:10,r:3,color:"#32CD32",opacity:.8}),f(h,{cx:32,cy:10,r:2.5,color:"#32CD32",opacity:.8})]})]})]})})},[D,I,j]),b=m(A)-(p.DINOSAUR_HEIGHT+20)-2;return f(e.View,{style:[w.container,Y,{top:b}],children:H})});const w=t.create({container:{position:"absolute",width:p.DINOSAUR_WIDTH+20,height:p.DINOSAUR_HEIGHT+20,left:p.DINOSAUR_X-10},canvas:{flex:1}});DinoSprite.displayName="DinoSprite";
@@ -1 +1 @@
1
- "use strict";import React,{useMemo,useCallback,useRef}from 'react';import{View,StyleSheet}from 'react-native';import{GestureDetector,Gesture}from 'react-native-gesture-handler';import{useDinoJumpStore,useIsPlaying,useIsGameOver}from "../DinoJumpStore.js";import{DinoSprite}from "./DinoSprite.js";import{ObstacleSprite}from "./ObstacleSprite.js";import{StarSprite}from "./StarSprite.js";import{playSound,GAME_SOUNDS}from "../../../services/SoundsService.js";import{playHaptic,HapticType}from "../../../services/HapticsService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const GameArea = React.memo(({settings})=>{const isPlaying = useIsPlaying();const isGameOver = useIsGameOver();const jump = useDinoJumpStore(state => state.jump);const settingsRef = useRef(settings);settingsRef.current = settings;const handleTapGesture = useCallback(()=>{try{if(isPlaying && !isGameOver && jump){requestAnimationFrame(()=>{try{jump();playSound(GAME_SOUNDS.SWOOSH,settingsRef.current.enableSounds);playHaptic(HapticType.LIGHT,settingsRef.current.enableHaptics);}catch(error){console.error('Jump execution error:',error);}});}}catch(error){console.error('Tap gesture handler error:',error);}},[isPlaying,isGameOver,jump]);const tapGesture = useMemo(()=> Gesture.Tap().runOnJS(true).onStart(handleTapGesture),[handleTapGesture]);return _jsx(GestureDetector,{gesture:tapGesture,children:_jsxs(View,{style:styles.gameArea,children:[_jsx(DinoSprite,{}),_jsx(StarSprite,{}),_jsx(ObstacleSprite,{})]})});},(prevProps,nextProps)=>{return prevProps.settings === nextProps.settings;});const styles = StyleSheet.create({gameArea:{flex:1,paddingTop:80,paddingBottom:120}});GameArea.displayName = 'GameArea';
1
+ "use strict";import r,{useMemo as t,useCallback as e,useRef as o}from"react";import{View as i,StyleSheet as s}from"react-native";import{GestureDetector as m,Gesture as a}from"react-native-gesture-handler";import{useDinoJumpStore as c,useIsPlaying as n,useIsGameOver as p}from"../DinoJumpStore.js";import{DinoSprite as f}from"./DinoSprite.js";import{ObstacleSprite as j}from"./ObstacleSprite.js";import{StarSprite as d}from"./StarSprite.js";import{playSound as u,GAME_SOUNDS as S}from"../../../services/SoundsService.js";import{playHaptic as g,HapticType as l}from"../../../services/HapticsService.js";import{jsx as v,jsxs as h}from"react/jsx-runtime";export const GameArea=r.memo(({settings:r})=>{const s=n(),A=p(),y=c(r=>r.jump),G=o(r);G.current=r;const D=e(()=>{try{s&&!A&&y&&requestAnimationFrame(()=>{try{y(),u(S.SWOOSH,G.current.enableSounds),g(l.LIGHT,G.current.enableHaptics)}catch(r){}})}catch(r){}},[s,A,y]),b=t(()=>a.Tap().runOnJS(!0).onStart(D),[D]);return v(m,{gesture:b,children:h(i,{style:x.gameArea,children:[v(f,{}),v(d,{}),v(j,{})]})})},(r,t)=>r.settings===t.settings);const x=s.create({gameArea:{flex:1,paddingTop:80,paddingBottom:120}});GameArea.displayName="GameArea";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,StyleSheet,Dimensions}from 'react-native';import{Canvas,LinearGradient,Rect,vec,Circle,Path,Skia,Group,Shadow}from '@shopify/react-native-skia';import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');const createGroundPath = groundY =>{const path = Skia.Path.Make();path.moveTo(0,groundY);path.lineTo(width,groundY);path.lineTo(width,height);path.lineTo(0,height);path.close();return path;};const createStaticSunRays =()=>{return Array.from({length:16},(_,index)=>{const angle = 360 / 16 * index;const radian = angle * Math.PI / 180;const isLongRay = index % 2 === 0;const rayLength = isLongRay ? 25:15;const rayWidth = isLongRay ? 4:2;const startDistance = 45;const startX = width * 0.8 + Math.cos(radian)* startDistance;const startY = height * 0.22 + Math.sin(radian)* startDistance;const endX = width * 0.8 + Math.cos(radian)*(startDistance + rayLength);const endY = height * 0.22 + Math.sin(radian)*(startDistance + rayLength);const rayPath = Skia.Path.Make();rayPath.moveTo(startX,startY);rayPath.lineTo(endX,endY);return{path:rayPath,width:rayWidth};});};const staticSunRays = createStaticSunRays();export const GameBackground = React.memo(({children,offset = 0})=>{const groundHeight = offset > 0 ? 150:250;const groundY = height - groundHeight;const groundPath = createGroundPath(groundY);const sunY = height * 0.20 + offset * 0.9;const cloud1Y = height * 0.25 + offset * 0.9;const cloud2Y = height * 0.30 + offset * 0.9;const cloud3Y = height * 0.35 + offset * 0.9;return _jsxs(View,{style:styles.container,children:[_jsxs(Canvas,{style:styles.canvas,children:[_jsx(Rect,{x:0,y:0,width:width,height:groundY,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(0,groundY),colors:['#87CEEB','#98D8E8','#B0E0E6']})}),_jsxs(Group,{children:[_jsxs(Circle,{cx:width * 0.8,cy:sunY,r:40,children:[_jsx(LinearGradient,{start:vec(-40,-40),end:vec(40,40),colors:['#FFFF99','#FFD700','#FFA500','#FF8C00']}),_jsx(Shadow,{dx:0,dy:0,blur:32,color:"#FFD700"})]}),_jsx(Circle,{cx:width * 0.8 - 8,cy:sunY - 8,r:15,children:_jsx(LinearGradient,{start:vec(-15,-15),end:vec(15,15),colors:['#FFFFFF','#FFFF99']})}),staticSunRays.map((_ray,index)=>{const angle = 360 / 16 * index;const radian = angle * Math.PI / 180;const isLongRay = index % 2 === 0;const rayLength = isLongRay ? 25:15;const rayWidth = isLongRay ? 4:2;const startDistance = 45;const startX = width * 0.8 + Math.cos(radian)* startDistance;const startY = sunY + Math.sin(radian)* startDistance;const endX = width * 0.8 + Math.cos(radian)*(startDistance + rayLength);const endY = sunY + Math.sin(radian)*(startDistance + rayLength);const rayPath = Skia.Path.Make();rayPath.moveTo(startX,startY);rayPath.lineTo(endX,endY);return _jsx(Path,{path:rayPath,style:"stroke",strokeWidth:rayWidth,color:"#FFD700",opacity:0.75},index);}),_jsx(Circle,{cx:width * 0.8,cy:sunY,r:60,opacity:0.1,children:_jsx(LinearGradient,{start:vec(-60,-60),end:vec(60,60),colors:['#FFD700','transparent']})})]}),_jsxs(Group,{children:[_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.12,cy:cloud1Y,r:16,color:"#F0F8FF",opacity:0.35,children:_jsx(Shadow,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),_jsx(Circle,{cx:width * 0.18,cy:cloud1Y - height * 0.03,r:22,color:"#FFFFFF",opacity:0.45,children:_jsx(Shadow,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),_jsx(Circle,{cx:width * 0.25,cy:cloud1Y - height * 0.05,r:26,color:"#F8F8FF",opacity:0.55,children:_jsx(Shadow,{dx:2,dy:3,blur:12,color:"rgba(0,0,0,0.06)"})}),_jsx(Circle,{cx:width * 0.32,cy:cloud1Y - height * 0.03,r:20,color:"#FFFFFF",opacity:0.50,children:_jsx(Shadow,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),_jsx(Circle,{cx:width * 0.37,cy:cloud1Y,r:14,color:"#F0F8FF",opacity:0.40,children:_jsx(Shadow,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.04)"})}),_jsx(Circle,{cx:width * 0.15,cy:cloud1Y + height * 0.02,r:8,color:"#F8F8FF",opacity:0.25}),_jsx(Circle,{cx:width * 0.35,cy:cloud1Y - height * 0.06,r:6,color:"#FFFFFF",opacity:0.30}),_jsx(Circle,{cx:width * 0.40,cy:cloud1Y - height * 0.02,r:5,color:"#F0F8FF",opacity:0.20}),_jsx(Circle,{cx:width * 0.22,cy:cloud1Y - height * 0.06,r:7,color:"#FFFFFF",opacity:0.35}),_jsx(Circle,{cx:width * 0.28,cy:cloud1Y - height * 0.04,r:5,color:"#FFFFFF",opacity:0.25})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.62,cy:cloud2Y,r:15,color:"#F0F8FF",opacity:0.40,children:_jsx(Shadow,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.04)"})}),_jsx(Circle,{cx:width * 0.69,cy:cloud2Y - height * 0.03,r:19,color:"#FFFFFF",opacity:0.50,children:_jsx(Shadow,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.05)"})}),_jsx(Circle,{cx:width * 0.76,cy:cloud2Y - height * 0.01,r:13,color:"#F8F8FF",opacity:0.45,children:_jsx(Shadow,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.04)"})}),_jsx(Circle,{cx:width * 0.81,cy:cloud2Y + height * 0.01,r:9,color:"#F0F8FF",opacity:0.35,children:_jsx(Shadow,{dx:1,dy:1,blur:8,color:"rgba(0,0,0,0.03)"})}),_jsx(Circle,{cx:width * 0.65,cy:cloud2Y + height * 0.02,r:6,color:"#F8F8FF",opacity:0.20}),_jsx(Circle,{cx:width * 0.78,cy:cloud2Y - height * 0.04,r:4,color:"#FFFFFF",opacity:0.25}),_jsx(Circle,{cx:width * 0.67,cy:cloud2Y - height * 0.04,r:5,color:"#FFFFFF",opacity:0.30})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.84,cy:cloud3Y,r:10,color:"#F0F8FF",opacity:0.35,children:_jsx(Shadow,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.03)"})}),_jsx(Circle,{cx:width * 0.89,cy:cloud3Y - height * 0.02,r:12,color:"#FFFFFF",opacity:0.40,children:_jsx(Shadow,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.03)"})}),_jsx(Circle,{cx:width * 0.93,cy:cloud3Y,r:8,color:"#F8F8FF",opacity:0.30,children:_jsx(Shadow,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.02)"})}),_jsx(Circle,{cx:width * 0.96,cy:cloud3Y - height * 0.01,r:4,color:"#F0F8FF",opacity:0.15}),_jsx(Circle,{cx:width * 0.86,cy:cloud3Y + height * 0.02,r:3,color:"#FFFFFF",opacity:0.20})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.45,cy:height * 0.21,r:8,color:"#F8F8FF",opacity:0.25,children:_jsx(Shadow,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.02)"})}),_jsx(Circle,{cx:width * 0.50,cy:height * 0.19,r:10,color:"#FFFFFF",opacity:0.30,children:_jsx(Shadow,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.02)"})}),_jsx(Circle,{cx:width * 0.54,cy:height * 0.21,r:6,color:"#F0F8FF",opacity:0.20,children:_jsx(Shadow,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.01)"})})]})]}),_jsxs(Path,{path:groundPath,children:[_jsx(LinearGradient,{start:vec(0,groundY),end:vec(0,height),colors:['#8B4513','#A0522D','#654321']}),_jsx(Shadow,{dx:0,dy:-3,blur:6,color:"rgba(0,0,0,0.3)"})]}),_jsx(Rect,{x:0,y:groundY - 15,width:width,height:15,children:_jsx(LinearGradient,{start:vec(0,groundY - 15),end:vec(0,groundY),colors:['#32CD32','#228B22','#006400']})}),_jsx(Rect,{x:0,y:groundY - 15,width:width,height:2,color:"#004d00"}),Array.from({length:15},(_,i)=>{const x = width / 15 * i + i % 3 * 20;const y = groundY + 30 + i % 4 * 20;const size = 2 + i % 3;return _jsx(Circle,{cx:x,cy:y,r:size,color:"#654321",opacity:0.6},`dirt-${i}`);})]}),children]});});const styles = StyleSheet.create({container:{flex:1},canvas:{position:'absolute',top:0,left:0,right:0,bottom:0,width,height}});GameBackground.displayName = 'GameBackground';
1
+ "use strict";import r from"react";import{View as c,StyleSheet as o,Dimensions as F}from"react-native";import{Canvas as t,LinearGradient as l,Rect as a,vec as i,Circle as d,Path as y,Skia as e,Group as h,Shadow as n}from"@shopify/react-native-skia";import{jsx as x,jsxs as p}from"react/jsx-runtime";const{width:s,height:b}=F.get("window"),g=r=>{const c=e.Path.Make();return c.moveTo(0,r),c.lineTo(s,r),c.lineTo(s,b),c.lineTo(0,b),c.close(),c},u=()=>Array.from({length:16},(r,c)=>{const o=22.5*c*Math.PI/180,F=c%2==0,t=F?25:15,l=F?4:2,a=.8*s+45*Math.cos(o),i=.22*b+45*Math.sin(o),d=.8*s+Math.cos(o)*(45+t),y=.22*b+Math.sin(o)*(45+t),h=e.Path.Make();return h.moveTo(a,i),h.lineTo(d,y),{path:h,width:l}}),m=u();export const GameBackground=r.memo(({children:r,offset:o=0})=>{const F=b-(o>0?150:250),u=g(F),f=.2*b+.9*o,w=.25*b+.9*o,B=.3*b+.9*o,D=.35*b+.9*o;return p(c,{style:M.container,children:[p(t,{style:M.canvas,children:[x(a,{x:0,y:0,width:s,height:F,children:x(l,{start:i(0,0),end:i(0,F),colors:["#87CEEB","#98D8E8","#B0E0E6"]})}),p(h,{children:[p(d,{cx:.8*s,cy:f,r:40,children:[x(l,{start:i(-40,-40),end:i(40,40),colors:["#FFFF99","#FFD700","#FFA500","#FF8C00"]}),x(n,{dx:0,dy:0,blur:32,color:"#FFD700"})]}),x(d,{cx:.8*s-8,cy:f-8,r:15,children:x(l,{start:i(-15,-15),end:i(15,15),colors:["#FFFFFF","#FFFF99"]})}),m.map((r,c)=>{const o=22.5*c*Math.PI/180,F=c%2==0,t=F?25:15,l=F?4:2,a=.8*s+45*Math.cos(o),i=f+45*Math.sin(o),d=.8*s+Math.cos(o)*(45+t),h=f+Math.sin(o)*(45+t),n=e.Path.Make();return n.moveTo(a,i),n.lineTo(d,h),x(y,{path:n,style:"stroke",strokeWidth:l,color:"#FFD700",opacity:.75},c)}),x(d,{cx:.8*s,cy:f,r:60,opacity:.1,children:x(l,{start:i(-60,-60),end:i(60,60),colors:["#FFD700","transparent"]})})]}),p(h,{children:[p(h,{children:[x(d,{cx:.12*s,cy:w,r:16,color:"#F0F8FF",opacity:.35,children:x(n,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),x(d,{cx:.18*s,cy:w-.03*b,r:22,color:"#FFFFFF",opacity:.45,children:x(n,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),x(d,{cx:.25*s,cy:w-.05*b,r:26,color:"#F8F8FF",opacity:.55,children:x(n,{dx:2,dy:3,blur:12,color:"rgba(0,0,0,0.06)"})}),x(d,{cx:.32*s,cy:w-.03*b,r:20,color:"#FFFFFF",opacity:.5,children:x(n,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),x(d,{cx:.37*s,cy:w,r:14,color:"#F0F8FF",opacity:.4,children:x(n,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.04)"})}),x(d,{cx:.15*s,cy:w+.02*b,r:8,color:"#F8F8FF",opacity:.25}),x(d,{cx:.35*s,cy:w-.06*b,r:6,color:"#FFFFFF",opacity:.3}),x(d,{cx:.4*s,cy:w-.02*b,r:5,color:"#F0F8FF",opacity:.2}),x(d,{cx:.22*s,cy:w-.06*b,r:7,color:"#FFFFFF",opacity:.35}),x(d,{cx:.28*s,cy:w-.04*b,r:5,color:"#FFFFFF",opacity:.25})]}),p(h,{children:[x(d,{cx:.62*s,cy:B,r:15,color:"#F0F8FF",opacity:.4,children:x(n,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.04)"})}),x(d,{cx:.69*s,cy:B-.03*b,r:19,color:"#FFFFFF",opacity:.5,children:x(n,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.05)"})}),x(d,{cx:.76*s,cy:B-.01*b,r:13,color:"#F8F8FF",opacity:.45,children:x(n,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.04)"})}),x(d,{cx:.81*s,cy:B+.01*b,r:9,color:"#F0F8FF",opacity:.35,children:x(n,{dx:1,dy:1,blur:8,color:"rgba(0,0,0,0.03)"})}),x(d,{cx:.65*s,cy:B+.02*b,r:6,color:"#F8F8FF",opacity:.2}),x(d,{cx:.78*s,cy:B-.04*b,r:4,color:"#FFFFFF",opacity:.25}),x(d,{cx:.67*s,cy:B-.04*b,r:5,color:"#FFFFFF",opacity:.3})]}),p(h,{children:[x(d,{cx:.84*s,cy:D,r:10,color:"#F0F8FF",opacity:.35,children:x(n,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.03)"})}),x(d,{cx:.89*s,cy:D-.02*b,r:12,color:"#FFFFFF",opacity:.4,children:x(n,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.03)"})}),x(d,{cx:.93*s,cy:D,r:8,color:"#F8F8FF",opacity:.3,children:x(n,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.02)"})}),x(d,{cx:.96*s,cy:D-.01*b,r:4,color:"#F0F8FF",opacity:.15}),x(d,{cx:.86*s,cy:D+.02*b,r:3,color:"#FFFFFF",opacity:.2})]}),p(h,{children:[x(d,{cx:.45*s,cy:.21*b,r:8,color:"#F8F8FF",opacity:.25,children:x(n,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.02)"})}),x(d,{cx:.5*s,cy:.19*b,r:10,color:"#FFFFFF",opacity:.3,children:x(n,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.02)"})}),x(d,{cx:.54*s,cy:.21*b,r:6,color:"#F0F8FF",opacity:.2,children:x(n,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.01)"})})]})]}),p(y,{path:u,children:[x(l,{start:i(0,F),end:i(0,b),colors:["#8B4513","#A0522D","#654321"]}),x(n,{dx:0,dy:-3,blur:6,color:"rgba(0,0,0,0.3)"})]}),x(a,{x:0,y:F-15,width:s,height:15,children:x(l,{start:i(0,F-15),end:i(0,F),colors:["#32CD32","#228B22","#006400"]})}),x(a,{x:0,y:F-15,width:s,height:2,color:"#004d00"}),Array.from({length:15},(r,c)=>x(d,{cx:s/15*c+c%3*20,cy:F+30+c%4*20,r:2+c%3,color:"#654321",opacity:.6},"dirt-"+c))]}),r]})});const M=o.create({container:{flex:1},canvas:{position:"absolute",top:0,left:0,right:0,bottom:0,width:s,height:b}});GameBackground.displayName="GameBackground";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,StyleSheet}from 'react-native';import{useObstacles}from "../DinoJumpStore.js";import{DINO_JUMP_COLORS}from "../DinoJumpConstants.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from "react/jsx-runtime";const SingleObstacle = React.memo(({obstacle})=>{if(!obstacle || typeof obstacle.x !== 'number' || typeof obstacle.y !== 'number'){return null;}const renderCactusSmall = React.useMemo(()=> _jsxs(View,{style:[styles.obstacleContainer,{left:obstacle.x,top:obstacle.y,width:obstacle.width,height:obstacle.height}],children:[_jsx(View,{style:[styles.cactusBody,{width:obstacle.width,height:obstacle.height,backgroundColor:DINO_JUMP_COLORS.OBSTACLE_PRIMARY}]}),_jsx(View,{style:[styles.cactusSpike,{left:2,top:6,width:3,height:3}]}),_jsx(View,{style:[styles.cactusSpike,{right:2,top:10,width:3,height:3}]}),_jsx(View,{style:[styles.cactusSpike,{left:obstacle.width / 2 - 1,top:15,width:3,height:3}]}),_jsx(View,{style:[styles.cactusPlantedBase,{left:obstacle.width / 4,bottom:-6,width:obstacle.width / 2,height:8,backgroundColor:'#654321',borderRadius:4}]}),_jsx(View,{style:[styles.cactusRoot,{left:obstacle.width / 3,bottom:-4,width:obstacle.width / 3,height:4,backgroundColor:DINO_JUMP_COLORS.OBSTACLE_PRIMARY}]})]}),[obstacle.x,obstacle.y,obstacle.width,obstacle.height]);const renderCactusLarge = React.useMemo(()=> _jsxs(View,{style:[styles.obstacleContainer,{left:obstacle.x,top:obstacle.y,width:obstacle.width,height:obstacle.height}],children:[_jsx(View,{style:[styles.cactusBody,{width:obstacle.width,height:obstacle.height,backgroundColor:DINO_JUMP_COLORS.OBSTACLE_PRIMARY}]}),_jsx(View,{style:[styles.cactusArm,{left:-6,top:15,width:8,height:15,backgroundColor:DINO_JUMP_COLORS.OBSTACLE_SECONDARY}]}),_jsx(View,{style:[styles.cactusArm,{right:-2,top:10,width:8,height:20,backgroundColor:DINO_JUMP_COLORS.OBSTACLE_SECONDARY}]}),Array.from({length:6},(_,i)=> _jsx(View,{style:[styles.cactusSpike,{left:2 + i % 3 * 7,top:8 + Math.floor(i / 3)* 15}]},i)),_jsx(View,{style:[styles.cactusPlantedBase,{left:obstacle.width / 4,bottom:-8,width:obstacle.width / 2,height:10,backgroundColor:'#654321',borderRadius:5}]}),_jsx(View,{style:[styles.cactusRoot,{left:obstacle.width / 3,bottom:-5,width:obstacle.width / 3,height:5,backgroundColor:DINO_JUMP_COLORS.OBSTACLE_PRIMARY}]})]}),[obstacle.x,obstacle.y,obstacle.width,obstacle.height]);const renderBird = React.useMemo(()=> _jsxs(View,{style:[styles.obstacleContainer,{left:obstacle.x,top:obstacle.y,width:obstacle.width,height:obstacle.height}],children:[_jsx(View,{style:[styles.birdBody,{left:10,top:15,width:20,height:10}]}),_jsx(View,{style:[styles.birdHead,{left:29,top:12}]}),_jsx(View,{style:[styles.birdBeak,{left:40,top:17}]}),_jsx(View,{style:[styles.birdWing,{left:5,top:10,width:15,height:6}]}),_jsx(View,{style:[styles.birdWing,{left:15,top:8,width:15,height:6}]}),_jsx(View,{style:[styles.birdTail,{left:0,top:18}]})]}),[obstacle.x,obstacle.y,obstacle.width,obstacle.height]);switch(obstacle.type){case 'cactus_small':return renderCactusSmall;case 'cactus_large':return renderCactusLarge;case 'bird':return renderBird;default:return null;}},(prevProps,nextProps)=>{return prevProps.obstacle.x === nextProps.obstacle.x && prevProps.obstacle.y === nextProps.obstacle.y && prevProps.obstacle.type === nextProps.obstacle.type && prevProps.obstacle.id === nextProps.obstacle.id;});export const ObstacleSprite = React.memo(()=>{const obstacles = useObstacles();const visibleObstacles = React.useMemo(()=>{if(!Array.isArray(obstacles)|| obstacles.length === 0){return [];}return obstacles.filter(obstacle => obstacle && obstacle.x > -100 && obstacle.x < 500).slice(0,5);},[obstacles]);if(visibleObstacles.length === 0){return null;}return _jsx(_Fragment,{children:visibleObstacles.map(obstacle => _jsx(SingleObstacle,{obstacle:obstacle},obstacle.id))});});const styles = StyleSheet.create({obstacleContainer:{position:'absolute',shadowColor:'#000',shadowOffset:{width:0,height:2},shadowOpacity:0.25,shadowRadius:3,elevation:4},cactusBody:{borderRadius:6,borderWidth:1,borderColor:DINO_JUMP_COLORS.OBSTACLE_OUTLINE},cactusArm:{position:'absolute',borderRadius:4,borderWidth:1,borderColor:DINO_JUMP_COLORS.OBSTACLE_OUTLINE},cactusSpike:{position:'absolute',width:2,height:2,borderRadius:1,backgroundColor:DINO_JUMP_COLORS.OBSTACLE_OUTLINE},cactusBase:{position:'absolute',borderRadius:2,borderWidth:1,borderColor:DINO_JUMP_COLORS.OBSTACLE_OUTLINE},cactusPlantedBase:{position:'absolute',borderWidth:1,borderColor:'#4a2c1a',shadowColor:'#000',shadowOffset:{width:0,height:1},shadowOpacity:0.3,shadowRadius:2,elevation:2},cactusRoot:{position:'absolute',borderRadius:2},birdBody:{position:'absolute',backgroundColor:'#8B4513',borderRadius:5,borderWidth:1,borderColor:'#654321'},birdHead:{position:'absolute',width:12,height:12,backgroundColor:'#8B4513',borderRadius:6,borderWidth:1,borderColor:'#654321'},birdBeak:{position:'absolute',width:4,height:2,backgroundColor:'#FFD700',borderRadius:1},birdWing:{position:'absolute',backgroundColor:'#A0522D',borderRadius:3,borderWidth:1,borderColor:'#654321'},birdTail:{position:'absolute',width:12,height:4,backgroundColor:'#8B4513',borderRadius:2,borderWidth:1,borderColor:'#654321'}});SingleObstacle.displayName = 'SingleObstacle';ObstacleSprite.displayName = 'ObstacleSprite';
1
+ "use strict";import t from"react";import{View as o,StyleSheet as e}from"react-native";import{useObstacles as r}from"../DinoJumpStore.js";import{DINO_JUMP_COLORS as i}from"../DinoJumpConstants.js";import{jsx as d,jsxs as s,Fragment as l}from"react/jsx-runtime";const h=t.memo(({obstacle:e})=>{if(!e||"number"!=typeof e.x||"number"!=typeof e.y)return null;const r=t.useMemo(()=>s(o,{style:[a.obstacleContainer,{left:e.x,top:e.y,width:e.width,height:e.height}],children:[d(o,{style:[a.cactusBody,{width:e.width,height:e.height,backgroundColor:i.OBSTACLE_PRIMARY}]}),d(o,{style:[a.cactusSpike,{left:2,top:6,width:3,height:3}]}),d(o,{style:[a.cactusSpike,{right:2,top:10,width:3,height:3}]}),d(o,{style:[a.cactusSpike,{left:e.width/2-1,top:15,width:3,height:3}]}),d(o,{style:[a.cactusPlantedBase,{left:e.width/4,bottom:-6,width:e.width/2,height:8,backgroundColor:"#654321",borderRadius:4}]}),d(o,{style:[a.cactusRoot,{left:e.width/3,bottom:-4,width:e.width/3,height:4,backgroundColor:i.OBSTACLE_PRIMARY}]})]}),[e.x,e.y,e.width,e.height]),l=t.useMemo(()=>s(o,{style:[a.obstacleContainer,{left:e.x,top:e.y,width:e.width,height:e.height}],children:[d(o,{style:[a.cactusBody,{width:e.width,height:e.height,backgroundColor:i.OBSTACLE_PRIMARY}]}),d(o,{style:[a.cactusArm,{left:-6,top:15,width:8,height:15,backgroundColor:i.OBSTACLE_SECONDARY}]}),d(o,{style:[a.cactusArm,{right:-2,top:10,width:8,height:20,backgroundColor:i.OBSTACLE_SECONDARY}]}),Array.from({length:6},(t,e)=>d(o,{style:[a.cactusSpike,{left:2+e%3*7,top:8+15*Math.floor(e/3)}]},e)),d(o,{style:[a.cactusPlantedBase,{left:e.width/4,bottom:-8,width:e.width/2,height:10,backgroundColor:"#654321",borderRadius:5}]}),d(o,{style:[a.cactusRoot,{left:e.width/3,bottom:-5,width:e.width/3,height:5,backgroundColor:i.OBSTACLE_PRIMARY}]})]}),[e.x,e.y,e.width,e.height]),h=t.useMemo(()=>s(o,{style:[a.obstacleContainer,{left:e.x,top:e.y,width:e.width,height:e.height}],children:[d(o,{style:[a.birdBody,{left:10,top:15,width:20,height:10}]}),d(o,{style:[a.birdHead,{left:29,top:12}]}),d(o,{style:[a.birdBeak,{left:40,top:17}]}),d(o,{style:[a.birdWing,{left:5,top:10,width:15,height:6}]}),d(o,{style:[a.birdWing,{left:15,top:8,width:15,height:6}]}),d(o,{style:[a.birdTail,{left:0,top:18}]})]}),[e.x,e.y,e.width,e.height]);switch(e.type){case"cactus_small":return r;case"cactus_large":return l;case"bird":return h;default:return null}},(t,o)=>t.obstacle.x===o.obstacle.x&&t.obstacle.y===o.obstacle.y&&t.obstacle.type===o.obstacle.type&&t.obstacle.id===o.obstacle.id);export const ObstacleSprite=t.memo(()=>{const o=r(),e=t.useMemo(()=>Array.isArray(o)&&0!==o.length?o.filter(t=>t&&t.x>-100&&500>t.x).slice(0,5):[],[o]);return 0===e.length?null:d(l,{children:e.map(t=>d(h,{obstacle:t},t.id))})});const a=e.create({obstacleContainer:{position:"absolute",shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.25,shadowRadius:3,elevation:4},cactusBody:{borderRadius:6,borderWidth:1,borderColor:i.OBSTACLE_OUTLINE},cactusArm:{position:"absolute",borderRadius:4,borderWidth:1,borderColor:i.OBSTACLE_OUTLINE},cactusSpike:{position:"absolute",width:2,height:2,borderRadius:1,backgroundColor:i.OBSTACLE_OUTLINE},cactusBase:{position:"absolute",borderRadius:2,borderWidth:1,borderColor:i.OBSTACLE_OUTLINE},cactusPlantedBase:{position:"absolute",borderWidth:1,borderColor:"#4a2c1a",shadowColor:"#000",shadowOffset:{width:0,height:1},shadowOpacity:.3,shadowRadius:2,elevation:2},cactusRoot:{position:"absolute",borderRadius:2},birdBody:{position:"absolute",backgroundColor:"#8B4513",borderRadius:5,borderWidth:1,borderColor:"#654321"},birdHead:{position:"absolute",width:12,height:12,backgroundColor:"#8B4513",borderRadius:6,borderWidth:1,borderColor:"#654321"},birdBeak:{position:"absolute",width:4,height:2,backgroundColor:"#FFD700",borderRadius:1},birdWing:{position:"absolute",backgroundColor:"#A0522D",borderRadius:3,borderWidth:1,borderColor:"#654321"},birdTail:{position:"absolute",width:12,height:4,backgroundColor:"#8B4513",borderRadius:2,borderWidth:1,borderColor:"#654321"}});h.displayName="SingleObstacle",ObstacleSprite.displayName="ObstacleSprite";
@@ -1 +1 @@
1
- "use strict";import React,{useMemo}from 'react';import{View,Text,StyleSheet}from 'react-native';import{useScore,useTimeLeft,useLives}from "../DinoJumpStore.js";import{DinoJumpService}from "../DinoJumpService.js";import{ScoreBoardContainer}from "../../../helpers/index.js";import{DINO_JUMP_COLORS}from "../DinoJumpConstants.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const gameService = new DinoJumpService();export const ScoreBoard = React.memo(({offset = 0})=>{const score = useScore();const timeLeft = useTimeLeft();const lives = useLives();const formattedTime = useMemo(()=> gameService.formatTime(timeLeft),[timeLeft]);const heartsDisplay = useMemo(()=>{const maxLives = 3;const currentLives = Math.max(0,Math.min(lives,maxLives));const lostLives = Math.max(0,maxLives - currentLives);const redHearts = '❤️'.repeat(currentLives);const blackHearts = '🖤'.repeat(lostLives);return redHearts + blackHearts;},[lives]);return _jsx(ScoreBoardContainer,{offset:offset,backgroundColor:"rgba(255,99,71,0.4)",borderColor:"rgba(255,99,71,0.4)",children:_jsxs(View,{style:styles.scoreBoard,children:[_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Score"}),_jsx(Text,{style:styles.scoreValue,children:score.toLocaleString()})]}),_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Time"}),_jsx(Text,{style:[styles.timeValue,{color:timeLeft < 60 ? '#ef4444':DINO_JUMP_COLORS.SCORE_TEXT}],children:formattedTime})]}),_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Lives"}),_jsx(Text,{style:styles.livesValue,numberOfLines:1,children:heartsDisplay})]})]})});});const styles = StyleSheet.create({scoreBoard:{flexDirection:'row',justifyContent:'space-between',alignItems:'center'},scoreSection:{alignItems:'center',flex:1},scoreLabel:{fontSize:16,fontWeight:'bold',color:'#ffffff',marginBottom:4,letterSpacing:0.5},scoreValue:{fontSize:25,fontWeight:'bold',color:'#ffffff'},timeValue:{fontSize:25,fontWeight:'bold',color:'#ffffff'},livesValue:{fontSize:25,fontWeight:'bold'}});ScoreBoard.displayName = 'ScoreBoard';
1
+ "use strict";import e,{useMemo as o}from"react";import{View as r,Text as t,StyleSheet as n}from"react-native";import{useScore as i,useTimeLeft as s,useLives as f}from"../DinoJumpStore.js";import{DinoJumpService as l}from"../DinoJumpService.js";import{ScoreBoardContainer as c}from"../../../helpers/index.js";import{DINO_JUMP_COLORS as a}from"../DinoJumpConstants.js";import{jsx as m,jsxs as d}from"react/jsx-runtime";const h=new l;export const ScoreBoard=e.memo(({offset:e=0})=>{const n=i(),l=s(),u=f(),S=o(()=>h.formatTime(l),[l]),b=o(()=>{const e=Math.max(0,Math.min(u,3)),o=Math.max(0,3-e);return"\u2764\ufe0f".repeat(e)+"\ud83d\udda4".repeat(o)},[u]);return m(c,{offset:e,backgroundColor:"rgba(255, 99, 71, 0.4)",borderColor:"rgba(255, 99, 71, 0.4)",children:d(r,{style:p.scoreBoard,children:[d(r,{style:p.scoreSection,children:[m(t,{style:p.scoreLabel,children:"Score"}),m(t,{style:p.scoreValue,children:n.toLocaleString()})]}),d(r,{style:p.scoreSection,children:[m(t,{style:p.scoreLabel,children:"Time"}),m(t,{style:[p.timeValue,{color:60>l?"#ef4444":a.SCORE_TEXT}],children:S})]}),d(r,{style:p.scoreSection,children:[m(t,{style:p.scoreLabel,children:"Lives"}),m(t,{style:p.livesValue,numberOfLines:1,children:b})]})]})})});const p=n.create({scoreBoard:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},scoreSection:{alignItems:"center",flex:1},scoreLabel:{fontSize:16,fontWeight:"bold",color:"#ffffff",marginBottom:4,letterSpacing:.5},scoreValue:{fontSize:25,fontWeight:"bold",color:"#ffffff"},timeValue:{fontSize:25,fontWeight:"bold",color:"#ffffff"},livesValue:{fontSize:25,fontWeight:"bold"}});ScoreBoard.displayName="ScoreBoard";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,Text,StyleSheet}from 'react-native';import{useStars}from "../DinoJumpStore.js";import{jsx as _jsx,Fragment as _Fragment}from "react/jsx-runtime";const SingleStar = React.memo(({star})=> _jsx(View,{style:[styles.starContainer,{left:star.x,top:star.y,width:star.width,height:star.height}],children:_jsx(Text,{style:styles.mushroom,children:"\uD83C\uDF44"})}),(prev,next)=> prev.star.id === next.star.id && prev.star.x === next.star.x);export const StarSprite = React.memo(()=>{const stars = useStars();if(!stars || stars.length === 0){return null;}return _jsx(_Fragment,{children:stars.map(star => _jsx(SingleStar,{star:star},star.id))});});const styles = StyleSheet.create({starContainer:{position:'absolute',justifyContent:'center',alignItems:'center'},mushroom:{fontSize:40,lineHeight:40}});StarSprite.displayName = 'StarSprite';
1
+ "use strict";import t from"react";import{View as r,Text as e,StyleSheet as i}from"react-native";import{useStars as o}from"../DinoJumpStore.js";import{jsx as n,Fragment as s}from"react/jsx-runtime";const a=t.memo(({star:t})=>n(r,{style:[m.starContainer,{left:t.x,top:t.y,width:t.width,height:t.height}],children:n(e,{style:m.mushroom,children:"\ud83c\udf44"})}),(t,r)=>t.star.id===r.star.id&&t.star.x===r.star.x);export const StarSprite=t.memo(()=>{const t=o();return t&&0!==t.length?n(s,{children:t.map(t=>n(a,{star:t},t.id))}):null});const m=i.create({starContainer:{position:"absolute",justifyContent:"center",alignItems:"center"},mushroom:{fontSize:40,lineHeight:40}});StarSprite.displayName="StarSprite";
@@ -1 +1 @@
1
- "use strict";export{GameBackground}from "./GameBackground.js";export{GameArea}from "./GameArea.js";export{DinoSprite}from "./DinoSprite.js";export{ObstacleSprite}from "./ObstacleSprite.js";export{StarSprite}from "./StarSprite.js";export{ScoreBoard}from "./ScoreBoard.js";
1
+ "use strict";export{GameBackground}from"./GameBackground.js";export{GameArea}from"./GameArea.js";export{DinoSprite}from"./DinoSprite.js";export{ObstacleSprite}from"./ObstacleSprite.js";export{StarSprite}from"./StarSprite.js";export{ScoreBoard}from"./ScoreBoard.js";
@@ -1 +1 @@
1
- "use strict";import React,{useEffect,useCallback,useMemo,useRef}from 'react';import{View,StyleSheet}from 'react-native';import{GestureHandlerRootView}from 'react-native-gesture-handler';import{useFlappyBirdStore}from "./FlappyBirdStore.js";import{ScoreBoard,GameArea,GameBackground}from "./components/index.js";import{GameControlButton,GameOverModal}from "../../helpers/index.js";import{GameSettingsModal}from "../../helpers/index.js";import{FLAPPY_BIRD_COLORS}from "./FlappyBirdConstants.js";import{GAME_IDS,DEFAULT_GAME_SETTINGS}from "../../services/UtilsService.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const formatTime = seconds =>{const mins = Math.floor(seconds / 60);const secs = seconds % 60;return `${mins.toString().padStart(2,'0')}:${secs.toString().padStart(2,'0')}`;};export const FlappyBird = React.memo(({settings = DEFAULT_GAME_SETTINGS,onSettingsChange,onEndGame})=>{const isPlaying = useFlappyBirdStore(state => state.isPlaying);const isGameOver = useFlappyBirdStore(state => state.isGameOver);const survivalTime = useFlappyBirdStore(state => state.survivalTime);const gameReportedRef = useRef(false);const reportGameEnd = useCallback(status =>{if(onEndGame && !gameReportedRef.current){onEndGame({status,score:survivalTime.toString()});gameReportedRef.current = true;}},[onEndGame,survivalTime]);const initializeGame = useFlappyBirdStore(state => state.initializeGame);const startGame = useFlappyBirdStore(state => state.startGame);const stopGame = useFlappyBirdStore(state => state.stopGame);const resetGame = useFlappyBirdStore(state => state.resetGame);useEffect(()=>{initializeGame();return()=>{stopGame();};},[initializeGame,stopGame]);const prevGameOverRef = useRef(false);useEffect(()=>{if(isGameOver && !prevGameOverRef.current){playSound(GAME_SOUNDS.FLAPPY_BIRD.HIT,settings.enableSounds);playHaptic(HapticType.HEAVY,settings.enableHaptics);reportGameEnd('lose');}prevGameOverRef.current = isGameOver;if(!isGameOver){gameReportedRef.current = false;}},[isGameOver,settings.enableSounds,settings.enableHaptics,reportGameEnd]);const handleStartGame = useCallback(()=>{gameReportedRef.current = false;initializeGame();startGame(settings);playSound(GAME_SOUNDS.FLAPPY_BIRD.START,settings.enableSounds);playHaptic(HapticType.MEDIUM,settings.enableHaptics);},[initializeGame,startGame,settings]);const handleStopGame = useCallback(()=>{reportGameEnd('cancel');stopGame();},[stopGame,reportGameEnd]);const handleResetGame = useCallback(()=>{resetGame();initializeGame();},[resetGame,initializeGame]);const gameOverModalProps = useMemo(()=>({isVisible:isGameOver,score:survivalTime,onPlayAgain:handleResetGame,buttonText:"Fly Again!",primaryColor:"rgba(92,184,92,0.5)",borderColor:"rgba(92,184,92,0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#5CB85C",scoreLabel:"Survival Time",scoreFormatter:formatTime}),[isGameOver,survivalTime,handleResetGame]);const gameSettingsModalProps = useMemo(()=>({gameId:GAME_IDS.FLAPPY_BIRD,settings,onSettingsChange}),[settings,onSettingsChange]);const offset = settings?.offset ?? 0;const gameControlButtonProps = useMemo(()=>({isPlaying,gameOver:isGameOver,onStartGame:handleStartGame,onStopGame:handleStopGame,startButtonText:"START FLYING",stopButtonText:"STOP GAME",startButtonSubtext:"Tap to flap!",startButtonColor:FLAPPY_BIRD_COLORS.BUTTON_PRIMARY,startButtonBorderColor:FLAPPY_BIRD_COLORS.BUTTON_SECONDARY}),[isPlaying,isGameOver,handleStartGame,handleStopGame]);return _jsx(View,{style:styles.root,children:_jsx(GestureHandlerRootView,{children:_jsx(GameBackground,{offset:offset,children:_jsxs(View,{style:styles.container,children:[_jsx(GameArea,{settings:settings}),_jsx(ScoreBoard,{offset:offset}),_jsx(GameControlButton,{...gameControlButtonProps}),_jsx(GameOverModal,{...gameOverModalProps}),_jsx(GameSettingsModal,{...gameSettingsModalProps})]})})})});});const styles = StyleSheet.create({root:{flex:1},container:{flex:1}});FlappyBird.displayName = 'FlappyBird';
1
+ "use strict";import t,{useEffect as r,useCallback as o,useMemo as e,useRef as s}from"react";import{View as n,StyleSheet as i}from"react-native";import{GestureHandlerRootView as a}from"react-native-gesture-handler";import{useFlappyBirdStore as m}from"./FlappyBirdStore.js";import{ScoreBoard as l,GameArea as p,GameBackground as c}from"./components/index.js";import{GameControlButton as f,GameOverModal as d}from"../../helpers/index.js";import{GameSettingsModal as u}from"../../helpers/index.js";import{FLAPPY_BIRD_COLORS as g}from"./FlappyBirdConstants.js";import{GAME_IDS as x,DEFAULT_GAME_SETTINGS as B}from"../../services/UtilsService.js";import{playSound as S,GAME_SOUNDS as C}from"../../services/SoundsService.js";import{playHaptic as j,HapticType as v}from"../../services/HapticsService.js";import{jsx as y,jsxs as b}from"react/jsx-runtime";const h=t=>{const r=t%60;return`${Math.floor(t/60).toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}`};export const FlappyBird=t.memo(({settings:t=B,onSettingsChange:i,onEndGame:F})=>{const G=m(t=>t.isPlaying),A=m(t=>t.isGameOver),P=m(t=>t.survivalTime),E=s(!1),I=o(t=>{F&&!E.current&&(F({status:t,score:P.toString()}),E.current=!0)},[F,P]),L=m(t=>t.initializeGame),M=m(t=>t.startGame),O=m(t=>t.stopGame),$=m(t=>t.resetGame);r(()=>(L(),()=>{O()}),[L,O]);const H=s(!1);r(()=>{A&&!H.current&&(S(C.FLAPPY_BIRD.HIT,t.enableSounds),j(v.HEAVY,t.enableHaptics),I("lose")),H.current=A,A||(E.current=!1)},[A,t.enableSounds,t.enableHaptics,I]);const N=o(()=>{E.current=!1,L(),M(t),S(C.FLAPPY_BIRD.START,t.enableSounds),j(v.MEDIUM,t.enableHaptics)},[L,M,t]),R=o(()=>{I("cancel"),O()},[O,I]),U=o(()=>{$(),L()},[$,L]),V=e(()=>({isVisible:A,score:P,onPlayAgain:U,buttonText:"Fly Again!",primaryColor:"rgba(92, 184, 92, 0.5)",borderColor:"rgba(92, 184, 92, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#5CB85C",scoreLabel:"Survival Time",scoreFormatter:h}),[A,P,U]),Y=e(()=>({gameId:x.FLAPPY_BIRD,settings:t,onSettingsChange:i}),[t,i]),k=t?.offset??0,q=e(()=>({isPlaying:G,gameOver:A,onStartGame:N,onStopGame:R,startButtonText:"START FLYING",stopButtonText:"STOP GAME",startButtonSubtext:"Tap to flap!",startButtonColor:g.BUTTON_PRIMARY,startButtonBorderColor:g.BUTTON_SECONDARY}),[G,A,N,R]);return y(n,{style:T.root,children:y(a,{children:y(c,{offset:k,children:b(n,{style:T.container,children:[y(p,{settings:t}),y(l,{offset:k}),y(f,{...q}),y(d,{...V}),y(u,{...Y})]})})})})});const T=i.create({root:{flex:1},container:{flex:1}});FlappyBird.displayName="FlappyBird";
@@ -1 +1 @@
1
- "use strict";import{Dimensions}from 'react-native';const{width,height}= Dimensions.get('window');export const FLAPPY_BIRD_GAME_CONFIG ={BIRD_SIZE:40,BIRD_START_X:width * 0.2,BIRD_START_Y:height * 0.4,GRAVITY:0.25,JUMP_VELOCITY:-4.5,MAX_FALL_SPEED:7,VELOCITY_DAMPING:0.98,PIPE_WIDTH:60,PIPE_GAP:200,PIPE_SPEED_EASY:1.5,PIPE_SPEED_MEDIUM:2.5,PIPE_SPEED_HARD:3.5,PIPE_SPAWN_INTERVAL:2800,MIN_PIPE_HEIGHT:100,MAX_PIPE_HEIGHT:height * 0.6,GROUND_HEIGHT:80,GAME_WIDTH:width,GAME_HEIGHT:height};export const FLAPPY_BIRD_COLORS ={SKY_START:'#87CEEB',SKY_END:'#E0F6FF',GROUND:'#DEB887',GROUND_DARK:'#8B7355',PIPE_GREEN:'#5CB85C',PIPE_DARK:'#4A934A',BIRD_YELLOW:'#FFD700',BIRD_ORANGE:'#FF8C00',SCORE_TEXT:'#FFFFFF',BUTTON_PRIMARY:'#5CB85C',BUTTON_SECONDARY:'#4A934A',GAME_OVER_BG:'rgba(74,147,74,0.95)',SCORE_BACKGROUND:'rgba(92,184,92,0.4)',SCORE_BORDER:'rgba(92,184,92,0.8)'};export const FLAPPY_BIRD_THEME ={backgroundColor:'rgba(0,0,0,0.7)',headerBackgroundColor:'#5CB85C',headerTextColor:'#ffffff',sectionBackgroundColor:'rgba(92,184,92,0.15)',sectionTitleColor:'#5CB85C',buttonSelectedColor:'#5CB85C',buttonUnselectedColor:'rgba(255,255,255,0.2)',buttonSelectedTextColor:'#ffffff',buttonUnselectedTextColor:'rgba(255,255,255,0.7)',switchTrackColorFalse:'rgba(92,184,92,0.3)',switchTrackColorTrue:'#5CB85C',switchThumbColor:'#ffffff',infoTextColor:'rgba(255,255,255,0.9)'};export const FLAPPY_BIRD_DIFFICULTY_DESCRIPTIONS ={easy:{title:'Easy Mode',description:'Perfect for beginners! Slower pipes and more time to react.',features:['Slower pipe speed','Easier timing','Great for learning']},medium:{title:'Medium Mode',description:'Balanced challenge for casual players.',features:['Moderate pipe speed','Standard difficulty','Good practice']},hard:{title:'Hard Mode',description:'Fast-paced action for experienced players!',features:['Fast pipe speed','Quick reflexes needed','Maximum challenge']}};export const DIFFICULTY_CONFIG ={easy:{pipeSpeed:FLAPPY_BIRD_GAME_CONFIG.PIPE_SPEED_EASY,pipeGap:250},medium:{pipeSpeed:FLAPPY_BIRD_GAME_CONFIG.PIPE_SPEED_MEDIUM,pipeGap:220},hard:{pipeSpeed:FLAPPY_BIRD_GAME_CONFIG.PIPE_SPEED_HARD,pipeGap:200}};
1
+ "use strict";import{Dimensions as e}from"react-native";const{width:o,height:r}=e.get("window");export const FLAPPY_BIRD_GAME_CONFIG={BIRD_SIZE:40,BIRD_START_X:.2*o,BIRD_START_Y:.4*r,GRAVITY:.25,JUMP_VELOCITY:-4.5,MAX_FALL_SPEED:7,VELOCITY_DAMPING:.98,PIPE_WIDTH:60,PIPE_GAP:200,PIPE_SPEED_EASY:1.5,PIPE_SPEED_MEDIUM:2.5,PIPE_SPEED_HARD:3.5,PIPE_SPAWN_INTERVAL:2800,MIN_PIPE_HEIGHT:100,MAX_PIPE_HEIGHT:.6*r,GROUND_HEIGHT:80,GAME_WIDTH:o,GAME_HEIGHT:r};export const FLAPPY_BIRD_COLORS={SKY_START:"#87CEEB",SKY_END:"#E0F6FF",GROUND:"#DEB887",GROUND_DARK:"#8B7355",PIPE_GREEN:"#5CB85C",PIPE_DARK:"#4A934A",BIRD_YELLOW:"#FFD700",BIRD_ORANGE:"#FF8C00",SCORE_TEXT:"#FFFFFF",BUTTON_PRIMARY:"#5CB85C",BUTTON_SECONDARY:"#4A934A",GAME_OVER_BG:"rgba(74, 147, 74, 0.95)",SCORE_BACKGROUND:"rgba(92, 184, 92, 0.4)",SCORE_BORDER:"rgba(92, 184, 92, 0.8)"};export const FLAPPY_BIRD_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#5CB85C",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(92, 184, 92, 0.15)",sectionTitleColor:"#5CB85C",buttonSelectedColor:"#5CB85C",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(92, 184, 92, 0.3)",switchTrackColorTrue:"#5CB85C",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const FLAPPY_BIRD_DIFFICULTY_DESCRIPTIONS={easy:{title:"Easy Mode",description:"Perfect for beginners! Slower pipes and more time to react.",features:["Slower pipe speed","Easier timing","Great for learning"]},medium:{title:"Medium Mode",description:"Balanced challenge for casual players.",features:["Moderate pipe speed","Standard difficulty","Good practice"]},hard:{title:"Hard Mode",description:"Fast-paced action for experienced players!",features:["Fast pipe speed","Quick reflexes needed","Maximum challenge"]}};export const DIFFICULTY_CONFIG={easy:{pipeSpeed:FLAPPY_BIRD_GAME_CONFIG.PIPE_SPEED_EASY,pipeGap:250},medium:{pipeSpeed:FLAPPY_BIRD_GAME_CONFIG.PIPE_SPEED_MEDIUM,pipeGap:220},hard:{pipeSpeed:FLAPPY_BIRD_GAME_CONFIG.PIPE_SPEED_HARD,pipeGap:200}};
@@ -1 +1 @@
1
- "use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{immerMiddleware}from "../../services/UtilsService.js";import{FLAPPY_BIRD_GAME_CONFIG,DIFFICULTY_CONFIG}from "./FlappyBirdConstants.js";const BASE_BRICK_WALL_HEIGHT = 150;const generateRandomPipeHeight =(offset = 0)=>{const{MIN_PIPE_HEIGHT,GAME_HEIGHT}= FLAPPY_BIRD_GAME_CONFIG;const topWallHeight = BASE_BRICK_WALL_HEIGHT + offset;const bottomWallHeight = offset > 0 ? 150:250;const playableHeight = GAME_HEIGHT - topWallHeight - bottomWallHeight;const minHeight = topWallHeight + MIN_PIPE_HEIGHT;const maxHeight = topWallHeight + playableHeight * 0.6;return minHeight + Math.random()*(maxHeight - minHeight);};export const useFlappyBirdStore = create()(subscribeWithSelector(immerMiddleware((set,get)=>({isPlaying:false,isGameOver:false,score:0,survivalTime:0,birdY:FLAPPY_BIRD_GAME_CONFIG.BIRD_START_Y,birdVelocity:0,pipes:[],collisionBlasts:[],gameLoopInterval:null,pipeSpawnInterval:null,timerInterval:null,initializeGame:()=>{set(state =>{state.isPlaying = false;state.isGameOver = false;state.score = 0;state.survivalTime = 0;state.birdY = FLAPPY_BIRD_GAME_CONFIG.BIRD_START_Y;state.birdVelocity = 0;state.pipes = [];state.collisionBlasts = [];});},startGame:settings =>{const state = get();if(state.gameLoopInterval)clearInterval(state.gameLoopInterval);if(state.pipeSpawnInterval)clearInterval(state.pipeSpawnInterval);if(state.timerInterval)clearInterval(state.timerInterval);set(state =>{state.isPlaying = true;state.isGameOver = false;state.birdY = FLAPPY_BIRD_GAME_CONFIG.BIRD_START_Y;state.birdVelocity = 0;state.pipes = [];state.score = 0;state.survivalTime = 0;});const gameLoop = setInterval(()=>{get().updatePhysics(settings);},1000 / 60);const pipeSpawn = setInterval(()=>{get().spawnPipe(settings);},FLAPPY_BIRD_GAME_CONFIG.PIPE_SPAWN_INTERVAL);const timer = setInterval(()=>{set(state =>{state.survivalTime += 1;});},1000);set(state =>{state.gameLoopInterval = gameLoop;state.pipeSpawnInterval = pipeSpawn;state.timerInterval = timer;});setTimeout(()=> get().spawnPipe(settings),500);},stopGame:()=>{const state = get();if(state.gameLoopInterval)clearInterval(state.gameLoopInterval);if(state.pipeSpawnInterval)clearInterval(state.pipeSpawnInterval);if(state.timerInterval)clearInterval(state.timerInterval);state.initializeGame();},resetGame:()=>{const state = get();if(state.gameLoopInterval)clearInterval(state.gameLoopInterval);if(state.pipeSpawnInterval)clearInterval(state.pipeSpawnInterval);if(state.timerInterval)clearInterval(state.timerInterval);set(state =>{state.isPlaying = false;state.isGameOver = false;state.score = 0;state.survivalTime = 0;state.birdY = FLAPPY_BIRD_GAME_CONFIG.BIRD_START_Y;state.birdVelocity = 0;state.pipes = [];state.collisionBlasts = [];state.gameLoopInterval = null;state.pipeSpawnInterval = null;state.timerInterval = null;});},jump:()=>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.birdVelocity = FLAPPY_BIRD_GAME_CONFIG.JUMP_VELOCITY;});},updatePhysics:settings =>{const state = get();if(!state.isPlaying || state.isGameOver)return;const config = DIFFICULTY_CONFIG[settings.difficulty];const{GAME_HEIGHT,GRAVITY,BIRD_SIZE,MAX_FALL_SPEED,VELOCITY_DAMPING}= FLAPPY_BIRD_GAME_CONFIG;const offset = settings.offset ?? 0;const topWallHeight = BASE_BRICK_WALL_HEIGHT + offset;const bottomWallHeight = offset > 0 ? 150:250;const bottomWallTop = GAME_HEIGHT - bottomWallHeight;let topWallCollision = false;let bottomWallCollision = false;set(draftState =>{draftState.birdVelocity += GRAVITY;draftState.birdVelocity *= VELOCITY_DAMPING;if(draftState.birdVelocity > MAX_FALL_SPEED){draftState.birdVelocity = MAX_FALL_SPEED;}draftState.birdY += draftState.birdVelocity;for(let i = draftState.pipes.length - 1;i >= 0;i--){const pipe = draftState.pipes[i];if(!pipe)continue;pipe.x -= config.pipeSpeed;if(!pipe.passed && pipe.x + FLAPPY_BIRD_GAME_CONFIG.PIPE_WIDTH < FLAPPY_BIRD_GAME_CONFIG.BIRD_START_X){pipe.passed = true;draftState.score += 1;}if(pipe.x + FLAPPY_BIRD_GAME_CONFIG.PIPE_WIDTH < 0){draftState.pipes.splice(i,1);}}if(draftState.birdY < topWallHeight){draftState.birdY = topWallHeight;draftState.birdVelocity = 0;draftState.isGameOver = true;draftState.isPlaying = false;topWallCollision = true;}if(draftState.birdY + BIRD_SIZE > bottomWallTop){draftState.birdY = bottomWallTop - BIRD_SIZE;draftState.isGameOver = true;draftState.isPlaying = false;bottomWallCollision = true;}});if(topWallCollision){const blastX = FLAPPY_BIRD_GAME_CONFIG.BIRD_START_X + BIRD_SIZE / 2;const blastY = topWallHeight + BIRD_SIZE / 2;get().addCollisionBlast(blastX,blastY);const state = get();if(state.gameLoopInterval)clearInterval(state.gameLoopInterval);if(state.pipeSpawnInterval)clearInterval(state.pipeSpawnInterval);if(state.timerInterval)clearInterval(state.timerInterval);}if(bottomWallCollision){const blastX = FLAPPY_BIRD_GAME_CONFIG.BIRD_START_X + BIRD_SIZE / 2;const blastY = bottomWallTop - BIRD_SIZE / 2;get().addCollisionBlast(blastX,blastY);const state = get();if(state.gameLoopInterval)clearInterval(state.gameLoopInterval);if(state.pipeSpawnInterval)clearInterval(state.pipeSpawnInterval);if(state.timerInterval)clearInterval(state.timerInterval);}if(get().checkCollision()){const state = get();if(state.gameLoopInterval)clearInterval(state.gameLoopInterval);if(state.pipeSpawnInterval)clearInterval(state.pipeSpawnInterval);if(state.timerInterval)clearInterval(state.timerInterval);}},spawnPipe:settings =>{const state = get();if(!state.isPlaying || state.isGameOver)return;const config = DIFFICULTY_CONFIG[settings.difficulty];const offset = settings.offset ?? 0;const topHeight = generateRandomPipeHeight(offset);const bottomY = topHeight + config.pipeGap;const pipe ={id:`pipe-${Date.now()}-${Math.random()}`,x:FLAPPY_BIRD_GAME_CONFIG.GAME_WIDTH,topHeight,bottomY,passed:false};set(state =>{state.pipes.push(pipe);});},checkCollision:()=>{const state = get();const{BIRD_START_X,BIRD_SIZE,PIPE_WIDTH}= FLAPPY_BIRD_GAME_CONFIG;const birdLeft = BIRD_START_X;const birdRight = BIRD_START_X + BIRD_SIZE;const birdTop = state.birdY;const birdBottom = state.birdY + BIRD_SIZE;const birdCenterX = BIRD_START_X + BIRD_SIZE / 2;const birdCenterY = state.birdY + BIRD_SIZE / 2;for(const pipe of state.pipes){const pipeLeft = pipe.x;const pipeRight = pipe.x + PIPE_WIDTH;if(birdRight > pipeLeft && birdLeft < pipeRight){if(birdTop < pipe.topHeight){get().addCollisionBlast(birdCenterX,birdCenterY);set(state =>{state.isGameOver = true;state.isPlaying = false;});return true;}if(birdBottom > pipe.bottomY){get().addCollisionBlast(birdCenterX,birdCenterY);set(state =>{state.isGameOver = true;state.isPlaying = false;});return true;}}}return false;},addCollisionBlast:(x,y)=>{set(state =>{state.collisionBlasts.push({id:`blast-${Date.now()}-${Math.random()}`,x,y});});},removeCollisionBlast:id =>{set(state =>{state.collisionBlasts = state.collisionBlasts.filter(blast => blast.id !== id);});}}))));export const useIsPlaying =()=> useFlappyBirdStore(state => state.isPlaying);export const useIsGameOver =()=> useFlappyBirdStore(state => state.isGameOver);export const useScore =()=> useFlappyBirdStore(state => state.score);export const useSurvivalTime =()=> useFlappyBirdStore(state => state.survivalTime);export const useBirdY =()=> useFlappyBirdStore(state => state.birdY);export const usePipes =()=> useFlappyBirdStore(state => state.pipes);export const useCollisionBlasts =()=> useFlappyBirdStore(state => state.collisionBlasts);
1
+ "use strict";import{create as e}from"zustand";import{subscribeWithSelector as t}from"zustand/middleware";import{immerMiddleware as r}from"../../services/UtilsService.js";import{FLAPPY_BIRD_GAME_CONFIG as l,DIFFICULTY_CONFIG as s}from"./FlappyBirdConstants.js";const a=150,n=(e=0)=>{const{MIN_PIPE_HEIGHT:t,GAME_HEIGHT:r}=l,s=a+e,n=s+t,o=s+.6*(r-s-(e>0?150:250));return n+Math.random()*(o-n)};export const useFlappyBirdStore=e()(t(r((e,t)=>({isPlaying:!1,isGameOver:!1,score:0,survivalTime:0,birdY:l.BIRD_START_Y,birdVelocity:0,pipes:[],collisionBlasts:[],gameLoopInterval:null,pipeSpawnInterval:null,timerInterval:null,initializeGame:()=>{e(e=>{e.isPlaying=!1,e.isGameOver=!1,e.score=0,e.survivalTime=0,e.birdY=l.BIRD_START_Y,e.birdVelocity=0,e.pipes=[],e.collisionBlasts=[]})},startGame:r=>{const s=t();s.gameLoopInterval&&clearInterval(s.gameLoopInterval),s.pipeSpawnInterval&&clearInterval(s.pipeSpawnInterval),s.timerInterval&&clearInterval(s.timerInterval),e(e=>{e.isPlaying=!0,e.isGameOver=!1,e.birdY=l.BIRD_START_Y,e.birdVelocity=0,e.pipes=[],e.score=0,e.survivalTime=0});const a=setInterval(()=>{t().updatePhysics(r)},1e3/60),n=setInterval(()=>{t().spawnPipe(r)},l.PIPE_SPAWN_INTERVAL),o=setInterval(()=>{e(e=>{e.survivalTime+=1})},1e3);e(e=>{e.gameLoopInterval=a,e.pipeSpawnInterval=n,e.timerInterval=o}),setTimeout(()=>t().spawnPipe(r),500)},stopGame:()=>{const e=t();e.gameLoopInterval&&clearInterval(e.gameLoopInterval),e.pipeSpawnInterval&&clearInterval(e.pipeSpawnInterval),e.timerInterval&&clearInterval(e.timerInterval),e.initializeGame()},resetGame:()=>{const r=t();r.gameLoopInterval&&clearInterval(r.gameLoopInterval),r.pipeSpawnInterval&&clearInterval(r.pipeSpawnInterval),r.timerInterval&&clearInterval(r.timerInterval),e(e=>{e.isPlaying=!1,e.isGameOver=!1,e.score=0,e.survivalTime=0,e.birdY=l.BIRD_START_Y,e.birdVelocity=0,e.pipes=[],e.collisionBlasts=[],e.gameLoopInterval=null,e.pipeSpawnInterval=null,e.timerInterval=null})},jump:()=>{const r=t();r.isPlaying&&!r.isGameOver&&e(e=>{e.birdVelocity=l.JUMP_VELOCITY})},updatePhysics:r=>{const n=t();if(!n.isPlaying||n.isGameOver)return;const o=s[r.difficulty],{GAME_HEIGHT:i,GRAVITY:c,BIRD_SIZE:p,MAX_FALL_SPEED:I,VELOCITY_DAMPING:u}=l,v=r.offset??0,m=a+v,d=i-(v>0?150:250);let B=!1,S=!1;if(e(e=>{e.birdVelocity+=c,e.birdVelocity*=u,e.birdVelocity>I&&(e.birdVelocity=I),e.birdY+=e.birdVelocity;for(let t=e.pipes.length-1;t>=0;t--){const r=e.pipes[t];r&&(r.x-=o.pipeSpeed,!r.passed&&r.x+l.PIPE_WIDTH<l.BIRD_START_X&&(r.passed=!0,e.score+=1),0>r.x+l.PIPE_WIDTH&&e.pipes.splice(t,1))}e.birdY<m&&(e.birdY=m,e.birdVelocity=0,e.isGameOver=!0,e.isPlaying=!1,B=!0),e.birdY+p>d&&(e.birdY=d-p,e.isGameOver=!0,e.isPlaying=!1,S=!0)}),B){const e=l.BIRD_START_X+p/2,r=m+p/2;t().addCollisionBlast(e,r);const s=t();s.gameLoopInterval&&clearInterval(s.gameLoopInterval),s.pipeSpawnInterval&&clearInterval(s.pipeSpawnInterval),s.timerInterval&&clearInterval(s.timerInterval)}if(S){const e=l.BIRD_START_X+p/2,r=d-p/2;t().addCollisionBlast(e,r);const s=t();s.gameLoopInterval&&clearInterval(s.gameLoopInterval),s.pipeSpawnInterval&&clearInterval(s.pipeSpawnInterval),s.timerInterval&&clearInterval(s.timerInterval)}if(t().checkCollision()){const e=t();e.gameLoopInterval&&clearInterval(e.gameLoopInterval),e.pipeSpawnInterval&&clearInterval(e.pipeSpawnInterval),e.timerInterval&&clearInterval(e.timerInterval)}},spawnPipe:r=>{const a=t();if(!a.isPlaying||a.isGameOver)return;const o=s[r.difficulty],i=r.offset??0,c=n(i),p=c+o.pipeGap,I={id:`pipe-${Date.now()}-${Math.random()}`,x:l.GAME_WIDTH,topHeight:c,bottomY:p,passed:!1};e(e=>{e.pipes.push(I)})},checkCollision:()=>{const r=t(),{BIRD_START_X:s,BIRD_SIZE:a,PIPE_WIDTH:n}=l,o=s,i=s+a,c=r.birdY,p=r.birdY+a,I=s+a/2,u=r.birdY+a/2;for(const l of r.pipes){const r=l.x,s=l.x+n;if(i>r&&s>o){if(c<l.topHeight)return t().addCollisionBlast(I,u),e(e=>{e.isGameOver=!0,e.isPlaying=!1}),!0;if(p>l.bottomY)return t().addCollisionBlast(I,u),e(e=>{e.isGameOver=!0,e.isPlaying=!1}),!0}}return!1},addCollisionBlast:(t,r)=>{e(e=>{e.collisionBlasts.push({id:`blast-${Date.now()}-${Math.random()}`,x:t,y:r})})},removeCollisionBlast:t=>{e(e=>{e.collisionBlasts=e.collisionBlasts.filter(e=>e.id!==t)})}}))));export const useIsPlaying=()=>useFlappyBirdStore(e=>e.isPlaying);export const useIsGameOver=()=>useFlappyBirdStore(e=>e.isGameOver);export const useScore=()=>useFlappyBirdStore(e=>e.score);export const useSurvivalTime=()=>useFlappyBirdStore(e=>e.survivalTime);export const useBirdY=()=>useFlappyBirdStore(e=>e.birdY);export const usePipes=()=>useFlappyBirdStore(e=>e.pipes);export const useCollisionBlasts=()=>useFlappyBirdStore(e=>e.collisionBlasts);