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 React from 'react';import{View,Dimensions}from 'react-native';import{Canvas,LinearGradient,Rect,Circle,Path,Skia,vec,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 createGrassPath = grassStartY =>{const path = Skia.Path.Make();const segmentWidth = width / 8;path.moveTo(0,grassStartY);for(let i = 0;i < 8;i++){const x = i * segmentWidth;const y = grassStartY + Math.sin(i * 0.5)* 8;const controlX = x + segmentWidth / 2;const controlY = y + Math.cos(i * 0.3)* 6;path.quadTo(controlX,controlY,x + segmentWidth,y);}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.15 + Math.sin(radian)* startDistance;const endX = width * 0.8 + Math.cos(radian)*(startDistance + rayLength);const endY = height * 0.15 + Math.sin(radian)*(startDistance + rayLength);const rayPath = Skia.Path.Make();rayPath.moveTo(startX,startY);rayPath.lineTo(endX,endY);return{path:rayPath,width:rayWidth};});};const createFlowerPositions = grassStartY =>{return Array.from({length:12},(_,i)=>({x:width / 12 * i + i % 3 * 15 + 20,y:grassStartY - 10 - i % 4 * 8}));};const staticSunRays = createStaticSunRays();export const GameBackground =({children,offset = 0})=>{const buttonAreaHeight = offset > 0 ? 150:250;const grassStartY = height - buttonAreaHeight;const grassPath = createGrassPath(grassStartY);const flowerPositions = createFlowerPositions(grassStartY);const sunY = height * 0.15 + offset * 0.9;const cloud1Y = height * 0.24 + offset * 0.9;const cloud2Y = height * 0.27 + offset * 0.9;const cloud3Y = height * 0.19 + offset * 0.9;const cloud4Y = height * 0.15 + offset * 0.9;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:grassStartY,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(0,grassStartY),colors:['#87CEEB','#98D8E8','#B0E0E6']})}),_jsx(Rect,{x:0,y:grassStartY,width:width,height:buttonAreaHeight,children:_jsx(LinearGradient,{start:vec(0,grassStartY),end:vec(0,height),colors:['#8B4513','#A0522D','#654321']})}),_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((_,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.24 - height * 0.21),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.24 - height * 0.19),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.24 - height * 0.21),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.26 - height * 0.24),r:8,color:"#F8F8FF",opacity:0.25}),_jsx(Circle,{cx:width * 0.35,cy:cloud1Y -(height * 0.24 - height * 0.18),r:6,color:"#FFFFFF",opacity:0.30}),_jsx(Circle,{cx:width * 0.40,cy:cloud1Y -(height * 0.24 - height * 0.22),r:5,color:"#F0F8FF",opacity:0.20}),_jsx(Circle,{cx:width * 0.22,cy:cloud1Y -(height * 0.24 - height * 0.18),r:7,color:"#FFFFFF",opacity:0.35}),_jsx(Circle,{cx:width * 0.28,cy:cloud1Y -(height * 0.24 - height * 0.20),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.27 - height * 0.24),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.27 - height * 0.26),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.28 - height * 0.27),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.29 - height * 0.27),r:6,color:"#F8F8FF",opacity:0.20}),_jsx(Circle,{cx:width * 0.78,cy:cloud2Y -(height * 0.27 - height * 0.23),r:4,color:"#FFFFFF",opacity:0.25}),_jsx(Circle,{cx:width * 0.67,cy:cloud2Y -(height * 0.27 - height * 0.23),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.19 - height * 0.17),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.19 - height * 0.18),r:4,color:"#F0F8FF",opacity:0.15}),_jsx(Circle,{cx:width * 0.86,cy:cloud3Y +(height * 0.21 - height * 0.19),r:3,color:"#FFFFFF",opacity:0.20})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.45,cy:cloud4Y,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.13,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.15,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:grassPath,children:[_jsx(LinearGradient,{start:vec(0,grassStartY - 20),end:vec(0,grassStartY + 20),colors:['#32CD32','#228B22','#006400']}),_jsx(Shadow,{dx:0,dy:-2,blur:4,color:"rgba(0,0,0,0.2)"})]}),Array.from({length:25},(_,i)=>{const x = width / 25 * i + i % 3 * 5;const grassHeight = 15 + i % 4 * 5;const grassType = i % 3;const bladePath = Skia.Path.Make();bladePath.moveTo(x,grassStartY);if(grassType === 0){bladePath.quadTo(x + 1,grassStartY - grassHeight * 0.6,x + 1,grassStartY - grassHeight);return _jsx(Path,{path:bladePath,style:"stroke",strokeWidth:1.5,color:"#16a34a",opacity:0.8},`grass-${i}`);}else if(grassType === 1){bladePath.quadTo(x + 2,grassStartY - grassHeight * 0.4,x + 3,grassStartY - grassHeight);return _jsx(Path,{path:bladePath,style:"stroke",strokeWidth:2,color:"#15803d",opacity:0.7},`grass-${i}`);}else{const midHeight = grassHeight * 0.5;bladePath.quadTo(x + 1,grassStartY - midHeight,x + 2,grassStartY - grassHeight);return _jsx(Path,{path:bladePath,style:"stroke",strokeWidth:2.5,color:"#166534",opacity:0.6},`grass-${i}`);}}),Array.from({length:20},(_,i)=>{const x = width / 20 * i + i % 2 * 10;const y = grassStartY - 5 + i % 3 * 5;const grassClusterHeight = 10 + i % 3 * 2;const clusterPath = Skia.Path.Make();clusterPath.moveTo(x,y);clusterPath.lineTo(x + 1,y - grassClusterHeight);clusterPath.moveTo(x + 2,y);clusterPath.lineTo(x + 3,y - grassClusterHeight * 0.8);clusterPath.moveTo(x + 4,y);clusterPath.lineTo(x + 5,y - grassClusterHeight * 0.6);return _jsx(Path,{path:clusterPath,style:"stroke",strokeWidth:1,color:"#22c55e",opacity:0.4},`cluster-${i}`);}),Array.from({length:8},(_,i)=>{const x = width / 8 * i + i % 3 * 20;const y = grassStartY + 30 + i % 4 * 15;const size = 2 + i % 3;return _jsx(Circle,{cx:x,cy:y,r:size,color:"#8B4513",opacity:0.6},i);}),_jsxs(Group,{children:[_jsxs(Group,{children:[_jsxs(Rect,{x:width * 0.05,y:grassStartY - 150,width:20,height:150,children:[_jsx(LinearGradient,{start:vec(0,0),end:vec(20,0),colors:['#654321','#8B4513','#A0522D','#8B4513']}),_jsx(Shadow,{dx:3,dy:0,blur:6,color:"rgba(0,0,0,0.4)"})]}),_jsx(Rect,{x:width * 0.05 + 3,y:grassStartY - 120,width:1,height:90,color:"#5D4037",opacity:0.8}),_jsx(Rect,{x:width * 0.05 + 7,y:grassStartY - 140,width:1.5,height:110,color:"#4A2C2A",opacity:0.7}),_jsx(Rect,{x:width * 0.05 + 12,y:grassStartY - 100,width:1,height:70,color:"#5D4037",opacity:0.6}),_jsx(Rect,{x:width * 0.05 + 16,y:grassStartY - 130,width:1.5,height:100,color:"#4A2C2A",opacity:0.8}),_jsx(Rect,{x:width * 0.05 + 18,y:grassStartY - 130,width:12,height:4,color:"#8B4513",opacity:0.9,children:_jsx(Shadow,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.3)"})}),_jsx(Rect,{x:width * 0.05 - 2,y:grassStartY - 100,width:10,height:3,color:"#A0522D",opacity:0.8,children:_jsx(Shadow,{dx:-1,dy:1,blur:2,color:"rgba(0,0,0,0.3)"})}),_jsx(Rect,{x:width * 0.05 + 15,y:grassStartY - 160,width:8,height:3,color:"#8B4513",opacity:0.7,children:_jsx(Shadow,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.2)"})}),_jsx(Circle,{cx:width * 0.05 + 10,cy:grassStartY - 150,r:38,color:"#1B5E20",opacity:0.9,children:_jsx(Shadow,{dx:4,dy:4,blur:10,color:"rgba(0,0,0,0.3)"})}),_jsx(Circle,{cx:width * 0.05 + 18,cy:grassStartY - 180,r:32,color:"#2E7D32",opacity:0.8}),_jsx(Circle,{cx:width * 0.05 + 25,cy:grassStartY - 140,r:28,color:"#388E3C",opacity:0.7}),_jsx(Circle,{cx:width * 0.05 + 2,cy:grassStartY - 120,r:30,color:"#2E7D32",opacity:0.75}),_jsx(Circle,{cx:width * 0.05 - 5,cy:grassStartY - 160,r:25,color:"#1B5E20",opacity:0.8}),_jsx(Circle,{cx:width * 0.05 + 8,cy:grassStartY - 200,r:26,color:"#4CAF50",opacity:0.6}),_jsx(Circle,{cx:width * 0.05 + 20,cy:grassStartY - 200,r:22,color:"#66BB6A",opacity:0.5}),_jsx(Circle,{cx:width * 0.05 + 12,cy:grassStartY - 170,r:20,color:"#388E3C",opacity:0.9}),_jsx(Circle,{cx:width * 0.05 + 6,cy:grassStartY - 140,r:18,color:"#2E7D32",opacity:0.8}),_jsx(Circle,{cx:width * 0.05 + 15,cy:grassStartY - 220,r:15,color:"#81C784",opacity:0.6}),_jsx(Circle,{cx:width * 0.05 + 3,cy:grassStartY - 210,r:12,color:"#A5D6A7",opacity:0.5}),_jsx(Circle,{cx:width * 0.05 + 28,cy:grassStartY - 180,r:14,color:"#81C784",opacity:0.6}),_jsx(Circle,{cx:width * 0.05 - 8,cy:grassStartY - 180,r:16,color:"#66BB6A",opacity:0.7}),_jsx(Circle,{cx:width * 0.05 + 5,cy:grassStartY - 230,r:10,color:"#C8E6C9",opacity:0.7}),_jsx(Circle,{cx:width * 0.05 + 18,cy:grassStartY - 240,r:8,color:"#E8F5E8",opacity:0.6}),_jsx(Circle,{cx:width * 0.05 + 22,cy:grassStartY - 190,r:6,color:"#C8E6C9",opacity:0.8})]}),_jsxs(Group,{children:[_jsxs(Rect,{x:width * 0.88,y:grassStartY - 200,width:18,height:200,children:[_jsx(LinearGradient,{start:vec(0,0),end:vec(18,0),colors:['#4A2C2A','#654321','#8B4513','#654321']}),_jsx(Shadow,{dx:-3,dy:0,blur:6,color:"rgba(0,0,0,0.4)"})]}),_jsx(Rect,{x:width * 0.88 + 2,y:grassStartY - 170,width:1,height:150,color:"#3E2723",opacity:0.9}),_jsx(Rect,{x:width * 0.88 + 6,y:grassStartY - 190,width:1.5,height:170,color:"#2E1A16",opacity:0.8}),_jsx(Rect,{x:width * 0.88 + 11,y:grassStartY - 160,width:1,height:130,color:"#3E2723",opacity:0.7}),_jsx(Rect,{x:width * 0.88 + 14,y:grassStartY - 180,width:1.5,height:160,color:"#2E1A16",opacity:0.9}),_jsx(Circle,{cx:width * 0.88 + 9,cy:grassStartY - 120,r:35,color:"#0D4F0C",opacity:0.95,children:_jsx(Shadow,{dx:-4,dy:4,blur:10,color:"rgba(0,0,0,0.3)"})}),_jsx(Circle,{cx:width * 0.88 + 5,cy:grassStartY - 100,r:30,color:"#1B5E20",opacity:0.9}),_jsx(Circle,{cx:width * 0.88 + 13,cy:grassStartY - 110,r:28,color:"#2E7D32",opacity:0.8}),_jsx(Circle,{cx:width * 0.88 + 9,cy:grassStartY - 180,r:32,color:"#1B5E20",opacity:0.9}),_jsx(Circle,{cx:width * 0.88 + 6,cy:grassStartY - 170,r:26,color:"#2E7D32",opacity:0.85}),_jsx(Circle,{cx:width * 0.88 + 12,cy:grassStartY - 190,r:24,color:"#388E3C",opacity:0.8}),_jsx(Circle,{cx:width * 0.88 + 9,cy:grassStartY - 240,r:28,color:"#2E7D32",opacity:0.9}),_jsx(Circle,{cx:width * 0.88 + 7,cy:grassStartY - 230,r:22,color:"#388E3C",opacity:0.85}),_jsx(Circle,{cx:width * 0.88 + 11,cy:grassStartY - 250,r:20,color:"#4CAF50",opacity:0.8}),_jsx(Circle,{cx:width * 0.88 + 9,cy:grassStartY - 300,r:22,color:"#388E3C",opacity:0.9}),_jsx(Circle,{cx:width * 0.88 + 8,cy:grassStartY - 290,r:18,color:"#4CAF50",opacity:0.8}),_jsx(Circle,{cx:width * 0.88 + 10,cy:grassStartY - 310,r:15,color:"#66BB6A",opacity:0.7}),_jsx(Circle,{cx:width * 0.88 + 4,cy:grassStartY - 150,r:8,color:"#0D4F0C",opacity:0.8}),_jsx(Circle,{cx:width * 0.88 + 14,cy:grassStartY - 170,r:6,color:"#1B5E20",opacity:0.9}),_jsx(Circle,{cx:width * 0.88 + 3,cy:grassStartY - 220,r:5,color:"#0D4F0C",opacity:0.7}),_jsx(Circle,{cx:width * 0.88 + 15,cy:grassStartY - 240,r:7,color:"#2E7D32",opacity:0.8}),_jsx(Circle,{cx:width * 0.88 + 12,cy:grassStartY - 280,r:8,color:"#81C784",opacity:0.6}),_jsx(Circle,{cx:width * 0.88 + 11,cy:grassStartY - 320,r:6,color:"#A5D6A7",opacity:0.5}),_jsx(Circle,{cx:width * 0.88 + 13,cy:grassStartY - 190,r:5,color:"#C8E6C9",opacity:0.7})]})]}),_jsxs(Group,{children:[_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.15,cy:grassStartY - 60,r:26,color:"#1B5E20",opacity:0.95,children:_jsx(Shadow,{dx:3,dy:3,blur:8,color:"rgba(0,0,0,0.3)"})}),_jsx(Circle,{cx:width * 0.18,cy:grassStartY - 90,r:22,color:"#2E7D32",opacity:0.9}),_jsx(Circle,{cx:width * 0.21,cy:grassStartY - 70,r:18,color:"#388E3C",opacity:0.8}),_jsx(Circle,{cx:width * 0.12,cy:grassStartY - 80,r:20,color:"#2E7D32",opacity:0.85}),_jsx(Circle,{cx:width * 0.09,cy:grassStartY - 50,r:16,color:"#1B5E20",opacity:0.9}),_jsx(Circle,{cx:width * 0.16,cy:grassStartY - 100,r:19,color:"#4CAF50",opacity:0.7}),_jsx(Circle,{cx:width * 0.19,cy:grassStartY - 95,r:15,color:"#66BB6A",opacity:0.6}),_jsx(Circle,{cx:width * 0.15,cy:grassStartY - 90,r:14,color:"#388E3C",opacity:0.9}),_jsx(Circle,{cx:width * 0.17,cy:grassStartY - 70,r:12,color:"#2E7D32",opacity:0.8}),_jsx(Circle,{cx:width * 0.13,cy:grassStartY - 95,r:10,color:"#81C784",opacity:0.7}),_jsx(Circle,{cx:width * 0.20,cy:grassStartY - 85,r:8,color:"#A5D6A7",opacity:0.6}),_jsx(Circle,{cx:width * 0.11,cy:grassStartY - 70,r:9,color:"#66BB6A",opacity:0.8}),_jsx(Circle,{cx:width * 0.22,cy:grassStartY - 80,r:7,color:"#81C784",opacity:0.7}),_jsx(Circle,{cx:width * 0.16,cy:grassStartY - 105,r:6,color:"#C8E6C9",opacity:0.8}),_jsx(Circle,{cx:width * 0.19,cy:grassStartY - 100,r:4,color:"#E8F5E8",opacity:0.7})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.35,cy:grassStartY - 40,r:21,color:"#1B5E20",opacity:0.9,children:_jsx(Shadow,{dx:2,dy:2,blur:6,color:"rgba(0,0,0,0.25)"})}),_jsx(Circle,{cx:width * 0.37,cy:grassStartY - 60,r:17,color:"#2E7D32",opacity:0.85}),_jsx(Circle,{cx:width * 0.33,cy:grassStartY - 30,r:15,color:"#388E3C",opacity:0.8}),_jsx(Circle,{cx:width * 0.36,cy:grassStartY - 80,r:13,color:"#4CAF50",opacity:0.7}),_jsx(Circle,{cx:width * 0.32,cy:grassStartY - 60,r:10,color:"#66BB6A",opacity:0.8}),_jsx(Circle,{cx:width * 0.38,cy:grassStartY - 50,r:8,color:"#81C784",opacity:0.7}),_jsx(Circle,{cx:width * 0.34,cy:grassStartY - 90,r:5,color:"#A5D6A7",opacity:0.8})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.52,cy:grassStartY - 45,r:25,color:"#1B5E20",opacity:0.95,children:_jsx(Shadow,{dx:2,dy:3,blur:8,color:"rgba(0,0,0,0.3)"})}),_jsx(Circle,{cx:width * 0.55,cy:grassStartY - 75,r:21,color:"#2E7D32",opacity:0.9}),_jsx(Circle,{cx:width * 0.49,cy:grassStartY - 35,r:19,color:"#388E3C",opacity:0.85}),_jsx(Circle,{cx:width * 0.54,cy:grassStartY - 100,r:16,color:"#4CAF50",opacity:0.8}),_jsx(Circle,{cx:width * 0.50,cy:grassStartY - 70,r:14,color:"#66BB6A",opacity:0.75}),_jsx(Circle,{cx:width * 0.47,cy:grassStartY - 90,r:11,color:"#81C784",opacity:0.7}),_jsx(Circle,{cx:width * 0.56,cy:grassStartY - 55,r:9,color:"#A5D6A7",opacity:0.6}),_jsx(Circle,{cx:width * 0.51,cy:grassStartY - 85,r:4,color:"#FF69B4",opacity:0.9}),_jsx(Circle,{cx:width * 0.54,cy:grassStartY - 75,r:3.5,color:"#FF6B6B",opacity:0.85}),_jsx(Circle,{cx:width * 0.49,cy:grassStartY - 55,r:3,color:"#FF1744",opacity:0.8}),_jsx(Circle,{cx:width * 0.52,cy:grassStartY - 105,r:6,color:"#C8E6C9",opacity:0.8})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.72,cy:grassStartY - 35,r:28,color:"#0D4F0C",opacity:0.95,children:_jsx(Shadow,{dx:-2,dy:3,blur:8,color:"rgba(0,0,0,0.3)"})}),_jsx(Circle,{cx:width * 0.75,cy:grassStartY - 70,r:24,color:"#1B5E20",opacity:0.9}),_jsx(Circle,{cx:width * 0.69,cy:grassStartY - 25,r:22,color:"#2E7D32",opacity:0.85}),_jsx(Circle,{cx:width * 0.74,cy:grassStartY - 85,r:19,color:"#388E3C",opacity:0.8}),_jsx(Circle,{cx:width * 0.68,cy:grassStartY - 55,r:17,color:"#4CAF50",opacity:0.75}),_jsx(Circle,{cx:width * 0.77,cy:grassStartY - 45,r:14,color:"#66BB6A",opacity:0.7}),_jsx(Circle,{cx:width * 0.66,cy:grassStartY - 75,r:12,color:"#81C784",opacity:0.65}),_jsx(Circle,{cx:width * 0.71,cy:grassStartY - 95,r:10,color:"#A5D6A7",opacity:0.6}),_jsx(Circle,{cx:width * 0.73,cy:grassStartY - 100,r:3,color:"#9C27B0",opacity:0.9}),_jsx(Circle,{cx:width * 0.70,cy:grassStartY - 90,r:2.5,color:"#673AB7",opacity:0.85}),_jsx(Circle,{cx:width * 0.76,cy:grassStartY - 55,r:3.5,color:"#FF9800",opacity:0.8}),_jsx(Circle,{cx:width * 0.73,cy:grassStartY - 110,r:7,color:"#C8E6C9",opacity:0.8}),_jsx(Circle,{cx:width * 0.75,cy:grassStartY - 90,r:5,color:"#E8F5E8",opacity:0.7})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.25,cy:grassStartY - 15,r:15,color:"#1B5E20",opacity:0.8,children:_jsx(Shadow,{dx:1,dy:2,blur:4,color:"rgba(0,0,0,0.2)"})}),_jsx(Circle,{cx:width * 0.27,cy:grassStartY - 35,r:12,color:"#2E7D32",opacity:0.75}),_jsx(Circle,{cx:width * 0.23,cy:grassStartY - 5,r:10,color:"#388E3C",opacity:0.7}),_jsx(Circle,{cx:width * 0.26,cy:grassStartY - 45,r:7,color:"#66BB6A",opacity:0.6}),_jsx(Circle,{cx:width * 0.65,cy:grassStartY - 5,r:13,color:"#2E7D32",opacity:0.8,children:_jsx(Shadow,{dx:-1,dy:2,blur:4,color:"rgba(0,0,0,0.2)"})}),_jsx(Circle,{cx:width * 0.67,cy:grassStartY - 25,r:10,color:"#388E3C",opacity:0.75}),_jsx(Circle,{cx:width * 0.63,cy:grassStartY + 5,r:8,color:"#4CAF50",opacity:0.7}),_jsx(Circle,{cx:width * 0.66,cy:grassStartY - 35,r:5,color:"#81C784",opacity:0.6})]})]}),_jsx(Group,{children:flowerPositions.map((pos,i)=>{const colors = ['#FF6B6B','#FF69B4','#9370DB','#4169E1','#FF8C00','#32CD32'];const color = colors[i % colors.length];const size = 3 + i % 3;return _jsxs(Group,{children:[_jsx(Circle,{cx:pos.x,cy:pos.y,r:size,color:color,opacity:0.8,children:_jsx(Shadow,{dx:0,dy:1,blur:1,color:"rgba(0,0,0,0.2)"})}),_jsx(Circle,{cx:pos.x,cy:pos.y,r:size * 0.4,color:"#FFD700",opacity:0.9})]},`flower-${i}`);})})]}),children]});};
1
+ "use strict";import c from"react";import{View as o,Dimensions as r}from"react-native";import{Canvas as y,LinearGradient as t,Rect as l,Circle as i,Path as a,Skia as F,vec as x,Group as d,Shadow as p}from"@shopify/react-native-skia";import{jsx as h,jsxs as e}from"react/jsx-runtime";const{width:n,height:s}=r.get("window"),b=c=>{const o=F.Path.Make(),r=n/8;o.moveTo(0,c);for(let y=0;8>y;y++){const t=y*r,l=c+8*Math.sin(.5*y),i=t+r/2,a=l+6*Math.cos(.3*y);o.quadTo(i,a,t+r,l)}return o.lineTo(n,s),o.lineTo(0,s),o.close(),o},E=()=>Array.from({length:16},(c,o)=>{const r=22.5*o*Math.PI/180,y=o%2==0,t=y?25:15,l=y?4:2,i=.8*n+45*Math.cos(r),a=.15*s+45*Math.sin(r),x=.8*n+Math.cos(r)*(45+t),d=.15*s+Math.sin(r)*(45+t),p=F.Path.Make();return p.moveTo(i,a),p.lineTo(x,d),{path:p,width:l}}),g=c=>Array.from({length:12},(o,r)=>({x:n/12*r+r%3*15+20,y:c-10-r%4*8})),C=E();export const GameBackground=({children:c,offset:r=0})=>{const E=r>0?150:250,B=s-E,A=b(B),u=g(B),D=.15*s+.9*r,w=.24*s+.9*r,f=.27*s+.9*r,k=.19*s+.9*r,M=.15*s+.9*r;return e(o,{style:{flex:1},children:[e(y,{style:{position:"absolute",top:0,left:0,right:0,bottom:0,width:n,height:s},children:[h(l,{x:0,y:0,width:n,height:B,children:h(t,{start:x(0,0),end:x(0,B),colors:["#87CEEB","#98D8E8","#B0E0E6"]})}),h(l,{x:0,y:B,width:n,height:E,children:h(t,{start:x(0,B),end:x(0,s),colors:["#8B4513","#A0522D","#654321"]})}),e(d,{children:[e(i,{cx:.8*n,cy:D,r:40,children:[h(t,{start:x(-40,-40),end:x(40,40),colors:["#FFFF99","#FFD700","#FFA500","#FF8C00"]}),h(p,{dx:0,dy:0,blur:32,color:"#FFD700"})]}),h(i,{cx:.8*n-8,cy:D-8,r:15,children:h(t,{start:x(-15,-15),end:x(15,15),colors:["#FFFFFF","#FFFF99"]})}),C.map((c,o)=>{const r=22.5*o*Math.PI/180,y=o%2==0,t=y?25:15,l=y?4:2,i=.8*n+45*Math.cos(r),x=D+45*Math.sin(r),d=.8*n+Math.cos(r)*(45+t),p=D+Math.sin(r)*(45+t),e=F.Path.Make();return e.moveTo(i,x),e.lineTo(d,p),h(a,{path:e,style:"stroke",strokeWidth:l,color:"#FFD700",opacity:.75},o)}),h(i,{cx:.8*n,cy:D,r:60,opacity:.1,children:h(t,{start:x(-60,-60),end:x(60,60),colors:["#FFD700","transparent"]})})]}),e(d,{children:[e(d,{children:[h(i,{cx:.12*n,cy:w,r:16,color:"#F0F8FF",opacity:.35,children:h(p,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),h(i,{cx:.18*n,cy:w-(.24*s-.21*s),r:22,color:"#FFFFFF",opacity:.45,children:h(p,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),h(i,{cx:.25*n,cy:w-(.24*s-.19*s),r:26,color:"#F8F8FF",opacity:.55,children:h(p,{dx:2,dy:3,blur:12,color:"rgba(0,0,0,0.06)"})}),h(i,{cx:.32*n,cy:w-(.24*s-.21*s),r:20,color:"#FFFFFF",opacity:.5,children:h(p,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.05)"})}),h(i,{cx:.37*n,cy:w,r:14,color:"#F0F8FF",opacity:.4,children:h(p,{dx:1,dy:2,blur:12,color:"rgba(0,0,0,0.04)"})}),h(i,{cx:.15*n,cy:w+(.26*s-.24*s),r:8,color:"#F8F8FF",opacity:.25}),h(i,{cx:.35*n,cy:w-(.24*s-.18*s),r:6,color:"#FFFFFF",opacity:.3}),h(i,{cx:.4*n,cy:w-(.24*s-.22*s),r:5,color:"#F0F8FF",opacity:.2}),h(i,{cx:.22*n,cy:w-(.24*s-.18*s),r:7,color:"#FFFFFF",opacity:.35}),h(i,{cx:.28*n,cy:w-(.24*s-.2*s),r:5,color:"#FFFFFF",opacity:.25})]}),e(d,{children:[h(i,{cx:.62*n,cy:f,r:15,color:"#F0F8FF",opacity:.4,children:h(p,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.04)"})}),h(i,{cx:.69*n,cy:f-(.27*s-.24*s),r:19,color:"#FFFFFF",opacity:.5,children:h(p,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.05)"})}),h(i,{cx:.76*n,cy:f-(.27*s-.26*s),r:13,color:"#F8F8FF",opacity:.45,children:h(p,{dx:1,dy:2,blur:10,color:"rgba(0,0,0,0.04)"})}),h(i,{cx:.81*n,cy:f+(.28*s-.27*s),r:9,color:"#F0F8FF",opacity:.35,children:h(p,{dx:1,dy:1,blur:8,color:"rgba(0,0,0,0.03)"})}),h(i,{cx:.65*n,cy:f+(.29*s-.27*s),r:6,color:"#F8F8FF",opacity:.2}),h(i,{cx:.78*n,cy:f-(.27*s-.23*s),r:4,color:"#FFFFFF",opacity:.25}),h(i,{cx:.67*n,cy:f-(.27*s-.23*s),r:5,color:"#FFFFFF",opacity:.3})]}),e(d,{children:[h(i,{cx:.84*n,cy:k,r:10,color:"#F0F8FF",opacity:.35,children:h(p,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.03)"})}),h(i,{cx:.89*n,cy:k-(.19*s-.17*s),r:12,color:"#FFFFFF",opacity:.4,children:h(p,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.03)"})}),h(i,{cx:.93*n,cy:k,r:8,color:"#F8F8FF",opacity:.3,children:h(p,{dx:0,dy:1,blur:6,color:"rgba(0,0,0,0.02)"})}),h(i,{cx:.96*n,cy:k-(.19*s-.18*s),r:4,color:"#F0F8FF",opacity:.15}),h(i,{cx:.86*n,cy:k+(.21*s-.19*s),r:3,color:"#FFFFFF",opacity:.2})]}),e(d,{children:[h(i,{cx:.45*n,cy:M,r:8,color:"#F8F8FF",opacity:.25,children:h(p,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.02)"})}),h(i,{cx:.5*n,cy:.13*s,r:10,color:"#FFFFFF",opacity:.3,children:h(p,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.02)"})}),h(i,{cx:.54*n,cy:.15*s,r:6,color:"#F0F8FF",opacity:.2,children:h(p,{dx:0,dy:1,blur:4,color:"rgba(0,0,0,0.01)"})})]})]}),e(a,{path:A,children:[h(t,{start:x(0,B-20),end:x(0,B+20),colors:["#32CD32","#228B22","#006400"]}),h(p,{dx:0,dy:-2,blur:4,color:"rgba(0,0,0,0.2)"})]}),Array.from({length:25},(c,o)=>{const r=n/25*o+o%3*5,y=15+o%4*5,t=o%3,l=F.Path.Make();if(l.moveTo(r,B),0===t)return l.quadTo(r+1,B-.6*y,r+1,B-y),h(a,{path:l,style:"stroke",strokeWidth:1.5,color:"#16a34a",opacity:.8},"grass-"+o);if(1===t)return l.quadTo(r+2,B-.4*y,r+3,B-y),h(a,{path:l,style:"stroke",strokeWidth:2,color:"#15803d",opacity:.7},"grass-"+o);{const c=.5*y;return l.quadTo(r+1,B-c,r+2,B-y),h(a,{path:l,style:"stroke",strokeWidth:2.5,color:"#166534",opacity:.6},"grass-"+o)}}),Array.from({length:20},(c,o)=>{const r=n/20*o+o%2*10,y=B-5+o%3*5,t=10+o%3*2,l=F.Path.Make();return l.moveTo(r,y),l.lineTo(r+1,y-t),l.moveTo(r+2,y),l.lineTo(r+3,y-.8*t),l.moveTo(r+4,y),l.lineTo(r+5,y-.6*t),h(a,{path:l,style:"stroke",strokeWidth:1,color:"#22c55e",opacity:.4},"cluster-"+o)}),Array.from({length:8},(c,o)=>h(i,{cx:n/8*o+o%3*20,cy:B+30+o%4*15,r:2+o%3,color:"#8B4513",opacity:.6},o)),e(d,{children:[e(d,{children:[e(l,{x:.05*n,y:B-150,width:20,height:150,children:[h(t,{start:x(0,0),end:x(20,0),colors:["#654321","#8B4513","#A0522D","#8B4513"]}),h(p,{dx:3,dy:0,blur:6,color:"rgba(0,0,0,0.4)"})]}),h(l,{x:.05*n+3,y:B-120,width:1,height:90,color:"#5D4037",opacity:.8}),h(l,{x:.05*n+7,y:B-140,width:1.5,height:110,color:"#4A2C2A",opacity:.7}),h(l,{x:.05*n+12,y:B-100,width:1,height:70,color:"#5D4037",opacity:.6}),h(l,{x:.05*n+16,y:B-130,width:1.5,height:100,color:"#4A2C2A",opacity:.8}),h(l,{x:.05*n+18,y:B-130,width:12,height:4,color:"#8B4513",opacity:.9,children:h(p,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.3)"})}),h(l,{x:.05*n-2,y:B-100,width:10,height:3,color:"#A0522D",opacity:.8,children:h(p,{dx:-1,dy:1,blur:2,color:"rgba(0,0,0,0.3)"})}),h(l,{x:.05*n+15,y:B-160,width:8,height:3,color:"#8B4513",opacity:.7,children:h(p,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.2)"})}),h(i,{cx:.05*n+10,cy:B-150,r:38,color:"#1B5E20",opacity:.9,children:h(p,{dx:4,dy:4,blur:10,color:"rgba(0,0,0,0.3)"})}),h(i,{cx:.05*n+18,cy:B-180,r:32,color:"#2E7D32",opacity:.8}),h(i,{cx:.05*n+25,cy:B-140,r:28,color:"#388E3C",opacity:.7}),h(i,{cx:.05*n+2,cy:B-120,r:30,color:"#2E7D32",opacity:.75}),h(i,{cx:.05*n-5,cy:B-160,r:25,color:"#1B5E20",opacity:.8}),h(i,{cx:.05*n+8,cy:B-200,r:26,color:"#4CAF50",opacity:.6}),h(i,{cx:.05*n+20,cy:B-200,r:22,color:"#66BB6A",opacity:.5}),h(i,{cx:.05*n+12,cy:B-170,r:20,color:"#388E3C",opacity:.9}),h(i,{cx:.05*n+6,cy:B-140,r:18,color:"#2E7D32",opacity:.8}),h(i,{cx:.05*n+15,cy:B-220,r:15,color:"#81C784",opacity:.6}),h(i,{cx:.05*n+3,cy:B-210,r:12,color:"#A5D6A7",opacity:.5}),h(i,{cx:.05*n+28,cy:B-180,r:14,color:"#81C784",opacity:.6}),h(i,{cx:.05*n-8,cy:B-180,r:16,color:"#66BB6A",opacity:.7}),h(i,{cx:.05*n+5,cy:B-230,r:10,color:"#C8E6C9",opacity:.7}),h(i,{cx:.05*n+18,cy:B-240,r:8,color:"#E8F5E8",opacity:.6}),h(i,{cx:.05*n+22,cy:B-190,r:6,color:"#C8E6C9",opacity:.8})]}),e(d,{children:[e(l,{x:.88*n,y:B-200,width:18,height:200,children:[h(t,{start:x(0,0),end:x(18,0),colors:["#4A2C2A","#654321","#8B4513","#654321"]}),h(p,{dx:-3,dy:0,blur:6,color:"rgba(0,0,0,0.4)"})]}),h(l,{x:.88*n+2,y:B-170,width:1,height:150,color:"#3E2723",opacity:.9}),h(l,{x:.88*n+6,y:B-190,width:1.5,height:170,color:"#2E1A16",opacity:.8}),h(l,{x:.88*n+11,y:B-160,width:1,height:130,color:"#3E2723",opacity:.7}),h(l,{x:.88*n+14,y:B-180,width:1.5,height:160,color:"#2E1A16",opacity:.9}),h(i,{cx:.88*n+9,cy:B-120,r:35,color:"#0D4F0C",opacity:.95,children:h(p,{dx:-4,dy:4,blur:10,color:"rgba(0,0,0,0.3)"})}),h(i,{cx:.88*n+5,cy:B-100,r:30,color:"#1B5E20",opacity:.9}),h(i,{cx:.88*n+13,cy:B-110,r:28,color:"#2E7D32",opacity:.8}),h(i,{cx:.88*n+9,cy:B-180,r:32,color:"#1B5E20",opacity:.9}),h(i,{cx:.88*n+6,cy:B-170,r:26,color:"#2E7D32",opacity:.85}),h(i,{cx:.88*n+12,cy:B-190,r:24,color:"#388E3C",opacity:.8}),h(i,{cx:.88*n+9,cy:B-240,r:28,color:"#2E7D32",opacity:.9}),h(i,{cx:.88*n+7,cy:B-230,r:22,color:"#388E3C",opacity:.85}),h(i,{cx:.88*n+11,cy:B-250,r:20,color:"#4CAF50",opacity:.8}),h(i,{cx:.88*n+9,cy:B-300,r:22,color:"#388E3C",opacity:.9}),h(i,{cx:.88*n+8,cy:B-290,r:18,color:"#4CAF50",opacity:.8}),h(i,{cx:.88*n+10,cy:B-310,r:15,color:"#66BB6A",opacity:.7}),h(i,{cx:.88*n+4,cy:B-150,r:8,color:"#0D4F0C",opacity:.8}),h(i,{cx:.88*n+14,cy:B-170,r:6,color:"#1B5E20",opacity:.9}),h(i,{cx:.88*n+3,cy:B-220,r:5,color:"#0D4F0C",opacity:.7}),h(i,{cx:.88*n+15,cy:B-240,r:7,color:"#2E7D32",opacity:.8}),h(i,{cx:.88*n+12,cy:B-280,r:8,color:"#81C784",opacity:.6}),h(i,{cx:.88*n+11,cy:B-320,r:6,color:"#A5D6A7",opacity:.5}),h(i,{cx:.88*n+13,cy:B-190,r:5,color:"#C8E6C9",opacity:.7})]})]}),e(d,{children:[e(d,{children:[h(i,{cx:.15*n,cy:B-60,r:26,color:"#1B5E20",opacity:.95,children:h(p,{dx:3,dy:3,blur:8,color:"rgba(0,0,0,0.3)"})}),h(i,{cx:.18*n,cy:B-90,r:22,color:"#2E7D32",opacity:.9}),h(i,{cx:.21*n,cy:B-70,r:18,color:"#388E3C",opacity:.8}),h(i,{cx:.12*n,cy:B-80,r:20,color:"#2E7D32",opacity:.85}),h(i,{cx:.09*n,cy:B-50,r:16,color:"#1B5E20",opacity:.9}),h(i,{cx:.16*n,cy:B-100,r:19,color:"#4CAF50",opacity:.7}),h(i,{cx:.19*n,cy:B-95,r:15,color:"#66BB6A",opacity:.6}),h(i,{cx:.15*n,cy:B-90,r:14,color:"#388E3C",opacity:.9}),h(i,{cx:.17*n,cy:B-70,r:12,color:"#2E7D32",opacity:.8}),h(i,{cx:.13*n,cy:B-95,r:10,color:"#81C784",opacity:.7}),h(i,{cx:.2*n,cy:B-85,r:8,color:"#A5D6A7",opacity:.6}),h(i,{cx:.11*n,cy:B-70,r:9,color:"#66BB6A",opacity:.8}),h(i,{cx:.22*n,cy:B-80,r:7,color:"#81C784",opacity:.7}),h(i,{cx:.16*n,cy:B-105,r:6,color:"#C8E6C9",opacity:.8}),h(i,{cx:.19*n,cy:B-100,r:4,color:"#E8F5E8",opacity:.7})]}),e(d,{children:[h(i,{cx:.35*n,cy:B-40,r:21,color:"#1B5E20",opacity:.9,children:h(p,{dx:2,dy:2,blur:6,color:"rgba(0,0,0,0.25)"})}),h(i,{cx:.37*n,cy:B-60,r:17,color:"#2E7D32",opacity:.85}),h(i,{cx:.33*n,cy:B-30,r:15,color:"#388E3C",opacity:.8}),h(i,{cx:.36*n,cy:B-80,r:13,color:"#4CAF50",opacity:.7}),h(i,{cx:.32*n,cy:B-60,r:10,color:"#66BB6A",opacity:.8}),h(i,{cx:.38*n,cy:B-50,r:8,color:"#81C784",opacity:.7}),h(i,{cx:.34*n,cy:B-90,r:5,color:"#A5D6A7",opacity:.8})]}),e(d,{children:[h(i,{cx:.52*n,cy:B-45,r:25,color:"#1B5E20",opacity:.95,children:h(p,{dx:2,dy:3,blur:8,color:"rgba(0,0,0,0.3)"})}),h(i,{cx:.55*n,cy:B-75,r:21,color:"#2E7D32",opacity:.9}),h(i,{cx:.49*n,cy:B-35,r:19,color:"#388E3C",opacity:.85}),h(i,{cx:.54*n,cy:B-100,r:16,color:"#4CAF50",opacity:.8}),h(i,{cx:.5*n,cy:B-70,r:14,color:"#66BB6A",opacity:.75}),h(i,{cx:.47*n,cy:B-90,r:11,color:"#81C784",opacity:.7}),h(i,{cx:.56*n,cy:B-55,r:9,color:"#A5D6A7",opacity:.6}),h(i,{cx:.51*n,cy:B-85,r:4,color:"#FF69B4",opacity:.9}),h(i,{cx:.54*n,cy:B-75,r:3.5,color:"#FF6B6B",opacity:.85}),h(i,{cx:.49*n,cy:B-55,r:3,color:"#FF1744",opacity:.8}),h(i,{cx:.52*n,cy:B-105,r:6,color:"#C8E6C9",opacity:.8})]}),e(d,{children:[h(i,{cx:.72*n,cy:B-35,r:28,color:"#0D4F0C",opacity:.95,children:h(p,{dx:-2,dy:3,blur:8,color:"rgba(0,0,0,0.3)"})}),h(i,{cx:.75*n,cy:B-70,r:24,color:"#1B5E20",opacity:.9}),h(i,{cx:.69*n,cy:B-25,r:22,color:"#2E7D32",opacity:.85}),h(i,{cx:.74*n,cy:B-85,r:19,color:"#388E3C",opacity:.8}),h(i,{cx:.68*n,cy:B-55,r:17,color:"#4CAF50",opacity:.75}),h(i,{cx:.77*n,cy:B-45,r:14,color:"#66BB6A",opacity:.7}),h(i,{cx:.66*n,cy:B-75,r:12,color:"#81C784",opacity:.65}),h(i,{cx:.71*n,cy:B-95,r:10,color:"#A5D6A7",opacity:.6}),h(i,{cx:.73*n,cy:B-100,r:3,color:"#9C27B0",opacity:.9}),h(i,{cx:.7*n,cy:B-90,r:2.5,color:"#673AB7",opacity:.85}),h(i,{cx:.76*n,cy:B-55,r:3.5,color:"#FF9800",opacity:.8}),h(i,{cx:.73*n,cy:B-110,r:7,color:"#C8E6C9",opacity:.8}),h(i,{cx:.75*n,cy:B-90,r:5,color:"#E8F5E8",opacity:.7})]}),e(d,{children:[h(i,{cx:.25*n,cy:B-15,r:15,color:"#1B5E20",opacity:.8,children:h(p,{dx:1,dy:2,blur:4,color:"rgba(0,0,0,0.2)"})}),h(i,{cx:.27*n,cy:B-35,r:12,color:"#2E7D32",opacity:.75}),h(i,{cx:.23*n,cy:B-5,r:10,color:"#388E3C",opacity:.7}),h(i,{cx:.26*n,cy:B-45,r:7,color:"#66BB6A",opacity:.6}),h(i,{cx:.65*n,cy:B-5,r:13,color:"#2E7D32",opacity:.8,children:h(p,{dx:-1,dy:2,blur:4,color:"rgba(0,0,0,0.2)"})}),h(i,{cx:.67*n,cy:B-25,r:10,color:"#388E3C",opacity:.75}),h(i,{cx:.63*n,cy:B+5,r:8,color:"#4CAF50",opacity:.7}),h(i,{cx:.66*n,cy:B-35,r:5,color:"#81C784",opacity:.6})]})]}),h(d,{children:u.map((c,o)=>{const r=["#FF6B6B","#FF69B4","#9370DB","#4169E1","#FF8C00","#32CD32"],y=r[o%r.length],t=3+o%3;return e(d,{children:[h(i,{cx:c.x,cy:c.y,r:t,color:y,opacity:.8,children:h(p,{dx:0,dy:1,blur:1,color:"rgba(0,0,0,0.2)"})}),h(i,{cx:c.x,cy:c.y,r:.4*t,color:"#FFD700",opacity:.9})]},"flower-"+o)})})]}),c]})};
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,Text,StyleSheet}from 'react-native';import{GAME_CONFIG}from "../FruitNinjaService.js";import{useFruitNinjaStore}from "../FruitNinjaStore.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 score = useFruitNinjaStore(state => state.score);const timeLeft = useFruitNinjaStore(state => state.timeLeft);const lives = useFruitNinjaStore(state => state.lives);const formatTime = seconds =>{const mins = Math.floor(seconds / 60);const secs = seconds % 60;return `${mins.toString().padStart(2,'0')}:${secs.toString().padStart(2,'0')}`;};return _jsx(ScoreBoardContainer,{offset:offset,backgroundColor:"rgba(34,139,34,0.3)",borderColor:"rgba(255,255,255,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})]}),_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Time"}),_jsx(Text,{style:styles.timeValue,children:formatTime(timeLeft)})]}),_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Lives"}),_jsx(View,{style:styles.livesRow,children:Array.from({length:GAME_CONFIG.MAX_LIVES}).map((_,index)=> _jsx(Text,{style:styles.heartIcon,children:index < lives ? '❤️':'🖤'},index))})]})]})});});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},scoreValue:{fontSize:25,fontWeight:'bold',color:'#fff'},timeValue:{fontSize:25,fontWeight:'bold',color:'#fff'},livesRow:{flexDirection:'row',justifyContent:'center'},heartIcon:{fontSize:25,marginHorizontal:3}});
1
+ "use strict";import e from"react";import{View as r,Text as t,StyleSheet as o}from"react-native";import{GAME_CONFIG as i}from"../FruitNinjaService.js";import{useFruitNinjaStore as n}from"../FruitNinjaStore.js";import{ScoreBoardContainer as l}from"../../../helpers/index.js";import{jsx as s,jsxs as c}from"react/jsx-runtime";export const ScoreBoard=e.memo(({offset:e=0})=>{const o=n(e=>e.score),a=n(e=>e.timeLeft),d=n(e=>e.lives);return s(l,{offset:e,backgroundColor:"rgba(34, 139, 34, 0.3)",borderColor:"rgba(255, 255, 255, 0.4)",children:c(r,{style:f.scoreBoard,children:[c(r,{style:f.scoreSection,children:[s(t,{style:f.scoreLabel,children:"Score"}),s(t,{style:f.scoreValue,children:o})]}),c(r,{style:f.scoreSection,children:[s(t,{style:f.scoreLabel,children:"Time"}),s(t,{style:f.timeValue,children:(e=>{const r=e%60;return`${Math.floor(e/60).toString().padStart(2,"0")}:${r.toString().padStart(2,"0")}`})(a)})]}),c(r,{style:f.scoreSection,children:[s(t,{style:f.scoreLabel,children:"Lives"}),s(r,{style:f.livesRow,children:Array.from({length:i.MAX_LIVES}).map((e,r)=>s(t,{style:f.heartIcon,children:d>r?"\u2764\ufe0f":"\ud83d\udda4"},r))})]})]})})});const f=o.create({scoreBoard:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},scoreSection:{alignItems:"center",flex:1},scoreLabel:{fontSize:16,fontWeight:"bold",color:"#ffffff",marginBottom:4},scoreValue:{fontSize:25,fontWeight:"bold",color:"#fff"},timeValue:{fontSize:25,fontWeight:"bold",color:"#fff"},livesRow:{flexDirection:"row",justifyContent:"center"},heartIcon:{fontSize:25,marginHorizontal:3}});
@@ -1 +1 @@
1
- "use strict";export{ScoreBoard}from "./ScoreBoard.js";export{FruitComponent}from "./FruitComponent.js";export{GameArea}from "./GameArea.js";export{GameBackground}from "./GameBackground.js";
1
+ "use strict";export{ScoreBoard}from"./ScoreBoard.js";export{FruitComponent}from"./FruitComponent.js";export{GameArea}from"./GameArea.js";export{GameBackground}from"./GameBackground.js";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,StyleSheet}from 'react-native';import{GameControlButton,GameOverModal,GameSettingsModal}from "../../helpers/index.js";import{GAME_IDS,DEFAULT_GAME_SETTINGS}from "../../services/UtilsService.js";import{GameBackground,GameGrid,ScoreBoard}from "./components/index.js";import{Game2048Service}from "./Game2048Service.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{calculateTimeBasedScore}from "../../services/ScoringService.js";import{useGame2048Store,useTimeElapsed,useIsPlaying,useIsGameOver,useIsWon}from "./Game2048Store.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const Game2048 = React.memo(({settings,onSettingsChange,onEndGame})=>{const timeElapsed = useTimeElapsed();const isPlaying = useIsPlaying();const isGameOver = useIsGameOver();const isWon = useIsWon();const gameReportedRef = React.useRef(false);const reportGameEnd = React.useCallback(status =>{if(onEndGame && !gameReportedRef.current){const expectedTimes ={easy:180,medium:300,hard:420};const difficulty = settings?.difficulty || 'easy';const expectedTime = expectedTimes[difficulty];const calculatedScore = status === 'win' ? calculateTimeBasedScore(timeElapsed,expectedTime):0;onEndGame({status,score:calculatedScore.toString()});gameReportedRef.current = true;}},[onEndGame,timeElapsed,settings?.difficulty]);const{startGame,resetGame,initializeGame,updateSettings,incrementTime}= useGame2048Store();const gameSettings = React.useMemo(()=>({difficulty:settings?.difficulty || 'easy',enableSounds:settings?.enableSounds ?? true,enableHaptics:settings?.enableHaptics ?? true}),[settings?.difficulty,settings?.enableSounds,settings?.enableHaptics]);const initGame = React.useCallback(()=>{initializeGame(gameSettings.difficulty);},[initializeGame,gameSettings.difficulty]);React.useEffect(()=>{updateSettings(gameSettings.enableSounds,gameSettings.enableHaptics);},[updateSettings,gameSettings.enableSounds,gameSettings.enableHaptics]);React.useEffect(()=>{initGame();},[initGame]);React.useEffect(()=>{if((isGameOver || isWon)&& !gameReportedRef.current){const status = isWon ? 'win':'lose';reportGameEnd(status);}if(!isGameOver && !isWon){gameReportedRef.current = false;}},[isGameOver,isWon,reportGameEnd]);React.useEffect(()=>{if(isPlaying && !isGameOver && !isWon){const timer = setInterval(()=>{incrementTime();},1000);return()=> clearInterval(timer);}return undefined;},[isPlaying,isGameOver,isWon,incrementTime]);React.useEffect(()=>{const gameService = new Game2048Service();return()=>{gameService.cleanup();};},[]);const offset = settings?.offset ?? 0;const dynamicStyles = React.useMemo(()=>({gameArea:{...styles.gameArea,marginTop:offset}}),[offset]);return _jsxs(GameBackground,{children:[_jsx(ScoreBoard,{offset:offset}),_jsx(View,{style:dynamicStyles.gameArea,children:_jsx(GameGrid,{difficulty:gameSettings.difficulty})}),_jsx(View,{style:styles.controlsContainer,children:_jsx(GameControlButton,{isPlaying:isPlaying,gameOver:isGameOver,onStartGame:React.useCallback(()=>{if(!isPlaying){playHaptic(HapticType.SELECTION,gameSettings.enableHaptics);startGame();}},[isPlaying,gameSettings.enableHaptics,startGame]),onStopGame:React.useCallback(()=>{playHaptic(HapticType.SELECTION,gameSettings.enableHaptics);resetGame();},[gameSettings.enableHaptics,resetGame]),startButtonText:isPlaying ? 'PLAYING':'START GAME',stopButtonText:"STOP GAME",startButtonSubtext:isPlaying ? 'Swipe to play':'Tap to start',stopButtonSubtext:"Stop game and reset",startButtonColor:"#8f7a66",stopButtonColor:"#dc2626",startButtonBorderColor:"#776e65",stopButtonBorderColor:"#f87171"})}),_jsx(GameOverModal,{isVisible:isGameOver || isWon,score:timeElapsed,scoreLabel:isWon ? "Time to Win":"Time Played",scoreFormatter:time =>{const minutes = Math.floor(time / 60);const seconds = time % 60;return `${minutes}:${seconds.toString().padStart(2,'0')}`;},onPlayAgain:resetGame,buttonText:isWon ? "Continue Playing!":"Play Again!",primaryColor:"rgba(143,122,102,0.5)",borderColor:"rgba(143,122,102,0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#8f7a66"}),_jsx(GameSettingsModal,{gameId:GAME_IDS.GAME_2048,settings:settings || DEFAULT_GAME_SETTINGS,onSettingsChange:onSettingsChange})]});});const styles = StyleSheet.create({gameArea:{flex:1,justifyContent:'center',alignItems:'center'},controlsContainer:{marginTop:25,zIndex:10,position:'relative'}});Game2048.displayName = 'Game2048';
1
+ "use strict";import t from"react";import{View as e,StyleSheet as o}from"react-native";import{GameControlButton as r,GameOverModal as n,GameSettingsModal as s}from"../../helpers/index.js";import{GAME_IDS as i,DEFAULT_GAME_SETTINGS as a}from"../../services/UtilsService.js";import{GameBackground as m,GameGrid as c,ScoreBoard as l}from"./components/index.js";import{Game2048Service as f}from"./Game2048Service.js";import{playHaptic as p,HapticType as u}from"../../services/HapticsService.js";import{calculateTimeBasedScore as g}from"../../services/ScoringService.js";import{useGame2048Store as d,useTimeElapsed as S,useIsPlaying as y,useIsGameOver as x,useIsWon as C}from"./Game2048Store.js";import{jsx as G,jsxs as b}from"react/jsx-runtime";export const Game2048=t.memo(({settings:o,onSettingsChange:v,onEndGame:j})=>{const B=S(),h=y(),A=x(),P=C(),I=t.useRef(!1),w=t.useCallback(t=>{if(j&&!I.current){const e="win"===t?g(B,{easy:180,medium:300,hard:420}[o?.difficulty||"easy"]):0;j({status:t,score:e.toString()}),I.current=!0}},[j,B,o?.difficulty]),{startGame:E,resetGame:M,initializeGame:z,updateSettings:H,incrementTime:L}=d(),O=t.useMemo(()=>({difficulty:o?.difficulty||"easy",enableSounds:o?.enableSounds??!0,enableHaptics:o?.enableHaptics??!0}),[o?.difficulty,o?.enableSounds,o?.enableHaptics]),$=t.useCallback(()=>{z(O.difficulty)},[z,O.difficulty]);t.useEffect(()=>{H(O.enableSounds,O.enableHaptics)},[H,O.enableSounds,O.enableHaptics]),t.useEffect(()=>{$()},[$]),t.useEffect(()=>{!A&&!P||I.current||w(P?"win":"lose"),A||P||(I.current=!1)},[A,P,w]),t.useEffect(()=>{if(h&&!A&&!P){const t=setInterval(()=>{L()},1e3);return()=>clearInterval(t)}},[h,A,P,L]),t.useEffect(()=>{const t=new f;return()=>{t.cleanup()}},[]);const F=o?.offset??0,N=t.useMemo(()=>({gameArea:{...T.gameArea,marginTop:F}}),[F]);return b(m,{children:[G(l,{offset:F}),G(e,{style:N.gameArea,children:G(c,{difficulty:O.difficulty})}),G(e,{style:T.controlsContainer,children:G(r,{isPlaying:h,gameOver:A,onStartGame:t.useCallback(()=>{h||(p(u.SELECTION,O.enableHaptics),E())},[h,O.enableHaptics,E]),onStopGame:t.useCallback(()=>{p(u.SELECTION,O.enableHaptics),M()},[O.enableHaptics,M]),startButtonText:h?"PLAYING":"START GAME",stopButtonText:"STOP GAME",startButtonSubtext:h?"Swipe to play":"Tap to start",stopButtonSubtext:"Stop game and reset",startButtonColor:"#8f7a66",stopButtonColor:"#dc2626",startButtonBorderColor:"#776e65",stopButtonBorderColor:"#f87171"})}),G(n,{isVisible:A||P,score:B,scoreLabel:P?"Time to Win":"Time Played",scoreFormatter:t=>`${Math.floor(t/60)}:${(""+t%60).padStart(2,"0")}`,onPlayAgain:M,buttonText:P?"Continue Playing!":"Play Again!",primaryColor:"rgba(143, 122, 102, 0.5)",borderColor:"rgba(143, 122, 102, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#8f7a66"}),G(s,{gameId:i.GAME_2048,settings:o||a,onSettingsChange:v})]})});const T=o.create({gameArea:{flex:1,justifyContent:"center",alignItems:"center"},controlsContainer:{marginTop:25,zIndex:10,position:"relative"}});Game2048.displayName="Game2048";
@@ -1 +1 @@
1
- "use strict";export const GAME_2048_COLORS ={BACKGROUND:'#faf8ef',GRID_BACKGROUND:'#bbada0',TILE_COLORS:{2:{background:'#eee4da',text:'#776e65'},4:{background:'#ede0c8',text:'#776e65'},8:{background:'#f2b179',text:'#f9f6f2'},16:{background:'#f59563',text:'#f9f6f2'},32:{background:'#f67c5f',text:'#f9f6f2'},64:{background:'#f65e3b',text:'#f9f6f2'},128:{background:'#edcf72',text:'#f9f6f2'},256:{background:'#edcc61',text:'#f9f6f2'},512:{background:'#edc850',text:'#f9f6f2'},1024:{background:'#edc53f',text:'#f9f6f2'},2048:{background:'#edc22e',text:'#f9f6f2'},4096:{background:'#3c3a32',text:'#f9f6f2'},8192:{background:'#3c3a32',text:'#f9f6f2'}},SCOREBOARD_BACKGROUND:'rgba(187,173,160,0.9)',SCOREBOARD_TEXT:'#776e65',BUTTON_BACKGROUND:'#8f7a66',BUTTON_TEXT:'#f9f6f2',BUTTON_BORDER:'#776e65',GAME_OVER_OVERLAY:'rgba(238,228,218,0.95)',GAME_WIN_OVERLAY:'rgba(237,194,46,0.95)'};export const GAME_2048_SETTINGS ={GRID_SIZE:4,TILE_SIZE:70,TILE_MARGIN:8,TILE_BORDER_RADIUS:6,ANIMATION_DURATION:50,MERGE_ANIMATION_DURATION:30,SPAWN_ANIMATION_DURATION:50,INITIAL_TILES:2,NEW_TILE_PROBABILITY_4:0.1,SCORE_MULTIPLIER:{easy:1,medium:1.5,hard:2},DIFFICULTY_SETTINGS:{easy:{gridSize:4,targetTile:1024},medium:{gridSize:4,targetTile:2048},hard:{gridSize:4,targetTile:4096}}};export const GAME_2048_GESTURES ={MIN_SWIPE_DISTANCE:50,MAX_SWIPE_TIME:300,MIN_VELOCITY:0.5};export const GAME_2048_SOUNDS = Object.freeze({TILE_MOVE:Object.freeze({text:'swipe',pitch:1.2,rate:1.5}),TILE_MERGE:Object.freeze({text:'merge',pitch:1.5,rate:1.2}),GAME_WIN:Object.freeze({text:'victory!',pitch:1.8,rate:0.8}),GAME_OVER:Object.freeze({text:'game over',pitch:0.8,rate:0.9}),NEW_TILE:Object.freeze({text:'pop',pitch:1.6,rate:1.8}),INVALID_MOVE:Object.freeze({text:'blocked',pitch:0.6,rate:1.5})});const tileColorCache = new Map();export const getTileColor = value =>{if(tileColorCache.has(value)){return tileColorCache.get(value);}let result;if(value === 0){result ={background:'rgba(238,228,218,0.35)',text:'#776e65'};}else{const colors = GAME_2048_COLORS.TILE_COLORS;result = colors[value] || colors[8192];}tileColorCache.set(value,result);return result;};export const formatScore = score =>{if(score >= 1000000){return `${(score / 1000000).toFixed(1)}M`;}else if(score >= 1000){return `${(score / 1000).toFixed(1)}K`;}return score.toString();};export const BACKGROUND_TILE_COLORS = ['#E91E63','#F44336','#FF5722','#FF9800','#FFC107','#CDDC39','#4CAF50','#009688','#00BCD4','#2196F3','#3F51B5','#9C27B0' ];export const GAME_CONFIG ={GRID_SIZE:4,INITIAL_TILES:2,NEW_TILE_PROBABILITY_4:0.1,TILE_SIZE:70,TILE_MARGIN:8,ANIMATION_CONFIG:{TENSION:200,FRICTION:10}};export const GAME_2048_THEME ={backgroundColor:'rgba(0,0,0,0.7)',headerBackgroundColor:'#8f7a66',headerTextColor:'#ffffff',sectionBackgroundColor:'rgba(143,122,102,0.15)',sectionTitleColor:'#8f7a66',buttonSelectedColor:'#8f7a66',buttonUnselectedColor:'rgba(255,255,255,0.2)',buttonSelectedTextColor:'#ffffff',buttonUnselectedTextColor:'rgba(255,255,255,0.7)',switchTrackColorFalse:'rgba(143,122,102,0.3)',switchTrackColorTrue:'#8f7a66',switchThumbColor:'#ffffff',infoTextColor:'rgba(255,255,255,0.9)'};export const GAME_2048_DIFFICULTY_DESCRIPTIONS ={easy:'Reach 1024 tile on 4x4 grid',medium:'Reach 2048 tile on 4x4 grid',hard:'Reach 4096 tile on 4x4 grid'};export const getGridDimensions = difficulty =>{const settings = GAME_2048_SETTINGS.DIFFICULTY_SETTINGS[difficulty];const gridSize = settings.gridSize;const tileSize = GAME_2048_SETTINGS.TILE_SIZE;const margin = GAME_2048_SETTINGS.TILE_MARGIN;const totalSize = tileSize * gridSize + margin *(gridSize + 1);return{gridSize,tileSize,margin,totalSize};};
1
+ "use strict";export const GAME_2048_COLORS={BACKGROUND:"#faf8ef",GRID_BACKGROUND:"#bbada0",TILE_COLORS:{2:{background:"#eee4da",text:"#776e65"},4:{background:"#ede0c8",text:"#776e65"},8:{background:"#f2b179",text:"#f9f6f2"},16:{background:"#f59563",text:"#f9f6f2"},32:{background:"#f67c5f",text:"#f9f6f2"},64:{background:"#f65e3b",text:"#f9f6f2"},128:{background:"#edcf72",text:"#f9f6f2"},256:{background:"#edcc61",text:"#f9f6f2"},512:{background:"#edc850",text:"#f9f6f2"},1024:{background:"#edc53f",text:"#f9f6f2"},2048:{background:"#edc22e",text:"#f9f6f2"},4096:{background:"#3c3a32",text:"#f9f6f2"},8192:{background:"#3c3a32",text:"#f9f6f2"}},SCOREBOARD_BACKGROUND:"rgba(187, 173, 160, 0.9)",SCOREBOARD_TEXT:"#776e65",BUTTON_BACKGROUND:"#8f7a66",BUTTON_TEXT:"#f9f6f2",BUTTON_BORDER:"#776e65",GAME_OVER_OVERLAY:"rgba(238, 228, 218, 0.95)",GAME_WIN_OVERLAY:"rgba(237, 194, 46, 0.95)"};export const GAME_2048_SETTINGS={GRID_SIZE:4,TILE_SIZE:70,TILE_MARGIN:8,TILE_BORDER_RADIUS:6,ANIMATION_DURATION:50,MERGE_ANIMATION_DURATION:30,SPAWN_ANIMATION_DURATION:50,INITIAL_TILES:2,NEW_TILE_PROBABILITY_4:.1,SCORE_MULTIPLIER:{easy:1,medium:1.5,hard:2},DIFFICULTY_SETTINGS:{easy:{gridSize:4,targetTile:1024},medium:{gridSize:4,targetTile:2048},hard:{gridSize:4,targetTile:4096}}};export const GAME_2048_GESTURES={MIN_SWIPE_DISTANCE:50,MAX_SWIPE_TIME:300,MIN_VELOCITY:.5};export const GAME_2048_SOUNDS=Object.freeze({TILE_MOVE:Object.freeze({text:"swipe",pitch:1.2,rate:1.5}),TILE_MERGE:Object.freeze({text:"merge",pitch:1.5,rate:1.2}),GAME_WIN:Object.freeze({text:"victory!",pitch:1.8,rate:.8}),GAME_OVER:Object.freeze({text:"game over",pitch:.8,rate:.9}),NEW_TILE:Object.freeze({text:"pop",pitch:1.6,rate:1.8}),INVALID_MOVE:Object.freeze({text:"blocked",pitch:.6,rate:1.5})});const e=new Map;export const getTileColor=t=>{if(e.has(t))return e.get(t);let r;if(0===t)r={background:"rgba(238, 228, 218, 0.35)",text:"#776e65"};else{const e=GAME_2048_COLORS.TILE_COLORS;r=e[t]||e[8192]}return e.set(t,r),r};export const formatScore=e=>1e6>e?1e3>e?e.toString():(e/1e3).toFixed(1)+"K":(e/1e6).toFixed(1)+"M";export const BACKGROUND_TILE_COLORS=["#E91E63","#F44336","#FF5722","#FF9800","#FFC107","#CDDC39","#4CAF50","#009688","#00BCD4","#2196F3","#3F51B5","#9C27B0"];export const GAME_CONFIG={GRID_SIZE:4,INITIAL_TILES:2,NEW_TILE_PROBABILITY_4:.1,TILE_SIZE:70,TILE_MARGIN:8,ANIMATION_CONFIG:{TENSION:200,FRICTION:10}};export const GAME_2048_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#8f7a66",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(143, 122, 102, 0.15)",sectionTitleColor:"#8f7a66",buttonSelectedColor:"#8f7a66",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(143, 122, 102, 0.3)",switchTrackColorTrue:"#8f7a66",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const GAME_2048_DIFFICULTY_DESCRIPTIONS={easy:"Reach 1024 tile on 4x4 grid",medium:"Reach 2048 tile on 4x4 grid",hard:"Reach 4096 tile on 4x4 grid"};export const getGridDimensions=e=>{const t=GAME_2048_SETTINGS.DIFFICULTY_SETTINGS[e].gridSize,r=GAME_2048_SETTINGS.TILE_SIZE,o=GAME_2048_SETTINGS.TILE_MARGIN;return{gridSize:t,tileSize:r,margin:o,totalSize:r*t+o*(t+1)}};
@@ -1 +1 @@
1
- "use strict";import{Animated}from 'react-native';import{GAME_2048_SETTINGS,GAME_2048_GESTURES,GAME_CONFIG}from "./Game2048Constants.js";export class Game2048Service{getDifficultySettings(difficulty){return GAME_2048_SETTINGS.DIFFICULTY_SETTINGS[difficulty];}calculateMergeScore(tileValue,difficulty){const multiplier = GAME_2048_SETTINGS.SCORE_MULTIPLIER[difficulty];return tileValue * multiplier;}formatTime(seconds){const minutes = Math.floor(seconds / 60);const remainingSeconds = seconds % 60;return `${minutes.toString().padStart(2,'0')}:${remainingSeconds.toString().padStart(2,'0')}`;}detectSwipeDirection(startX,startY,endX,endY,velocity){const deltaX = endX - startX;const deltaY = endY - startY;const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);if(distance < GAME_2048_GESTURES.MIN_SWIPE_DISTANCE){return null;}if(velocity){const velocityMagnitude = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);if(velocityMagnitude < GAME_2048_GESTURES.MIN_VELOCITY){return null;}}const absDeltaX = Math.abs(deltaX);const absDeltaY = Math.abs(deltaY);if(absDeltaX > absDeltaY){return deltaX > 0 ? 'right':'left';}else{return deltaY > 0 ? 'down':'up';}}calculateTilePosition(row,col,gridSize,containerSize){const tileSize = GAME_2048_SETTINGS.TILE_SIZE;const margin = GAME_2048_SETTINGS.TILE_MARGIN;const totalGridSize = tileSize * gridSize + margin *(gridSize + 1);const startX =(containerSize - totalGridSize)/ 2;const startY =(containerSize - totalGridSize)/ 2;const x = startX + margin + col *(tileSize + margin);const y = startY + margin + row *(tileSize + margin);return{x,y};}generateHapticFeedback(type){const patterns ={move:'impactLight',merge:'impactMedium',win:'notificationSuccess',gameOver:'notificationError'};return patterns[type];}generateSoundEffect(type){const sounds ={move:'tile_move.mp3',merge:'tile_merge.mp3',win:'game_win.mp3',gameOver:'game_over.mp3',newTile:'new_tile.mp3'};return sounds[type];}animateTileMovement(fromPosition,toPosition,duration = GAME_2048_SETTINGS.ANIMATION_DURATION){return{from:fromPosition,to:toPosition,duration,easing:'easeOutCubic'};}animateTileMerge(position,duration = GAME_2048_SETTINGS.MERGE_ANIMATION_DURATION){return{position,duration,scaleFrom:1,scaleTo:1.1,scaleBack:1,easing:'easeInOutCubic'};}animateNewTileSpawn(position,duration = GAME_2048_SETTINGS.SPAWN_ANIMATION_DURATION){return{position,duration,scaleFrom:0,scaleTo:1,easing:'easeOutBack'};}isValidPosition(row,col,gridSize){return row >= 0 && row < gridSize && col >= 0 && col < gridSize;}getAdjacentPositions(row,col,gridSize){const directions = [{row:-1,col:0,direction:'up'},{row:1,col:0,direction:'down'},{row:0,col:-1,direction:'left'},{row:0,col:1,direction:'right'}];return directions.map(dir =>({row:row + dir.row,col:col + dir.col,direction:dir.direction})).filter(pos => this.isValidPosition(pos.row,pos.col,gridSize));}calculateGameStats(score,moves,timeElapsed){const averageScorePerMove = moves > 0 ? Math.round(score / moves):0;const scorePerSecond = timeElapsed > 0 ? Math.round(score / timeElapsed):0;return{averageScorePerMove,scorePerSecond,efficiency:moves > 0 ? Math.round(score / moves * 100)/ 100:0};}async saveGameState(gameState){try{JSON.stringify(gameState);return true;}catch(error){console.error('Failed to save game state:',error);return false;}}async loadGameState(){try{return null;}catch(error){console.error('Failed to load game state:',error);return null;}}cleanup(){}createGrid(){return Array(GAME_CONFIG.GRID_SIZE).fill(null).map(()=> Array(GAME_CONFIG.GRID_SIZE).fill(null));}addRandomTile(grid,tileId){const emptyCells = [];for(let row = 0;row < GAME_CONFIG.GRID_SIZE;row++){for(let col = 0;col < GAME_CONFIG.GRID_SIZE;col++){const gridRow = grid[row];if(gridRow && !gridRow[col]){emptyCells.push({row,col});}}}if(emptyCells.length === 0)return null;const randomCell = emptyCells[Math.floor(Math.random()* emptyCells.length)];if(!randomCell)return null;const newTile ={id:tileId,value:Math.random()< GAME_CONFIG.NEW_TILE_PROBABILITY_4 ? 4:2,row:randomCell.row,col:randomCell.col,animatedValue:new Animated.Value(0),scaleValue:new Animated.Value(0)};const targetRow = grid[randomCell.row];if(targetRow){targetRow[randomCell.col] = newTile;}return newTile;}moveTiles(grid,direction){let moved = false;let score = 0;const isHorizontal = direction === 'left' || direction === 'right';const isReverse = direction === 'right' || direction === 'down';const gridSize = GAME_CONFIG.GRID_SIZE;const newGrid = this.createGrid();for(let i = 0;i < gridSize;i++){const tiles = [];for(let j = 0;j < gridSize;j++){const index = isReverse ? gridSize - 1 - j:j;const row = isHorizontal ? grid[i]:grid[index];const tile = row ? isHorizontal ? row[index]:row[i]:null;if(tile)tiles.push(tile);}const merged = [];let j = 0;while(j < tiles.length){const currentTile = tiles[j];const nextTile = tiles[j + 1];if(currentTile && nextTile && j < tiles.length - 1 && currentTile.value === nextTile.value){const mergedTile ={...currentTile,value:currentTile.value * 2,scaleValue:currentTile.scaleValue || new Animated.Value(1)};merged.push(mergedTile);score += mergedTile.value;j += 2;}else{const tile = tiles[j];merged.push(tile || null);j++;}}while(merged.length < gridSize){merged.push(null);}for(let j = 0;j < gridSize;j++){const tile = merged[j];const index = isReverse ? gridSize - 1 - j:j;const newRow = isHorizontal ? i:index;const newCol = isHorizontal ? index:i;const originalRow = isHorizontal ? grid[i]:grid[index];const originalTile = originalRow ? isHorizontal ? originalRow[index]:originalRow[i]:null;if(tile !== originalTile || tile &&(tile.row !== newRow || tile.col !== newCol)){moved = true;}if(tile){const updatedTile ={...tile,row:newRow,col:newCol};const targetRow = newGrid[newRow];if(targetRow){targetRow[newCol] = updatedTile;}}else{const targetRow = newGrid[newRow];if(targetRow){targetRow[newCol] = null;}}}}for(let row = 0;row < gridSize;row++){for(let col = 0;col < gridSize;col++){const sourceRow = newGrid[row];const targetRow = grid[row];if(sourceRow && targetRow){targetRow[col] = sourceRow[col] || null;}}}return{moved,score};}checkGameOver(grid){const gridSize = GAME_CONFIG.GRID_SIZE;for(let row = 0;row < gridSize;row++){for(let col = 0;col < gridSize;col++){const currentRow = grid[row];if(!currentRow)continue;const tile = currentRow[col];if(!tile)return false;if(col < gridSize - 1){const rightTile = currentRow[col + 1];if(rightTile && rightTile.value === tile.value)return false;}if(row < gridSize - 1){const nextRow = grid[row + 1];const downTile = nextRow ? nextRow[col]:null;if(downTile && downTile.value === tile.value)return false;}}}return true;}hasWon(grid,targetValue){for(let row = 0;row < GAME_CONFIG.GRID_SIZE;row++){const currentRow = grid[row];if(!currentRow)continue;for(let col = 0;col < GAME_CONFIG.GRID_SIZE;col++){const tile = currentRow[col];if(tile && tile.value >= targetValue)return true;}}return false;}getTileBackgroundColor(value){const colors ={2:'#eee4da',4:'#ede0c8',8:'#f2b179',16:'#f59563',32:'#f67c5f',64:'#f65e3b',128:'#edcf72',256:'#edcc61',512:'#edc850',1024:'#edc53f',2048:'#edc22e',4096:'#ff6b6b',8192:'#ee5a52'};if(value > 8192)return '#ff4757';return colors[value] || '#3c3a32';}getTileTextColor(value){return value <= 4 ? '#776e65':'#f9f6f2';}getTileTextSize(value){if(value < 100)return 28;if(value < 1000)return 24;if(value < 10000)return 20;return 16;}getTileAnimationDelay(row,col,direction){const baseDelay = 50;switch(direction){case 'up':return row * baseDelay;case 'down':return(3 - row)* baseDelay;case 'left':return col * baseDelay;case 'right':return(3 - col)* baseDelay;default:return 0;}}interpolate(from,to,progress){return from +(to - from)* progress;}easeOutCubic(t){return 1 - Math.pow(1 - t,3);}easeInOutCubic(t){return t < 0.5 ? 4 * t * t * t:1 - Math.pow(-2 * t + 2,3)/ 2;}easeOutBack(t){const c1 = 1.70158;const c3 = c1 + 1;return 1 + c3 * Math.pow(t - 1,3)+ c1 * Math.pow(t - 1,2);}}
1
+ "use strict";import{Animated as e}from"react-native";import{GAME_2048_SETTINGS as t,GAME_2048_GESTURES as r,GAME_CONFIG as n}from"./Game2048Constants.js";export class Game2048Service{getDifficultySettings(e){return t.DIFFICULTY_SETTINGS[e]}calculateMergeScore(e,r){return e*t.SCORE_MULTIPLIER[r]}formatTime(e){const t=e%60;return`${Math.floor(e/60).toString().padStart(2,"0")}:${t.toString().padStart(2,"0")}`}detectSwipeDirection(e,t,n,o,a){const c=n-e,i=o-t;return Math.sqrt(c*c+i*i)<r.MIN_SWIPE_DISTANCE||a&&Math.sqrt(a.x*a.x+a.y*a.y)<r.MIN_VELOCITY?null:Math.abs(c)>Math.abs(i)?c>0?"right":"left":i>0?"down":"up"}calculateTilePosition(e,r,n,o){const a=t.TILE_SIZE,c=t.TILE_MARGIN,i=a*n+c*(n+1);return{x:(o-i)/2+c+r*(a+c),y:(o-i)/2+c+e*(a+c)}}generateHapticFeedback(e){return{move:"impactLight",merge:"impactMedium",win:"notificationSuccess",gameOver:"notificationError"}[e]}generateSoundEffect(e){return{move:"tile_move.mp3",merge:"tile_merge.mp3",win:"game_win.mp3",gameOver:"game_over.mp3",newTile:"new_tile.mp3"}[e]}animateTileMovement(e,r,n=t.ANIMATION_DURATION){return{from:e,to:r,duration:n,easing:"easeOutCubic"}}animateTileMerge(e,r=t.MERGE_ANIMATION_DURATION){return{position:e,duration:r,scaleFrom:1,scaleTo:1.1,scaleBack:1,easing:"easeInOutCubic"}}animateNewTileSpawn(e,r=t.SPAWN_ANIMATION_DURATION){return{position:e,duration:r,scaleFrom:0,scaleTo:1,easing:"easeOutBack"}}isValidPosition(e,t,r){return e>=0&&r>e&&t>=0&&r>t}getAdjacentPositions(e,t,r){return[{row:-1,col:0,direction:"up"},{row:1,col:0,direction:"down"},{row:0,col:-1,direction:"left"},{row:0,col:1,direction:"right"}].map(r=>({row:e+r.row,col:t+r.col,direction:r.direction})).filter(e=>this.isValidPosition(e.row,e.col,r))}calculateGameStats(e,t,r){return{averageScorePerMove:t>0?Math.round(e/t):0,scorePerSecond:r>0?Math.round(e/r):0,efficiency:t>0?Math.round(e/t*100)/100:0}}async saveGameState(e){try{return JSON.stringify(e),!0}catch(e){return!1}}async loadGameState(){try{return null}catch(e){return null}}cleanup(){}createGrid(){return Array(n.GRID_SIZE).fill(null).map(()=>Array(n.GRID_SIZE).fill(null))}addRandomTile(t,r){const o=[];for(let e=0;e<n.GRID_SIZE;e++)for(let r=0;r<n.GRID_SIZE;r++){const n=t[e];n&&!n[r]&&o.push({row:e,col:r})}if(0===o.length)return null;const a=o[Math.floor(Math.random()*o.length)];if(!a)return null;const c={id:r,value:Math.random()<n.NEW_TILE_PROBABILITY_4?4:2,row:a.row,col:a.col,animatedValue:new e.Value(0),scaleValue:new e.Value(0)},i=t[a.row];return i&&(i[a.col]=c),c}moveTiles(t,r){let o=!1,a=0;const c="left"===r||"right"===r,i="right"===r||"down"===r,l=n.GRID_SIZE,u=this.createGrid();for(let r=0;l>r;r++){const n=[];for(let e=0;l>e;e++){const o=i?l-1-e:e,a=c?t[r]:t[o],u=a?c?a[o]:a[r]:null;u&&n.push(u)}const s=[];let f=0;for(;f<n.length;){const t=n[f],r=n[f+1];if(t&&r&&f<n.length-1&&t.value===r.value){const r={...t,value:2*t.value,scaleValue:t.scaleValue||new e.Value(1)};s.push(r),a+=r.value,f+=2}else{const e=n[f];s.push(e||null),f++}}for(;s.length<l;)s.push(null);for(let e=0;l>e;e++){const n=s[e],a=i?l-1-e:e,f=c?r:a,m=c?a:r,d=c?t[r]:t[a];if((n!==(d?c?d[a]:d[r]:null)||n&&(n.row!==f||n.col!==m))&&(o=!0),n){const e={...n,row:f,col:m},t=u[f];t&&(t[m]=e)}else{const e=u[f];e&&(e[m]=null)}}}for(let e=0;l>e;e++)for(let r=0;l>r;r++){const n=u[e],o=t[e];n&&o&&(o[r]=n[r]||null)}return{moved:o,score:a}}checkGameOver(e){const t=n.GRID_SIZE;for(let r=0;t>r;r++)for(let n=0;t>n;n++){const o=e[r];if(!o)continue;const a=o[n];if(!a)return!1;if(t-1>n){const e=o[n+1];if(e&&e.value===a.value)return!1}if(t-1>r){const t=e[r+1],o=t?t[n]:null;if(o&&o.value===a.value)return!1}}return!0}hasWon(e,t){for(let r=0;r<n.GRID_SIZE;r++){const o=e[r];if(o)for(let e=0;e<n.GRID_SIZE;e++){const r=o[e];if(r&&r.value>=t)return!0}}return!1}getTileBackgroundColor(e){return e>8192?"#ff4757":{2:"#eee4da",4:"#ede0c8",8:"#f2b179",16:"#f59563",32:"#f67c5f",64:"#f65e3b",128:"#edcf72",256:"#edcc61",512:"#edc850",1024:"#edc53f",2048:"#edc22e",4096:"#ff6b6b",8192:"#ee5a52"}[e]||"#3c3a32"}getTileTextColor(e){return e>4?"#f9f6f2":"#776e65"}getTileTextSize(e){return 100>e?28:1e3>e?24:1e4>e?20:16}getTileAnimationDelay(e,t,r){switch(r){case"up":return 50*e;case"down":return 50*(3-e);case"left":return 50*t;case"right":return 50*(3-t);default:return 0}}interpolate(e,t,r){return e+(t-e)*r}easeOutCubic(e){return 1-Math.pow(1-e,3)}easeInOutCubic(e){return.5>e?4*e*e*e:1-Math.pow(-2*e+2,3)/2}easeOutBack(e){return 1+2.70158*Math.pow(e-1,3)+1.70158*Math.pow(e-1,2)}}
@@ -1 +1 @@
1
- "use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{Game2048Service}from "./Game2048Service.js";import{GAME_CONFIG,GAME_2048_SOUNDS,GAME_2048_SETTINGS}from "./Game2048Constants.js";import{immerMiddleware}from "../../services/UtilsService.js";import{playSound}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";export const useGame2048Store = create()(subscribeWithSelector(immerMiddleware((set,get)=>{const gameService = new Game2048Service();return{timeElapsed:0,isPlaying:false,isGameOver:false,isWon:false,isAnimating:false,grid:gameService.createGrid(),nextTileId:1,difficulty:'easy',targetValue:2048,gridSize:4,enableSounds:true,enableHaptics:true,startGame:()=>{set(state =>{state.isPlaying = true;state.timeElapsed = 0;});},stopGame:()=>{const state = get();state.initializeGame(state.difficulty);},resetGame:()=>{const state = get();state.initializeGame(state.difficulty);},initializeGame:(difficulty = 'easy')=>{set(state =>{const difficultySettings = GAME_2048_SETTINGS.DIFFICULTY_SETTINGS[difficulty];state.grid = gameService.createGrid();let tileId = 1;const tile1 = gameService.addRandomTile(state.grid,tileId++);const tile2 = gameService.addRandomTile(state.grid,tileId++);state.timeElapsed = 0;state.isPlaying = false;state.isGameOver = false;state.isWon = false;state.isAnimating = false;state.nextTileId = tileId;state.difficulty = difficulty;state.targetValue = difficultySettings.targetTile;state.gridSize = difficultySettings.gridSize;[tile1,tile2].forEach(tile =>{if(tile?.scaleValue){setTimeout(()=>{tile.scaleValue?.setValue(0);const{Animated}= require('react-native');Animated.spring(tile.scaleValue,{toValue:1,useNativeDriver:true,tension:GAME_CONFIG.ANIMATION_CONFIG.TENSION,friction:GAME_CONFIG.ANIMATION_CONFIG.FRICTION}).start();},100);}});});},updateGrid:newGrid =>{set(state =>{state.grid = newGrid;});},incrementTime:()=>{set(state =>{state.timeElapsed += 1;});},setIsAnimating:animating =>{set(state =>{state.isAnimating = animating;});},setGameOver:gameOver =>{set(state =>{state.isGameOver = gameOver;if(gameOver){state.isPlaying = false;}});},setWon:won =>{set(state =>{state.isWon = won;});},incrementTileId:()=>{const state = get();const newId = state.nextTileId;set(draft =>{draft.nextTileId = newId + 1;});return newId;},handleMove:direction =>{const state = get();if(state.isGameOver || state.isWon || state.isAnimating){return false;}set(draft =>{if(!draft.isPlaying){draft.isPlaying = true;}draft.isAnimating = true;});const gridCopy = state.grid.map(row => row.slice());const{moved,score:moveScore}= gameService.moveTiles(gridCopy,direction);if(moved){const newTileId = state.nextTileId;const newTile = gameService.addRandomTile(gridCopy,newTileId);const hasWon = gameService.hasWon(gridCopy,state.targetValue);const isGameOver = gameService.checkGameOver(gridCopy);set(draft =>{draft.grid = gridCopy;draft.nextTileId = newTileId + 1;if(hasWon)draft.isWon = true;if(isGameOver)draft.isGameOver = true;});Promise.resolve().then(()=>{playSound(GAME_2048_SOUNDS.TILE_MOVE,state.enableSounds);playHaptic(HapticType.LIGHT,state.enableHaptics);if(moveScore > 0){playSound(GAME_2048_SOUNDS.TILE_MERGE,state.enableSounds);playHaptic(HapticType.MEDIUM,state.enableHaptics);}if(newTile){playSound(GAME_2048_SOUNDS.NEW_TILE,state.enableSounds);}if(hasWon){playSound(GAME_2048_SOUNDS.GAME_WIN,state.enableSounds);playHaptic(HapticType.SUCCESS,state.enableHaptics);}else if(isGameOver){playSound(GAME_2048_SOUNDS.GAME_OVER,state.enableSounds);playHaptic(HapticType.ERROR,state.enableHaptics);}});if(newTile?.scaleValue){const{Animated}= require('react-native');newTile.scaleValue.setValue(0);Animated.spring(newTile.scaleValue,{toValue:1,useNativeDriver:true,tension:GAME_CONFIG.ANIMATION_CONFIG.TENSION,friction:GAME_CONFIG.ANIMATION_CONFIG.FRICTION}).start(()=>{set(draft =>{draft.isAnimating = false;});});}else{set(draft =>{draft.isAnimating = false;});}return true;}else{Promise.resolve().then(()=>{playSound(GAME_2048_SOUNDS.INVALID_MOVE,state.enableSounds);playHaptic(HapticType.WARNING,state.enableHaptics);});set(draft =>{draft.isAnimating = false;});return false;}},updateSettings:(enableSounds,enableHaptics)=>{set(state =>{state.enableSounds = enableSounds;state.enableHaptics = enableHaptics;});}};})));export const useTimeElapsed =()=> useGame2048Store(state => state.timeElapsed);export const useGrid =()=> useGame2048Store(state => state.grid);export const useIsPlaying =()=> useGame2048Store(state => state.isPlaying);export const useIsGameOver =()=> useGame2048Store(state => state.isGameOver);export const useIsWon =()=> useGame2048Store(state => state.isWon);export const useIsAnimating =()=> useGame2048Store(state => state.isAnimating);export const useDifficulty =()=> useGame2048Store(state => state.difficulty);export const useTargetValue =()=> useGame2048Store(state => state.targetValue);export const useGridSize =()=> useGame2048Store(state => state.gridSize);
1
+ "use strict";import{create as e}from"zustand";import{subscribeWithSelector as t}from"zustand/middleware";import{Game2048Service as s}from"./Game2048Service.js";import{GAME_CONFIG as r,GAME_2048_SOUNDS as i,GAME_2048_SETTINGS as o}from"./Game2048Constants.js";import{immerMiddleware as n}from"../../services/UtilsService.js";import{playSound as a}from"../../services/SoundsService.js";import{playHaptic as m,HapticType as u}from"../../services/HapticsService.js";export const useGame2048Store=e()(t(n((e,t)=>{const n=new s;return{timeElapsed:0,isPlaying:!1,isGameOver:!1,isWon:!1,isAnimating:!1,grid:n.createGrid(),nextTileId:1,difficulty:"easy",targetValue:2048,gridSize:4,enableSounds:!0,enableHaptics:!0,startGame:()=>{e(e=>{e.isPlaying=!0,e.timeElapsed=0})},stopGame:()=>{const e=t();e.initializeGame(e.difficulty)},resetGame:()=>{const e=t();e.initializeGame(e.difficulty)},initializeGame:(t="easy")=>{e(e=>{const s=o.DIFFICULTY_SETTINGS[t];e.grid=n.createGrid();let i=1;const a=n.addRandomTile(e.grid,i++),m=n.addRandomTile(e.grid,i++);e.timeElapsed=0,e.isPlaying=!1,e.isGameOver=!1,e.isWon=!1,e.isAnimating=!1,e.nextTileId=3,e.difficulty=t,e.targetValue=s.targetTile,e.gridSize=s.gridSize,[a,m].forEach(e=>{e?.scaleValue&&setTimeout(()=>{e.scaleValue?.setValue(0);const{Animated:t}=require("react-native");t.spring(e.scaleValue,{toValue:1,useNativeDriver:!0,tension:r.ANIMATION_CONFIG.TENSION,friction:r.ANIMATION_CONFIG.FRICTION}).start()},100)})})},updateGrid:t=>{e(e=>{e.grid=t})},incrementTime:()=>{e(e=>{e.timeElapsed+=1})},setIsAnimating:t=>{e(e=>{e.isAnimating=t})},setGameOver:t=>{e(e=>{e.isGameOver=t,t&&(e.isPlaying=!1)})},setWon:t=>{e(e=>{e.isWon=t})},incrementTileId:()=>{const s=t().nextTileId;return e(e=>{e.nextTileId=s+1}),s},handleMove:s=>{const o=t();if(o.isGameOver||o.isWon||o.isAnimating)return!1;e(e=>{e.isPlaying||(e.isPlaying=!0),e.isAnimating=!0});const c=o.grid.map(e=>e.slice()),{moved:p,score:d}=n.moveTiles(c,s);if(p){const t=o.nextTileId,s=n.addRandomTile(c,t),p=n.hasWon(c,o.targetValue),G=n.checkGameOver(c);if(e(e=>{e.grid=c,e.nextTileId=t+1,p&&(e.isWon=!0),G&&(e.isGameOver=!0)}),Promise.resolve().then(()=>{a(i.TILE_MOVE,o.enableSounds),m(u.LIGHT,o.enableHaptics),d>0&&(a(i.TILE_MERGE,o.enableSounds),m(u.MEDIUM,o.enableHaptics)),s&&a(i.NEW_TILE,o.enableSounds),p?(a(i.GAME_WIN,o.enableSounds),m(u.SUCCESS,o.enableHaptics)):G&&(a(i.GAME_OVER,o.enableSounds),m(u.ERROR,o.enableHaptics))}),s?.scaleValue){const{Animated:t}=require("react-native");s.scaleValue.setValue(0),t.spring(s.scaleValue,{toValue:1,useNativeDriver:!0,tension:r.ANIMATION_CONFIG.TENSION,friction:r.ANIMATION_CONFIG.FRICTION}).start(()=>{e(e=>{e.isAnimating=!1})})}else e(e=>{e.isAnimating=!1});return!0}return Promise.resolve().then(()=>{a(i.INVALID_MOVE,o.enableSounds),m(u.WARNING,o.enableHaptics)}),e(e=>{e.isAnimating=!1}),!1},updateSettings:(t,s)=>{e(e=>{e.enableSounds=t,e.enableHaptics=s})}}})));export const useTimeElapsed=()=>useGame2048Store(e=>e.timeElapsed);export const useGrid=()=>useGame2048Store(e=>e.grid);export const useIsPlaying=()=>useGame2048Store(e=>e.isPlaying);export const useIsGameOver=()=>useGame2048Store(e=>e.isGameOver);export const useIsWon=()=>useGame2048Store(e=>e.isWon);export const useIsAnimating=()=>useGame2048Store(e=>e.isAnimating);export const useDifficulty=()=>useGame2048Store(e=>e.difficulty);export const useTargetValue=()=>useGame2048Store(e=>e.targetValue);export const useGridSize=()=>useGame2048Store(e=>e.gridSize);
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,StyleSheet,Dimensions}from 'react-native';import{Canvas,LinearGradient,Rect,vec,Circle,RoundedRect}from '@shopify/react-native-skia';import{BACKGROUND_TILE_COLORS}from "../Game2048Constants.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 generateFloatingTiles = React.useMemo(()=>{const elements = [];const tileCount = 30;for(let i = 0;i < tileCount;i++){const baseX = width / tileCount * i;const baseY = height / tileCount * i;const x = baseX + Math.sin(i * 0.5)* 60 + Math.random()* 120;const y = baseY + Math.cos(i * 0.7)* 80 + Math.random()* 140;const tileSize = 15 + Math.random()* 25;const colorIndex = i % BACKGROUND_TILE_COLORS.length;const opacity = 0.25 + Math.sin(i)* 0.15;const tileX = Math.max(tileSize / 2,Math.min(width - tileSize,x));const tileY = Math.max(tileSize / 2,Math.min(height - tileSize,y));if(i % 5 === 0){elements.push(_jsx(RoundedRect,{x:tileX,y:tileY,width:tileSize,height:tileSize,r:tileSize * 0.25,color:`${BACKGROUND_TILE_COLORS[colorIndex]}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`square-tile-${i}`));}else if(i % 5 === 1){elements.push(_jsx(RoundedRect,{x:tileX,y:tileY,width:tileSize * 0.7,height:tileSize,r:tileSize * 0.2,color:`${BACKGROUND_TILE_COLORS[colorIndex]}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`rect-tile-${i}`));}else if(i % 5 === 2){elements.push(_jsx(RoundedRect,{x:tileX,y:tileY,width:tileSize * 1.3,height:tileSize * 0.8,r:tileSize * 0.15,color:`${BACKGROUND_TILE_COLORS[colorIndex]}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`wide-tile-${i}`));}else if(i % 5 === 3){elements.push(_jsx(Circle,{cx:tileX + tileSize / 2,cy:tileY + tileSize / 2,r:tileSize / 2,color:`${BACKGROUND_TILE_COLORS[colorIndex]}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`circle-tile-${i}`));}else{elements.push(_jsx(RoundedRect,{x:tileX,y:tileY,width:tileSize * 0.9,height:tileSize * 0.9,r:tileSize * 0.3,color:`${BACKGROUND_TILE_COLORS[colorIndex]}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`diamond-tile-${i}`));}}return elements;},[]);return _jsxs(View,{style:styles.container,children:[_jsxs(Canvas,{style:styles.backgroundCanvas,children:[_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(width,height),colors:[`${BACKGROUND_TILE_COLORS[0]}35`,`${BACKGROUND_TILE_COLORS[3]}30`,`${BACKGROUND_TILE_COLORS[6]}35`,`${BACKGROUND_TILE_COLORS[9]}30`,`${BACKGROUND_TILE_COLORS[11]}35` ]})}),_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(width / 2,height / 2),colors:[`${BACKGROUND_TILE_COLORS[1]}25`,'transparent',`${BACKGROUND_TILE_COLORS[4]}25`,'transparent',`${BACKGROUND_TILE_COLORS[7]}25`,'transparent']})}),_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(width,0),end:vec(0,height),colors:[`${BACKGROUND_TILE_COLORS[2]}20`,'transparent',`${BACKGROUND_TILE_COLORS[5]}20`,'transparent',`${BACKGROUND_TILE_COLORS[8]}20`,'transparent']})}),generateFloatingTiles,_jsx(RoundedRect,{x:width * 0.08,y:height * 0.12,width:55,height:55,r:12,color:`${BACKGROUND_TILE_COLORS[10]}60`}),_jsx(RoundedRect,{x:width * 0.82,y:height * 0.78,width:50,height:50,r:10,color:`${BACKGROUND_TILE_COLORS[9]}60`}),_jsx(RoundedRect,{x:width * 0.78,y:height * 0.15,width:45,height:45,r:9,color:`${BACKGROUND_TILE_COLORS[8]}60`}),_jsx(RoundedRect,{x:width * 0.12,y:height * 0.72,width:60,height:60,r:14,color:`${BACKGROUND_TILE_COLORS[7]}60`}),_jsx(RoundedRect,{x:width * 0.45,y:height * 0.08,width:40,height:40,r:8,color:`${BACKGROUND_TILE_COLORS[6]}60`}),_jsx(RoundedRect,{x:width * 0.15,y:height * 0.45,width:48,height:48,r:10,color:`${BACKGROUND_TILE_COLORS[5]}60`}),_jsx(RoundedRect,{x:width * 0.72,y:height * 0.55,width:42,height:42,r:8,color:`${BACKGROUND_TILE_COLORS[4]}60`}),_jsx(RoundedRect,{x:width * 0.55,y:height * 0.85,width:38,height:38,r:7,color:`${BACKGROUND_TILE_COLORS[3]}60`}),_jsx(Circle,{cx:width * 0.25,cy:height * 0.28,r:22,color:`${BACKGROUND_TILE_COLORS[2]}50`}),_jsx(Circle,{cx:width * 0.62,cy:height * 0.32,r:26,color:`${BACKGROUND_TILE_COLORS[1]}50`}),_jsx(Circle,{cx:width * 0.38,cy:height * 0.68,r:20,color:`${BACKGROUND_TILE_COLORS[0]}50`}),Array.from({length:Math.floor(width / 80)},(_,i)=> _jsx(Rect,{x:i * 80,y:0,width:1,height:height,color:"rgba(255,255,255,0.08)"},`grid-v-${i}`)),Array.from({length:Math.floor(height / 80)},(_,i)=> _jsx(Rect,{x:0,y:i * 80,width:width,height:1,color:"rgba(255,255,255,0.08)"},`grid-h-${i}`))]}),children]});});const styles = StyleSheet.create({container:{flex:1},backgroundCanvas:{position:'absolute',top:0,left:0,right:0,bottom:0,width,height}});
1
+ "use strict";import t from"react";import{View as r,StyleSheet as h,Dimensions as o}from"react-native";import{Canvas as i,LinearGradient as e,Rect as a,vec as c,Circle as n,RoundedRect as l}from"@shopify/react-native-skia";import{BACKGROUND_TILE_COLORS as s}from"../Game2048Constants.js";import{jsx as d,jsxs as g}from"react/jsx-runtime";const{width:x,height:y}=o.get("window");export const GameBackground=t.memo(({children:h})=>{const o=t.useMemo(()=>{const t=[];for(let r=0;30>r;r++){const h=y/30*r,o=x/30*r+60*Math.sin(.5*r)+120*Math.random(),i=h+80*Math.cos(.7*r)+140*Math.random(),e=15+25*Math.random(),a=r%s.length,c=.25+.15*Math.sin(r),g=Math.max(e/2,Math.min(x-e,o)),w=Math.max(e/2,Math.min(y-e,i));r%5==0?t.push(d(l,{x:g,y:w,width:e,height:e,r:.25*e,color:`${s[a]}${Math.floor(255*c).toString(16).padStart(2,"0")}`},"square-tile-"+r)):r%5==1?t.push(d(l,{x:g,y:w,width:.7*e,height:e,r:.2*e,color:`${s[a]}${Math.floor(255*c).toString(16).padStart(2,"0")}`},"rect-tile-"+r)):r%5==2?t.push(d(l,{x:g,y:w,width:1.3*e,height:.8*e,r:.15*e,color:`${s[a]}${Math.floor(255*c).toString(16).padStart(2,"0")}`},"wide-tile-"+r)):r%5==3?t.push(d(n,{cx:g+e/2,cy:w+e/2,r:e/2,color:`${s[a]}${Math.floor(255*c).toString(16).padStart(2,"0")}`},"circle-tile-"+r)):t.push(d(l,{x:g,y:w,width:.9*e,height:.9*e,r:.3*e,color:`${s[a]}${Math.floor(255*c).toString(16).padStart(2,"0")}`},"diamond-tile-"+r))}return t},[]);return g(r,{style:w.container,children:[g(i,{style:w.backgroundCanvas,children:[d(a,{x:0,y:0,width:x,height:y,children:d(e,{start:c(0,0),end:c(x,y),colors:[s[0]+"35",s[3]+"30",s[6]+"35",s[9]+"30",s[11]+"35"]})}),d(a,{x:0,y:0,width:x,height:y,children:d(e,{start:c(0,0),end:c(x/2,y/2),colors:[s[1]+"25","transparent",s[4]+"25","transparent",s[7]+"25","transparent"]})}),d(a,{x:0,y:0,width:x,height:y,children:d(e,{start:c(x,0),end:c(0,y),colors:[s[2]+"20","transparent",s[5]+"20","transparent",s[8]+"20","transparent"]})}),o,d(l,{x:.08*x,y:.12*y,width:55,height:55,r:12,color:s[10]+"60"}),d(l,{x:.82*x,y:.78*y,width:50,height:50,r:10,color:s[9]+"60"}),d(l,{x:.78*x,y:.15*y,width:45,height:45,r:9,color:s[8]+"60"}),d(l,{x:.12*x,y:.72*y,width:60,height:60,r:14,color:s[7]+"60"}),d(l,{x:.45*x,y:.08*y,width:40,height:40,r:8,color:s[6]+"60"}),d(l,{x:.15*x,y:.45*y,width:48,height:48,r:10,color:s[5]+"60"}),d(l,{x:.72*x,y:.55*y,width:42,height:42,r:8,color:s[4]+"60"}),d(l,{x:.55*x,y:.85*y,width:38,height:38,r:7,color:s[3]+"60"}),d(n,{cx:.25*x,cy:.28*y,r:22,color:s[2]+"50"}),d(n,{cx:.62*x,cy:.32*y,r:26,color:s[1]+"50"}),d(n,{cx:.38*x,cy:.68*y,r:20,color:s[0]+"50"}),Array.from({length:Math.floor(x/80)},(t,r)=>d(a,{x:80*r,y:0,width:1,height:y,color:"rgba(255, 255, 255, 0.08)"},"grid-v-"+r)),Array.from({length:Math.floor(y/80)},(t,r)=>d(a,{x:0,y:80*r,width:x,height:1,color:"rgba(255, 255, 255, 0.08)"},"grid-h-"+r))]}),h]})});const w=h.create({container:{flex:1},backgroundCanvas:{position:"absolute",top:0,left:0,right:0,bottom:0,width:x,height:y}});
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,StyleSheet,Dimensions}from 'react-native';import{Gesture,GestureDetector}from 'react-native-gesture-handler';import{useGrid,useGame2048Store}from "../Game2048Store.js";import{GameTile}from "./GameTile.js";import{GAME_CONFIG}from "../Game2048Constants.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width:screenWidth}= Dimensions.get('window');export const GameGrid = React.memo(()=>{const grid = useGrid();const{handleMove}= useGame2048Store();const gridCalculations = React.useMemo(()=>{const horizontalPadding = 40;const availableWidth = screenWidth - horizontalPadding;const margin = GAME_CONFIG.TILE_MARGIN;const responsiveTileSize = Math.floor((availableWidth - margin * 5)/ 4);const tileSize = Math.max(responsiveTileSize,60);const gridContainerSize = tileSize * 4 + margin * 5;return{margin,tileSize,gridContainerSize};},[]);const renderTile = React.useCallback(tile =>{const{margin,tileSize}= gridCalculations;const x = margin + tile.col *(tileSize + margin);const y = margin + tile.row *(tileSize + margin);return _jsx(GameTile,{tile:tile,position:{x,y},size:tileSize},tile.id);},[gridCalculations]);const panGesture = React.useMemo(()=> Gesture.Pan().onEnd(event =>{const{translationX,translationY}= event;const minDistance = 50;const absX = Math.abs(translationX);const absY = Math.abs(translationY);if(absX > absY && absX > minDistance){handleMove(translationX > 0 ? 'right':'left');}else if(absY > minDistance){handleMove(translationY > 0 ? 'down':'up');}}).runOnJS(true),[handleMove]);return _jsx(View,{style:styles.gameContainer,children:_jsx(GestureDetector,{gesture:panGesture,children:_jsxs(View,{style:[styles.grid,{width:gridCalculations.gridContainerSize,height:gridCalculations.gridContainerSize}],children:[React.useMemo(()=> Array(16).fill(0).map((_,index)=>{const row = Math.floor(index / 4);const col = index % 4;const{margin,tileSize}= gridCalculations;const x = margin + col *(tileSize + margin);const y = margin + row *(tileSize + margin);return _jsx(View,{style:[styles.cell,{left:x,top:y,width:tileSize,height:tileSize}]},index);}),[gridCalculations]),React.useMemo(()=>{const tiles = [];for(const row of grid){for(const tile of row){if(tile)tiles.push(renderTile(tile));}}return tiles;},[grid,renderTile])]})})});});const styles = StyleSheet.create({gameContainer:{flex:1,justifyContent:'center',alignItems:'center',paddingHorizontal:20,paddingVertical:10,zIndex:10,position:'relative'},grid:{backgroundColor:'rgba(187,173,160,0.9)',borderRadius:15,position:'relative',shadowColor:'#000',shadowOffset:{width:0,height:8},shadowOpacity:0.25,shadowRadius:15,elevation:15,maxWidth:screenWidth - 40},cell:{position:'absolute',backgroundColor:'rgba(238,228,218,0.4)',borderRadius:6}});GameGrid.displayName = 'GameGrid';
1
+ "use strict";import t from"react";import{View as e,StyleSheet as r,Dimensions as i}from"react-native";import{Gesture as o,GestureDetector as a}from"react-native-gesture-handler";import{useGrid as n,useGame2048Store as s}from"../Game2048Store.js";import{GameTile as d}from"./GameTile.js";import{GAME_CONFIG as l}from"../Game2048Constants.js";import{jsx as m,jsxs as c}from"react/jsx-runtime";const{width:h}=i.get("window");export const GameGrid=t.memo(()=>{const r=n(),{handleMove:i}=s(),f=t.useMemo(()=>{const t=h-40,e=l.TILE_MARGIN,r=Math.max(Math.floor((t-5*e)/4),60);return{margin:e,tileSize:r,gridContainerSize:4*r+5*e}},[]),p=t.useCallback(t=>{const{margin:e,tileSize:r}=f,i=e+t.col*(r+e),o=e+t.row*(r+e);return m(d,{tile:t,position:{x:i,y:o},size:r},t.id)},[f]),u=t.useMemo(()=>o.Pan().onEnd(t=>{const{translationX:e,translationY:r}=t,o=Math.abs(e),a=Math.abs(r);o>a&&o>50?i(e>0?"right":"left"):a>50&&i(r>0?"down":"up")}).runOnJS(!0),[i]);return m(e,{style:g.gameContainer,children:m(a,{gesture:u,children:c(e,{style:[g.grid,{width:f.gridContainerSize,height:f.gridContainerSize}],children:[t.useMemo(()=>Array(16).fill(0).map((t,r)=>{const i=Math.floor(r/4),o=r%4,{margin:a,tileSize:n}=f,s=a+o*(n+a),d=a+i*(n+a);return m(e,{style:[g.cell,{left:s,top:d,width:n,height:n}]},r)}),[f]),t.useMemo(()=>{const t=[];for(const e of r)for(const r of e)r&&t.push(p(r));return t},[r,p])]})})})});const g=r.create({gameContainer:{flex:1,justifyContent:"center",alignItems:"center",paddingHorizontal:20,paddingVertical:10,zIndex:10,position:"relative"},grid:{backgroundColor:"rgba(187, 173, 160, 0.9)",borderRadius:15,position:"relative",shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.25,shadowRadius:15,elevation:15,maxWidth:h-40},cell:{position:"absolute",backgroundColor:"rgba(238, 228, 218, 0.4)",borderRadius:6}});GameGrid.displayName="GameGrid";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{Text,StyleSheet,Animated}from 'react-native';import{Game2048Service}from "../Game2048Service.js";import{jsx as _jsx}from "react/jsx-runtime";const gameService = new Game2048Service();export const GameTile = React.memo(({tile,position,size})=>{const tileStyles = React.useMemo(()=>{const backgroundColor = gameService.getTileBackgroundColor(tile.value);return{left:position.x,top:position.y,width:size,height:size,backgroundColor,shadowColor:backgroundColor,transform:[{scale:tile.scaleValue || 1}]};},[tile.value,tile.scaleValue,position.x,position.y,size]);const textStyles = React.useMemo(()=>({fontSize:gameService.getTileTextSize(tile.value),color:gameService.getTileTextColor(tile.value),fontWeight:'800'}),[tile.value]);return _jsx(Animated.View,{style:[styles.tile,tileStyles,styles.shadow],children:_jsx(Text,{style:[styles.tileText,textStyles],children:tile.value})});},(prevProps,nextProps)=>{return prevProps.tile.id === nextProps.tile.id && prevProps.tile.value === nextProps.tile.value && prevProps.position.x === nextProps.position.x && prevProps.position.y === nextProps.position.y && prevProps.size === nextProps.size && prevProps.tile.scaleValue === nextProps.tile.scaleValue;});const styles = StyleSheet.create({tile:{position:'absolute',borderRadius:8,justifyContent:'center',alignItems:'center'},shadow:{shadowOffset:{width:0,height:4},shadowOpacity:0.3,shadowRadius:8,elevation:8},tileText:{textAlign:'center',textShadowColor:'rgba(0,0,0,0.3)',textShadowOffset:{width:1,height:1},textShadowRadius:2}});GameTile.displayName = 'GameTile';
1
+ "use strict";import t from"react";import{Text as e,StyleSheet as o,Animated as i}from"react-native";import{Game2048Service as r}from"../Game2048Service.js";import{jsx as s}from"react/jsx-runtime";const a=new r;export const GameTile=t.memo(({tile:o,position:r,size:h})=>{const l=t.useMemo(()=>{const t=a.getTileBackgroundColor(o.value);return{left:r.x,top:r.y,width:h,height:h,backgroundColor:t,shadowColor:t,transform:[{scale:o.scaleValue||1}]}},[o.value,o.scaleValue,r.x,r.y,h]),c=t.useMemo(()=>({fontSize:a.getTileTextSize(o.value),color:a.getTileTextColor(o.value),fontWeight:"800"}),[o.value]);return s(i.View,{style:[n.tile,l,n.shadow],children:s(e,{style:[n.tileText,c],children:o.value})})},(t,e)=>t.tile.id===e.tile.id&&t.tile.value===e.tile.value&&t.position.x===e.position.x&&t.position.y===e.position.y&&t.size===e.size&&t.tile.scaleValue===e.tile.scaleValue);const n=o.create({tile:{position:"absolute",borderRadius:8,justifyContent:"center",alignItems:"center"},shadow:{shadowOffset:{width:0,height:4},shadowOpacity:.3,shadowRadius:8,elevation:8},tileText:{textAlign:"center",textShadowColor:"rgba(0, 0, 0, 0.3)",textShadowOffset:{width:1,height:1},textShadowRadius:2}});GameTile.displayName="GameTile";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,Text,StyleSheet}from 'react-native';import{useTimeElapsed}from "../Game2048Store.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 timeElapsed = useTimeElapsed();const formattedTime = React.useMemo(()=>{const minutes = Math.floor(timeElapsed / 60);const seconds = timeElapsed % 60;return `${minutes}:${seconds.toString().padStart(2,'0')}`;},[timeElapsed]);return _jsx(ScoreBoardContainer,{offset:offset,backgroundColor:"rgba(187,173,160,0.4)",borderColor:"rgba(119,110,101,0.6)",children:_jsxs(View,{style:styles.scoreBoard,children:[_jsx(Text,{style:styles.scoreLabel,children:"Time Elapsed"}),_jsx(Text,{style:styles.scoreValue,children:formattedTime})]})});});const styles = StyleSheet.create({scoreBoard:{alignItems:'center'},scoreLabel:{fontSize:16,fontWeight:'bold',color:'#ffffff',marginBottom:4},scoreValue:{fontSize:25,fontWeight:'bold',color:'#ffffff'}});ScoreBoard.displayName = 'ScoreBoard';
1
+ "use strict";import o from"react";import{View as r,Text as e,StyleSheet as t}from"react-native";import{useTimeElapsed as f}from"../Game2048Store.js";import{ScoreBoardContainer as s}from"../../../helpers/index.js";import{jsx as c,jsxs as a}from"react/jsx-runtime";export const ScoreBoard=o.memo(({offset:t=0})=>{const n=f(),l=o.useMemo(()=>`${Math.floor(n/60)}:${(""+n%60).padStart(2,"0")}`,[n]);return c(s,{offset:t,backgroundColor:"rgba(187, 173, 160, 0.4)",borderColor:"rgba(119, 110, 101, 0.6)",children:a(r,{style:i.scoreBoard,children:[c(e,{style:i.scoreLabel,children:"Time Elapsed"}),c(e,{style:i.scoreValue,children:l})]})})});const i=t.create({scoreBoard:{alignItems:"center"},scoreLabel:{fontSize:16,fontWeight:"bold",color:"#ffffff",marginBottom:4},scoreValue:{fontSize:25,fontWeight:"bold",color:"#ffffff"}});ScoreBoard.displayName="ScoreBoard";
@@ -1 +1 @@
1
- "use strict";export{GameGrid}from "./GameGrid.js";export{GameTile}from "./GameTile.js";export{ScoreBoard}from "./ScoreBoard.js";export{GameBackground}from "./GameBackground.js";
1
+ "use strict";export{GameGrid}from"./GameGrid.js";export{GameTile}from"./GameTile.js";export{ScoreBoard}from"./ScoreBoard.js";export{GameBackground}from"./GameBackground.js";
@@ -1 +1 @@
1
- "use strict";import React,{useState,useEffect,useCallback,useRef,useMemo}from 'react';import{View,StyleSheet,Dimensions}from 'react-native';import{GestureHandlerRootView}from 'react-native-gesture-handler';import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{calculateTimeBasedScore}from "../../services/ScoringService.js";import{MazeRunnerService}from "./MazeRunnerService.js";import{DEFAULT_MAZE_RUNNER_SETTINGS,MAZE_RUNNER_DIFFICULTY_CONFIG}from "./MazeRunnerConstants.js";import{GameBackground,ScoreBoard,EnhancedGameArea}from "./components/index.js";import{GameControlButton,GameOverModal}from "../../helpers/index.js";import{GameSettingsModal}from "../../helpers/index.js";import{GAME_IDS,DEFAULT_GAME_SETTINGS}from "../../services/UtilsService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const useResponsiveDimensions =()=>{const [dimensions,setDimensions] = useState(()=>{const{width,height}= Dimensions.get('window');return{width,height};});useEffect(()=>{const handleDimensionChange =({window})=>{setDimensions(prev =>{if(prev.width !== window.width || prev.height !== window.height){return{width:window.width,height:window.height};}return prev;});};const subscription = Dimensions.addEventListener('change',handleDimensionChange);return()=> subscription?.remove();},[]);return dimensions;};export const MazeRunner =({settings = DEFAULT_GAME_SETTINGS,onSettingsChange,onEndGame})=>{const{width:screenWidth,height:screenHeight}= useResponsiveDimensions();const gameReportedRef = useRef(false);const reportGameEnd = useCallback((status,currentScore)=>{if(onEndGame && !gameReportedRef.current){const difficultyConfig = MAZE_RUNNER_DIFFICULTY_CONFIG[settings.difficulty];const expectedTime = difficultyConfig.gameDuration;const calculatedScore = status === 'win' ? calculateTimeBasedScore(currentScore,expectedTime):0;onEndGame({status,score:calculatedScore.toString()});gameReportedRef.current = true;}},[onEndGame,settings.difficulty]);const responsiveDimensions = useMemo(()=>{const reservedHeight = 220;const availableHeight = screenHeight - reservedHeight;const availableWidth = screenWidth - 40;const maxDimension = Math.min(availableWidth,availableHeight);const gameAreaSize = Math.max(300,Math.min(maxDimension,600));return{width:gameAreaSize,height:gameAreaSize};},[screenWidth,screenHeight]);const gameService = useMemo(()=>{const currentSettings ={...DEFAULT_MAZE_RUNNER_SETTINGS,...settings};const{width:initialWidth,height:initialHeight}= Dimensions.get('window');const reservedHeight = 220;const availableHeight = initialHeight - reservedHeight;const availableWidth = initialWidth - 40;const maxDimension = Math.min(availableWidth,availableHeight);const gameAreaSize = Math.max(300,Math.min(maxDimension,600));return new MazeRunnerService(currentSettings.gridSize,gameAreaSize,gameAreaSize,currentSettings.gameDuration);},[]);const [gameState,setGameState] = useState(gameService.getGameState());const [showGameOverModal,setShowGameOverModal] = useState(false);const [walls,setWalls] = useState(()=> gameService.getWalls());const completionHandledRef = useRef(false);const gameConfig = useMemo(()=> gameService.getGameConfig(),[gameService,responsiveDimensions]);const gameControlButtonProps = useMemo(()=>({isPlaying:gameState.isPlaying,gameOver:gameState.isCompleted || gameState.gameOver,startButtonText:"START MAZE",stopButtonText:"STOP GAME",startButtonSubtext:"Navigate the maze!",stopButtonSubtext:"End current game",startButtonColor:"#8b4513",stopButtonColor:"#dc2626",startButtonBorderColor:"#cd853f",stopButtonBorderColor:"#f87171"}),[gameState.isPlaying,gameState.isCompleted,gameState.gameOver]);const gameOverModalProps = useMemo(()=>({isVisible:showGameOverModal,score:gameState.timeElapsed,scoreLabel:"Completion Time",scoreFormatter:time =>{const minutes = Math.floor(time / 60);const seconds = time % 60;return `${minutes}:${seconds.toString().padStart(2,'0')}`;},buttonText:gameState.isCompleted ? "Navigate Again!":"Try Again!",primaryColor:"rgba(139,69,19,0.5)",borderColor:"rgba(139,69,19,0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#8b4513"}),[showGameOverModal,gameState.timeElapsed,gameState.isCompleted]);useEffect(()=>{gameService.resetGame();},[gameService]);useEffect(()=>{const difficultyConfig = MAZE_RUNNER_DIFFICULTY_CONFIG[settings.difficulty];const gridSize = difficultyConfig.gridSize;const gameDuration = difficultyConfig.gameDuration;gameService.updateSettings(gridSize,gameDuration,responsiveDimensions.width,responsiveDimensions.height);},[settings.difficulty,gameService,responsiveDimensions]);const handleStateChange = useCallback(newState =>{setGameState(()=>{if(newState.isCompleted && !completionHandledRef.current){completionHandledRef.current = true;handleGameCompleted();reportGameEnd('win',newState.timeElapsed);setTimeout(()=>{setShowGameOverModal(true);},500);}return newState;});setWalls(gameService.getWalls());},[gameService,reportGameEnd]);useEffect(()=>{gameService.setGameStateChangeCallback(handleStateChange);return()=>{try{gameService.stopGame();}catch{}try{gameService.resetGame();}catch{}gameService.cleanup();};},[gameService,handleStateChange]);const handleGameCompleted = useCallback(()=>{playSound(GAME_SOUNDS.MAZE_RUNNER.COMPLETE,settings.enableSounds);playHaptic(HapticType.SUCCESS,settings.enableHaptics);},[settings.enableSounds,settings.enableHaptics]);const handleStartGame = useCallback(()=>{gameReportedRef.current = false;completionHandledRef.current = false;gameService.startGame();setShowGameOverModal(false);playSound(GAME_SOUNDS.MAZE_RUNNER.START,settings.enableSounds);playHaptic(HapticType.MEDIUM,settings.enableHaptics);},[gameService,settings.enableSounds,settings.enableHaptics]);const handleStopGame = useCallback(()=>{reportGameEnd('cancel',gameState.timeElapsed);gameService.stopGame();playSound(GAME_SOUNDS.MAZE_RUNNER.STOP,settings.enableSounds);},[gameService,settings.enableSounds,reportGameEnd,gameState.timeElapsed]);const handleBallPositionChange = useCallback(position =>{return gameService.updateBallPosition(position);},[gameService]);const handlePlayAgain = useCallback(()=>{completionHandledRef.current = false;setShowGameOverModal(false);gameService.resetGame();},[gameService]);const offset = settings?.offset ?? 0;return _jsx(View,{style:styles.container,children:_jsx(GestureHandlerRootView,{children:_jsxs(View,{style:styles.gameContainer,children:[_jsx(GameBackground,{width:screenWidth,height:screenHeight}),_jsx(ScoreBoard,{gameState:gameState,offset:offset}),_jsx(View,{style:[styles.gameAreaContainer,{marginTop:offset}],children:_jsx(EnhancedGameArea,{gameState:gameState,gameConfig:gameConfig,walls:walls,onBallPositionChange:handleBallPositionChange,hapticEnabled:settings.enableHaptics})}),_jsx(GameControlButton,{...gameControlButtonProps,onStartGame:handleStartGame,onStopGame:handleStopGame}),_jsx(GameOverModal,{...gameOverModalProps,onPlayAgain:handlePlayAgain}),_jsx(GameSettingsModal,{gameId:GAME_IDS.MAZE_RUNNER,settings:settings || DEFAULT_GAME_SETTINGS,onSettingsChange:onSettingsChange})]})})});};const styles = StyleSheet.create({container:{flex:1},gameContainer:{flex:1},gameAreaContainer:{flex:1,justifyContent:'center',alignItems:'center',paddingHorizontal:10,paddingVertical:5}});
1
+ "use strict";import t,{useState as e,useEffect as o,useCallback as r,useRef as n,useMemo as i}from"react";import{View as s,StyleSheet as a,Dimensions as c}from"react-native";import{GestureHandlerRootView as m}from"react-native-gesture-handler";import{playSound as h,GAME_SOUNDS as g}from"../../services/SoundsService.js";import{playHaptic as l,HapticType as f}from"../../services/HapticsService.js";import{calculateTimeBasedScore as d}from"../../services/ScoringService.js";import{MazeRunnerService as u}from"./MazeRunnerService.js";import{DEFAULT_MAZE_RUNNER_SETTINGS as p,MAZE_RUNNER_DIFFICULTY_CONFIG as C}from"./MazeRunnerConstants.js";import{GameBackground as w,ScoreBoard as S,EnhancedGameArea as x}from"./components/index.js";import{GameControlButton as b,GameOverModal as v}from"../../helpers/index.js";import{GameSettingsModal as j}from"../../helpers/index.js";import{GAME_IDS as B,DEFAULT_GAME_SETTINGS as M}from"../../services/UtilsService.js";import{jsx as T,jsxs as y}from"react/jsx-runtime";const A=()=>{const[t,r]=e(()=>{const{width:t,height:e}=c.get("window");return{width:t,height:e}});return o(()=>{const t=c.addEventListener("change",({window:t})=>{r(e=>e.width!==t.width||e.height!==t.height?{width:t.width,height:t.height}:e)});return()=>t?.remove()},[]),t};export const MazeRunner=({settings:t=M,onSettingsChange:a,onEndGame:E})=>{const{width:G,height:P}=A(),R=n(!1),H=r((e,o)=>{if(E&&!R.current){const r=C[t.difficulty].gameDuration,n="win"===e?d(o,r):0;E({status:e,score:n.toString()}),R.current=!0}},[E,t.difficulty]),I=i(()=>{const t=Math.max(300,Math.min(Math.min(G-40,P-220),600));return{width:t,height:t}},[G,P]),N=i(()=>{const e={...p,...t},{width:o,height:r}=c.get("window"),n=Math.max(300,Math.min(Math.min(o-40,r-220),600));return new u(e.gridSize,n,n,e.gameDuration)},[]),[O,V]=e(N.getGameState()),[$,F]=e(!1),[L,U]=e(()=>N.getWalls()),Z=n(!1),k=i(()=>N.getGameConfig(),[N,I]),q=i(()=>({isPlaying:O.isPlaying,gameOver:O.isCompleted||O.gameOver,startButtonText:"START MAZE",stopButtonText:"STOP GAME",startButtonSubtext:"Navigate the maze!",stopButtonSubtext:"End current game",startButtonColor:"#8b4513",stopButtonColor:"#dc2626",startButtonBorderColor:"#cd853f",stopButtonBorderColor:"#f87171"}),[O.isPlaying,O.isCompleted,O.gameOver]),D=i(()=>({isVisible:$,score:O.timeElapsed,scoreLabel:"Completion Time",scoreFormatter:t=>`${Math.floor(t/60)}:${(""+t%60).padStart(2,"0")}`,buttonText:O.isCompleted?"Navigate Again!":"Try Again!",primaryColor:"rgba(139, 69, 19, 0.5)",borderColor:"rgba(139, 69, 19, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#8b4513"}),[$,O.timeElapsed,O.isCompleted]);o(()=>{N.resetGame()},[N]),o(()=>{const e=C[t.difficulty],o=e.gridSize,r=e.gameDuration;N.updateSettings(o,r,I.width,I.height)},[t.difficulty,N,I]);const J=r(t=>{V(()=>(t.isCompleted&&!Z.current&&(Z.current=!0,K(),H("win",t.timeElapsed),setTimeout(()=>{F(!0)},500)),t)),U(N.getWalls())},[N,H]);o(()=>(N.setGameStateChangeCallback(J),()=>{try{N.stopGame()}catch{}try{N.resetGame()}catch{}N.cleanup()}),[N,J]);const K=r(()=>{h(g.MAZE_RUNNER.COMPLETE,t.enableSounds),l(f.SUCCESS,t.enableHaptics)},[t.enableSounds,t.enableHaptics]),Q=r(()=>{R.current=!1,Z.current=!1,N.startGame(),F(!1),h(g.MAZE_RUNNER.START,t.enableSounds),l(f.MEDIUM,t.enableHaptics)},[N,t.enableSounds,t.enableHaptics]),W=r(()=>{H("cancel",O.timeElapsed),N.stopGame(),h(g.MAZE_RUNNER.STOP,t.enableSounds)},[N,t.enableSounds,H,O.timeElapsed]),X=r(t=>N.updateBallPosition(t),[N]),Y=r(()=>{Z.current=!1,F(!1),N.resetGame()},[N]),_=t?.offset??0;return T(s,{style:z.container,children:T(m,{children:y(s,{style:z.gameContainer,children:[T(w,{width:G,height:P}),T(S,{gameState:O,offset:_}),T(s,{style:[z.gameAreaContainer,{marginTop:_}],children:T(x,{gameState:O,gameConfig:k,walls:L,onBallPositionChange:X,hapticEnabled:t.enableHaptics})}),T(b,{...q,onStartGame:Q,onStopGame:W}),T(v,{...D,onPlayAgain:Y}),T(j,{gameId:B.MAZE_RUNNER,settings:t||M,onSettingsChange:a})]})})})};const z=a.create({container:{flex:1},gameContainer:{flex:1},gameAreaContainer:{flex:1,justifyContent:"center",alignItems:"center",paddingHorizontal:10,paddingVertical:5}});
@@ -1 +1 @@
1
- "use strict";export const DEFAULT_MAZE_RUNNER_SETTINGS ={difficulty:'medium',gameDuration:120,soundEnabled:true,hapticEnabled:true,gridSize:10,showHints:false};export const MAZE_RUNNER_DIFFICULTY_CONFIG ={easy:{gridSize:8,timeBonus:1.5,scoreMultiplier:1.0,hintAvailable:true,gameDuration:60},medium:{gridSize:10,timeBonus:1.2,scoreMultiplier:1.2,hintAvailable:false,gameDuration:120},hard:{gridSize:12,timeBonus:1.0,scoreMultiplier:1.5,hintAvailable:false,gameDuration:180}};export const MAZE_RUNNER_THEME ={backgroundColor:'rgba(0,0,0,0.7)',headerBackgroundColor:'#8b4513',headerTextColor:'#ffffff',sectionBackgroundColor:'rgba(139,69,19,0.15)',sectionTitleColor:'#8b4513',buttonSelectedColor:'#8b4513',buttonUnselectedColor:'rgba(255,255,255,0.2)',buttonSelectedTextColor:'#ffffff',buttonUnselectedTextColor:'rgba(255,255,255,0.7)',switchTrackColorFalse:'rgba(139,69,19,0.3)',switchTrackColorTrue:'#8b4513',switchThumbColor:'#ffffff',infoTextColor:'rgba(255,255,255,0.9)'};export const MAZE_RUNNER_DIFFICULTY_DESCRIPTIONS ={easy:'Small maze,more forgiving maze',medium:'Balanced maze,balanced challenge',hard:'Complex maze,maximum challenge!'};export const MAZE_ADVENTURE_COLORS = ['#FF6B6B','#4ECDC4','#45B7D1','#96CEB4','#FFEAA7','#DDA0DD','#98D8C8','#F7DC6F','#BB8FCE','#85C1E9','#82E0AA','#F8C471','#D7BDE2','#A9DFBF','#FAD7A0','#D5A6BD' ];
1
+ "use strict";export const DEFAULT_MAZE_RUNNER_SETTINGS={difficulty:"medium",gameDuration:120,soundEnabled:!0,hapticEnabled:!0,gridSize:10,showHints:!1};export const MAZE_RUNNER_DIFFICULTY_CONFIG={easy:{gridSize:8,timeBonus:1.5,scoreMultiplier:1,hintAvailable:!0,gameDuration:60},medium:{gridSize:10,timeBonus:1.2,scoreMultiplier:1.2,hintAvailable:!1,gameDuration:120},hard:{gridSize:12,timeBonus:1,scoreMultiplier:1.5,hintAvailable:!1,gameDuration:180}};export const MAZE_RUNNER_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#8b4513",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(139, 69, 19, 0.15)",sectionTitleColor:"#8b4513",buttonSelectedColor:"#8b4513",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(139, 69, 19, 0.3)",switchTrackColorTrue:"#8b4513",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const MAZE_RUNNER_DIFFICULTY_DESCRIPTIONS={easy:"Small maze, more forgiving maze",medium:"Balanced maze, balanced challenge",hard:"Complex maze, maximum challenge!"};export const MAZE_ADVENTURE_COLORS=["#FF6B6B","#4ECDC4","#45B7D1","#96CEB4","#FFEAA7","#DDA0DD","#98D8C8","#F7DC6F","#BB8FCE","#85C1E9","#82E0AA","#F8C471","#D7BDE2","#A9DFBF","#FAD7A0","#D5A6BD"];
@@ -1 +1 @@
1
- "use strict";export class MazeRunnerService{gameTimer = null;constructor(gridSize = 15,gameAreaWidth = 350,gameAreaHeight = 500,gameDuration = 120){this.gameConfig ={GRID_SIZE:gridSize,CELL_SIZE:Math.min(gameAreaWidth,gameAreaHeight)/ gridSize,BALL_SIZE:18,PIPE_WIDTH:8,GAME_AREA_WIDTH:gameAreaWidth,GAME_AREA_HEIGHT:gameAreaHeight,COLLISION_TOLERANCE:5,SCORE_PER_COMPLETION:100,TIME_BONUS_MULTIPLIER:10,GAME_DURATION:gameDuration};this.gameState ={isPlaying:false,isPaused:false,score:0,timeElapsed:0,ballPosition:{x:0,y:0},targetPosition:{x:0,y:0},isCompleted:false,gameOver:false};this.maze = [];this.walls = [];this.initializeMaze();this.generateMazeWithBacktracking();this.generateWalls();this.setStartAndEndPositions();}setGameStateChangeCallback(callback){this.onGameStateChange = callback;}notifyGameStateChange(){if(this.onGameStateChange){this.onGameStateChange({...this.gameState});}}initializeMaze(){this.maze = [];for(let y = 0;y < this.gameConfig.GRID_SIZE;y++){this.maze[y] = [];for(let x = 0;x < this.gameConfig.GRID_SIZE;x++){if(this.maze[y]){this.maze[y][x] ={x,y,walls:{top:true,right:true,bottom:true,left:true},visited:false};}}}}generateNewMaze(){this.initializeMaze();this.generateMazeWithBacktracking();this.generateWalls();this.setStartAndEndPositions();this.gameState.isCompleted = false;this.gameState.isPlaying = false;this.gameState.isPaused = false;this.gameState.gameOver = false;this.gameState.score = 0;this.gameState.timeElapsed = 0;this.notifyGameStateChange();}generateMazeWithBacktracking(){const stack = [];const startCell = this.maze[0]?.[0];if(startCell){startCell.visited = true;stack.push(startCell);}while(stack.length > 0){const current = stack[stack.length - 1];const neighbors = current ? this.getUnvisitedNeighbors(current):[];if(neighbors.length > 0){const next = neighbors[Math.floor(Math.random()* neighbors.length)];if(current && next)this.removeWallBetween(current,next);if(next){next.visited = true;stack.push(next);}}else{stack.pop();}}this.ensureConnectivity();}ensureConnectivity(){if(!this.hasPathFromStartToEnd()){this.createMinimalPath();}}hasPathFromStartToEnd(){const visited = Array(this.gameConfig.GRID_SIZE).fill(null).map(()=> Array(this.gameConfig.GRID_SIZE).fill(false));const queue = [{x:0,y:0}];if(visited[0])visited[0][0] = true;while(queue.length > 0){const current = queue.shift();if(current.x === this.gameConfig.GRID_SIZE - 1 && current.y === this.gameConfig.GRID_SIZE - 1){return true;}const directions = [{dx:0,dy:-1,wall:'top'},{dx:1,dy:0,wall:'right'},{dx:0,dy:1,wall:'bottom'},{dx:-1,dy:0,wall:'left'}];for(const dir of directions){const newX = current.x + dir.dx;const newY = current.y + dir.dy;if(newX >= 0 && newX < this.gameConfig.GRID_SIZE && newY >= 0 && newY < this.gameConfig.GRID_SIZE && !visited[newY]?.[newX]){const currentCell = this.maze[current.y]?.[current.x];if(currentCell && !currentCell.walls[dir.wall]){if(visited[newY])visited[newY][newX] = true;queue.push({x:newX,y:newY});}}}}return false;}createMinimalPath(){let currentX = 0;let currentY = 0;const endX = this.gameConfig.GRID_SIZE - 1;const endY = this.gameConfig.GRID_SIZE - 1;const visited = new Set();while(currentX !== endX || currentY !== endY){const key = `${currentX},${currentY}`;if(visited.has(key)){break;}visited.add(key);const possibleMoves = [];if(currentX < endX)possibleMoves.push('right');if(currentY < endY)possibleMoves.push('down');if(currentX > 0)possibleMoves.push('left');if(currentY > 0)possibleMoves.push('up');if(possibleMoves.length === 0)break;let direction;if(Math.random()< 0.6 &&(currentX !== endX || currentY !== endY)){if(currentX < endX && Math.random()< 0.5){direction = 'right';}else if(currentY < endY){direction = 'down';}else if(currentX < endX){direction = 'right';}else{direction = possibleMoves[Math.floor(Math.random()* possibleMoves.length)];}}else{direction = possibleMoves[Math.floor(Math.random()* possibleMoves.length)];}const cell = this.maze[currentY]?.[currentX];if(direction === 'right' && currentX < this.gameConfig.GRID_SIZE - 1 && cell){cell.walls.right = false;const rightCell = this.maze[currentY]?.[currentX + 1];if(rightCell)rightCell.walls.left = false;currentX++;}else if(direction === 'down' && currentY < this.gameConfig.GRID_SIZE - 1 && cell){cell.walls.bottom = false;const bottomCell = this.maze[currentY + 1]?.[currentX];if(bottomCell)bottomCell.walls.top = false;currentY++;}else if(direction === 'left' && currentX > 0 && cell){cell.walls.left = false;const leftCell = this.maze[currentY]?.[currentX - 1];if(leftCell)leftCell.walls.right = false;currentX--;}else if(direction === 'up' && currentY > 0 && cell){cell.walls.top = false;const topCell = this.maze[currentY - 1]?.[currentX];if(topCell)topCell.walls.bottom = false;currentY--;}}}getUnvisitedNeighbors(cell){const neighbors = [];const{x,y}= cell;if(y > 0 && this.maze[y - 1]?.[x] && !this.maze[y - 1]?.[x]?.visited){const topCell = this.maze[y - 1]?.[x];if(topCell){neighbors.push(topCell);}}if(x < this.gameConfig.GRID_SIZE - 1 && this.maze[y]?.[x + 1] && !this.maze[y]?.[x + 1]?.visited){const rightCell = this.maze[y]?.[x + 1];if(rightCell){neighbors.push(rightCell);}}if(y < this.gameConfig.GRID_SIZE - 1 && this.maze[y + 1]?.[x] && !this.maze[y + 1]?.[x]?.visited){const bottomCell = this.maze[y + 1]?.[x];if(bottomCell){neighbors.push(bottomCell);}}if(x > 0 && this.maze[y]?.[x - 1] && !this.maze[y]?.[x - 1]?.visited){const leftCell = this.maze[y]?.[x - 1];if(leftCell){neighbors.push(leftCell);}}return neighbors;}removeWallBetween(current,next){const dx = current.x - next.x;const dy = current.y - next.y;if(dx === 1){current.walls.left = false;next.walls.right = false;}else if(dx === -1){current.walls.right = false;next.walls.left = false;}else if(dy === 1){current.walls.top = false;next.walls.bottom = false;}else if(dy === -1){current.walls.bottom = false;next.walls.top = false;}}generateWalls(){this.walls = [];const wallThickness = 4;const cellSize = this.gameConfig.CELL_SIZE;const mazeWidth = this.gameConfig.GRID_SIZE * cellSize;const mazeHeight = this.gameConfig.GRID_SIZE * cellSize;this.walls.push({x:0,y:0,width:mazeWidth,height:wallThickness,type:'horizontal'});this.walls.push({x:0,y:mazeHeight - wallThickness,width:mazeWidth,height:wallThickness,type:'horizontal'});this.walls.push({x:0,y:0,width:wallThickness,height:mazeHeight,type:'vertical'});this.walls.push({x:mazeWidth - wallThickness,y:0,width:wallThickness,height:mazeHeight,type:'vertical'});for(let y = 0;y < this.gameConfig.GRID_SIZE;y++){for(let x = 0;x < this.gameConfig.GRID_SIZE;x++){const cell = this.maze[y]?.[x];if(!cell)continue;const cellX = x * cellSize;const cellY = y * cellSize;if(cell.walls.top && y > 0){this.walls.push({x:cellX,y:cellY,width:cellSize,height:wallThickness,type:'horizontal'});}if(cell.walls.left && x > 0){this.walls.push({x:cellX,y:cellY,width:wallThickness,height:cellSize,type:'vertical'});}}}}setStartAndEndPositions(){const cellSize = this.gameConfig.CELL_SIZE;this.gameState.ballPosition ={x:cellSize / 2,y:cellSize / 2};this.gameState.targetPosition ={x:(this.gameConfig.GRID_SIZE - 1)* cellSize + cellSize / 2,y:(this.gameConfig.GRID_SIZE - 1)* cellSize + cellSize / 2};}updateSettings(gridSize,gameDuration,gameAreaWidth,gameAreaHeight){const newGameAreaWidth = gameAreaWidth || this.gameConfig.GAME_AREA_WIDTH;const newGameAreaHeight = gameAreaHeight || this.gameConfig.GAME_AREA_HEIGHT;this.gameConfig.GRID_SIZE = gridSize;this.gameConfig.GAME_AREA_WIDTH = newGameAreaWidth;this.gameConfig.GAME_AREA_HEIGHT = newGameAreaHeight;this.gameConfig.CELL_SIZE = Math.min(newGameAreaWidth,newGameAreaHeight)/ gridSize;this.gameConfig.GAME_DURATION = gameDuration;this.generateNewMaze();this.gameState.isPlaying = false;this.gameState.isPaused = false;this.gameState.timeElapsed = 0;this.gameState.isCompleted = false;this.gameState.gameOver = false;this.stopTimer();this.notifyGameStateChange();}resetGame(){this.generateNewMaze();this.gameState.isPlaying = false;this.gameState.isPaused = false;this.gameState.score = 0;this.gameState.timeElapsed = 0;this.gameState.isCompleted = false;this.gameState.gameOver = false;this.stopTimer();this.notifyGameStateChange();}startGame(){this.gameState.ballPosition ={x:this.gameConfig.CELL_SIZE / 2,y:this.gameConfig.CELL_SIZE / 2};this.gameState.targetPosition ={x:(this.gameConfig.GRID_SIZE - 1)* this.gameConfig.CELL_SIZE + this.gameConfig.CELL_SIZE / 2,y:(this.gameConfig.GRID_SIZE - 1)* this.gameConfig.CELL_SIZE + this.gameConfig.CELL_SIZE / 2};this.gameState.isPlaying = true;this.gameState.isPaused = false;this.gameState.score = 0;this.gameState.timeElapsed = 0;this.gameState.isCompleted = false;this.gameState.gameOver = false;this.startTimer();this.notifyGameStateChange();}pauseGame(){this.gameState.isPaused = true;this.stopTimer();this.notifyGameStateChange();}resumeGame(){this.gameState.isPaused = false;this.startTimer();this.notifyGameStateChange();}stopGame(){this.gameState.isPlaying = false;this.gameState.isPaused = false;this.stopTimer();this.notifyGameStateChange();}startTimer(){this.stopTimer();this.gameTimer = setInterval(()=>{if(!this.gameState.isPaused && this.gameState.isPlaying){this.gameState.timeElapsed += 1;this.notifyGameStateChange();}},1000);}stopTimer(){if(this.gameTimer){clearInterval(this.gameTimer);this.gameTimer = null;}}updateBallPosition(newPosition){if(!this.gameState.isPlaying || this.gameState.isPaused){return false;}if(this.isValidPosition(newPosition)){this.gameState.ballPosition = newPosition;if(!this.gameState.isCompleted && this.isNearTarget(newPosition)){this.completeLevel();}this.notifyGameStateChange();return true;}return false;}isValidPosition(position){const{x,y}= position;const ballRadius = this.gameConfig.BALL_SIZE / 2;for(const wall of this.walls){if(this.ballCollidesWithWall(x,y,ballRadius,wall)){return false;}}const padding = ballRadius + 2;if(x - ballRadius < padding || x + ballRadius > this.gameConfig.GAME_AREA_WIDTH - padding || y - ballRadius < padding || y + ballRadius > this.gameConfig.GAME_AREA_HEIGHT - padding){return false;}return true;}ballCollidesWithWall(ballX,ballY,ballRadius,wall){const closestX = Math.max(wall.x,Math.min(ballX,wall.x + wall.width));const closestY = Math.max(wall.y,Math.min(ballY,wall.y + wall.height));const distanceX = ballX - closestX;const distanceY = ballY - closestY;const distanceSquared = distanceX * distanceX + distanceY * distanceY;return distanceSquared < ballRadius * ballRadius;}isNearTarget(position){const distance = Math.sqrt(Math.pow(position.x - this.gameState.targetPosition.x,2)+ Math.pow(position.y - this.gameState.targetPosition.y,2));return distance < this.gameConfig.BALL_SIZE * 1.5;}completeLevel(){this.gameState.score += this.gameConfig.SCORE_PER_COMPLETION;this.gameState.isCompleted = true;this.gameState.isPlaying = false;this.stopTimer();this.notifyGameStateChange();}getGameState(){return{...this.gameState};}getGameConfig(){return{...this.gameConfig};}getWalls(){return [...this.walls];}getMaze(){return this.maze.map(row => row.map(cell =>({...cell})));}formatTime(seconds){const minutes = Math.floor(seconds / 60);const remainingSeconds = seconds % 60;return `${minutes}:${remainingSeconds.toString().padStart(2,'0')}`;}cleanup(){this.stopTimer();}}
1
+ "use strict";export class MazeRunnerService{gameTimer=null;constructor(t=15,i=350,s=500,h=120){this.gameConfig={GRID_SIZE:t,CELL_SIZE:Math.min(i,s)/t,BALL_SIZE:18,PIPE_WIDTH:8,GAME_AREA_WIDTH:i,GAME_AREA_HEIGHT:s,COLLISION_TOLERANCE:5,SCORE_PER_COMPLETION:100,TIME_BONUS_MULTIPLIER:10,GAME_DURATION:h},this.gameState={isPlaying:!1,isPaused:!1,score:0,timeElapsed:0,ballPosition:{x:0,y:0},targetPosition:{x:0,y:0},isCompleted:!1,gameOver:!1},this.maze=[],this.walls=[],this.initializeMaze(),this.generateMazeWithBacktracking(),this.generateWalls(),this.setStartAndEndPositions()}setGameStateChangeCallback(t){this.onGameStateChange=t}notifyGameStateChange(){this.onGameStateChange&&this.onGameStateChange({...this.gameState})}initializeMaze(){this.maze=[];for(let t=0;t<this.gameConfig.GRID_SIZE;t++){this.maze[t]=[];for(let i=0;i<this.gameConfig.GRID_SIZE;i++)this.maze[t]&&(this.maze[t][i]={x:i,y:t,walls:{top:!0,right:!0,bottom:!0,left:!0},visited:!1})}}generateNewMaze(){this.initializeMaze(),this.generateMazeWithBacktracking(),this.generateWalls(),this.setStartAndEndPositions(),this.gameState.isCompleted=!1,this.gameState.isPlaying=!1,this.gameState.isPaused=!1,this.gameState.gameOver=!1,this.gameState.score=0,this.gameState.timeElapsed=0,this.notifyGameStateChange()}generateMazeWithBacktracking(){const t=[],i=this.maze[0]?.[0];for(i&&(i.visited=!0,t.push(i));t.length>0;){const i=t[t.length-1],s=i?this.getUnvisitedNeighbors(i):[];if(s.length>0){const h=s[Math.floor(Math.random()*s.length)];i&&h&&this.removeWallBetween(i,h),h&&(h.visited=!0,t.push(h))}else t.pop()}this.ensureConnectivity()}ensureConnectivity(){this.hasPathFromStartToEnd()||this.createMinimalPath()}hasPathFromStartToEnd(){const t=Array(this.gameConfig.GRID_SIZE).fill(null).map(()=>Array(this.gameConfig.GRID_SIZE).fill(!1)),i=[{x:0,y:0}];for(t[0]&&(t[0][0]=!0);i.length>0;){const s=i.shift();if(s.x===this.gameConfig.GRID_SIZE-1&&s.y===this.gameConfig.GRID_SIZE-1)return!0;const h=[{dx:0,dy:-1,wall:"top"},{dx:1,dy:0,wall:"right"},{dx:0,dy:1,wall:"bottom"},{dx:-1,dy:0,wall:"left"}];for(const e of h){const h=s.x+e.dx,a=s.y+e.dy;if(h>=0&&h<this.gameConfig.GRID_SIZE&&a>=0&&a<this.gameConfig.GRID_SIZE&&!t[a]?.[h]){const n=this.maze[s.y]?.[s.x];n&&!n.walls[e.wall]&&(t[a]&&(t[a][h]=!0),i.push({x:h,y:a}))}}}return!1}createMinimalPath(){let t=0,i=0;const s=this.gameConfig.GRID_SIZE-1,h=this.gameConfig.GRID_SIZE-1,e=new Set;for(;t!==s||i!==h;){const a=`${t},${i}`;if(e.has(a))break;e.add(a);const n=[];if(s>t&&n.push("right"),h>i&&n.push("down"),t>0&&n.push("left"),i>0&&n.push("up"),0===n.length)break;let o;o=Math.random()>=.6||t===s&&i===h?n[Math.floor(Math.random()*n.length)]:s>t&&.5>Math.random()?"right":h>i?"down":s>t?"right":n[Math.floor(Math.random()*n.length)];const r=this.maze[i]?.[t];if("right"===o&&t<this.gameConfig.GRID_SIZE-1&&r){r.walls.right=!1;const s=this.maze[i]?.[t+1];s&&(s.walls.left=!1),t++}else if("down"===o&&i<this.gameConfig.GRID_SIZE-1&&r){r.walls.bottom=!1;const s=this.maze[i+1]?.[t];s&&(s.walls.top=!1),i++}else if("left"===o&&t>0&&r){r.walls.left=!1;const s=this.maze[i]?.[t-1];s&&(s.walls.right=!1),t--}else if("up"===o&&i>0&&r){r.walls.top=!1;const s=this.maze[i-1]?.[t];s&&(s.walls.bottom=!1),i--}}}getUnvisitedNeighbors(t){const i=[],{x:s,y:h}=t;if(h>0&&this.maze[h-1]?.[s]&&!this.maze[h-1]?.[s]?.visited){const t=this.maze[h-1]?.[s];t&&i.push(t)}if(s<this.gameConfig.GRID_SIZE-1&&this.maze[h]?.[s+1]&&!this.maze[h]?.[s+1]?.visited){const t=this.maze[h]?.[s+1];t&&i.push(t)}if(h<this.gameConfig.GRID_SIZE-1&&this.maze[h+1]?.[s]&&!this.maze[h+1]?.[s]?.visited){const t=this.maze[h+1]?.[s];t&&i.push(t)}if(s>0&&this.maze[h]?.[s-1]&&!this.maze[h]?.[s-1]?.visited){const t=this.maze[h]?.[s-1];t&&i.push(t)}return i}removeWallBetween(t,i){const s=t.x-i.x,h=t.y-i.y;1===s?(t.walls.left=!1,i.walls.right=!1):-1===s?(t.walls.right=!1,i.walls.left=!1):1===h?(t.walls.top=!1,i.walls.bottom=!1):-1===h&&(t.walls.bottom=!1,i.walls.top=!1)}generateWalls(){this.walls=[];const t=this.gameConfig.CELL_SIZE,i=this.gameConfig.GRID_SIZE*t,s=this.gameConfig.GRID_SIZE*t;this.walls.push({x:0,y:0,width:i,height:4,type:"horizontal"}),this.walls.push({x:0,y:s-4,width:i,height:4,type:"horizontal"}),this.walls.push({x:0,y:0,width:4,height:s,type:"vertical"}),this.walls.push({x:i-4,y:0,width:4,height:s,type:"vertical"});for(let i=0;i<this.gameConfig.GRID_SIZE;i++)for(let s=0;s<this.gameConfig.GRID_SIZE;s++){const h=this.maze[i]?.[s];if(!h)continue;const e=s*t,a=i*t;h.walls.top&&i>0&&this.walls.push({x:e,y:a,width:t,height:4,type:"horizontal"}),h.walls.left&&s>0&&this.walls.push({x:e,y:a,width:4,height:t,type:"vertical"})}}setStartAndEndPositions(){const t=this.gameConfig.CELL_SIZE;this.gameState.ballPosition={x:t/2,y:t/2},this.gameState.targetPosition={x:(this.gameConfig.GRID_SIZE-1)*t+t/2,y:(this.gameConfig.GRID_SIZE-1)*t+t/2}}updateSettings(t,i,s,h){const e=s||this.gameConfig.GAME_AREA_WIDTH,a=h||this.gameConfig.GAME_AREA_HEIGHT;this.gameConfig.GRID_SIZE=t,this.gameConfig.GAME_AREA_WIDTH=e,this.gameConfig.GAME_AREA_HEIGHT=a,this.gameConfig.CELL_SIZE=Math.min(e,a)/t,this.gameConfig.GAME_DURATION=i,this.generateNewMaze(),this.gameState.isPlaying=!1,this.gameState.isPaused=!1,this.gameState.timeElapsed=0,this.gameState.isCompleted=!1,this.gameState.gameOver=!1,this.stopTimer(),this.notifyGameStateChange()}resetGame(){this.generateNewMaze(),this.gameState.isPlaying=!1,this.gameState.isPaused=!1,this.gameState.score=0,this.gameState.timeElapsed=0,this.gameState.isCompleted=!1,this.gameState.gameOver=!1,this.stopTimer(),this.notifyGameStateChange()}startGame(){this.gameState.ballPosition={x:this.gameConfig.CELL_SIZE/2,y:this.gameConfig.CELL_SIZE/2},this.gameState.targetPosition={x:(this.gameConfig.GRID_SIZE-1)*this.gameConfig.CELL_SIZE+this.gameConfig.CELL_SIZE/2,y:(this.gameConfig.GRID_SIZE-1)*this.gameConfig.CELL_SIZE+this.gameConfig.CELL_SIZE/2},this.gameState.isPlaying=!0,this.gameState.isPaused=!1,this.gameState.score=0,this.gameState.timeElapsed=0,this.gameState.isCompleted=!1,this.gameState.gameOver=!1,this.startTimer(),this.notifyGameStateChange()}pauseGame(){this.gameState.isPaused=!0,this.stopTimer(),this.notifyGameStateChange()}resumeGame(){this.gameState.isPaused=!1,this.startTimer(),this.notifyGameStateChange()}stopGame(){this.gameState.isPlaying=!1,this.gameState.isPaused=!1,this.stopTimer(),this.notifyGameStateChange()}startTimer(){this.stopTimer(),this.gameTimer=setInterval(()=>{!this.gameState.isPaused&&this.gameState.isPlaying&&(this.gameState.timeElapsed+=1,this.notifyGameStateChange())},1e3)}stopTimer(){this.gameTimer&&(clearInterval(this.gameTimer),this.gameTimer=null)}updateBallPosition(t){return!(!this.gameState.isPlaying||this.gameState.isPaused||!this.isValidPosition(t)||(this.gameState.ballPosition=t,!this.gameState.isCompleted&&this.isNearTarget(t)&&this.completeLevel(),this.notifyGameStateChange(),0))}isValidPosition(t){const{x:i,y:s}=t,h=this.gameConfig.BALL_SIZE/2;for(const t of this.walls)if(this.ballCollidesWithWall(i,s,h,t))return!1;const e=h+2;return!(e>i-h||i+h>this.gameConfig.GAME_AREA_WIDTH-e||e>s-h||s+h>this.gameConfig.GAME_AREA_HEIGHT-e)}ballCollidesWithWall(t,i,s,h){const e=t-Math.max(h.x,Math.min(t,h.x+h.width)),a=i-Math.max(h.y,Math.min(i,h.y+h.height));return s*s>e*e+a*a}isNearTarget(t){return Math.sqrt(Math.pow(t.x-this.gameState.targetPosition.x,2)+Math.pow(t.y-this.gameState.targetPosition.y,2))<1.5*this.gameConfig.BALL_SIZE}completeLevel(){this.gameState.score+=this.gameConfig.SCORE_PER_COMPLETION,this.gameState.isCompleted=!0,this.gameState.isPlaying=!1,this.stopTimer(),this.notifyGameStateChange()}getGameState(){return{...this.gameState}}getGameConfig(){return{...this.gameConfig}}getWalls(){return[...this.walls]}getMaze(){return this.maze.map(t=>t.map(t=>({...t})))}formatTime(t){return`${Math.floor(t/60)}:${(""+t%60).padStart(2,"0")}`}cleanup(){this.stopTimer()}}
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{Canvas,Circle,RadialGradient,vec,Shadow}from '@shopify/react-native-skia';import{useSharedValue,useAnimatedStyle,withRepeat,withTiming,withSequence}from 'react-native-reanimated';import Animated from 'react-native-reanimated';import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const EnhancedBallComponent = React.memo(({position,size,isDragging,isCompleted})=>{const rotation = useSharedValue(0);const glowIntensity = useSharedValue(0.6);const pulseScale = useSharedValue(1);const completionGlow = useSharedValue(0);React.useEffect(()=>{rotation.value = withRepeat(withTiming(360,{duration:4000}),-1,false);glowIntensity.value = withRepeat(withSequence(withTiming(0.3,{duration:1500}),withTiming(0.8,{duration:1500})),-1,true);},[]);React.useEffect(()=>{if(isDragging){pulseScale.value = withTiming(1.05,{duration:200});}else{pulseScale.value = withTiming(1,{duration:200});}},[isDragging]);React.useEffect(()=>{if(isCompleted){completionGlow.value = withRepeat(withSequence(withTiming(1,{duration:300}),withTiming(0.3,{duration:300})),5,true);}else{completionGlow.value = withTiming(0,{duration:200});}},[isCompleted]);const animatedStyle = useAnimatedStyle(()=>{const scale = pulseScale.value;const rotationDegrees = rotation.value;return{position:'absolute',left:position.x - size / 2,top:position.y - size / 2,width:size * 1.5,height:size * 1.5,transform:[{scale},{rotate:`${rotationDegrees}deg`}]};});const canvasSize = size * 1.5;const ballRadius = size / 2;const centerX = canvasSize / 2;const centerY = canvasSize / 2;return _jsx(Animated.View,{style:animatedStyle,children:_jsxs(Canvas,{style:{width:canvasSize,height:canvasSize},children:[_jsx(Circle,{cx:centerX,cy:centerY,r:ballRadius * 1.3,opacity:glowIntensity,children:_jsx(RadialGradient,{c:vec(centerX,centerY),r:ballRadius * 1.3,colors:isDragging ? ['#ff6b6b','#ff8e8e','transparent']:['#4ecdc4','#45b7b8','transparent']})}),isCompleted && _jsx(Circle,{cx:centerX,cy:centerY,r:ballRadius * 1.6,opacity:completionGlow,children:_jsx(RadialGradient,{c:vec(centerX,centerY),r:ballRadius * 1.6,colors:['#ffd700','#ffed4e','#fff9c4','transparent']})}),_jsxs(Circle,{cx:centerX,cy:centerY,r:ballRadius,children:[_jsx(RadialGradient,{c:vec(centerX - ballRadius * 0.3,centerY - ballRadius * 0.3),r:ballRadius * 1.2,colors:isDragging ? ['#ff6b6b','#e55656','#cc4545']:['#4ecdc4','#45b7b8','#3ca6a6']}),_jsx(Shadow,{dx:2,dy:2,blur:4,color:"rgba(0,0,0,0.3)"})]}),_jsx(Circle,{cx:centerX - ballRadius * 0.3,cy:centerY - ballRadius * 0.3,r:ballRadius * 0.3,opacity:0.8,children:_jsx(RadialGradient,{c:vec(centerX - ballRadius * 0.3,centerY - ballRadius * 0.3),r:ballRadius * 0.3,colors:['rgba(255,255,255,0.9)','rgba(255,255,255,0.3)','transparent']})}),_jsx(Circle,{cx:centerX,cy:centerY,r:ballRadius * 0.4,opacity:0.7,children:_jsx(RadialGradient,{c:vec(centerX,centerY),r:ballRadius * 0.4,colors:['rgba(255,255,255,0.8)','rgba(255,255,255,0.2)','transparent']})}),_jsx(Circle,{cx:centerX,cy:centerY,r:ballRadius * 0.8,opacity:0.4,style:"stroke",strokeWidth:2,color:isDragging ? '#ff8e8e':'#7dd3d8'})]})});});
1
+ "use strict";import r from"react";import{Canvas as t,Circle as c,RadialGradient as e,vec as o,Shadow as a}from"@shopify/react-native-skia";import{useSharedValue as i,useAnimatedStyle as n,withRepeat as s,withTiming as d,withSequence as l}from"react-native-reanimated";import f from"react-native-reanimated";import{jsx as p,jsxs as h}from"react/jsx-runtime";export const EnhancedBallComponent=r.memo(({position:m,size:y,isDragging:b,isCompleted:u})=>{const g=i(0),x=i(.6),j=i(1),k=i(0);r.useEffect(()=>{g.value=s(d(360,{duration:4e3}),-1,!1),x.value=s(l(d(.3,{duration:1500}),d(.8,{duration:1500})),-1,!0)},[]),r.useEffect(()=>{j.value=d(b?1.05:1,{duration:200})},[b]),r.useEffect(()=>{k.value=u?s(l(d(1,{duration:300}),d(.3,{duration:300})),5,!0):d(0,{duration:200})},[u]);const v=n(()=>{const r=j.value,t=g.value;return{position:"absolute",left:m.x-y/2,top:m.y-y/2,width:1.5*y,height:1.5*y,transform:[{scale:r},{rotate:t+"deg"}]}}),w=1.5*y,C=y/2,z=w/2,B=w/2;return p(f.View,{style:v,children:h(t,{style:{width:w,height:w},children:[p(c,{cx:z,cy:B,r:1.3*C,opacity:x,children:p(e,{c:o(z,B),r:1.3*C,colors:b?["#ff6b6b","#ff8e8e","transparent"]:["#4ecdc4","#45b7b8","transparent"]})}),u&&p(c,{cx:z,cy:B,r:1.6*C,opacity:k,children:p(e,{c:o(z,B),r:1.6*C,colors:["#ffd700","#ffed4e","#fff9c4","transparent"]})}),h(c,{cx:z,cy:B,r:C,children:[p(e,{c:o(z-.3*C,B-.3*C),r:1.2*C,colors:b?["#ff6b6b","#e55656","#cc4545"]:["#4ecdc4","#45b7b8","#3ca6a6"]}),p(a,{dx:2,dy:2,blur:4,color:"rgba(0,0,0,0.3)"})]}),p(c,{cx:z-.3*C,cy:B-.3*C,r:.3*C,opacity:.8,children:p(e,{c:o(z-.3*C,B-.3*C),r:.3*C,colors:["rgba(255,255,255,0.9)","rgba(255,255,255,0.3)","transparent"]})}),p(c,{cx:z,cy:B,r:.4*C,opacity:.7,children:p(e,{c:o(z,B),r:.4*C,colors:["rgba(255,255,255,0.8)","rgba(255,255,255,0.2)","transparent"]})}),p(c,{cx:z,cy:B,r:.8*C,opacity:.4,style:"stroke",strokeWidth:2,color:b?"#ff8e8e":"#7dd3d8"})]})})});
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,StyleSheet}from 'react-native';import{Gesture,GestureDetector}from 'react-native-gesture-handler';import Animated,{useSharedValue,useAnimatedStyle,runOnJS,withSpring}from 'react-native-reanimated';import{playHaptic,HapticType}from "../../../services/HapticsService.js";import{EnhancedBallComponent}from "./EnhancedBallComponent.js";import{WallComponent}from "./WallComponent.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const EnhancedGameArea = React.memo(({gameState,gameConfig,walls,onBallPositionChange,hapticEnabled})=>{const translateX = useSharedValue(gameState.ballPosition.x);const translateY = useSharedValue(gameState.ballPosition.y);const isDragging = useSharedValue(false);const wallsSharedValue = useSharedValue(walls);React.useEffect(()=>{translateX.value = withSpring(gameState.ballPosition.x,{damping:15,stiffness:150,mass:1});translateY.value = withSpring(gameState.ballPosition.y,{damping:15,stiffness:150,mass:1});},[gameState.ballPosition]);React.useEffect(()=>{wallsSharedValue.value = walls;},[walls]);const triggerMoveHaptic = React.useCallback(()=>{playHaptic(HapticType.LIGHT,hapticEnabled);},[hapticEnabled]);const triggerCollisionHaptic = React.useCallback(()=>{playHaptic(HapticType.MEDIUM,hapticEnabled);},[hapticEnabled]);const startPosition = useSharedValue({x:0,y:0});const checkWallCollision =(ballX,ballY,ballRadius)=>{'worklet';const currentWalls = wallsSharedValue.value;const collisionMargin = 0.1;const effectiveRadius = ballRadius + collisionMargin;for(let i = 0;i < currentWalls.length;i++){const wall = currentWalls[i];const closestX = Math.max(wall.x,Math.min(ballX,wall.x + wall.width));const closestY = Math.max(wall.y,Math.min(ballY,wall.y + wall.height));const distanceX = ballX - closestX;const distanceY = ballY - closestY;const distanceSquared = distanceX * distanceX + distanceY * distanceY;if(distanceSquared < effectiveRadius * effectiveRadius){return true;}}return false;};const checkPathCollision =(fromX,fromY,toX,toY,ballRadius)=>{'worklet';const deltaX = toX - fromX;const deltaY = toY - fromY;const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);if(distance < 3){return checkWallCollision(toX,toY,ballRadius);}if(distance > 10){const steps = Math.ceil(distance / 4);for(let i = 1;i < steps;i++){const t = i / steps;const checkX = fromX + deltaX * t;const checkY = fromY + deltaY * t;if(checkWallCollision(checkX,checkY,ballRadius)){return true;}}}return checkWallCollision(toX,toY,ballRadius);};const panGesture = Gesture.Pan().onStart(()=>{if(!gameState.isPlaying || gameState.isPaused)return;startPosition.value ={x:gameState.ballPosition.x,y:gameState.ballPosition.y};isDragging.value = true;runOnJS(triggerMoveHaptic)();}).onUpdate(event =>{if(!gameState.isPlaying || gameState.isPaused)return;const newX = startPosition.value.x + event.translationX;const newY = startPosition.value.y + event.translationY;const ballRadius = gameConfig.BALL_SIZE / 2;const clampedX = Math.max(ballRadius,Math.min(gameConfig.GAME_AREA_WIDTH - ballRadius,newX));const clampedY = Math.max(ballRadius,Math.min(gameConfig.GAME_AREA_HEIGHT - ballRadius,newY));const currentX = translateX.value;const currentY = translateY.value;const deltaX = clampedX - currentX;const deltaY = clampedY - currentY;const movementDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);let finalX = clampedX;let finalY = clampedY;let hasCollision = false;if(movementDistance < 8){hasCollision = checkWallCollision(clampedX,clampedY,ballRadius);}else{hasCollision = checkPathCollision(currentX,currentY,clampedX,clampedY,ballRadius);}if(hasCollision){let foundValidPosition = false;const horizontalOnlyX = clampedX;const horizontalOnlyY = currentY;const horizontalDistance = Math.abs(horizontalOnlyX - currentX);if(horizontalDistance < ballRadius * 3 && !checkWallCollision(horizontalOnlyX,horizontalOnlyY,ballRadius)){const steps = Math.max(2,Math.ceil(horizontalDistance / 2));let canSlideHorizontally = true;for(let i = 1;i <= steps;i++){const t = i / steps;const testX = currentX +(horizontalOnlyX - currentX)* t;if(checkWallCollision(testX,horizontalOnlyY,ballRadius)){canSlideHorizontally = false;break;}}if(canSlideHorizontally){finalX = horizontalOnlyX;finalY = horizontalOnlyY;foundValidPosition = true;}}if(!foundValidPosition){const verticalOnlyX = currentX;const verticalOnlyY = clampedY;const verticalDistance = Math.abs(verticalOnlyY - currentY);if(verticalDistance < ballRadius * 3 && !checkWallCollision(verticalOnlyX,verticalOnlyY,ballRadius)){const steps = Math.max(2,Math.ceil(verticalDistance / 2));let canSlideVertically = true;for(let i = 1;i <= steps;i++){const t = i / steps;const testY = currentY +(verticalOnlyY - currentY)* t;if(checkWallCollision(verticalOnlyX,testY,ballRadius)){canSlideVertically = false;break;}}if(canSlideVertically){finalX = verticalOnlyX;finalY = verticalOnlyY;foundValidPosition = true;}}}hasCollision = !foundValidPosition;}if(!hasCollision){translateX.value = finalX;translateY.value = finalY;runOnJS(onBallPositionChange)({x:finalX,y:finalY});}else{runOnJS(triggerCollisionHaptic)();}}).onEnd(()=>{isDragging.value = false;});const animatedBallStyle = useAnimatedStyle(()=>({transform:[{translateX:translateX.value - gameConfig.BALL_SIZE / 2},{translateY:translateY.value - gameConfig.BALL_SIZE / 2}]}));const renderStartMarker =()=>{const startPos ={x:gameConfig.CELL_SIZE / 2,y:gameConfig.CELL_SIZE / 2};return _jsx(View,{style:[styles.marker,styles.startMarker,{left:startPos.x - 15,top:startPos.y - 15}],children:_jsx(View,{style:styles.startMarkerInner})});};const renderEndMarker =()=>{const endPos ={x:(gameConfig.GRID_SIZE - 1)* gameConfig.CELL_SIZE + gameConfig.CELL_SIZE / 2,y:(gameConfig.GRID_SIZE - 1)* gameConfig.CELL_SIZE + gameConfig.CELL_SIZE / 2};return _jsx(View,{style:[styles.marker,styles.endMarker,{left:endPos.x - 15,top:endPos.y - 15}],children:_jsx(View,{style:styles.endMarkerInner})});};return _jsx(View,{style:[styles.container,{width:gameConfig.GAME_AREA_WIDTH,height:gameConfig.GAME_AREA_HEIGHT}],children:_jsxs(View,{style:[styles.gameArea,{width:gameConfig.GRID_SIZE * gameConfig.CELL_SIZE,height:gameConfig.GRID_SIZE * gameConfig.CELL_SIZE}],children:[_jsx(WallComponent,{walls:walls,width:gameConfig.GRID_SIZE * gameConfig.CELL_SIZE,height:gameConfig.GRID_SIZE * gameConfig.CELL_SIZE}),renderStartMarker(),renderEndMarker(),_jsx(GestureDetector,{gesture:panGesture,children:_jsx(Animated.View,{style:[styles.ballContainer,animatedBallStyle],children:_jsx(EnhancedBallComponent,{position:{x:gameConfig.BALL_SIZE / 2,y:gameConfig.BALL_SIZE / 2},size:gameConfig.BALL_SIZE,isDragging:isDragging.value,isCompleted:gameState.isCompleted})})})]})});});const styles = StyleSheet.create({container:{backgroundColor:'transparent',overflow:'hidden',justifyContent:'center',alignItems:'center'},gameArea:{position:'relative',backgroundColor:'transparent'},ballContainer:{position:'absolute',width:40,height:40,top:0,left:0},marker:{position:'absolute',width:30,height:30,borderRadius:15,justifyContent:'center',alignItems:'center',elevation:5,shadowColor:'#000',shadowOffset:{width:0,height:2},shadowOpacity:0.3,shadowRadius:4},startMarker:{backgroundColor:'#4CAF50',borderWidth:3,borderColor:'#2E7D32'},startMarkerInner:{width:12,height:12,borderRadius:6,backgroundColor:'#81C784'},endMarker:{backgroundColor:'#FF5722',borderWidth:3,borderColor:'#D84315'},endMarkerInner:{width:12,height:12,borderRadius:6,backgroundColor:'#FF8A65'}});
1
+ "use strict";import t from"react";import{View as e,StyleSheet as r}from"react-native";import{Gesture as o,GestureDetector as a}from"react-native-gesture-handler";import n,{useSharedValue as i,useAnimatedStyle as s,runOnJS as h,withSpring as l}from"react-native-reanimated";import{playHaptic as d,HapticType as c}from"../../../services/HapticsService.js";import{EnhancedBallComponent as f}from"./EnhancedBallComponent.js";import{WallComponent as m}from"./WallComponent.js";import{jsx as g,jsxs as u}from"react/jsx-runtime";export const EnhancedGameArea=t.memo(({gameState:r,gameConfig:M,walls:b,onBallPositionChange:C,hapticEnabled:w})=>{const y=i(r.ballPosition.x),k=i(r.ballPosition.y),j=i(!1),v=i(b);t.useEffect(()=>{y.value=l(r.ballPosition.x,{damping:15,stiffness:150,mass:1}),k.value=l(r.ballPosition.y,{damping:15,stiffness:150,mass:1})},[r.ballPosition]),t.useEffect(()=>{v.value=b},[b]);const x=t.useCallback(()=>{d(c.LIGHT,w)},[w]),F=t.useCallback(()=>{d(c.MEDIUM,w)},[w]),A=i({x:0,y:0}),E=(t,e,r)=>{const o=v.value,a=r+.1;for(let r=0;r<o.length;r++){const n=o[r],i=t-Math.max(n.x,Math.min(t,n.x+n.width)),s=e-Math.max(n.y,Math.min(e,n.y+n.height));if(a*a>i*i+s*s)return!0}return!1},I=o.Pan().onStart(()=>{r.isPlaying&&!r.isPaused&&(A.value={x:r.ballPosition.x,y:r.ballPosition.y},j.value=!0,h(x)())}).onUpdate(t=>{if(!r.isPlaying||r.isPaused)return;const e=A.value.x+t.translationX,o=A.value.y+t.translationY,a=M.BALL_SIZE/2,n=Math.max(a,Math.min(M.GAME_AREA_WIDTH-a,e)),i=Math.max(a,Math.min(M.GAME_AREA_HEIGHT-a,o)),s=y.value,l=k.value,d=n-s,c=i-l;let f=n,m=i,g=!1;if(g=8>Math.sqrt(d*d+c*c)?E(n,i,a):((t,e,r,o,a)=>{const n=r-t,i=o-e,s=Math.sqrt(n*n+i*i);if(3>s)return E(r,o,a);if(s>10){const r=Math.ceil(s/4);for(let o=1;r>o;o++){const s=o/r;if(E(t+n*s,e+i*s,a))return!0}}return E(r,o,a)})(s,l,n,i,a),g){let t=!1;const e=n,r=l,o=Math.abs(e-s);if(3*a>o&&!E(e,r,a)){const n=Math.max(2,Math.ceil(o/2));let i=!0;for(let t=1;n>=t;t++)if(E(s+t/n*(e-s),r,a)){i=!1;break}i&&(f=e,m=r,t=!0)}if(!t){const e=s,r=i,o=Math.abs(r-l);if(3*a>o&&!E(e,r,a)){const n=Math.max(2,Math.ceil(o/2));let i=!0;for(let t=1;n>=t;t++)if(E(e,l+t/n*(r-l),a)){i=!1;break}i&&(f=e,m=r,t=!0)}}g=!t}g?h(F)():(y.value=f,k.value=m,h(C)({x:f,y:m}))}).onEnd(()=>{j.value=!1}),R=s(()=>({transform:[{translateX:y.value-M.BALL_SIZE/2},{translateY:k.value-M.BALL_SIZE/2}]}));return g(e,{style:[p.container,{width:M.GAME_AREA_WIDTH,height:M.GAME_AREA_HEIGHT}],children:u(e,{style:[p.gameArea,{width:M.GRID_SIZE*M.CELL_SIZE,height:M.GRID_SIZE*M.CELL_SIZE}],children:[g(m,{walls:b,width:M.GRID_SIZE*M.CELL_SIZE,height:M.GRID_SIZE*M.CELL_SIZE}),(()=>{const t=M.CELL_SIZE/2,r=M.CELL_SIZE/2;return g(e,{style:[p.marker,p.startMarker,{left:t-15,top:r-15}],children:g(e,{style:p.startMarkerInner})})})(),(()=>{const t=(M.GRID_SIZE-1)*M.CELL_SIZE+M.CELL_SIZE/2,r=(M.GRID_SIZE-1)*M.CELL_SIZE+M.CELL_SIZE/2;return g(e,{style:[p.marker,p.endMarker,{left:t-15,top:r-15}],children:g(e,{style:p.endMarkerInner})})})(),g(a,{gesture:I,children:g(n.View,{style:[p.ballContainer,R],children:g(f,{position:{x:M.BALL_SIZE/2,y:M.BALL_SIZE/2},size:M.BALL_SIZE,isDragging:j.value,isCompleted:r.isCompleted})})})]})})});const p=r.create({container:{backgroundColor:"transparent",overflow:"hidden",justifyContent:"center",alignItems:"center"},gameArea:{position:"relative",backgroundColor:"transparent"},ballContainer:{position:"absolute",width:40,height:40,top:0,left:0},marker:{position:"absolute",width:30,height:30,borderRadius:15,justifyContent:"center",alignItems:"center",elevation:5,shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.3,shadowRadius:4},startMarker:{backgroundColor:"#4CAF50",borderWidth:3,borderColor:"#2E7D32"},startMarkerInner:{width:12,height:12,borderRadius:6,backgroundColor:"#81C784"},endMarker:{backgroundColor:"#FF5722",borderWidth:3,borderColor:"#D84315"},endMarkerInner:{width:12,height:12,borderRadius:6,backgroundColor:"#FF8A65"}});