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{StyleSheet,View}from 'react-native';import{Canvas,LinearGradient,Rect,Circle,vec}from '@shopify/react-native-skia';import{MAZE_ADVENTURE_COLORS}from "../MazeRunnerConstants.js";import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from "react/jsx-runtime";export const GameBackground =({width,height})=>{const generateFloatingElements = React.useMemo(()=>{const elements = [];const elementCount = 12;for(let i = 0;i < elementCount;i++){const baseX = width / elementCount * i;const baseY = height / elementCount * i;const x = baseX + Math.sin(i * 0.5)* 40 + i % 3 * 20;const y = baseY + Math.cos(i * 0.7)* 50 + i % 4 * 25;const radius = 10 + i % 8 + Math.sin(i)* 5;const colorIndex = i % MAZE_ADVENTURE_COLORS.length;const opacity = 0.25 + Math.sin(i * 0.3)* 0.1;elements.push(_jsx(Circle,{cx:Math.max(radius,Math.min(width - radius,x)),cy:Math.max(radius,Math.min(height - radius,y)),r:radius,color:`${MAZE_ADVENTURE_COLORS[colorIndex]}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`floating-element-${i}`));}return elements;},[width,height]);return _jsx(_Fragment,{children:_jsx(View,{style:StyleSheet.absoluteFillObject,children:_jsxs(Canvas,{style:{width,height},children:[_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(width,height),colors:[`${MAZE_ADVENTURE_COLORS[0]}40`,`${MAZE_ADVENTURE_COLORS[2]}35`,`${MAZE_ADVENTURE_COLORS[4]}40`,`${MAZE_ADVENTURE_COLORS[6]}35`,`${MAZE_ADVENTURE_COLORS[8]}40`,`${MAZE_ADVENTURE_COLORS[10]}35`,`${MAZE_ADVENTURE_COLORS[12]}40`,`${MAZE_ADVENTURE_COLORS[14]}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:[`${MAZE_ADVENTURE_COLORS[1]}25`,'transparent',`${MAZE_ADVENTURE_COLORS[5]}25`,'transparent',`${MAZE_ADVENTURE_COLORS[9]}25`,'transparent',`${MAZE_ADVENTURE_COLORS[13]}25`,'transparent']})}),_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(width,0),end:vec(0,height),colors:[`${MAZE_ADVENTURE_COLORS[3]}20`,'transparent',`${MAZE_ADVENTURE_COLORS[7]}20`,'transparent',`${MAZE_ADVENTURE_COLORS[11]}20`,'transparent']})}),generateFloatingElements,_jsx(Circle,{cx:width * 0.1,cy:height * 0.15,r:40,color:`${MAZE_ADVENTURE_COLORS[0]}30`}),_jsx(Circle,{cx:width * 0.9,cy:height * 0.85,r:35,color:`${MAZE_ADVENTURE_COLORS[3]}30`}),_jsx(Circle,{cx:width * 0.85,cy:height * 0.2,r:30,color:`${MAZE_ADVENTURE_COLORS[8]}30`}),_jsx(Circle,{cx:width * 0.15,cy:height * 0.8,r:45,color:`${MAZE_ADVENTURE_COLORS[12]}30`}),_jsx(Circle,{cx:width * 0.5,cy:height * 0.1,r:25,color:`${MAZE_ADVENTURE_COLORS[14]}30`}),_jsx(Circle,{cx:width * 0.2,cy:height * 0.5,r:32,color:`${MAZE_ADVENTURE_COLORS[6]}30`}),_jsx(Circle,{cx:width * 0.8,cy:height * 0.6,r:28,color:`${MAZE_ADVENTURE_COLORS[10]}30`}),_jsx(Circle,{cx:width * 0.6,cy:height * 0.9,r:20,color:`${MAZE_ADVENTURE_COLORS[1]}30`}),_jsx(Circle,{cx:width * 0.3,cy:height * 0.25,r:24,color:`${MAZE_ADVENTURE_COLORS[4]}30`}),_jsx(Circle,{cx:width * 0.7,cy:height * 0.35,r:26,color:`${MAZE_ADVENTURE_COLORS[9]}30`}),Array.from({length:Math.floor(width / 40)},(_,i)=> _jsx(Rect,{x:i * 40,y:0,width:1,height:height,color:"rgba(0,0,0,0.02)"},`grid-v-${i}`)),Array.from({length:Math.floor(height / 40)},(_,i)=> _jsx(Rect,{x:0,y:i * 40,width:width,height:1,color:"rgba(0,0,0,0.02)"},`grid-h-${i}`))]})})});};
1
+ "use strict";import r from"react";import{StyleSheet as t,View as c}from"react-native";import{Canvas as o,LinearGradient as a,Rect as e,Circle as h,vec as n}from"@shopify/react-native-skia";import{MAZE_ADVENTURE_COLORS as i}from"../MazeRunnerConstants.js";import{jsx as s,jsxs as l,Fragment as y}from"react/jsx-runtime";export const GameBackground=({width:x,height:d})=>{const g=r.useMemo(()=>{const r=[];for(let t=0;12>t;t++){const c=d/12*t,o=x/12*t+40*Math.sin(.5*t)+t%3*20,a=c+50*Math.cos(.7*t)+t%4*25,e=10+t%8+5*Math.sin(t),n=t%i.length,l=.25+.1*Math.sin(.3*t);r.push(s(h,{cx:Math.max(e,Math.min(x-e,o)),cy:Math.max(e,Math.min(d-e,a)),r:e,color:`${i[n]}${Math.floor(255*l).toString(16).padStart(2,"0")}`},"floating-element-"+t))}return r},[x,d]);return s(y,{children:s(c,{style:t.absoluteFillObject,children:l(o,{style:{width:x,height:d},children:[s(e,{x:0,y:0,width:x,height:d,children:s(a,{start:n(0,0),end:n(x,d),colors:[i[0]+"40",i[2]+"35",i[4]+"40",i[6]+"35",i[8]+"40",i[10]+"35",i[12]+"40",i[14]+"35"]})}),s(e,{x:0,y:0,width:x,height:d,children:s(a,{start:n(0,0),end:n(x/2,d/2),colors:[i[1]+"25","transparent",i[5]+"25","transparent",i[9]+"25","transparent",i[13]+"25","transparent"]})}),s(e,{x:0,y:0,width:x,height:d,children:s(a,{start:n(x,0),end:n(0,d),colors:[i[3]+"20","transparent",i[7]+"20","transparent",i[11]+"20","transparent"]})}),g,s(h,{cx:.1*x,cy:.15*d,r:40,color:i[0]+"30"}),s(h,{cx:.9*x,cy:.85*d,r:35,color:i[3]+"30"}),s(h,{cx:.85*x,cy:.2*d,r:30,color:i[8]+"30"}),s(h,{cx:.15*x,cy:.8*d,r:45,color:i[12]+"30"}),s(h,{cx:.5*x,cy:.1*d,r:25,color:i[14]+"30"}),s(h,{cx:.2*x,cy:.5*d,r:32,color:i[6]+"30"}),s(h,{cx:.8*x,cy:.6*d,r:28,color:i[10]+"30"}),s(h,{cx:.6*x,cy:.9*d,r:20,color:i[1]+"30"}),s(h,{cx:.3*x,cy:.25*d,r:24,color:i[4]+"30"}),s(h,{cx:.7*x,cy:.35*d,r:26,color:i[9]+"30"}),Array.from({length:Math.floor(x/40)},(r,t)=>s(e,{x:40*t,y:0,width:1,height:d,color:"rgba(0, 0, 0, 0.02)"},"grid-v-"+t)),Array.from({length:Math.floor(d/40)},(r,t)=>s(e,{x:0,y:40*t,width:x,height:1,color:"rgba(0, 0, 0, 0.02)"},"grid-h-"+t))]})})})};
@@ -1 +1 @@
1
- "use strict";import React,{useMemo}from 'react';import{View,Text,StyleSheet}from 'react-native';import{MazeRunnerService}from "../MazeRunnerService.js";import{ScoreBoardContainer}from "../../../helpers/index.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const ScoreBoard = React.memo(({gameState,offset = 0})=>{const gameService = useMemo(()=> new MazeRunnerService(10,400,400,120),[]);const formattedTime = useMemo(()=> gameService.formatTime(gameState.timeElapsed),[gameService,gameState.timeElapsed]);return _jsx(ScoreBoardContainer,{offset:offset,backgroundColor:"rgba(139,69,19,0.4)",borderColor:"rgba(255,255,255,0.3)",children:_jsx(View,{style:styles.scoreBoard,children:_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Time Elapsed"}),_jsx(Text,{style:styles.timeValue,children:formattedTime})]})})});});const styles = StyleSheet.create({scoreBoard:{flexDirection:'row',justifyContent:'center',alignItems:'center'},scoreSection:{alignItems:'center'},scoreLabel:{fontSize:16,fontWeight:'bold',color:'#ffffff',marginBottom:4},scoreValue:{fontSize:25,fontWeight:'bold',color:'#92400e'},timeValue:{fontSize:25,fontWeight:'bold',color:'#ffffff'}});
1
+ "use strict";import e,{useMemo as o}from"react";import{View as r,Text as t,StyleSheet as n}from"react-native";import{MazeRunnerService as i}from"../MazeRunnerService.js";import{ScoreBoardContainer as f}from"../../../helpers/index.js";import{jsx as s,jsxs as c}from"react/jsx-runtime";export const ScoreBoard=e.memo(({gameState:e,offset:n=0})=>{const a=o(()=>new i(10,400,400,120),[]),m=o(()=>a.formatTime(e.timeElapsed),[a,e.timeElapsed]);return s(f,{offset:n,backgroundColor:"rgba(139, 69, 19, 0.4)",borderColor:"rgba(255, 255, 255, 0.3)",children:s(r,{style:l.scoreBoard,children:c(r,{style:l.scoreSection,children:[s(t,{style:l.scoreLabel,children:"Time Elapsed"}),s(t,{style:l.timeValue,children:m})]})})})});const l=n.create({scoreBoard:{flexDirection:"row",justifyContent:"center",alignItems:"center"},scoreSection:{alignItems:"center"},scoreLabel:{fontSize:16,fontWeight:"bold",color:"#ffffff",marginBottom:4},scoreValue:{fontSize:25,fontWeight:"bold",color:"#92400e"},timeValue:{fontSize:25,fontWeight:"bold",color:"#ffffff"}});
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{Canvas,Path,Circle,LinearGradient,vec,Shadow}from '@shopify/react-native-skia';import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from "react/jsx-runtime";export const SkiaPipeComponent =({segment,pipeWidth})=>{const canvasWidth = Math.abs(segment.end.x - segment.start.x)+ pipeWidth * 2;const canvasHeight = Math.abs(segment.end.y - segment.start.y)+ pipeWidth * 2;const canvasSize = Math.max(canvasWidth,canvasHeight,pipeWidth * 3);const renderStraightPipe =()=>{const{start,end}= segment;const centerX = canvasSize / 2;const centerY = canvasSize / 2;if(segment.direction === 'horizontal'){const length = Math.abs(end.x - start.x);const pipeLeft = centerX - length / 2;const pipeRight = centerX + length / 2;const pipeTop = centerY - pipeWidth / 2;const pipeBottom = centerY + pipeWidth / 2;return _jsxs(_Fragment,{children:[_jsxs(Path,{path:`M ${pipeLeft}${pipeTop}L ${pipeRight}${pipeTop}L ${pipeRight}${pipeBottom}L ${pipeLeft}${pipeBottom}Z`,children:[_jsx(LinearGradient,{start:vec(centerX,pipeTop),end:vec(centerX,pipeBottom),colors:['#8B4513','#A0522D','#654321','#4A4A4A','#2F2F2F']}),_jsx(Shadow,{dx:0,dy:2,blur:4,color:"rgba(0,0,0,0.4)"})]}),_jsx(Path,{path:`M ${pipeLeft}${pipeTop}L ${pipeRight}${pipeTop}L ${pipeRight}${pipeTop + 2}L ${pipeLeft}${pipeTop + 2}Z`,color:"rgba(160,82,45,0.8)"}),_jsx(Path,{path:`M ${pipeLeft}${pipeBottom - 2}L ${pipeRight}${pipeBottom - 2}L ${pipeRight}${pipeBottom}L ${pipeLeft}${pipeBottom}Z`,color:"rgba(47,47,47,0.8)"}),_jsx(Circle,{cx:pipeLeft,cy:centerY,r:pipeWidth / 2,children:_jsx(LinearGradient,{start:vec(pipeLeft - pipeWidth / 4,centerY - pipeWidth / 4),end:vec(pipeLeft + pipeWidth / 4,centerY + pipeWidth / 4),colors:['#A0522D','#8B4513','#654321']})}),_jsx(Circle,{cx:pipeRight,cy:centerY,r:pipeWidth / 2,children:_jsx(LinearGradient,{start:vec(pipeRight - pipeWidth / 4,centerY - pipeWidth / 4),end:vec(pipeRight + pipeWidth / 4,centerY + pipeWidth / 4),colors:['#A0522D','#8B4513','#654321']})})]});}else{const length = Math.abs(end.y - start.y);const pipeTop = centerY - length / 2;const pipeBottom = centerY + length / 2;const pipeLeft = centerX - pipeWidth / 2;const pipeRight = centerX + pipeWidth / 2;return _jsxs(_Fragment,{children:[_jsxs(Path,{path:`M ${pipeLeft}${pipeTop}L ${pipeRight}${pipeTop}L ${pipeRight}${pipeBottom}L ${pipeLeft}${pipeBottom}Z`,children:[_jsx(LinearGradient,{start:vec(pipeLeft,centerY),end:vec(pipeRight,centerY),colors:['#8B4513','#A0522D','#654321','#4A4A4A','#2F2F2F']}),_jsx(Shadow,{dx:2,dy:0,blur:4,color:"rgba(0,0,0,0.4)"})]}),_jsx(Path,{path:`M ${pipeLeft}${pipeTop}L ${pipeLeft + 2}${pipeTop}L ${pipeLeft + 2}${pipeBottom}L ${pipeLeft}${pipeBottom}Z`,color:"rgba(160,82,45,0.8)"}),_jsx(Path,{path:`M ${pipeRight - 2}${pipeTop}L ${pipeRight}${pipeTop}L ${pipeRight}${pipeBottom}L ${pipeRight - 2}${pipeBottom}Z`,color:"rgba(47,47,47,0.8)"}),_jsx(Circle,{cx:centerX,cy:pipeTop,r:pipeWidth / 2,children:_jsx(LinearGradient,{start:vec(centerX - pipeWidth / 4,pipeTop - pipeWidth / 4),end:vec(centerX + pipeWidth / 4,pipeTop + pipeWidth / 4),colors:['#A0522D','#8B4513','#654321']})}),_jsx(Circle,{cx:centerX,cy:pipeBottom,r:pipeWidth / 2,children:_jsx(LinearGradient,{start:vec(centerX - pipeWidth / 4,pipeBottom - pipeWidth / 4),end:vec(centerX + pipeWidth / 4,pipeBottom + pipeWidth / 4),colors:['#A0522D','#8B4513','#654321']})})]});}};const renderCornerPipe =()=>{const centerX = canvasSize / 2;const centerY = canvasSize / 2;const radius = pipeWidth * 1.5;const{cornerType}= segment;let startAngle = 0;let endAngle = 90;let sweepAngle = 90;switch(cornerType){case 'top-right':startAngle = 0;endAngle = 90;break;case 'bottom-right':startAngle = 270;endAngle = 360;break;case 'bottom-left':startAngle = 180;endAngle = 270;break;case 'top-left':startAngle = 90;endAngle = 180;break;}const startAngleRad = startAngle * Math.PI / 180;const endAngleRad = endAngle * Math.PI / 180;const innerRadius = radius - pipeWidth / 2;const outerRadius = radius + pipeWidth / 2;const innerStartX = centerX + innerRadius * Math.cos(startAngleRad);const innerStartY = centerY + innerRadius * Math.sin(startAngleRad);const innerEndX = centerX + innerRadius * Math.cos(endAngleRad);const innerEndY = centerY + innerRadius * Math.sin(endAngleRad);const outerStartX = centerX + outerRadius * Math.cos(startAngleRad);const outerStartY = centerY + outerRadius * Math.sin(startAngleRad);const outerEndX = centerX + outerRadius * Math.cos(endAngleRad);const outerEndY = centerY + outerRadius * Math.sin(endAngleRad);const largeArcFlag = sweepAngle > 180 ? 1:0;return _jsxs(_Fragment,{children:[_jsxs(Path,{path:` M ${innerStartX}${innerStartY}A ${innerRadius}${innerRadius}0 ${largeArcFlag}1 ${innerEndX}${innerEndY}L ${outerEndX}${outerEndY}A ${outerRadius}${outerRadius}0 ${largeArcFlag}0 ${outerStartX}${outerStartY}Z `,children:[_jsx(LinearGradient,{start:vec(centerX - radius,centerY - radius),end:vec(centerX + radius,centerY + radius),colors:['#8B4513','#A0522D','#654321','#4A4A4A','#2F2F2F']}),_jsx(Shadow,{dx:2,dy:2,blur:4,color:"rgba(0,0,0,0.4)"})]}),_jsx(Path,{path:` M ${innerStartX}${innerStartY}A ${innerRadius}${innerRadius}0 ${largeArcFlag}1 ${innerEndX}${innerEndY}L ${centerX +(innerRadius + 2)* Math.cos(endAngleRad)}${centerY +(innerRadius + 2)* Math.sin(endAngleRad)}A ${innerRadius + 2}${innerRadius + 2}0 ${largeArcFlag}0 ${centerX +(innerRadius + 2)* Math.cos(startAngleRad)}${centerY +(innerRadius + 2)* Math.sin(startAngleRad)}Z `,color:"rgba(160,82,45,0.6)"}),_jsx(Circle,{cx:centerX,cy:centerY,r:pipeWidth / 3,children:_jsx(LinearGradient,{start:vec(centerX - pipeWidth / 6,centerY - pipeWidth / 6),end:vec(centerX + pipeWidth / 6,centerY + pipeWidth / 6),colors:['#A0522D','#8B4513','#654321']})})]});};return _jsx(Canvas,{style:{position:'absolute',left:segment.start.x - canvasSize / 2,top:segment.start.y - canvasSize / 2,width:canvasSize,height:canvasSize},children:segment.type === 'straight' ? renderStraightPipe():renderCornerPipe()});};
1
+ "use strict";import t from"react";import{Canvas as r,Path as $,Circle as a,LinearGradient as o,vec as c,Shadow as e}from"@shopify/react-native-skia";import{jsx as n,jsxs as h,Fragment as s}from"react/jsx-runtime";export const SkiaPipeComponent=({segment:t,pipeWidth:l})=>{const i=Math.abs(t.end.x-t.start.x)+2*l,d=Math.abs(t.end.y-t.start.y)+2*l,M=Math.max(i,d,3*l);return n(r,{style:{position:"absolute",left:t.start.x-M/2,top:t.start.y-M/2,width:M,height:M},children:"straight"===t.type?(()=>{const{start:r,end:i}=t,d=M/2,p=M/2;if("horizontal"===t.direction){const t=Math.abs(i.x-r.x),M=d-t/2,A=d+t/2,L=p-l/2,b=p+l/2;return h(s,{children:[h($,{path:`M ${M} ${L} L ${A} ${L} L ${A} ${b} L ${M} ${b} Z`,children:[n(o,{start:c(d,L),end:c(d,b),colors:["#8B4513","#A0522D","#654321","#4A4A4A","#2F2F2F"]}),n(e,{dx:0,dy:2,blur:4,color:"rgba(0,0,0,0.4)"})]}),n($,{path:`M ${M} ${L} L ${A} ${L} L ${A} ${L+2} L ${M} ${L+2} Z`,color:"rgba(160, 82, 45, 0.8)"}),n($,{path:`M ${M} ${b-2} L ${A} ${b-2} L ${A} ${b} L ${M} ${b} Z`,color:"rgba(47, 47, 47, 0.8)"}),n(a,{cx:M,cy:p,r:l/2,children:n(o,{start:c(M-l/4,p-l/4),end:c(M+l/4,p+l/4),colors:["#A0522D","#8B4513","#654321"]})}),n(a,{cx:A,cy:p,r:l/2,children:n(o,{start:c(A-l/4,p-l/4),end:c(A+l/4,p+l/4),colors:["#A0522D","#8B4513","#654321"]})})]})}{const t=Math.abs(i.y-r.y),M=p-t/2,A=p+t/2,L=d-l/2,b=d+l/2;return h(s,{children:[h($,{path:`M ${L} ${M} L ${b} ${M} L ${b} ${A} L ${L} ${A} Z`,children:[n(o,{start:c(L,p),end:c(b,p),colors:["#8B4513","#A0522D","#654321","#4A4A4A","#2F2F2F"]}),n(e,{dx:2,dy:0,blur:4,color:"rgba(0,0,0,0.4)"})]}),n($,{path:`M ${L} ${M} L ${L+2} ${M} L ${L+2} ${A} L ${L} ${A} Z`,color:"rgba(160, 82, 45, 0.8)"}),n($,{path:`M ${b-2} ${M} L ${b} ${M} L ${b} ${A} L ${b-2} ${A} Z`,color:"rgba(47, 47, 47, 0.8)"}),n(a,{cx:d,cy:M,r:l/2,children:n(o,{start:c(d-l/4,M-l/4),end:c(d+l/4,M+l/4),colors:["#A0522D","#8B4513","#654321"]})}),n(a,{cx:d,cy:A,r:l/2,children:n(o,{start:c(d-l/4,A-l/4),end:c(d+l/4,A+l/4),colors:["#A0522D","#8B4513","#654321"]})})]})}})():(()=>{const r=M/2,i=M/2,d=1.5*l,{cornerType:p}=t;let A=0,L=90;switch(p){case"top-right":A=0,L=90;break;case"bottom-right":A=270,L=360;break;case"bottom-left":A=180,L=270;break;case"top-left":A=90,L=180}const b=A*Math.PI/180,g=L*Math.PI/180,m=d-l/2,x=d+l/2,y=r+m*Math.cos(b),u=i+m*Math.sin(b),F=r+m*Math.cos(g),f=i+m*Math.sin(g),B=r+x*Math.cos(b),D=i+x*Math.sin(b);return h(s,{children:[h($,{path:`\n M ${y} ${u}\n A ${m} ${m} 0 0 1 ${F} ${f}\n L ${r+x*Math.cos(g)} ${i+x*Math.sin(g)}\n A ${x} ${x} 0 0 0 ${B} ${D}\n Z\n `,children:[n(o,{start:c(r-d,i-d),end:c(r+d,i+d),colors:["#8B4513","#A0522D","#654321","#4A4A4A","#2F2F2F"]}),n(e,{dx:2,dy:2,blur:4,color:"rgba(0,0,0,0.4)"})]}),n($,{path:`\n M ${y} ${u}\n A ${m} ${m} 0 0 1 ${F} ${f}\n L ${r+(m+2)*Math.cos(g)} ${i+(m+2)*Math.sin(g)}\n A ${m+2} ${m+2} 0 0 0 ${r+(m+2)*Math.cos(b)} ${i+(m+2)*Math.sin(b)}\n Z\n `,color:"rgba(160, 82, 45, 0.6)"}),n(a,{cx:r,cy:i,r:l/3,children:n(o,{start:c(r-l/6,i-l/6),end:c(r+l/6,i+l/6),colors:["#A0522D","#8B4513","#654321"]})})]})})()})};
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{Canvas,LinearGradient,vec,Circle,Path,Shadow}from '@shopify/react-native-skia';import Animated from 'react-native-reanimated';import{Dimensions}from 'react-native';import{jsx as _jsx,jsxs as _jsxs,Fragment as _Fragment}from "react/jsx-runtime";const{width:screenWidth,height:screenHeight}= Dimensions.get('window');export const GameBackground =({children})=>{const staticStyle ={position:'absolute',top:0,left:0,right:0,bottom:0,zIndex:-1};const staticMazePattern = React.useMemo(()=>{const gridSize = 20;const cellSize = screenWidth / gridSize;const elements = [];for(let i = 0;i < gridSize;i++){for(let j = 0;j < gridSize;j++){const x = i * cellSize;const y = j * cellSize;const seed =(i * 31 + j * 17)% 100;const opacity = seed > 70 ? 0.08:0.04;if((i + j * 2)% 5 > 2){elements.push(_jsx(Path,{path:`M ${x}${y}L ${x}${y + cellSize}`,style:"stroke",strokeWidth:1,color:`rgba(139,69,19,${opacity})`},`v-${i}-${j}`));}if((i * 2 + j)% 5 > 2){elements.push(_jsx(Path,{path:`M ${x}${y}L ${x + cellSize}${y}`,style:"stroke",strokeWidth:1,color:`rgba(139,69,19,${opacity})`},`h-${i}-${j}`));}}}return elements;},[]);const staticFloatingElements = React.useMemo(()=>{const elements = [];for(let i = 0;i < 6;i++){const seed = i * 37;const x = screenWidth / 6 * i + seed % 40;const y = screenHeight / 3 *(i % 3)+ seed * 2 % 80;const size = 12 + seed * 3 % 8;elements.push(_jsx(Circle,{cx:x,cy:y,r:size,opacity:0.1,color:"rgba(139,69,19,0.2)",children:_jsx(Shadow,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.1)"})},`maze-piece-${i}`));}const cornerSize = 30;elements.push(_jsx(Path,{path:`M 15 15 L ${cornerSize + 15}15 L ${cornerSize + 15}30 L 30 30 L 30 ${cornerSize + 15}L 15 ${cornerSize + 15}Z`,color:"rgba(139,69,19,0.15)",opacity:0.5,children:_jsx(Shadow,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.05)"})},"corner-tl"),_jsx(Path,{path:`M ${screenWidth - cornerSize - 15}15 L ${screenWidth - 15}15 L ${screenWidth - 15}${cornerSize + 15}L ${screenWidth - 30}${cornerSize + 15}L ${screenWidth - 30}30 L ${screenWidth - cornerSize - 15}30 Z`,color:"rgba(139,69,19,0.15)",opacity:0.5,children:_jsx(Shadow,{dx:-1,dy:1,blur:2,color:"rgba(0,0,0,0.05)"})},"corner-tr"));return elements;},[]);const staticParticles = React.useMemo(()=>{const particles = [];for(let i = 0;i < 12;i++){const seed = i * 43;const x = seed % screenWidth;const y = seed * 7 % screenHeight;const size = 1.5 + seed * 3 % 2;const opacity = 0.08 + seed * 5 % 15 / 100;particles.push(_jsx(Circle,{cx:x,cy:y,r:size,color:`rgba(160,82,45,${opacity})`},`particle-${i}`));}return particles;},[]);return _jsxs(_Fragment,{children:[_jsx(Animated.View,{style:staticStyle,children:_jsxs(Canvas,{style:{width:screenWidth,height:screenHeight},children:[_jsx(Path,{path:`M 0 0 L ${screenWidth}0 L ${screenWidth}${screenHeight}L 0 ${screenHeight}Z`,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(0,screenHeight),colors:['#f8f4e6','#f0e6d2','#e8d5b7','#d4c4a8' ]})}),staticMazePattern,staticFloatingElements,staticParticles,_jsx(Path,{path:`M 0 0 L ${screenWidth}0 L ${screenWidth}${screenHeight}L 0 ${screenHeight}Z`,color:"rgba(139,69,19,0.02)"})]})}),children]});};
1
+ "use strict";import r from"react";import{Canvas as t,LinearGradient as o,vec as e,Circle as c,Path as a,Shadow as i}from"@shopify/react-native-skia";import l from"react-native-reanimated";import{Dimensions as n}from"react-native";import{jsx as s,jsxs as $,Fragment as d}from"react/jsx-runtime";const{width:h,height:p}=n.get("window");export const GameBackground=({children:n})=>{const L=r.useMemo(()=>{const r=h/20,t=[];for(let o=0;20>o;o++)for(let e=0;20>e;e++){const c=o*r,i=e*r,l=(31*o+17*e)%100>70?.08:.04;(o+2*e)%5>2&&t.push(s(a,{path:`M ${c} ${i} L ${c} ${i+r}`,style:"stroke",strokeWidth:1,color:`rgba(139, 69, 19, ${l})`},`v-${o}-${e}`)),(2*o+e)%5>2&&t.push(s(a,{path:`M ${c} ${i} L ${c+r} ${i}`,style:"stroke",strokeWidth:1,color:`rgba(139, 69, 19, ${l})`},`h-${o}-${e}`))}return t},[]),b=r.useMemo(()=>{const r=[];for(let t=0;6>t;t++){const o=37*t,e=h/6*t+o%40,a=p/3*(t%3)+2*o%80,l=12+3*o%8;r.push(s(c,{cx:e,cy:a,r:l,opacity:.1,color:"rgba(139, 69, 19, 0.2)",children:s(i,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.1)"})},"maze-piece-"+t))}return r.push(s(a,{path:"M 15 15 L 45 15 L 45 30 L 30 30 L 30 45 L 15 45 Z",color:"rgba(139, 69, 19, 0.15)",opacity:.5,children:s(i,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.05)"})},"corner-tl"),s(a,{path:`M ${h-30-15} 15 L ${h-15} 15 L ${h-15} 45 L ${h-30} 45 L ${h-30} 30 L ${h-30-15} 30 Z`,color:"rgba(139, 69, 19, 0.15)",opacity:.5,children:s(i,{dx:-1,dy:1,blur:2,color:"rgba(0,0,0,0.05)"})},"corner-tr")),r},[]),m=r.useMemo(()=>{const r=[];for(let t=0;12>t;t++){const o=43*t,e=o%h,a=7*o%p,i=1.5+3*o%2,l=.08+5*o%15/100;r.push(s(c,{cx:e,cy:a,r:i,color:`rgba(160, 82, 45, ${l})`},"particle-"+t))}return r},[]);return $(d,{children:[s(l.View,{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:-1},children:$(t,{style:{width:h,height:p},children:[s(a,{path:`M 0 0 L ${h} 0 L ${h} ${p} L 0 ${p} Z`,children:s(o,{start:e(0,0),end:e(0,p),colors:["#f8f4e6","#f0e6d2","#e8d5b7","#d4c4a8"]})}),L,b,m,s(a,{path:`M 0 0 L ${h} 0 L ${h} ${p} L 0 ${p} Z`,color:"rgba(139, 69, 19, 0.02)"})]})}),n]})};
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{Canvas,Rect,LinearGradient,vec,Shadow,RoundedRect}from '@shopify/react-native-skia';import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const WallComponent = React.memo(({walls,width,height})=>{const renderWall =(wall,index)=>{const cornerRadius = 2;const shadowOffset = 1.5;return _jsxs(React.Fragment,{children:[_jsxs(RoundedRect,{x:wall.x,y:wall.y,width:wall.width,height:wall.height,r:cornerRadius,children:[_jsx(LinearGradient,{start:vec(0,0),end:wall.type === 'horizontal' ? vec(0,wall.height):vec(wall.width,0),colors:['#654321','#8B4513','#A0522D','#CD853F','#D2691E' ]}),_jsx(Shadow,{dx:shadowOffset,dy:shadowOffset,blur:3,color:"rgba(0,0,0,0.4)"})]}),_jsx(RoundedRect,{x:wall.x + 1,y:wall.y + 1,width:Math.max(0,wall.width - 2),height:Math.max(0,wall.height - 2),r:Math.max(0,cornerRadius - 1),children:_jsx(LinearGradient,{start:vec(0,0),end:wall.type === 'horizontal' ? vec(0,wall.height - 2):vec(wall.width - 2,0),colors:['rgba(255,255,255,0.3)','rgba(255,255,255,0.1)','rgba(0,0,0,0.1)','rgba(0,0,0,0.2)' ]})}),wall.type === 'horizontal' && _jsx(Rect,{x:wall.x,y:wall.y,width:wall.width,height:1,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(wall.width,0),colors:['rgba(255,255,255,0.6)','rgba(255,255,255,0.3)']})}),wall.type === 'vertical' && _jsx(Rect,{x:wall.x,y:wall.y,width:1,height:wall.height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(0,wall.height),colors:['rgba(255,255,255,0.6)','rgba(255,255,255,0.3)']})})]},index);};return _jsx(Canvas,{style:{width,height},children:walls.map((wall,index)=> renderWall(wall,index))});});
1
+ "use strict";import r from"react";import{Canvas as t,Rect as h,LinearGradient as i,vec as a,Shadow as o,RoundedRect as e}from"@shopify/react-native-skia";import{jsx as l,jsxs as s}from"react/jsx-runtime";export const WallComponent=r.memo(({walls:d,width:n,height:c})=>l(t,{style:{width:n,height:c},children:d.map((t,d)=>((t,d)=>s(r.Fragment,{children:[s(e,{x:t.x,y:t.y,width:t.width,height:t.height,r:2,children:[l(i,{start:a(0,0),end:"horizontal"===t.type?a(0,t.height):a(t.width,0),colors:["#654321","#8B4513","#A0522D","#CD853F","#D2691E"]}),l(o,{dx:1.5,dy:1.5,blur:3,color:"rgba(0, 0, 0, 0.4)"})]}),l(e,{x:t.x+1,y:t.y+1,width:Math.max(0,t.width-2),height:Math.max(0,t.height-2),r:1,children:l(i,{start:a(0,0),end:"horizontal"===t.type?a(0,t.height-2):a(t.width-2,0),colors:["rgba(255, 255, 255, 0.3)","rgba(255, 255, 255, 0.1)","rgba(0, 0, 0, 0.1)","rgba(0, 0, 0, 0.2)"]})}),"horizontal"===t.type&&l(h,{x:t.x,y:t.y,width:t.width,height:1,children:l(i,{start:a(0,0),end:a(t.width,0),colors:["rgba(255, 255, 255, 0.6)","rgba(255, 255, 255, 0.3)"]})}),"vertical"===t.type&&l(h,{x:t.x,y:t.y,width:1,height:t.height,children:l(i,{start:a(0,0),end:a(0,t.height),colors:["rgba(255, 255, 255, 0.6)","rgba(255, 255, 255, 0.3)"]})})]},d))(t,d))}));
@@ -1 +1 @@
1
- "use strict";export{EnhancedBallComponent}from "./EnhancedBallComponent.js";export{WallComponent}from "./WallComponent.js";export{EnhancedGameArea}from "./EnhancedGameArea.js";export{GameBackground}from "./GameBackground.js";export{ScoreBoard}from "./ScoreBoard.js";
1
+ "use strict";export{EnhancedBallComponent}from"./EnhancedBallComponent.js";export{WallComponent}from"./WallComponent.js";export{EnhancedGameArea}from"./EnhancedGameArea.js";export{GameBackground}from"./GameBackground.js";export{ScoreBoard}from"./ScoreBoard.js";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,StyleSheet}from 'react-native';import{GestureHandlerRootView}from 'react-native-gesture-handler';import{GameControlButton,GameOverModal,GameSettingsModal}from "../../helpers/index.js";import{DEFAULT_GAME_SETTINGS,GAME_IDS}from "../../services/UtilsService.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{usePerfectCircleStore,useIsPlaying,useGameOver,useGameWon,useAccuracy}from "./PerfectCircleStore.js";import{PerfectCircleService}from "./PerfectCircleService.js";import{PERFECT_CIRCLE_COLORS,getDifficultySettings,ACCURACY_LEVELS}from "./PerfectCircleConstants.js";import{GameBackground}from "./components/GameBackground.js";import{ScoreBoard}from "./components/ScoreBoard.js";import{DrawingCanvas}from "./components/DrawingCanvas.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const PerfectCircleComponent =({settings:externalSettings = DEFAULT_GAME_SETTINGS,onSettingsChange,onEndGame})=>{const{difficulty,soundEnabled,hapticEnabled,offset}= React.useMemo(()=>({difficulty:externalSettings?.difficulty || 'medium',soundEnabled:externalSettings?.enableSounds ?? true,hapticEnabled:externalSettings?.enableHaptics ?? true,offset:externalSettings?.offset ?? 0}),[externalSettings?.difficulty,externalSettings?.enableSounds,externalSettings?.enableHaptics,externalSettings?.offset]);const isPlaying = useIsPlaying();const gameOver = useGameOver();const gameWon = useGameWon();const accuracy = useAccuracy();const gameReportedRef = React.useRef(false);const reportGameEnd = React.useCallback(status =>{if(onEndGame && !gameReportedRef.current){onEndGame({status,score:accuracy.toFixed(2)});gameReportedRef.current = true;}},[onEndGame,accuracy]);const resetGame = React.useCallback(()=> usePerfectCircleStore.getState().resetGame(),[]);const gameService = React.useMemo(()=> new PerfectCircleService(),[]);const difficultySettings = React.useMemo(()=> getDifficultySettings(difficulty),[difficulty]);const handleAccuracyCalculated = React.useCallback(calculatedAccuracy =>{if(calculatedAccuracy >= difficultySettings.minAccuracy){playSound(GAME_SOUNDS.PERFECT_CIRCLE.SUCCESS,soundEnabled);playHaptic(HapticType.SUCCESS,hapticEnabled);}else{playSound(GAME_SOUNDS.PERFECT_CIRCLE.FAIL,soundEnabled);playHaptic(HapticType.HEAVY,hapticEnabled);}},[soundEnabled,hapticEnabled,difficultySettings.minAccuracy]);React.useEffect(()=>{gameService.setCallbacks(handleAccuracyCalculated);},[gameService,handleAccuracyCalculated]);React.useEffect(()=>{if((gameOver || gameWon)&& !gameReportedRef.current){const status = gameWon ? 'win':'lose';reportGameEnd(status);}if(!gameOver && !gameWon){gameReportedRef.current = false;}},[gameOver,gameWon,reportGameEnd]);React.useEffect(()=>{return()=>{gameService.cleanup();usePerfectCircleStore.getState().resetGame();};},[gameService]);const handleStartGame = React.useCallback(()=>{gameReportedRef.current = false;gameService.startGame();playSound(GAME_SOUNDS.PERFECT_CIRCLE.START,soundEnabled);playHaptic(HapticType.SUCCESS,hapticEnabled);},[gameService,soundEnabled,hapticEnabled]);const handleStopGame = React.useCallback(()=>{reportGameEnd('cancel');resetGame();gameService.resetGame();},[resetGame,gameService,reportGameEnd]);const handleResetGame = React.useCallback(()=>{resetGame();gameService.resetGame();},[resetGame,gameService]);const handlePlayAgain = React.useCallback(()=>{handleResetGame();},[handleResetGame]);const accuracyLevel = React.useMemo(()=>{for(const level of Object.values(ACCURACY_LEVELS)){if(accuracy >= level.min){return level;}}return ACCURACY_LEVELS.POOR;},[accuracy]);const gameControlButtonProps = React.useMemo(()=>({isPlaying,gameOver,onStartGame:handleStartGame,onStopGame:handleStopGame,startButtonColor:PERFECT_CIRCLE_COLORS.UI,stopButtonColor:PERFECT_CIRCLE_COLORS.UI,startButtonBorderColor:PERFECT_CIRCLE_COLORS.UI,stopButtonBorderColor:PERFECT_CIRCLE_COLORS.UI,startButtonText:'START DRAWING',stopButtonText:'STOP GAME',startButtonSubtext:'Draw the perfect circle!'}),[isPlaying,gameOver,handleStartGame,handleStopGame]);const gameOverModalProps = React.useMemo(()=>({isVisible:gameOver,score:accuracy,onPlayAgain:handlePlayAgain,buttonText:'Try Again',primaryColor:'rgba(0,212,255,0.85)',borderColor:PERFECT_CIRCLE_COLORS.UI,buttonColor:'#ffffff',buttonBorderColor:'#ffffff',buttonTextColor:PERFECT_CIRCLE_COLORS.UI,title:gameWon ? `${accuracyLevel.emoji}${accuracyLevel.label}`:'😔 NOT QUITE!',message:gameWon ? `${accuracy}% accuracy - Amazing circle!`:`${accuracy}% accuracy - Need >50% to win`}),[gameOver,accuracy,handlePlayAgain,gameWon,accuracyLevel]);return _jsx(View,{style:styles.container,children:_jsx(GestureHandlerRootView,{style:styles.gestureRoot,children:_jsxs(GameBackground,{offset:offset,children:[_jsx(ScoreBoard,{offset:offset}),_jsx(DrawingCanvas,{gameService:gameService,offset:offset}),_jsx(GameControlButton,{...gameControlButtonProps}),_jsx(GameOverModal,{...gameOverModalProps}),_jsx(GameSettingsModal,{gameId:GAME_IDS.PERFECT_CIRCLE,settings:{...DEFAULT_GAME_SETTINGS,...externalSettings},onSettingsChange:onSettingsChange})]})})});};const styles = StyleSheet.create({container:{flex:1},gestureRoot:{flex:1}});const arePropsEqual =(prevProps,nextProps)=>{return prevProps.settings?.difficulty === nextProps.settings?.difficulty && prevProps.settings?.enableSounds === nextProps.settings?.enableSounds && prevProps.settings?.enableHaptics === nextProps.settings?.enableHaptics && prevProps.settings?.offset === nextProps.settings?.offset && prevProps.settings?.isVisible === nextProps.settings?.isVisible && prevProps.onSettingsChange === nextProps.onSettingsChange;};export const PerfectCircle = React.memo(PerfectCircleComponent,arePropsEqual);PerfectCircle.displayName = 'PerfectCircle';
1
+ "use strict";import t from"react";import{View as e,StyleSheet as r}from"react-native";import{GestureHandlerRootView as o}from"react-native-gesture-handler";import{GameControlButton as s,GameOverModal as n,GameSettingsModal as i}from"../../helpers/index.js";import{DEFAULT_GAME_SETTINGS as c,GAME_IDS as a}from"../../services/UtilsService.js";import{playSound as f,GAME_SOUNDS as m}from"../../services/SoundsService.js";import{playHaptic as l,HapticType as u}from"../../services/HapticsService.js";import{usePerfectCircleStore as p,useIsPlaying as d,useGameOver as g,useGameWon as C,useAccuracy as S}from"./PerfectCircleStore.js";import{PerfectCircleService as j}from"./PerfectCircleService.js";import{PERFECT_CIRCLE_COLORS as b,getDifficultySettings as v,ACCURACY_LEVELS as x}from"./PerfectCircleConstants.js";import{GameBackground as B}from"./components/GameBackground.js";import{ScoreBoard as h}from"./components/ScoreBoard.js";import{DrawingCanvas as y}from"./components/DrawingCanvas.js";import{jsx as T,jsxs as P}from"react/jsx-runtime";const E=({settings:r=c,onSettingsChange:E,onEndGame:G})=>{const{difficulty:w,soundEnabled:O,hapticEnabled:D,offset:I}=t.useMemo(()=>({difficulty:r?.difficulty||"medium",soundEnabled:r?.enableSounds??!0,hapticEnabled:r?.enableHaptics??!0,offset:r?.offset??0}),[r?.difficulty,r?.enableSounds,r?.enableHaptics,r?.offset]),N=d(),R=g(),U=C(),$=S(),k=t.useRef(!1),z=t.useCallback(t=>{G&&!k.current&&(G({status:t,score:$.toFixed(2)}),k.current=!0)},[G,$]),H=t.useCallback(()=>p.getState().resetGame(),[]),M=t.useMemo(()=>new j,[]),Q=t.useMemo(()=>v(w),[w]),V=t.useCallback(t=>{t<Q.minAccuracy?(f(m.PERFECT_CIRCLE.FAIL,O),l(u.HEAVY,D)):(f(m.PERFECT_CIRCLE.SUCCESS,O),l(u.SUCCESS,D))},[O,D,Q.minAccuracy]);t.useEffect(()=>{M.setCallbacks(V)},[M,V]),t.useEffect(()=>{!R&&!U||k.current||z(U?"win":"lose"),R||U||(k.current=!1)},[R,U,z]),t.useEffect(()=>()=>{M.cleanup(),p.getState().resetGame()},[M]);const W=t.useCallback(()=>{k.current=!1,M.startGame(),f(m.PERFECT_CIRCLE.START,O),l(u.SUCCESS,D)},[M,O,D]),q=t.useCallback(()=>{z("cancel"),H(),M.resetGame()},[H,M,z]),F=t.useCallback(()=>{H(),M.resetGame()},[H,M]),J=t.useCallback(()=>{F()},[F]),K=t.useMemo(()=>{for(const t of Object.values(x))if($>=t.min)return t;return x.POOR},[$]),L=t.useMemo(()=>({isPlaying:N,gameOver:R,onStartGame:W,onStopGame:q,startButtonColor:b.UI,stopButtonColor:b.UI,startButtonBorderColor:b.UI,stopButtonBorderColor:b.UI,startButtonText:"START DRAWING",stopButtonText:"STOP GAME",startButtonSubtext:"Draw the perfect circle!"}),[N,R,W,q]),X=t.useMemo(()=>({isVisible:R,score:$,onPlayAgain:J,buttonText:"Try Again",primaryColor:"rgba(0, 212, 255, 0.85)",borderColor:b.UI,buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:b.UI,title:U?`${K.emoji} ${K.label}`:"\ud83d\ude14 NOT QUITE!",message:U?$+"% accuracy - Amazing circle!":$+"% accuracy - Need >50% to win"}),[R,$,J,U,K]);return T(e,{style:A.container,children:T(o,{style:A.gestureRoot,children:P(B,{offset:I,children:[T(h,{offset:I}),T(y,{gameService:M,offset:I}),T(s,{...L}),T(n,{...X}),T(i,{gameId:a.PERFECT_CIRCLE,settings:{...c,...r},onSettingsChange:E})]})})})},A=r.create({container:{flex:1},gestureRoot:{flex:1}}),G=(t,e)=>t.settings?.difficulty===e.settings?.difficulty&&t.settings?.enableSounds===e.settings?.enableSounds&&t.settings?.enableHaptics===e.settings?.enableHaptics&&t.settings?.offset===e.settings?.offset&&t.settings?.isVisible===e.settings?.isVisible&&t.onSettingsChange===e.onSettingsChange;export const PerfectCircle=t.memo(E,G);PerfectCircle.displayName="PerfectCircle";
@@ -1 +1 @@
1
- "use strict";export const PERFECT_CIRCLE_DIFFICULTY_CONFIG ={easy:{minAccuracy:70},medium:{minAccuracy:80},hard:{minAccuracy:90}};export const getDifficultySettings = difficulty =>{return PERFECT_CIRCLE_DIFFICULTY_CONFIG[difficulty];};export const DEFAULT_PERFECT_CIRCLE_SETTINGS ={difficulty:'medium',soundEnabled:true,hapticEnabled:true,minAccuracy:PERFECT_CIRCLE_DIFFICULTY_CONFIG.medium.minAccuracy};export const PERFECT_CIRCLE_GAME_CONFIG ={MIN_POINTS:20,SAMPLE_POINTS:100,STROKE_WIDTH:4,GUIDE_CIRCLE_OPACITY:0.15};export const PERFECT_CIRCLE_COLORS ={BACKGROUND:'#1a1a2e',CANVAS:'#16213e',STROKE:'#00d4ff',GUIDE:'#ffffff',SUCCESS:'#4ecca3',FAIL:'#ff6b6b',UI:'#00d4ff',TEXT:'#ffffff'};export const PERFECT_CIRCLE_THEME ={backgroundColor:'rgba(0,0,0,0.7)',headerBackgroundColor:'#00d4ff',headerTextColor:'#ffffff',sectionBackgroundColor:'rgba(0,212,255,0.15)',sectionTitleColor:'#00d4ff',buttonSelectedColor:'#00d4ff',buttonUnselectedColor:'rgba(255,255,255,0.2)',buttonSelectedTextColor:'#ffffff',buttonUnselectedTextColor:'rgba(255,255,255,0.7)',switchTrackColorFalse:'rgba(0,212,255,0.3)',switchTrackColorTrue:'#00d4ff',switchThumbColor:'#ffffff',infoTextColor:'rgba(255,255,255,0.9)'};export const PERFECT_CIRCLE_DIFFICULTY_DESCRIPTIONS ={easy:'70% accuracy needed to win',medium:'80% accuracy needed to win',hard:'90% accuracy needed to win'};export const ACCURACY_LEVELS ={PERFECT:{min:95,label:'PERFECT!',emoji:'🎯'},EXCELLENT:{min:90,label:'EXCELLENT!',emoji:'⭐'},GREAT:{min:85,label:'GREAT!',emoji:'✨'},GOOD:{min:80,label:'GOOD!',emoji:'👍'},NICE:{min:70,label:'NICE TRY!',emoji:'👌'},POOR:{min:0,label:'KEEP TRYING!',emoji:'💪'}};
1
+ "use strict";export const PERFECT_CIRCLE_DIFFICULTY_CONFIG={easy:{minAccuracy:70},medium:{minAccuracy:80},hard:{minAccuracy:90}};export const getDifficultySettings=e=>PERFECT_CIRCLE_DIFFICULTY_CONFIG[e];export const DEFAULT_PERFECT_CIRCLE_SETTINGS={difficulty:"medium",soundEnabled:!0,hapticEnabled:!0,minAccuracy:PERFECT_CIRCLE_DIFFICULTY_CONFIG.medium.minAccuracy};export const PERFECT_CIRCLE_GAME_CONFIG={MIN_POINTS:20,SAMPLE_POINTS:100,STROKE_WIDTH:4,GUIDE_CIRCLE_OPACITY:.15};export const PERFECT_CIRCLE_COLORS={BACKGROUND:"#1a1a2e",CANVAS:"#16213e",STROKE:"#00d4ff",GUIDE:"#ffffff",SUCCESS:"#4ecca3",FAIL:"#ff6b6b",UI:"#00d4ff",TEXT:"#ffffff"};export const PERFECT_CIRCLE_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#00d4ff",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(0, 212, 255, 0.15)",sectionTitleColor:"#00d4ff",buttonSelectedColor:"#00d4ff",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(0, 212, 255, 0.3)",switchTrackColorTrue:"#00d4ff",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const PERFECT_CIRCLE_DIFFICULTY_DESCRIPTIONS={easy:"70% accuracy needed to win",medium:"80% accuracy needed to win",hard:"90% accuracy needed to win"};export const ACCURACY_LEVELS={PERFECT:{min:95,label:"PERFECT!",emoji:"\ud83c\udfaf"},EXCELLENT:{min:90,label:"EXCELLENT!",emoji:"\u2b50"},GREAT:{min:85,label:"GREAT!",emoji:"\u2728"},GOOD:{min:80,label:"GOOD!",emoji:"\ud83d\udc4d"},NICE:{min:70,label:"NICE TRY!",emoji:"\ud83d\udc4c"},POOR:{min:0,label:"KEEP TRYING!",emoji:"\ud83d\udcaa"}};
@@ -1 +1 @@
1
- "use strict";import{usePerfectCircleStore}from "./PerfectCircleStore.js";import{PERFECT_CIRCLE_GAME_CONFIG}from "./PerfectCircleConstants.js";export class PerfectCircleService{constructor(){}setCallbacks(onAccuracyCalculated){this.onAccuracyCalculated = onAccuracyCalculated;}startGame(){const store = usePerfectCircleStore.getState();store.startGame();}stopGame(){usePerfectCircleStore.getState().stopGame();}resetGame(){usePerfectCircleStore.getState().resetGame();}cleanup(){}calculateCircleAccuracy(points){if(points.length < PERFECT_CIRCLE_GAME_CONFIG.MIN_POINTS){return 0;}const centerX = points.reduce((sum,p)=> sum + p.x,0)/ points.length;const centerY = points.reduce((sum,p)=> sum + p.y,0)/ points.length;const radii = points.map(p =>{const dx = p.x - centerX;const dy = p.y - centerY;return Math.sqrt(dx * dx + dy * dy);});const avgRadius = radii.reduce((sum,r)=> sum + r,0)/ radii.length;if(avgRadius === 0){return 0;}const variance = radii.reduce((sum,r)=> sum + Math.pow(r - avgRadius,2),0)/ radii.length;const stdDev = Math.sqrt(variance);const coefficientOfVariation = stdDev / avgRadius;const accuracy = 100 * Math.exp(-coefficientOfVariation * 2.5);return Math.round(accuracy);}evaluateDrawing(){const store = usePerfectCircleStore.getState();const points = store.drawnPoints;if(points.length < PERFECT_CIRCLE_GAME_CONFIG.MIN_POINTS){store.setAccuracy(0);store.setGameResult(false);return;}const accuracy = this.calculateCircleAccuracy(points);store.setAccuracy(accuracy);this.onAccuracyCalculated?.(accuracy);const won = accuracy > 50;store.setGameResult(won);}finishDrawing(){this.evaluateDrawing();}}
1
+ "use strict";import{usePerfectCircleStore as t}from"./PerfectCircleStore.js";import{PERFECT_CIRCLE_GAME_CONFIG as r}from"./PerfectCircleConstants.js";export class PerfectCircleService{constructor(){}setCallbacks(t){this.onAccuracyCalculated=t}startGame(){t.getState().startGame()}stopGame(){t.getState().stopGame()}resetGame(){t.getState().resetGame()}cleanup(){}calculateCircleAccuracy(t){if(t.length<r.MIN_POINTS)return 0;const e=t.reduce((t,r)=>t+r.x,0)/t.length,c=t.reduce((t,r)=>t+r.y,0)/t.length,s=t.map(t=>{const r=t.x-e,s=t.y-c;return Math.sqrt(r*r+s*s)}),a=s.reduce((t,r)=>t+r,0)/s.length;if(0===a)return 0;const i=s.reduce((t,r)=>t+Math.pow(r-a,2),0)/s.length;return Math.round(100*Math.exp(-Math.sqrt(i)/a*2.5))}evaluateDrawing(){const e=t.getState(),c=e.drawnPoints;if(c.length<r.MIN_POINTS)return e.setAccuracy(0),void e.setGameResult(!1);const s=this.calculateCircleAccuracy(c);e.setAccuracy(s),this.onAccuracyCalculated?.(s);const a=s>50;e.setGameResult(a)}finishDrawing(){this.evaluateDrawing()}}
@@ -1 +1 @@
1
- "use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{immerMiddleware}from "../../services/UtilsService.js";export const usePerfectCircleStore = create()(subscribeWithSelector(immerMiddleware(set =>({isPlaying:false,isDrawing:false,gameOver:false,gameWon:false,accuracy:0,drawnPoints:[],startPoint:null,startGame:()=>{set(draft =>{draft.isPlaying = true;draft.isDrawing = false;draft.gameOver = false;draft.gameWon = false;draft.accuracy = 0;draft.drawnPoints = [];draft.startPoint = null;});},stopGame:()=>{set(draft =>{draft.isPlaying = false;draft.isDrawing = false;});},resetGame:()=>{set(draft =>{draft.isPlaying = false;draft.isDrawing = false;draft.gameOver = false;draft.gameWon = false;draft.accuracy = 0;draft.drawnPoints = [];draft.startPoint = null;});},startDrawing:point =>{set(draft =>{draft.isDrawing = true;draft.startPoint = point;draft.drawnPoints = [point];});},addPoint:point =>{set(draft =>{draft.drawnPoints.push(point);});},finishDrawing:()=>{set(draft =>{draft.isDrawing = false;});},setAccuracy:accuracy =>{set(draft =>{draft.accuracy = accuracy;});},setGameResult:won =>{set(draft =>{draft.gameOver = true;draft.gameWon = won;draft.isPlaying = false;draft.isDrawing = false;});},clearDrawing:()=>{set(draft =>{draft.drawnPoints = [];draft.startPoint = null;draft.isDrawing = false;draft.accuracy = 0;});}}))));export const useIsPlaying =()=> usePerfectCircleStore(state => state.isPlaying);export const useIsDrawing =()=> usePerfectCircleStore(state => state.isDrawing);export const useGameOver =()=> usePerfectCircleStore(state => state.gameOver);export const useGameWon =()=> usePerfectCircleStore(state => state.gameWon);export const useAccuracy =()=> usePerfectCircleStore(state => state.accuracy);export const useDrawnPoints =()=> usePerfectCircleStore(state => state.drawnPoints);
1
+ "use strict";import{create as e}from"zustand";import{subscribeWithSelector as r}from"zustand/middleware";import{immerMiddleware as t}from"../../services/UtilsService.js";export const usePerfectCircleStore=e()(r(t(e=>({isPlaying:!1,isDrawing:!1,gameOver:!1,gameWon:!1,accuracy:0,drawnPoints:[],startPoint:null,startGame:()=>{e(e=>{e.isPlaying=!0,e.isDrawing=!1,e.gameOver=!1,e.gameWon=!1,e.accuracy=0,e.drawnPoints=[],e.startPoint=null})},stopGame:()=>{e(e=>{e.isPlaying=!1,e.isDrawing=!1})},resetGame:()=>{e(e=>{e.isPlaying=!1,e.isDrawing=!1,e.gameOver=!1,e.gameWon=!1,e.accuracy=0,e.drawnPoints=[],e.startPoint=null})},startDrawing:r=>{e(e=>{e.isDrawing=!0,e.startPoint=r,e.drawnPoints=[r]})},addPoint:r=>{e(e=>{e.drawnPoints.push(r)})},finishDrawing:()=>{e(e=>{e.isDrawing=!1})},setAccuracy:r=>{e(e=>{e.accuracy=r})},setGameResult:r=>{e(e=>{e.gameOver=!0,e.gameWon=r,e.isPlaying=!1,e.isDrawing=!1})},clearDrawing:()=>{e(e=>{e.drawnPoints=[],e.startPoint=null,e.isDrawing=!1,e.accuracy=0})}}))));export const useIsPlaying=()=>usePerfectCircleStore(e=>e.isPlaying);export const useIsDrawing=()=>usePerfectCircleStore(e=>e.isDrawing);export const useGameOver=()=>usePerfectCircleStore(e=>e.gameOver);export const useGameWon=()=>usePerfectCircleStore(e=>e.gameWon);export const useAccuracy=()=>usePerfectCircleStore(e=>e.accuracy);export const useDrawnPoints=()=>usePerfectCircleStore(e=>e.drawnPoints);
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,Dimensions,StyleSheet}from 'react-native';import{Canvas,Path,Skia,Circle}from '@shopify/react-native-skia';import{Gesture,GestureDetector}from 'react-native-gesture-handler';import{runOnJS}from 'react-native-reanimated';import{usePerfectCircleStore,useDrawnPoints,useIsPlaying}from "../PerfectCircleStore.js";import{PERFECT_CIRCLE_COLORS,PERFECT_CIRCLE_GAME_CONFIG}from "../PerfectCircleConstants.js";import{playHaptic,HapticType}from "../../../services/HapticsService.js";import{playSound,GAME_SOUNDS}from "../../../services/SoundsService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');const GUIDE_CIRCLE_RADIUS = width / 2 - 20;const DrawingCanvasComponent =({gameService,offset = 0})=>{const drawnPoints = useDrawnPoints();const isPlaying = useIsPlaying();const path = React.useMemo(()=>{if(drawnPoints.length === 0)return null;const skPath = Skia.Path.Make();const firstPoint = drawnPoints[0];if(!firstPoint)return null;skPath.moveTo(firstPoint.x,firstPoint.y);for(let i = 1;i < drawnPoints.length;i++){const point = drawnPoints[i];if(point){skPath.lineTo(point.x,point.y);}}return skPath;},[drawnPoints]);const startDrawingJS = React.useCallback((x,y)=>{usePerfectCircleStore.getState().startDrawing({x,y});playHaptic(HapticType.LIGHT,true);},[]);const addPointJS = React.useCallback((x,y)=>{usePerfectCircleStore.getState().addPoint({x,y});},[]);const finishDrawingJS = React.useCallback(()=>{usePerfectCircleStore.getState().finishDrawing();playHaptic(HapticType.MEDIUM,true);playSound(GAME_SOUNDS.PERFECT_CIRCLE.DRAW_END,true);gameService.finishDrawing();},[gameService]);const panGesture = React.useMemo(()=> Gesture.Pan().onStart(event =>{'worklet';if(isPlaying){runOnJS(startDrawingJS)(event.x,event.y);}}).onUpdate(event =>{'worklet';if(isPlaying){runOnJS(addPointJS)(event.x,event.y);}}).onEnd(()=>{'worklet';if(isPlaying){runOnJS(finishDrawingJS)();}}),[isPlaying,startDrawingJS,addPointJS,finishDrawingJS]);const{circleCenterX,circleCenterY}= React.useMemo(()=>{const canvasHeight = height - offset + 100 - 350;return{circleCenterX:width / 2,circleCenterY:canvasHeight / 2};},[offset]);return _jsx(View,{style:[styles.container,{top:offset + 260}],children:_jsx(GestureDetector,{gesture:panGesture,children:_jsxs(Canvas,{style:styles.canvas,children:[_jsx(Circle,{cx:circleCenterX,cy:circleCenterY,r:GUIDE_CIRCLE_RADIUS,color:PERFECT_CIRCLE_COLORS.GUIDE,opacity:PERFECT_CIRCLE_GAME_CONFIG.GUIDE_CIRCLE_OPACITY,style:"stroke",strokeWidth:2}),path && _jsx(Path,{path:path,color:PERFECT_CIRCLE_COLORS.STROKE,style:"stroke",strokeWidth:PERFECT_CIRCLE_GAME_CONFIG.STROKE_WIDTH,strokeCap:"round",strokeJoin:"round"})]})})});};const styles = StyleSheet.create({container:{position:'absolute',left:0,right:0,bottom:250,justifyContent:'center',alignItems:'center'},canvas:{width,height:height - 350,justifyContent:'center',alignItems:'center'}});const arePropsEqual =(prevProps,nextProps)=>{return prevProps.offset === nextProps.offset && prevProps.gameService === nextProps.gameService;};export const DrawingCanvas = React.memo(DrawingCanvasComponent,arePropsEqual);DrawingCanvas.displayName = 'DrawingCanvas';
1
+ "use strict";import e from"react";import{View as t,Dimensions as r,StyleSheet as i}from"react-native";import{Canvas as o,Path as n,Skia as s,Circle as c}from"@shopify/react-native-skia";import{Gesture as a,GestureDetector as m}from"react-native-gesture-handler";import{runOnJS as l}from"react-native-reanimated";import{usePerfectCircleStore as f,useDrawnPoints as p,useIsPlaying as u}from"../PerfectCircleStore.js";import{PERFECT_CIRCLE_COLORS as h,PERFECT_CIRCLE_GAME_CONFIG as d}from"../PerfectCircleConstants.js";import{playHaptic as v,HapticType as C}from"../../../services/HapticsService.js";import{playSound as g,GAME_SOUNDS as y}from"../../../services/SoundsService.js";import{jsx as j,jsxs as k}from"react/jsx-runtime";const{width:w,height:x}=r.get("window"),S=w/2-20,D=({gameService:r,offset:i=0})=>{const D=p(),I=u(),P=e.useMemo(()=>{if(0===D.length)return null;const e=s.Path.Make(),t=D[0];if(!t)return null;e.moveTo(t.x,t.y);for(let t=1;t<D.length;t++){const r=D[t];r&&e.lineTo(r.x,r.y)}return e},[D]),W=e.useCallback((e,t)=>{f.getState().startDrawing({x:e,y:t}),v(C.LIGHT,!0)},[]),X=e.useCallback((e,t)=>{f.getState().addPoint({x:e,y:t})},[]),Y=e.useCallback(()=>{f.getState().finishDrawing(),v(C.MEDIUM,!0),g(y.PERFECT_CIRCLE.DRAW_END,!0),r.finishDrawing()},[r]),H=e.useMemo(()=>a.Pan().onStart(e=>{I&&l(W)(e.x,e.y)}).onUpdate(e=>{I&&l(X)(e.x,e.y)}).onEnd(()=>{I&&l(Y)()}),[I,W,X,Y]),{circleCenterX:J,circleCenterY:q}=e.useMemo(()=>({circleCenterX:w/2,circleCenterY:(x-i+100-350)/2}),[i]);return j(t,{style:[b.container,{top:i+260}],children:j(m,{gesture:H,children:k(o,{style:b.canvas,children:[j(c,{cx:J,cy:q,r:S,color:h.GUIDE,opacity:d.GUIDE_CIRCLE_OPACITY,style:"stroke",strokeWidth:2}),P&&j(n,{path:P,color:h.STROKE,style:"stroke",strokeWidth:d.STROKE_WIDTH,strokeCap:"round",strokeJoin:"round"})]})})})},b=i.create({container:{position:"absolute",left:0,right:0,bottom:250,justifyContent:"center",alignItems:"center"},canvas:{width:w,height:x-350,justifyContent:"center",alignItems:"center"}}),I=(e,t)=>e.offset===t.offset&&e.gameService===t.gameService;export const DrawingCanvas=e.memo(D,I);DrawingCanvas.displayName="DrawingCanvas";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,Dimensions}from 'react-native';import{Canvas,LinearGradient,Rect,vec,Circle}from '@shopify/react-native-skia';import{PERFECT_CIRCLE_COLORS}from "../PerfectCircleConstants.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');const verticalGridLines = Array.from({length:Math.floor(width / 80)},(_,i)=> i);const horizontalGridLines = Array.from({length:Math.floor(height / 80)},(_,i)=> i);export const GameBackground = React.memo(({children})=>{const decorativeCircles = React.useMemo(()=>{const circles = [];const circleCount = 15;for(let i = 0;i < circleCount;i++){const x = width / circleCount * i + Math.random()* 100;const y = height / circleCount * i + Math.random()* 100;const size = 20 + Math.random()* 40;const opacity = 0.05 + Math.random()* 0.1;circles.push(_jsx(Circle,{cx:x,cy:y,r:size,color:`${PERFECT_CIRCLE_COLORS.GUIDE}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`circle-${i}`));}return circles;},[]);return _jsxs(View,{style:{flex:1},children:[_jsxs(Canvas,{style:{position:'absolute',top:0,left:0,right:0,bottom:0,width,height},children:[_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(width,height),colors:[PERFECT_CIRCLE_COLORS.BACKGROUND,PERFECT_CIRCLE_COLORS.CANVAS,PERFECT_CIRCLE_COLORS.BACKGROUND]})}),_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(width / 2,height / 2),end:vec(width,height),colors:['rgba(0,212,255,0.1)','transparent','rgba(0,212,255,0.05)']})}),decorativeCircles,verticalGridLines.map(i => _jsx(Rect,{x:i * 80,y:0,width:1,height:height,color:"rgba(255,255,255,0.03)"},`grid-v-${i}`)),horizontalGridLines.map(i => _jsx(Rect,{x:0,y:i * 80,width:width,height:1,color:"rgba(255,255,255,0.03)"},`grid-h-${i}`))]}),children]});});GameBackground.displayName = 'GameBackground';
1
+ "use strict";import t from"react";import{View as r,Dimensions as e}from"react-native";import{Canvas as o,LinearGradient as i,Rect as h,vec as a,Circle as c}from"@shopify/react-native-skia";import{PERFECT_CIRCLE_COLORS as n}from"../PerfectCircleConstants.js";import{jsx as s,jsxs as l}from"react/jsx-runtime";const{width:d,height:g}=e.get("window"),m=Array.from({length:Math.floor(d/80)},(t,r)=>r),f=Array.from({length:Math.floor(g/80)},(t,r)=>r);export const GameBackground=t.memo(({children:e})=>{const p=t.useMemo(()=>{const t=[];for(let r=0;15>r;r++){const e=d/15*r+100*Math.random(),o=g/15*r+100*Math.random(),i=20+40*Math.random(),h=.05+.1*Math.random();t.push(s(c,{cx:e,cy:o,r:i,color:`${n.GUIDE}${Math.floor(255*h).toString(16).padStart(2,"0")}`},"circle-"+r))}return t},[]);return l(r,{style:{flex:1},children:[l(o,{style:{position:"absolute",top:0,left:0,right:0,bottom:0,width:d,height:g},children:[s(h,{x:0,y:0,width:d,height:g,children:s(i,{start:a(0,0),end:a(d,g),colors:[n.BACKGROUND,n.CANVAS,n.BACKGROUND]})}),s(h,{x:0,y:0,width:d,height:g,children:s(i,{start:a(d/2,g/2),end:a(d,g),colors:["rgba(0, 212, 255, 0.1)","transparent","rgba(0, 212, 255, 0.05)"]})}),p,m.map(t=>s(h,{x:80*t,y:0,width:1,height:g,color:"rgba(255, 255, 255, 0.03)"},"grid-v-"+t)),f.map(t=>s(h,{x:0,y:80*t,width:d,height:1,color:"rgba(255, 255, 255, 0.03)"},"grid-h-"+t))]}),e]})});GameBackground.displayName="GameBackground";
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,Text,StyleSheet}from 'react-native';import{useAccuracy}from "../PerfectCircleStore.js";import{PERFECT_CIRCLE_COLORS}from "../PerfectCircleConstants.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 accuracy = useAccuracy();return _jsx(ScoreBoardContainer,{offset:offset,backgroundColor:"rgba(0,212,255,0.3)",borderColor:PERFECT_CIRCLE_COLORS.UI,children:_jsx(View,{style:styles.scoreBoard,children:_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Accuracy"}),_jsx(Text,{style:[styles.scoreValue,accuracy > 0 && styles.accuracyActive],children:accuracy})]})})});});ScoreBoard.displayName = 'ScoreBoard';const styles = StyleSheet.create({scoreBoard:{flexDirection:'row',justifyContent:'center',alignItems:'center'},scoreSection:{alignItems:'center',flex:1},scoreLabel:{fontSize:16,fontWeight:'bold',color:PERFECT_CIRCLE_COLORS.TEXT,marginBottom:4},scoreValue:{fontSize:25,fontWeight:'bold',color:PERFECT_CIRCLE_COLORS.TEXT},accuracyActive:{color:PERFECT_CIRCLE_COLORS.UI}});
1
+ "use strict";import r from"react";import{View as e,Text as o,StyleSheet as t}from"react-native";import{useAccuracy as c}from"../PerfectCircleStore.js";import{PERFECT_CIRCLE_COLORS as s}from"../PerfectCircleConstants.js";import{ScoreBoardContainer as i}from"../../../helpers/index.js";import{jsx as n,jsxs as l}from"react/jsx-runtime";export const ScoreBoard=r.memo(({offset:r=0})=>{const t=c();return n(i,{offset:r,backgroundColor:"rgba(0, 212, 255, 0.3)",borderColor:s.UI,children:n(e,{style:a.scoreBoard,children:l(e,{style:a.scoreSection,children:[n(o,{style:a.scoreLabel,children:"Accuracy"}),n(o,{style:[a.scoreValue,t>0&&a.accuracyActive],children:t})]})})})});ScoreBoard.displayName="ScoreBoard";const a=t.create({scoreBoard:{flexDirection:"row",justifyContent:"center",alignItems:"center"},scoreSection:{alignItems:"center",flex:1},scoreLabel:{fontSize:16,fontWeight:"bold",color:s.TEXT,marginBottom:4},scoreValue:{fontSize:25,fontWeight:"bold",color:s.TEXT},accuracyActive:{color:s.UI}});
@@ -1 +1 @@
1
- "use strict";export{PerfectCircle}from "./PerfectCircle.js";export{PERFECT_CIRCLE_THEME}from "./PerfectCircleConstants.js";
1
+ "use strict";export{PerfectCircle}from"./PerfectCircle.js";export{PERFECT_CIRCLE_THEME}from"./PerfectCircleConstants.js";
@@ -1 +1 @@
1
- "use strict";import React,{useEffect,useRef,useCallback,useMemo}from 'react';import{View,StyleSheet,Dimensions}from 'react-native';import{GestureHandlerRootView}from 'react-native-gesture-handler';import{usePopitFidgetStore}from "./PopitFidgetStore.js";import{PopitFidgetService}from "./PopitFidgetService.js";import{GAME_IDS,DEFAULT_GAME_SETTINGS}from "../../services/UtilsService.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{calculateTimeBasedScore}from "../../services/ScoringService.js";import{GameBackground,FidgetGrid as FidgetGridComponent,ScoreBoard}from "./components/index.js";import{GameControlButton,GameOverModal}from "../../helpers/index.js";import{GameSettingsModal}from "../../helpers/index.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');const PopitFidget =({settings,onSettingsChange,onEndGame})=>{const fidgetGrid = usePopitFidgetStore(state => state.fidgetGrid);const timeElapsed = usePopitFidgetStore(state => state.timeElapsed);const isPlaying = usePopitFidgetStore(state => state.isPlaying);const gameOver = usePopitFidgetStore(state => state.gameOver);const gameWon = usePopitFidgetStore(state => state.gameWon);const gameReportedRef = useRef(false);const{difficulty = 'medium',enableSounds = true,enableHaptics = true}= settings ||{};const reportGameEnd = useCallback((status,currentTime)=>{if(onEndGame && !gameReportedRef.current){const expectedTimes ={easy:30,medium:45,hard:60};const expectedTime = expectedTimes[difficulty];const calculatedScore = status === 'win' ? calculateTimeBasedScore(currentTime,expectedTime):0;onEndGame({status,score:calculatedScore.toString()});gameReportedRef.current = true;}},[onEndGame,difficulty]);const startGame = usePopitFidgetStore(state => state.startGame);const resetGame = usePopitFidgetStore(state => state.resetGame);const setFidgetGrid = usePopitFidgetStore(state => state.setFidgetGrid);const popBubble = usePopitFidgetStore(state => state.popBubble);const incrementTime = usePopitFidgetStore(state => state.incrementTime);const serviceRef = useRef(null);useEffect(()=>{if(!serviceRef.current){serviceRef.current = new PopitFidgetService();}if(serviceRef.current && !fidgetGrid){const grid = serviceRef.current.generateFidgetGrid(difficulty);setFidgetGrid(grid);}},[fidgetGrid,setFidgetGrid,difficulty]);useEffect(()=>{return()=>{try{serviceRef.current?.stopGameTimer();}catch{}try{resetGame();}catch{}try{serviceRef.current?.cleanup();}catch{}};},[]);const service = useMemo(()=>{if(!serviceRef.current){serviceRef.current = new PopitFidgetService();}return serviceRef.current;},[]);const generateNewFidget = useCallback(()=>{const grid = service.generateFidgetGrid(difficulty);setFidgetGrid(grid);},[service,setFidgetGrid,difficulty]);const prevDifficultyRef = React.useRef(difficulty);const handleDifficultyChange = useCallback(()=>{if(prevDifficultyRef.current !== difficulty){if(!isPlaying){generateNewFidget();}prevDifficultyRef.current = difficulty;}},[difficulty,isPlaying,generateNewFidget]);useEffect(()=>{handleDifficultyChange();},[handleDifficultyChange]);React.useEffect(()=>{if(gameOver && !isPlaying && !gameReportedRef.current){if(gameWon){playSound(GAME_SOUNDS.BUBBLE_POPPER.COMPLETE,enableSounds);reportGameEnd('win',timeElapsed);}else{playSound(GAME_SOUNDS.TIME_UP,enableSounds);reportGameEnd('lose',timeElapsed);}}if(!gameOver){gameReportedRef.current = false;}},[gameOver,gameWon,isPlaying,enableSounds,reportGameEnd,timeElapsed]);useEffect(()=>{let timerInterval = null;if(isPlaying){timerInterval = setInterval(()=>{incrementTime();},1000);}return()=>{if(timerInterval){clearInterval(timerInterval);}};},[isPlaying,incrementTime]);const startGameHandler = useCallback(()=>{gameReportedRef.current = false;generateNewFidget();playSound(GAME_SOUNDS.BUBBLE_POPPER.START,enableSounds);startGame();playHaptic(HapticType.MEDIUM,enableHaptics);},[startGame,enableSounds,enableHaptics,generateNewFidget]);const stopGameHandler = useCallback(()=>{reportGameEnd('cancel',timeElapsed);service.stopGameTimer();resetGame();generateNewFidget();},[service,resetGame,generateNewFidget,reportGameEnd,timeElapsed]);const resetGameHandler = useCallback(()=>{service.stopGameTimer();resetGame();generateNewFidget();},[service,resetGame,generateNewFidget]);const handleBubblePop = useCallback((row,col)=>{if(!fidgetGrid)return;const bubble = fidgetGrid.bubbles[row]?.[col];if(!bubble || bubble.isPopped)return;playSound(GAME_SOUNDS.BUBBLE_POPPER.POP,enableSounds);popBubble(row,col);playHaptic(HapticType.LIGHT,enableHaptics);},[fidgetGrid,popBubble,enableSounds,enableHaptics]);const screenDimensions = useMemo(()=>({width,height}),[]);const bubbleSize = useMemo(()=>{if(!fidgetGrid)return 60;const availableWidth = screenDimensions.width * 0.85;const availableHeight = screenDimensions.height * 0.6;const maxSize = Math.min(availableWidth / fidgetGrid.size,availableHeight / fidgetGrid.size);return Math.max(45,Math.min(80,maxSize * 0.9));},[fidgetGrid,screenDimensions]);const gameControlButtonProps = useMemo(()=>({isPlaying,gameOver,onStartGame:startGameHandler,onStopGame:stopGameHandler,startButtonText:"START POPPING",stopButtonText:"STOP GAME",startButtonSubtext:"Pop bubbles to relax!",stopButtonSubtext:"End current game",startButtonColor:"#9c27b0",stopButtonColor:"#dc2626",startButtonBorderColor:"#ce93d8",stopButtonBorderColor:"#f87171"}),[isPlaying,gameOver,startGameHandler,stopGameHandler]);const gameOverModalProps = useMemo(()=>({isVisible:gameOver,score:timeElapsed,onPlayAgain:resetGameHandler,buttonText:"Pop Again!",primaryColor:"rgba(156,39,176,0.5)",borderColor:"rgba(156,39,176,0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#9c27b0",scoreFormatter:time =>{const mins = Math.floor(time / 60);const secs = time % 60;return `${mins.toString().padStart(2,'0')}:${secs.toString().padStart(2,'0')}`;},scoreLabel:"Time Elapsed"}),[gameOver,timeElapsed,resetGameHandler]);const offset = settings?.offset ?? 0;return _jsx(View,{style:styles.container,children:_jsx(GestureHandlerRootView,{children:_jsxs(View,{style:[styles.gameContainer,{paddingTop:offset}],children:[_jsx(GameBackground,{width:screenDimensions.width,height:screenDimensions.height,isPlaying:isPlaying}),_jsx(ScoreBoard,{timeElapsed:timeElapsed,offset:offset}),_jsx(View,{style:styles.gameArea,children:fidgetGrid && _jsx(FidgetGridComponent,{grid:fidgetGrid,bubbleSize:bubbleSize,onBubblePop:handleBubblePop,hapticEnabled:enableHaptics,isPlaying:isPlaying})}),_jsx(GameControlButton,{...gameControlButtonProps}),_jsx(GameOverModal,{...gameOverModalProps}),_jsx(GameSettingsModal,{gameId:GAME_IDS.POPIT_FIDGET,settings:settings || DEFAULT_GAME_SETTINGS,onSettingsChange:onSettingsChange})]})})});};const styles = StyleSheet.create({container:{flex:1},gameContainer:{flex:1,backgroundColor:'#fef7ff'},gameArea:{flex:1,justifyContent:'center',alignItems:'center',paddingHorizontal:20}});export{PopitFidget};
1
+ "use strict";import t,{useEffect as e,useRef as r,useCallback as o,useMemo as n}from"react";import{View as i,StyleSheet as s,Dimensions as a}from"react-native";import{GestureHandlerRootView as c}from"react-native-gesture-handler";import{usePopitFidgetStore as l}from"./PopitFidgetStore.js";import{PopitFidgetService as m}from"./PopitFidgetService.js";import{GAME_IDS as f,DEFAULT_GAME_SETTINGS as d}from"../../services/UtilsService.js";import{playSound as u,GAME_SOUNDS as p}from"../../services/SoundsService.js";import{playHaptic as g,HapticType as h}from"../../services/HapticsService.js";import{calculateTimeBasedScore as b}from"../../services/ScoringService.js";import{GameBackground as S,FidgetGrid as x,ScoreBoard as v}from"./components/index.js";import{GameControlButton as y,GameOverModal as C}from"../../helpers/index.js";import{GameSettingsModal as j}from"../../helpers/index.js";import{jsx as P,jsxs as B}from"react/jsx-runtime";const{width:w,height:T}=a.get("window"),E=({settings:s,onSettingsChange:a,onEndGame:E})=>{const A=l(t=>t.fidgetGrid),I=l(t=>t.timeElapsed),M=l(t=>t.isPlaying),F=l(t=>t.gameOver),H=l(t=>t.gameWon),O=r(!1),{difficulty:z="medium",enableSounds:$=!0,enableHaptics:k=!0}=s||{},L=o((t,e)=>{if(E&&!O.current){const r="win"===t?b(e,{easy:30,medium:45,hard:60}[z]):0;E({status:t,score:r.toString()}),O.current=!0}},[E,z]),N=l(t=>t.startGame),R=l(t=>t.resetGame),U=l(t=>t.setFidgetGrid),V=l(t=>t.popBubble),q=l(t=>t.incrementTime),D=r(null);e(()=>{if(D.current||(D.current=new m),D.current&&!A){const t=D.current.generateFidgetGrid(z);U(t)}},[A,U,z]),e(()=>()=>{try{D.current?.stopGameTimer()}catch{}try{R()}catch{}try{D.current?.cleanup()}catch{}},[]);const J=n(()=>(D.current||(D.current=new m),D.current),[]),K=o(()=>{const t=J.generateFidgetGrid(z);U(t)},[J,U,z]),Q=t.useRef(z),W=o(()=>{Q.current!==z&&(M||K(),Q.current=z)},[z,M,K]);e(()=>{W()},[W]),t.useEffect(()=>{!F||M||O.current||(H?(u(p.BUBBLE_POPPER.COMPLETE,$),L("win",I)):(u(p.TIME_UP,$),L("lose",I))),F||(O.current=!1)},[F,H,M,$,L,I]),e(()=>{let t=null;return M&&(t=setInterval(()=>{q()},1e3)),()=>{t&&clearInterval(t)}},[M,q]);const X=o(()=>{O.current=!1,K(),u(p.BUBBLE_POPPER.START,$),N(),g(h.MEDIUM,k)},[N,$,k,K]),Y=o(()=>{L("cancel",I),J.stopGameTimer(),R(),K()},[J,R,K,L,I]),Z=o(()=>{J.stopGameTimer(),R(),K()},[J,R,K]),_=o((t,e)=>{if(!A)return;const r=A.bubbles[t]?.[e];r&&!r.isPopped&&(u(p.BUBBLE_POPPER.POP,$),V(t,e),g(h.LIGHT,k))},[A,V,$,k]),tt=n(()=>({width:w,height:T}),[]),et=n(()=>{if(!A)return 60;const t=.85*tt.width,e=.6*tt.height,r=Math.min(t/A.size,e/A.size);return Math.max(45,Math.min(80,.9*r))},[A,tt]),rt=n(()=>({isPlaying:M,gameOver:F,onStartGame:X,onStopGame:Y,startButtonText:"START POPPING",stopButtonText:"STOP GAME",startButtonSubtext:"Pop bubbles to relax!",stopButtonSubtext:"End current game",startButtonColor:"#9c27b0",stopButtonColor:"#dc2626",startButtonBorderColor:"#ce93d8",stopButtonBorderColor:"#f87171"}),[M,F,X,Y]),ot=n(()=>({isVisible:F,score:I,onPlayAgain:Z,buttonText:"Pop Again!",primaryColor:"rgba(156, 39, 176, 0.5)",borderColor:"rgba(156, 39, 176, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#9c27b0",scoreFormatter:t=>{const e=t%60;return`${Math.floor(t/60).toString().padStart(2,"0")}:${e.toString().padStart(2,"0")}`},scoreLabel:"Time Elapsed"}),[F,I,Z]),nt=s?.offset??0;return P(i,{style:G.container,children:P(c,{children:B(i,{style:[G.gameContainer,{paddingTop:nt}],children:[P(S,{width:tt.width,height:tt.height,isPlaying:M}),P(v,{timeElapsed:I,offset:nt}),P(i,{style:G.gameArea,children:A&&P(x,{grid:A,bubbleSize:et,onBubblePop:_,hapticEnabled:k,isPlaying:M})}),P(y,{...rt}),P(C,{...ot}),P(j,{gameId:f.POPIT_FIDGET,settings:s||d,onSettingsChange:a})]})})})},G=s.create({container:{flex:1},gameContainer:{flex:1,backgroundColor:"#fef7ff"},gameArea:{flex:1,justifyContent:"center",alignItems:"center",paddingHorizontal:20}});export{E as PopitFidget};
@@ -1 +1 @@
1
- "use strict";export const POPIT_FIDGET_GAME_CONFIG ={GAME_DURATION:120,POINTS_PER_BUBBLE:10,COMPLETION_BONUS:500,TIME_BONUS_MULTIPLIER:5,BUBBLE_SIZE:40,ANIMATION_DURATION:300,PARTICLE_COUNT:4,PARTICLE_LIFETIME:800,GRID_SIZES:{easy:5,medium:6,hard:7}};export const POPIT_FIDGET_ANIMATION_CONFIG ={POP_SCALE:1.3,POP_DURATION:200,FADE_DURATION:300,BOUNCE_SCALE:0.9,PARTICLE_VELOCITY:3,PARTICLE_GRAVITY:0.2};export const POPIT_FIDGET_COLORS ={BACKGROUND:'#f5f5f5',FIDGET_BORDER:'#333',FIDGET_SHADOW:'rgba(0,0,0,0.3)',SCORE:'#4a90e2',UI:'#6c5ce7',POPPED_BUBBLE:'#d0d0d0',PARTICLE_GLOW:'rgba(255,255,255,0.9)',FIDGET_BASE:'#ffffff',BUBBLE_SHADOW:'rgba(0,0,0,0.2)',BUBBLE_HIGHLIGHT:'rgba(255,255,255,0.6)'};export const RAINBOW_COLORS = ['#E91E63','#F44336','#FF5722','#FF9800','#FFC107','#8E24AA','#CDDC39','#8BC34A','#4CAF50','#009688','#00BCD4','#03A9F4','#2196F3','#3F51B5','#9C27B0','#E91E63' ];export const BUBBLE_COLORS = RAINBOW_COLORS;export const POPIT_FIDGET_THEME ={backgroundColor:'rgba(0,0,0,0.7)',headerBackgroundColor:'#9c27b0',headerTextColor:'#ffffff',sectionBackgroundColor:'rgba(156,39,176,0.15)',sectionTitleColor:'#9c27b0',buttonSelectedColor:'#9c27b0',buttonUnselectedColor:'rgba(255,255,255,0.2)',buttonSelectedTextColor:'#ffffff',buttonUnselectedTextColor:'rgba(255,255,255,0.7)',switchTrackColorFalse:'rgba(156,39,176,0.3)',switchTrackColorTrue:'#9c27b0',switchThumbColor:'#ffffff',infoTextColor:'rgba(255,255,255,0.9)'};export const POPIT_FIDGET_DIFFICULTY_DESCRIPTIONS ={easy:'Smaller fidget grids,relaxing pace',medium:'Medium grids,satisfying pops',hard:'Large complex shapes,ultimate satisfaction!'};
1
+ "use strict";export const POPIT_FIDGET_GAME_CONFIG={GAME_DURATION:120,POINTS_PER_BUBBLE:10,COMPLETION_BONUS:500,TIME_BONUS_MULTIPLIER:5,BUBBLE_SIZE:40,ANIMATION_DURATION:300,PARTICLE_COUNT:4,PARTICLE_LIFETIME:800,GRID_SIZES:{easy:5,medium:6,hard:7}};export const POPIT_FIDGET_ANIMATION_CONFIG={POP_SCALE:1.3,POP_DURATION:200,FADE_DURATION:300,BOUNCE_SCALE:.9,PARTICLE_VELOCITY:3,PARTICLE_GRAVITY:.2};export const POPIT_FIDGET_COLORS={BACKGROUND:"#f5f5f5",FIDGET_BORDER:"#333",FIDGET_SHADOW:"rgba(0,0,0,0.3)",SCORE:"#4a90e2",UI:"#6c5ce7",POPPED_BUBBLE:"#d0d0d0",PARTICLE_GLOW:"rgba(255,255,255,0.9)",FIDGET_BASE:"#ffffff",BUBBLE_SHADOW:"rgba(0,0,0,0.2)",BUBBLE_HIGHLIGHT:"rgba(255,255,255,0.6)"};export const RAINBOW_COLORS=["#E91E63","#F44336","#FF5722","#FF9800","#FFC107","#8E24AA","#CDDC39","#8BC34A","#4CAF50","#009688","#00BCD4","#03A9F4","#2196F3","#3F51B5","#9C27B0","#E91E63"];export const BUBBLE_COLORS=RAINBOW_COLORS;export const POPIT_FIDGET_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#9c27b0",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(156, 39, 176, 0.15)",sectionTitleColor:"#9c27b0",buttonSelectedColor:"#9c27b0",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(156, 39, 176, 0.3)",switchTrackColorTrue:"#9c27b0",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const POPIT_FIDGET_DIFFICULTY_DESCRIPTIONS={easy:"Smaller fidget grids, relaxing pace",medium:"Medium grids, satisfying pops",hard:"Large complex shapes, ultimate satisfaction!"};
@@ -1 +1 @@
1
- "use strict";import{Dimensions}from 'react-native';import{POPIT_FIDGET_GAME_CONFIG as GAME_CONFIG,POPIT_FIDGET_ANIMATION_CONFIG as ANIMATION_CONFIG,POPIT_FIDGET_COLORS as COLORS,RAINBOW_COLORS,BUBBLE_COLORS}from "./PopitFidgetConstants.js";const{width,height}= Dimensions.get('window');export{GAME_CONFIG,ANIMATION_CONFIG,COLORS,BUBBLE_COLORS};export class PopitFidgetService{gameTimerRef = null;constructor(){}generateFidgetGrid(difficulty){const availableWidth = width * 0.85;const availableHeight = height * 0.6;const gridSize = GAME_CONFIG.GRID_SIZES[difficulty];const maxSize = Math.min(availableWidth / gridSize,availableHeight / gridSize);const bubbleSize = Math.max(45,Math.min(80,maxSize * 0.9));const spacing = bubbleSize * 1.1;const gridWidth =(gridSize - 1)* spacing + bubbleSize;const gridHeight =(gridSize - 1)* spacing + bubbleSize;const bubbles = [];for(let row = 0;row < gridSize;row++){bubbles[row] = [];for(let col = 0;col < gridSize;col++){const x = col * spacing + bubbleSize / 2;const y = row * spacing + bubbleSize / 2;bubbles[row][col] ={id:`${row}-${col}`,row,col,x,y,isPopped:false,color:this.getRainbowColorForPosition(row,gridSize),animationProgress:0};}}return{size:gridSize,bubbles,centerX:gridWidth / 2,centerY:gridHeight / 2,width:gridWidth,height:gridHeight};}getRainbowColorForPosition(row,totalRows){const colorIndex = Math.floor(row / totalRows * RAINBOW_COLORS.length);return RAINBOW_COLORS[colorIndex] || RAINBOW_COLORS[0];}checkAllBubblesPopped(grid){for(let row = 0;row < grid.size;row++){for(let col = 0;col < grid.size;col++){const bubble = grid.bubbles[row]?.[col];if(bubble && !bubble.isPopped){return false;}}}return true;}calculateCompletionPercentage(grid){let totalBubbles = 0;let poppedBubbles = 0;for(let row = 0;row < grid.size;row++){for(let col = 0;col < grid.size;col++){const bubble = grid.bubbles[row]?.[col];if(bubble){totalBubbles++;if(bubble.isPopped){poppedBubbles++;}}}}return totalBubbles > 0 ? poppedBubbles / totalBubbles * 100:0;}startGameTimer(duration,onTick,onComplete){this.stopGameTimer();let timeLeft = duration;this.gameTimerRef = setInterval(()=>{timeLeft -= 1;onTick(timeLeft);if(timeLeft <= 0){this.stopGameTimer();onComplete();}},1000);}stopGameTimer(){if(this.gameTimerRef){clearInterval(this.gameTimerRef);this.gameTimerRef = null;}}cleanup(){this.stopGameTimer();}}
1
+ "use strict";import{Dimensions as t}from"react-native";import{POPIT_FIDGET_GAME_CONFIG as e,POPIT_FIDGET_ANIMATION_CONFIG as r,POPIT_FIDGET_COLORS as o,RAINBOW_COLORS as i,BUBBLE_COLORS as s}from"./PopitFidgetConstants.js";const{width:n,height:l}=t.get("window");export{e as GAME_CONFIG,r as ANIMATION_CONFIG,o as COLORS,s as BUBBLE_COLORS};export class PopitFidgetService{gameTimerRef=null;constructor(){}generateFidgetGrid(t){const r=.85*n,o=.6*l,i=e.GRID_SIZES[t],s=Math.max(45,Math.min(80,.9*Math.min(r/i,o/i))),a=1.1*s,c=(i-1)*a+s,h=(i-1)*a+s,p=[];for(let t=0;i>t;t++){p[t]=[];for(let e=0;i>e;e++){const r=e*a+s/2,o=t*a+s/2;p[t][e]={id:`${t}-${e}`,row:t,col:e,x:r,y:o,isPopped:!1,color:this.getRainbowColorForPosition(t,i),animationProgress:0}}}return{size:i,bubbles:p,centerX:c/2,centerY:h/2,width:c,height:h}}getRainbowColorForPosition(t,e){const r=Math.floor(t/e*i.length);return i[r]||i[0]}checkAllBubblesPopped(t){for(let e=0;e<t.size;e++)for(let r=0;r<t.size;r++){const o=t.bubbles[e]?.[r];if(o&&!o.isPopped)return!1}return!0}calculateCompletionPercentage(t){let e=0,r=0;for(let o=0;o<t.size;o++)for(let i=0;i<t.size;i++){const s=t.bubbles[o]?.[i];s&&(e++,s.isPopped&&r++)}return e>0?r/e*100:0}startGameTimer(t,e,r){this.stopGameTimer();let o=t;this.gameTimerRef=setInterval(()=>{o-=1,e(o),o>0||(this.stopGameTimer(),r())},1e3)}stopGameTimer(){this.gameTimerRef&&(clearInterval(this.gameTimerRef),this.gameTimerRef=null)}cleanup(){this.stopGameTimer()}}
@@ -1 +1 @@
1
- "use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{immerMiddleware}from "../../services/UtilsService.js";export const usePopitFidgetStore = create()(subscribeWithSelector(immerMiddleware((set,get)=>({timeElapsed:0,isPlaying:false,gameOver:false,gameWon:false,fidgetGrid:null,bubblesPopped:0,totalBubbles:0,bubbleStates:{},startGame:_gameDuration =>{set(draft =>{draft.isPlaying = true;draft.gameOver = false;draft.gameWon = false;draft.timeElapsed = 0;draft.bubblesPopped = 0;});},stopGame:()=>{set(draft =>{draft.isPlaying = false;draft.gameOver = true;});},resetGame:()=>{set(draft =>{draft.timeElapsed = 0;draft.isPlaying = false;draft.gameOver = false;draft.gameWon = false;draft.fidgetGrid = null;draft.bubblesPopped = 0;draft.totalBubbles = 0;});},setFidgetGrid:grid =>{const totalCount = grid.size * grid.size;set(draft =>{draft.fidgetGrid = grid;draft.totalBubbles = totalCount;draft.bubblesPopped = 0;draft.bubbleStates ={};for(let row = 0;row < grid.size;row++){for(let col = 0;col < grid.size;col++){const bubble = grid.bubbles[row]?.[col];if(bubble){draft.bubbleStates[bubble.id] ={isPopped:bubble.isPopped || false,popTime:bubble.popTime};}}}});},popBubble:(row,col)=>{set(draft =>{if(!draft.fidgetGrid)return;const bubble = draft.fidgetGrid.bubbles[row]?.[col];if(!bubble)return;const bubbleState = draft.bubbleStates[bubble.id];if(bubbleState?.isPopped)return;draft.bubbleStates[bubble.id] ={isPopped:true,popTime:Date.now()};draft.bubblesPopped = draft.bubblesPopped + 1;});const state = get();if(state.isPlaying){get().checkGameWon();}},incrementTime:()=>{set(draft =>{draft.timeElapsed = draft.timeElapsed + 1;});},checkGameWon:()=>{const state = get();if(!state.fidgetGrid)return;let allPopped = true;for(let row = 0;row < state.fidgetGrid.size;row++){for(let col = 0;col < state.fidgetGrid.size;col++){const bubble = state.fidgetGrid.bubbles[row]?.[col];if(bubble){const bubbleState = state.bubbleStates[bubble.id];if(!bubbleState?.isPopped){allPopped = false;break;}}}if(!allPopped)break;}if(allPopped && state.isPlaying){set(draft =>{draft.isPlaying = false;draft.gameWon = true;draft.gameOver = true;});}}}))));
1
+ "use strict";import{create as e}from"zustand";import{subscribeWithSelector as t}from"zustand/middleware";import{immerMiddleware as o}from"../../services/UtilsService.js";export const usePopitFidgetStore=e()(t(o((e,t)=>({timeElapsed:0,isPlaying:!1,gameOver:!1,gameWon:!1,fidgetGrid:null,bubblesPopped:0,totalBubbles:0,bubbleStates:{},startGame:t=>{e(e=>{e.isPlaying=!0,e.gameOver=!1,e.gameWon=!1,e.timeElapsed=0,e.bubblesPopped=0})},stopGame:()=>{e(e=>{e.isPlaying=!1,e.gameOver=!0})},resetGame:()=>{e(e=>{e.timeElapsed=0,e.isPlaying=!1,e.gameOver=!1,e.gameWon=!1,e.fidgetGrid=null,e.bubblesPopped=0,e.totalBubbles=0})},setFidgetGrid:t=>{const o=t.size*t.size;e(e=>{e.fidgetGrid=t,e.totalBubbles=o,e.bubblesPopped=0,e.bubbleStates={};for(let o=0;o<t.size;o++)for(let r=0;r<t.size;r++){const i=t.bubbles[o]?.[r];i&&(e.bubbleStates[i.id]={isPopped:i.isPopped||!1,popTime:i.popTime})}})},popBubble:(o,r)=>{e(e=>{if(!e.fidgetGrid)return;const t=e.fidgetGrid.bubbles[o]?.[r];if(!t)return;const i=e.bubbleStates[t.id];i?.isPopped||(e.bubbleStates[t.id]={isPopped:!0,popTime:Date.now()},e.bubblesPopped=e.bubblesPopped+1)}),t().isPlaying&&t().checkGameWon()},incrementTime:()=>{e(e=>{e.timeElapsed=e.timeElapsed+1})},checkGameWon:()=>{const o=t();if(!o.fidgetGrid)return;let r=!0;for(let e=0;e<o.fidgetGrid.size;e++){for(let t=0;t<o.fidgetGrid.size;t++){const i=o.fidgetGrid.bubbles[e]?.[t];if(i){const e=o.bubbleStates[i.id];if(!e?.isPopped){r=!1;break}}}if(!r)break}r&&o.isPlaying&&e(e=>{e.isPlaying=!1,e.gameWon=!0,e.gameOver=!0})}}))));
@@ -1 +1 @@
1
- "use strict";import React,{useState,useCallback,useMemo}from 'react';import{View,TouchableOpacity}from 'react-native';import{Canvas,Circle,LinearGradient,vec,Shadow}from '@shopify/react-native-skia';import{playHaptic,HapticType}from "../../../services/HapticsService.js";import{usePopitFidgetStore}from "../PopitFidgetStore.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const BubbleComponent =({bubble,size,onPop,hapticEnabled = true,isPlaying})=>{const bubbleState = usePopitFidgetStore(state => state.bubbleStates[bubble.id]);const isPopped = bubbleState?.isPopped || false;const [isPressed,setIsPressed] = useState(false);const handlePop = useCallback(()=>{if(!isPlaying || isPopped)return;playHaptic(HapticType.MEDIUM,hapticEnabled || false);onPop();},[onPop,hapticEnabled,isPlaying,isPopped]);const handlePressIn = useCallback(()=>{if(!isPopped && isPlaying){setIsPressed(true);playHaptic(HapticType.LIGHT,hapticEnabled || false);}},[isPopped,isPlaying,hapticEnabled]);const handlePressOut = useCallback(()=>{setIsPressed(false);},[]);const bubbleStyle = useMemo(()=>({position:'absolute',left:bubble.x - size / 2,top:bubble.y - size / 2,width:size,height:size,transform:[{scale:isPressed ? 0.95:1}]}),[bubble.x,bubble.y,size,isPressed]);if(isPopped){return _jsx(View,{style:bubbleStyle,children:_jsxs(Canvas,{style:{width:size,height:size},children:[_jsx(Circle,{cx:size / 2,cy:size / 2,r:size / 2,color:bubble.color,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(size,size),colors:[`${bubble.color}60`,`${bubble.color}40`,`${bubble.color}30` ]})}),_jsx(Circle,{cx:size / 2,cy:size / 2 + 1,r:size / 2 - 6,color:bubble.color,children:_jsx(LinearGradient,{start:vec(size * 0.7,size * 0.7),end:vec(size * 0.3,size * 0.3),colors:['#FFFFFF30',`${bubble.color}80`,'#00000020' ]})}),_jsx(Circle,{cx:size / 2 + size * 0.15,cy:size / 2 + size * 0.2,r:size * 0.06,color:"#FFFFFF",opacity:0.6})]})});}return _jsxs(View,{style:bubbleStyle,children:[_jsxs(Canvas,{style:{width:size,height:size},children:[_jsx(Circle,{cx:size / 2,cy:size / 2,r:size / 2,color:bubble.color,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(size,size),colors:[`${bubble.color}E0`,`${bubble.color}A0`,`${bubble.color}80`]})}),_jsx(Circle,{cx:size / 2,cy:size / 2 + 2,r:size / 2 - 4,color:"rgba(0,0,0,0.15)"}),_jsxs(Circle,{cx:size / 2,cy:size / 2 - 1,r:size / 2 - 4,color:bubble.color,children:[_jsx(LinearGradient,{start:vec(size * 0.2,size * 0.2),end:vec(size * 0.8,size * 0.8),colors:['#FFFFFF','#FFFFFFA0',bubble.color,`${bubble.color}C0`,'#00000020']}),_jsx(Shadow,{dx:0,dy:3,blur:6,color:"rgba(0,0,0,0.2)"})]}),_jsx(Circle,{cx:size / 2 - size * 0.15,cy:size / 2 - size * 0.2,r:size * 0.12,color:"#FFFFFF",opacity:0.8,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(size * 0.24,size * 0.24),colors:['#FFFFFF','#FFFFFF80','#FFFFFF00']})}),_jsx(Circle,{cx:size / 2 + size * 0.1,cy:size / 2 - size * 0.15,r:size * 0.06,color:"#FFFFFF",opacity:0.6})]}),_jsx(TouchableOpacity,{style:{position:'absolute',top:0,left:0,width:size,height:size,backgroundColor:'transparent'},onPress:handlePop,onPressIn:handlePressIn,onPressOut:handlePressOut,activeOpacity:1,disabled:isPopped || !isPlaying,hitSlop:{top:10,bottom:10,left:10,right:10},delayPressIn:0,delayPressOut:0})]});};const MemoizedBubbleComponent = React.memo(BubbleComponent,(prevProps,nextProps)=>{return prevProps.bubble.id === nextProps.bubble.id && prevProps.bubble.x === nextProps.bubble.x && prevProps.bubble.y === nextProps.bubble.y && prevProps.bubble.color === nextProps.bubble.color && prevProps.size === nextProps.size && prevProps.hapticEnabled === nextProps.hapticEnabled && prevProps.isPlaying === nextProps.isPlaying;});export default MemoizedBubbleComponent;
1
+ "use strict";import r,{useState as t,useCallback as o,useMemo as e}from"react";import{View as c,TouchableOpacity as F}from"react-native";import{Canvas as s,Circle as i,LinearGradient as l,vec as a,Shadow as n}from"@shopify/react-native-skia";import{playHaptic as d,HapticType as h}from"../../../services/HapticsService.js";import{usePopitFidgetStore as p}from"../PopitFidgetStore.js";import{jsx as y,jsxs as m}from"react/jsx-runtime";const x=({bubble:r,size:x,onPop:b,hapticEnabled:f=!0,isPlaying:u})=>{const g=p(t=>t.bubbleStates[r.id]),P=g?.isPopped||!1,[j,v]=t(!1),w=o(()=>{u&&!P&&(d(h.MEDIUM,f||!1),b())},[b,f,u,P]),O=o(()=>{!P&&u&&(v(!0),d(h.LIGHT,f||!1))},[P,u,f]),S=o(()=>{v(!1)},[]),k=e(()=>({position:"absolute",left:r.x-x/2,top:r.y-x/2,width:x,height:x,transform:[{scale:j?.95:1}]}),[r.x,r.y,x,j]);return P?y(c,{style:k,children:m(s,{style:{width:x,height:x},children:[y(i,{cx:x/2,cy:x/2,r:x/2,color:r.color,children:y(l,{start:a(0,0),end:a(x,x),colors:[r.color+"60",r.color+"40",r.color+"30"]})}),y(i,{cx:x/2,cy:x/2+1,r:x/2-6,color:r.color,children:y(l,{start:a(.7*x,.7*x),end:a(.3*x,.3*x),colors:["#FFFFFF30",r.color+"80","#00000020"]})}),y(i,{cx:x/2+.15*x,cy:x/2+.2*x,r:.06*x,color:"#FFFFFF",opacity:.6})]})}):m(c,{style:k,children:[m(s,{style:{width:x,height:x},children:[y(i,{cx:x/2,cy:x/2,r:x/2,color:r.color,children:y(l,{start:a(0,0),end:a(x,x),colors:[r.color+"E0",r.color+"A0",r.color+"80"]})}),y(i,{cx:x/2,cy:x/2+2,r:x/2-4,color:"rgba(0,0,0,0.15)"}),m(i,{cx:x/2,cy:x/2-1,r:x/2-4,color:r.color,children:[y(l,{start:a(.2*x,.2*x),end:a(.8*x,.8*x),colors:["#FFFFFF","#FFFFFFA0",r.color,r.color+"C0","#00000020"]}),y(n,{dx:0,dy:3,blur:6,color:"rgba(0,0,0,0.2)"})]}),y(i,{cx:x/2-.15*x,cy:x/2-.2*x,r:.12*x,color:"#FFFFFF",opacity:.8,children:y(l,{start:a(0,0),end:a(.24*x,.24*x),colors:["#FFFFFF","#FFFFFF80","#FFFFFF00"]})}),y(i,{cx:x/2+.1*x,cy:x/2-.15*x,r:.06*x,color:"#FFFFFF",opacity:.6})]}),y(F,{style:{position:"absolute",top:0,left:0,width:x,height:x,backgroundColor:"transparent"},onPress:w,onPressIn:O,onPressOut:S,activeOpacity:1,disabled:P||!u,hitSlop:{top:10,bottom:10,left:10,right:10},delayPressIn:0,delayPressOut:0})]})},b=r.memo(x,(r,t)=>r.bubble.id===t.bubble.id&&r.bubble.x===t.bubble.x&&r.bubble.y===t.bubble.y&&r.bubble.color===t.bubble.color&&r.size===t.size&&r.hapticEnabled===t.hapticEnabled&&r.isPlaying===t.isPlaying);export default b;
@@ -1 +1 @@
1
- "use strict";import React,{useMemo,useCallback}from 'react';import{View,StyleSheet}from 'react-native';import{RAINBOW_COLORS}from "../PopitFidgetConstants.js";import BubbleComponent from "./BubbleComponent.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const FidgetGrid =({grid,bubbleSize,onBubblePop,hapticEnabled = true,isPlaying})=>{const padding = 20;const getRowColor = useCallback(rowIndex =>{const colorIndex = Math.floor(rowIndex /(grid.size - 1)*(RAINBOW_COLORS.length - 1));return RAINBOW_COLORS[colorIndex] || RAINBOW_COLORS[0];},[grid.size]);const containerDimensions = useMemo(()=>({width:grid.width + padding * 2,height:grid.height + padding * 2}),[grid.width,grid.height,padding]);const bubblePopHandlers = useMemo(()=>{const handlers ={};grid.bubbles.forEach((row,rowIndex)=>{row.forEach((bubble,colIndex)=>{if(bubble){handlers[bubble.id] =()=> onBubblePop(rowIndex,colIndex);}});});return handlers;},[grid.bubbles,onBubblePop]);return _jsxs(View,{style:[styles.container,containerDimensions],children:[_jsxs(View,{style:[styles.backgroundContainer,styles.fidget3D,{...containerDimensions,borderRadius:20,overflow:'hidden'}],children:[_jsx(View,{style:[styles.outerBorder,{...containerDimensions,borderRadius:20}]}),_jsx(View,{style:[styles.innerRecess,{position:'absolute',left:8,top:8,width:containerDimensions.width - 16,height:containerDimensions.height - 16,borderRadius:12,overflow:'hidden'}],children:grid.bubbles.map((_,rowIndex)=>{const rowHeight = grid.height / grid.size;const rowColor = getRowColor(rowIndex);return _jsx(View,{style:{position:'absolute',left:padding - 8,top:padding - 8 + rowIndex * rowHeight,width:grid.width,height:rowHeight,backgroundColor:`${rowColor}50`}},`row-bg-${rowIndex}`);})})]}),_jsx(View,{style:{position:'absolute',left:padding,top:padding},children:grid.bubbles.map((row,_rowIndex)=> row.map((bubble,_colIndex)=>{if(!bubble)return null;const bubbleHandler = bubblePopHandlers[bubble.id];if(!bubbleHandler)return null;return _jsx(BubbleComponent,{bubble:bubble,size:bubbleSize,onPop:bubbleHandler,hapticEnabled:hapticEnabled,isPlaying:isPlaying},bubble.id);}))})]});};const styles = StyleSheet.create({container:{position:'relative',padding:15},backgroundContainer:{position:'absolute'},fidget3D:{shadowColor:'#000',shadowOffset:{width:0,height:8},shadowOpacity:0.4,shadowRadius:12,elevation:12},outerBorder:{position:'absolute',backgroundColor:'#f0f0f0',borderWidth:2,borderTopColor:'#ffffff',borderLeftColor:'#ffffff',borderRightColor:'#cccccc',borderBottomColor:'#aaaaaa'},innerRecess:{backgroundColor:'#e8e8e8',borderWidth:1,borderTopColor:'#cccccc',borderLeftColor:'#cccccc',borderRightColor:'#ffffff',borderBottomColor:'#ffffff',shadowColor:'#000',shadowOffset:{width:0,height:-2},shadowOpacity:0.2,shadowRadius:4,elevation:-2}});const MemoizedFidgetGrid = React.memo(FidgetGrid,(prevProps,nextProps)=>{return prevProps.grid.size === nextProps.grid.size && prevProps.grid.width === nextProps.grid.width && prevProps.grid.height === nextProps.grid.height && prevProps.bubbleSize === nextProps.bubbleSize && prevProps.hapticEnabled === nextProps.hapticEnabled && prevProps.isPlaying === nextProps.isPlaying && prevProps.onBubblePop === nextProps.onBubblePop && JSON.stringify(prevProps.grid.bubbles.map(row => row.map(bubble => bubble ?{id:bubble.id,isPopped:bubble.isPopped}:null)))=== JSON.stringify(nextProps.grid.bubbles.map(row => row.map(bubble => bubble ?{id:bubble.id,isPopped:bubble.isPopped}:null)));});export default MemoizedFidgetGrid;
1
+ "use strict";import o,{useMemo as t,useCallback as e}from"react";import{View as r,StyleSheet as i}from"react-native";import{RAINBOW_COLORS as d}from"../PopitFidgetConstants.js";import s from"./BubbleComponent.js";import{jsx as l,jsxs as n}from"react/jsx-runtime";const a=({grid:o,bubbleSize:i,onBubblePop:a,hapticEnabled:c=!0,isPlaying:h})=>{const b=e(t=>{const e=Math.floor(t/(o.size-1)*(d.length-1));return d[e]||d[0]},[o.size]),u=t(()=>({width:o.width+40,height:o.height+40}),[o.width,o.height,20]),p=t(()=>{const t={};return o.bubbles.forEach((o,e)=>{o.forEach((o,r)=>{o&&(t[o.id]=()=>a(e,r))})}),t},[o.bubbles,a]);return n(r,{style:[f.container,u],children:[n(r,{style:[f.backgroundContainer,f.fidget3D,{...u,borderRadius:20,overflow:"hidden"}],children:[l(r,{style:[f.outerBorder,{...u,borderRadius:20}]}),l(r,{style:[f.innerRecess,{position:"absolute",left:8,top:8,width:u.width-16,height:u.height-16,borderRadius:12,overflow:"hidden"}],children:o.bubbles.map((t,e)=>{const i=o.height/o.size,d=b(e);return l(r,{style:{position:"absolute",left:12,top:12+e*i,width:o.width,height:i,backgroundColor:d+"50"}},"row-bg-"+e)})})]}),l(r,{style:{position:"absolute",left:20,top:20},children:o.bubbles.map((o,t)=>o.map((o,t)=>{if(!o)return null;const e=p[o.id];return e?l(s,{bubble:o,size:i,onPop:e,hapticEnabled:c,isPlaying:h},o.id):null}))})]})},f=i.create({container:{position:"relative",padding:15},backgroundContainer:{position:"absolute"},fidget3D:{shadowColor:"#000",shadowOffset:{width:0,height:8},shadowOpacity:.4,shadowRadius:12,elevation:12},outerBorder:{position:"absolute",backgroundColor:"#f0f0f0",borderWidth:2,borderTopColor:"#ffffff",borderLeftColor:"#ffffff",borderRightColor:"#cccccc",borderBottomColor:"#aaaaaa"},innerRecess:{backgroundColor:"#e8e8e8",borderWidth:1,borderTopColor:"#cccccc",borderLeftColor:"#cccccc",borderRightColor:"#ffffff",borderBottomColor:"#ffffff",shadowColor:"#000",shadowOffset:{width:0,height:-2},shadowOpacity:.2,shadowRadius:4,elevation:-2}}),c=o.memo(a,(o,t)=>o.grid.size===t.grid.size&&o.grid.width===t.grid.width&&o.grid.height===t.grid.height&&o.bubbleSize===t.bubbleSize&&o.hapticEnabled===t.hapticEnabled&&o.isPlaying===t.isPlaying&&o.onBubblePop===t.onBubblePop&&JSON.stringify(o.grid.bubbles.map(o=>o.map(o=>o?{id:o.id,isPopped:o.isPopped}:null)))===JSON.stringify(t.grid.bubbles.map(o=>o.map(o=>o?{id:o.id,isPopped:o.isPopped}:null))));export default c;
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{StyleSheet,View}from 'react-native';import{Canvas,LinearGradient,Rect,Circle,vec}from '@shopify/react-native-skia';import{RAINBOW_COLORS}from "../PopitFidgetConstants.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const GameBackground =({width,height})=>{const generateFloatingBubbles = React.useMemo(()=>{const bubbles = [];const bubbleCount = 15;for(let i = 0;i < bubbleCount;i++){const baseX = width / bubbleCount * i;const baseY = height / bubbleCount * i;const x = baseX + Math.sin(i * 0.5)* 30 + Math.random()* 60;const y = baseY + Math.cos(i * 0.7)* 40 + Math.random()* 80;const radius = 8 + Math.random()* 12;const colorIndex = i % RAINBOW_COLORS.length;const opacity = 0.2 + Math.sin(i)* 0.1;bubbles.push(_jsx(Circle,{cx:Math.max(radius,Math.min(width - radius,x)),cy:Math.max(radius,Math.min(height - radius,y)),r:radius,color:`${RAINBOW_COLORS[colorIndex]}${Math.floor(opacity * 255).toString(16).padStart(2,'0')}`},`floating-bubble-${i}`));}return bubbles;},[width,height]);return _jsx(View,{style:StyleSheet.absoluteFillObject,children:_jsxs(Canvas,{style:{width,height},children:[_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(0,0),end:vec(width,height),colors:[`${RAINBOW_COLORS[0]}40`,`${RAINBOW_COLORS[2]}35`,`${RAINBOW_COLORS[4]}40`,`${RAINBOW_COLORS[6]}35`,`${RAINBOW_COLORS[8]}40`,`${RAINBOW_COLORS[10]}35`,`${RAINBOW_COLORS[12]}40`,`${RAINBOW_COLORS[14]}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:[`${RAINBOW_COLORS[1]}25`,'transparent',`${RAINBOW_COLORS[5]}25`,'transparent',`${RAINBOW_COLORS[9]}25`,'transparent',`${RAINBOW_COLORS[13]}25`,'transparent']})}),_jsx(Rect,{x:0,y:0,width:width,height:height,children:_jsx(LinearGradient,{start:vec(width,0),end:vec(0,height),colors:[`${RAINBOW_COLORS[3]}20`,'transparent',`${RAINBOW_COLORS[7]}20`,'transparent',`${RAINBOW_COLORS[11]}20`,'transparent']})}),generateFloatingBubbles,_jsx(Circle,{cx:width * 0.1,cy:height * 0.15,r:40,color:`${RAINBOW_COLORS[0]}30`}),_jsx(Circle,{cx:width * 0.9,cy:height * 0.85,r:35,color:`${RAINBOW_COLORS[3]}30`}),_jsx(Circle,{cx:width * 0.85,cy:height * 0.2,r:30,color:`${RAINBOW_COLORS[8]}30`}),_jsx(Circle,{cx:width * 0.15,cy:height * 0.8,r:45,color:`${RAINBOW_COLORS[12]}30`}),_jsx(Circle,{cx:width * 0.5,cy:height * 0.1,r:25,color:`${RAINBOW_COLORS[14]}30`}),_jsx(Circle,{cx:width * 0.2,cy:height * 0.5,r:32,color:`${RAINBOW_COLORS[6]}30`}),_jsx(Circle,{cx:width * 0.8,cy:height * 0.6,r:28,color:`${RAINBOW_COLORS[10]}30`}),_jsx(Circle,{cx:width * 0.6,cy:height * 0.9,r:20,color:`${RAINBOW_COLORS[1]}30`}),_jsx(Circle,{cx:width * 0.3,cy:height * 0.25,r:24,color:`${RAINBOW_COLORS[4]}30`}),_jsx(Circle,{cx:width * 0.7,cy:height * 0.35,r:26,color:`${RAINBOW_COLORS[9]}30`}),Array.from({length:Math.floor(width / 40)},(_,i)=> _jsx(Rect,{x:i * 40,y:0,width:1,height:height,color:"rgba(0,0,0,0.02)"},`grid-v-${i}`)),Array.from({length:Math.floor(height / 40)},(_,i)=> _jsx(Rect,{x:0,y:i * 40,width:width,height:1,color:"rgba(0,0,0,0.02)"},`grid-h-${i}`))]})});};const MemoizedGameBackground = React.memo(GameBackground);export default MemoizedGameBackground;
1
+ "use strict";import r from"react";import{StyleSheet as t,View as c}from"react-native";import{Canvas as o,LinearGradient as a,Rect as h,Circle as e,vec as n}from"@shopify/react-native-skia";import{RAINBOW_COLORS as i}from"../PopitFidgetConstants.js";import{jsx as s,jsxs as l}from"react/jsx-runtime";const y=({width:y,height:x})=>{const d=r.useMemo(()=>{const r=[];for(let t=0;15>t;t++){const c=x/15*t,o=y/15*t+30*Math.sin(.5*t)+60*Math.random(),a=c+40*Math.cos(.7*t)+80*Math.random(),h=8+12*Math.random(),n=t%i.length,l=.2+.1*Math.sin(t);r.push(s(e,{cx:Math.max(h,Math.min(y-h,o)),cy:Math.max(h,Math.min(x-h,a)),r:h,color:`${i[n]}${Math.floor(255*l).toString(16).padStart(2,"0")}`},"floating-bubble-"+t))}return r},[y,x]);return s(c,{style:t.absoluteFillObject,children:l(o,{style:{width:y,height:x},children:[s(h,{x:0,y:0,width:y,height:x,children:s(a,{start:n(0,0),end:n(y,x),colors:[i[0]+"40",i[2]+"35",i[4]+"40",i[6]+"35",i[8]+"40",i[10]+"35",i[12]+"40",i[14]+"35"]})}),s(h,{x:0,y:0,width:y,height:x,children:s(a,{start:n(0,0),end:n(y/2,x/2),colors:[i[1]+"25","transparent",i[5]+"25","transparent",i[9]+"25","transparent",i[13]+"25","transparent"]})}),s(h,{x:0,y:0,width:y,height:x,children:s(a,{start:n(y,0),end:n(0,x),colors:[i[3]+"20","transparent",i[7]+"20","transparent",i[11]+"20","transparent"]})}),d,s(e,{cx:.1*y,cy:.15*x,r:40,color:i[0]+"30"}),s(e,{cx:.9*y,cy:.85*x,r:35,color:i[3]+"30"}),s(e,{cx:.85*y,cy:.2*x,r:30,color:i[8]+"30"}),s(e,{cx:.15*y,cy:.8*x,r:45,color:i[12]+"30"}),s(e,{cx:.5*y,cy:.1*x,r:25,color:i[14]+"30"}),s(e,{cx:.2*y,cy:.5*x,r:32,color:i[6]+"30"}),s(e,{cx:.8*y,cy:.6*x,r:28,color:i[10]+"30"}),s(e,{cx:.6*y,cy:.9*x,r:20,color:i[1]+"30"}),s(e,{cx:.3*y,cy:.25*x,r:24,color:i[4]+"30"}),s(e,{cx:.7*y,cy:.35*x,r:26,color:i[9]+"30"}),Array.from({length:Math.floor(y/40)},(r,t)=>s(h,{x:40*t,y:0,width:1,height:x,color:"rgba(0, 0, 0, 0.02)"},"grid-v-"+t)),Array.from({length:Math.floor(x/40)},(r,t)=>s(h,{x:0,y:40*t,width:y,height:1,color:"rgba(0, 0, 0, 0.02)"},"grid-h-"+t))]})})},x=r.memo(y);export default x;
@@ -1 +1 @@
1
- "use strict";import React from 'react';import{View,Text,StyleSheet}from 'react-native';import{ScoreBoardContainer}from "../../../helpers/index.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const ScoreBoard =({timeElapsed,offset = 0})=>{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(108,92,231,0.4)",borderColor:"rgba(139,92,246,0.3)",children:_jsx(View,{style:styles.scoreBoard,children:_jsxs(View,{style:styles.scoreSection,children:[_jsx(Text,{style:styles.scoreLabel,children:"Time Elapsed"}),_jsx(Text,{style:styles.timeValue,children:formatTime(timeElapsed)})]})})});};const MemoizedScoreBoard = React.memo(ScoreBoard);const styles = StyleSheet.create({scoreBoard:{flexDirection:'row',justifyContent:'center',alignItems:'center'},scoreSection:{alignItems:'center'},scoreLabel:{fontSize:16,fontWeight:'bold',color:'#ffffff',marginBottom:4},timeValue:{fontSize:25,fontWeight:'bold',color:'#1e1b4b'}});export default MemoizedScoreBoard;
1
+ "use strict";import e from"react";import{View as t,Text as r,StyleSheet as o}from"react-native";import{ScoreBoardContainer as i}from"../../../helpers/index.js";import{jsx as n,jsxs as s}from"react/jsx-runtime";const l=({timeElapsed:e,offset:o=0})=>n(i,{offset:o,backgroundColor:"rgba(108, 92, 231, 0.4)",borderColor:"rgba(139, 92, 246, 0.3)",children:n(t,{style:f.scoreBoard,children:s(t,{style:f.scoreSection,children:[n(r,{style:f.scoreLabel,children:"Time Elapsed"}),n(r,{style:f.timeValue,children:(e=>{const t=e%60;return`${Math.floor(e/60).toString().padStart(2,"0")}:${t.toString().padStart(2,"0")}`})(e)})]})})}),c=e.memo(l),f=o.create({scoreBoard:{flexDirection:"row",justifyContent:"center",alignItems:"center"},scoreSection:{alignItems:"center"},scoreLabel:{fontSize:16,fontWeight:"bold",color:"#ffffff",marginBottom:4},timeValue:{fontSize:25,fontWeight:"bold",color:"#1e1b4b"}});export default c;
@@ -1 +1 @@
1
- "use strict";export{default as BubbleComponent}from "./BubbleComponent.js";export{default as FidgetGrid}from "./FidgetGrid.js";export{default as ScoreBoard}from "./ScoreBoard.js";export{default as GameBackground}from "./GameBackground.js";
1
+ "use strict";export{default as BubbleComponent}from"./BubbleComponent.js";export{default as FidgetGrid}from"./FidgetGrid.js";export{default as ScoreBoard}from"./ScoreBoard.js";export{default as GameBackground}from"./GameBackground.js";
@@ -1 +1 @@
1
- "use strict";import React,{useEffect,useMemo,useCallback}from 'react';import{View,StyleSheet}from 'react-native';import{GestureHandlerRootView}from 'react-native-gesture-handler';import{useSlidingNumbersStore}from "./SlidingNumbersStore.js";import{SlidingNumbersService}from "./SlidingNumbersService.js";import{GameBackground,NumbersGrid,ScoreBoard}from "./components/index.js";import{GameControlButton,GameOverModal}from "../../helpers/index.js";import{GameSettingsModal}from "../../helpers/index.js";import{SLIDING_NUMBERS_COLORS}from "./SlidingNumbersConstants.js";import{GAME_IDS,DEFAULT_GAME_SETTINGS}from "../../services/UtilsService.js";import{calculateTimeBasedScore}from "../../services/ScoringService.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const SlidingNumbers = React.memo(({settings = DEFAULT_GAME_SETTINGS,onSettingsChange,onEndGame})=>{const score = useSlidingNumbersStore(state => state.score);const timeElapsed = useSlidingNumbersStore(state => state.timeElapsed);const isPlaying = useSlidingNumbersStore(state => state.isPlaying);const isCompleted = useSlidingNumbersStore(state => state.isCompleted);const gameReportedRef = React.useRef(false);const difficulty = settings?.difficulty || 'easy';const reportGameEnd = React.useCallback(status =>{if(onEndGame && !gameReportedRef.current){const expectedTimes ={easy:120,medium:180,hard:240};const expectedTime = expectedTimes[difficulty];const calculatedScore = status === 'win' ? calculateTimeBasedScore(timeElapsed,expectedTime):0;onEndGame({status,score:calculatedScore.toString()});gameReportedRef.current = true;}},[onEndGame,timeElapsed,difficulty]);const initializePuzzle = useSlidingNumbersStore(state => state.initializePuzzle);const shufflePuzzle = useSlidingNumbersStore(state => state.shufflePuzzle);const startGame = useSlidingNumbersStore(state => state.startGame);const stopGame = useSlidingNumbersStore(state => state.stopGame);const resetGame = useSlidingNumbersStore(state => state.resetGame);const decrementTime = useSlidingNumbersStore(state => state.decrementTime);const gameService = useMemo(()=> new SlidingNumbersService(),[]);const difficultySettings = useMemo(()=> gameService.getDifficultySettings(difficulty),[gameService,difficulty]);useEffect(()=>{initializePuzzle(difficultySettings.gridSize);},[difficulty,difficultySettings.gridSize,initializePuzzle]);useEffect(()=>{if(isPlaying){gameService.startTimer(()=>{decrementTime();});}else{gameService.stopTimer();}return()=>{gameService.stopTimer();};},[isPlaying,gameService,decrementTime]);useEffect(()=>{if(isCompleted && !gameReportedRef.current){reportGameEnd('win');}if(!isCompleted){gameReportedRef.current = false;}},[isCompleted,reportGameEnd]);useEffect(()=>{return()=>{gameService.cleanup();};},[gameService]);const handleStartGame = useCallback(()=>{gameReportedRef.current = false;shufflePuzzle();startGame();},[shufflePuzzle,startGame]);const handleStopGame = useCallback(()=>{reportGameEnd('cancel');stopGame();},[stopGame,reportGameEnd]);const handleResetGame = useCallback(()=>{resetGame();initializePuzzle(difficultySettings.gridSize);},[resetGame,initializePuzzle,difficultySettings.gridSize]);const gameControlButtonProps = useMemo(()=>({isPlaying,gameOver:isCompleted,onStartGame:handleStartGame,onStopGame:handleStopGame,startButtonText:"START GAME",stopButtonText:"STOP GAME",startButtonSubtext:"Shuffle and begin solving!",stopButtonSubtext:"End current game",startButtonColor:SLIDING_NUMBERS_COLORS.START_BUTTON,stopButtonColor:"#dc2626",startButtonBorderColor:SLIDING_NUMBERS_COLORS.BUTTON_BORDER,stopButtonBorderColor:"#f87171"}),[isPlaying,isCompleted,handleStartGame,handleStopGame]);const gameOverModalProps = useMemo(()=>({isVisible:isCompleted,score,onPlayAgain:handleResetGame,buttonText:"Play Again!",primaryColor:"rgba(245,158,11,0.5)",borderColor:"rgba(245,158,11,0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#f59e0b"}),[isCompleted,score,handleResetGame]);const gameSettingsModalProps = useMemo(()=>({gameId:GAME_IDS.SLIDING_NUMBERS,settings:settings || DEFAULT_GAME_SETTINGS,onSettingsChange}),[settings,onSettingsChange]);const offset = settings?.offset ?? 0;const dynamicStyles = useMemo(()=>({gameArea:{...styles.gameArea,marginTop:offset}}),[offset]);return _jsx(View,{style:styles.container,children:_jsx(GestureHandlerRootView,{children:_jsxs(GameBackground,{children:[_jsx(View,{style:dynamicStyles.gameArea,children:_jsx(NumbersGrid,{difficulty:difficulty})}),_jsx(ScoreBoard,{offset:offset}),_jsx(GameControlButton,{...gameControlButtonProps}),_jsx(GameOverModal,{...gameOverModalProps}),_jsx(GameSettingsModal,{...gameSettingsModalProps})]})})});});const styles = StyleSheet.create({container:{flex:1,backgroundColor:SLIDING_NUMBERS_COLORS.BACKGROUND},gameArea:{flex:1,justifyContent:'center',alignItems:'center'}});SlidingNumbers.displayName = 'SlidingNumbers';
1
+ "use strict";import t,{useEffect as r,useMemo as e,useCallback as o}from"react";import{View as n,StyleSheet as s}from"react-native";import{GestureHandlerRootView as i}from"react-native-gesture-handler";import{useSlidingNumbersStore as a}from"./SlidingNumbersStore.js";import{SlidingNumbersService as m}from"./SlidingNumbersService.js";import{GameBackground as l,NumbersGrid as f,ScoreBoard as c}from"./components/index.js";import{GameControlButton as u,GameOverModal as g}from"../../helpers/index.js";import{GameSettingsModal as d}from"../../helpers/index.js";import{SLIDING_NUMBERS_COLORS as p}from"./SlidingNumbersConstants.js";import{GAME_IDS as S,DEFAULT_GAME_SETTINGS as b}from"../../services/UtilsService.js";import{calculateTimeBasedScore as x}from"../../services/ScoringService.js";import{jsx as C,jsxs as j}from"react/jsx-runtime";export const SlidingNumbers=t.memo(({settings:s=b,onSettingsChange:B,onEndGame:y})=>{const v=a(t=>t.score),T=a(t=>t.timeElapsed),A=a(t=>t.isPlaying),N=a(t=>t.isCompleted),G=t.useRef(!1),E=s?.difficulty||"easy",P=t.useCallback(t=>{if(y&&!G.current){const r="win"===t?x(T,{easy:120,medium:180,hard:240}[E]):0;y({status:t,score:r.toString()}),G.current=!0}},[y,T,E]),w=a(t=>t.initializePuzzle),I=a(t=>t.shufflePuzzle),M=a(t=>t.startGame),O=a(t=>t.stopGame),k=a(t=>t.resetGame),R=a(t=>t.decrementTime),U=e(()=>new m,[]),V=e(()=>U.getDifficultySettings(E),[U,E]);r(()=>{w(V.gridSize)},[E,V.gridSize,w]),r(()=>(A?U.startTimer(()=>{R()}):U.stopTimer(),()=>{U.stopTimer()}),[A,U,R]),r(()=>{N&&!G.current&&P("win"),N||(G.current=!1)},[N,P]),r(()=>()=>{U.cleanup()},[U]);const q=o(()=>{G.current=!1,I(),M()},[I,M]),z=o(()=>{P("cancel"),O()},[O,P]),D=o(()=>{k(),w(V.gridSize)},[k,w,V.gridSize]),F=e(()=>({isPlaying:A,gameOver:N,onStartGame:q,onStopGame:z,startButtonText:"START GAME",stopButtonText:"STOP GAME",startButtonSubtext:"Shuffle and begin solving!",stopButtonSubtext:"End current game",startButtonColor:p.START_BUTTON,stopButtonColor:"#dc2626",startButtonBorderColor:p.BUTTON_BORDER,stopButtonBorderColor:"#f87171"}),[A,N,q,z]),H=e(()=>({isVisible:N,score:v,onPlayAgain:D,buttonText:"Play Again!",primaryColor:"rgba(245, 158, 11, 0.5)",borderColor:"rgba(245, 158, 11, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#f59e0b"}),[N,v,D]),J=e(()=>({gameId:S.SLIDING_NUMBERS,settings:s||b,onSettingsChange:B}),[s,B]),K=s?.offset??0,L=e(()=>({gameArea:{...h.gameArea,marginTop:K}}),[K]);return C(n,{style:h.container,children:C(i,{children:j(l,{children:[C(n,{style:L.gameArea,children:C(f,{difficulty:E})}),C(c,{offset:K}),C(u,{...F}),C(g,{...H}),C(d,{...J})]})})})});const h=s.create({container:{flex:1,backgroundColor:p.BACKGROUND},gameArea:{flex:1,justifyContent:"center",alignItems:"center"}});SlidingNumbers.displayName="SlidingNumbers";