react-native-games 1.1.0 → 1.2.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 (212) hide show
  1. package/README.md +58 -7
  2. package/lib/module/games/balloon-blaster/BalloonBlaster.js +1 -167
  3. package/lib/module/games/balloon-blaster/BalloonBlaster.js.map +1 -1
  4. package/lib/module/games/balloon-blaster/BalloonBlasterConstants.js +1 -182
  5. package/lib/module/games/balloon-blaster/BalloonBlasterConstants.js.map +1 -1
  6. package/lib/module/games/balloon-blaster/BalloonBlasterService.js +1 -318
  7. package/lib/module/games/balloon-blaster/BalloonBlasterStore.js +1 -183
  8. package/lib/module/games/balloon-blaster/components/BalloonComponent.js +1 -237
  9. package/lib/module/games/balloon-blaster/components/GameArea.js +1 -156
  10. package/lib/module/games/balloon-blaster/components/GameBackground.js +1 -476
  11. package/lib/module/games/balloon-blaster/components/ScoreBoard.js +1 -112
  12. package/lib/module/games/balloon-blaster/components/ScoreBoard.js.map +1 -1
  13. package/lib/module/games/balloon-blaster/components/index.js +1 -7
  14. package/lib/module/games/candy-crush/CandyCrush.js +1 -131
  15. package/lib/module/games/candy-crush/CandyCrush.js.map +1 -1
  16. package/lib/module/games/candy-crush/CandyCrushConstants.js +1 -125
  17. package/lib/module/games/candy-crush/CandyCrushConstants.js.map +1 -1
  18. package/lib/module/games/candy-crush/CandyCrushService.js +1 -370
  19. package/lib/module/games/candy-crush/CandyCrushStore.js +1 -303
  20. package/lib/module/games/candy-crush/components/CandyItem.js +1 -191
  21. package/lib/module/games/candy-crush/components/GameBackground.js +1 -85
  22. package/lib/module/games/candy-crush/components/GameGrid.js +1 -314
  23. package/lib/module/games/candy-crush/components/ScoreBoard.js +1 -79
  24. package/lib/module/games/candy-crush/components/index.js +1 -7
  25. package/lib/module/games/candy-crush/index.js +1 -6
  26. package/lib/module/games/colors-sort/ColorsSort.js +1 -143
  27. package/lib/module/games/colors-sort/ColorsSort.js.map +1 -1
  28. package/lib/module/games/colors-sort/ColorsSortConstants.js +1 -72
  29. package/lib/module/games/colors-sort/ColorsSortConstants.js.map +1 -1
  30. package/lib/module/games/colors-sort/ColorsSortService.js +1 -255
  31. package/lib/module/games/colors-sort/ColorsSortStore.js +1 -257
  32. package/lib/module/games/colors-sort/ColorsSortStore.js.map +1 -1
  33. package/lib/module/games/colors-sort/components/ColorContainer.js +1 -140
  34. package/lib/module/games/colors-sort/components/GameBackground.js +1 -135
  35. package/lib/module/games/colors-sort/components/ScoreBoard.js +1 -70
  36. package/lib/module/games/colors-sort/components/index.js +1 -6
  37. package/lib/module/games/dino-jump/DinoJump.js +1 -209
  38. package/lib/module/games/dino-jump/DinoJump.js.map +1 -1
  39. package/lib/module/games/dino-jump/DinoJumpConstants.js +1 -189
  40. package/lib/module/games/dino-jump/DinoJumpConstants.js.map +1 -1
  41. package/lib/module/games/dino-jump/DinoJumpService.js +1 -270
  42. package/lib/module/games/dino-jump/DinoJumpStore.js +1 -381
  43. package/lib/module/games/dino-jump/components/DinoSprite.js +1 -418
  44. package/lib/module/games/dino-jump/components/DinoSprite.js.map +1 -1
  45. package/lib/module/games/dino-jump/components/GameArea.js +1 -68
  46. package/lib/module/games/dino-jump/components/GameBackground.js +1 -444
  47. package/lib/module/games/dino-jump/components/ObstacleSprite.js +1 -306
  48. package/lib/module/games/dino-jump/components/ScoreBoard.js +1 -105
  49. package/lib/module/games/dino-jump/components/ScoreBoard.js.map +1 -1
  50. package/lib/module/games/dino-jump/components/StarSprite.js +1 -45
  51. package/lib/module/games/dino-jump/components/index.js +1 -9
  52. package/lib/module/games/flappy-bird/FlappyBird.js +1 -126
  53. package/lib/module/games/flappy-bird/FlappyBird.js.map +1 -1
  54. package/lib/module/games/flappy-bird/FlappyBirdConstants.js +1 -90
  55. package/lib/module/games/flappy-bird/FlappyBirdConstants.js.map +1 -1
  56. package/lib/module/games/flappy-bird/FlappyBirdStore.js +1 -300
  57. package/lib/module/games/flappy-bird/components/Bird.js +1 -87
  58. package/lib/module/games/flappy-bird/components/GameArea.js +1 -87
  59. package/lib/module/games/flappy-bird/components/GameBackground.js +1 -79
  60. package/lib/module/games/flappy-bird/components/Pipes.js +1 -172
  61. package/lib/module/games/flappy-bird/components/ScoreBoard.js +1 -73
  62. package/lib/module/games/flappy-bird/components/index.js +1 -8
  63. package/lib/module/games/fruit-merger/FruitMerger.js +1 -120
  64. package/lib/module/games/fruit-merger/FruitMerger.js.map +1 -1
  65. package/lib/module/games/fruit-merger/FruitMergerConstants.js +1 -119
  66. package/lib/module/games/fruit-merger/FruitMergerConstants.js.map +1 -1
  67. package/lib/module/games/fruit-merger/FruitMergerService.js +1 -13
  68. package/lib/module/games/fruit-merger/FruitMergerStore.js +1 -315
  69. package/lib/module/games/fruit-merger/components/FruitItem.js +1 -102
  70. package/lib/module/games/fruit-merger/components/GameArea.js +1 -103
  71. package/lib/module/games/fruit-merger/components/GameBackground.js +1 -498
  72. package/lib/module/games/fruit-merger/components/ScoreBoard.js +1 -58
  73. package/lib/module/games/fruit-merger/components/index.js +1 -7
  74. package/lib/module/games/fruit-ninja/FruitNinja.js +1 -134
  75. package/lib/module/games/fruit-ninja/FruitNinja.js.map +1 -1
  76. package/lib/module/games/fruit-ninja/FruitNinjaConstants.js +1 -148
  77. package/lib/module/games/fruit-ninja/FruitNinjaConstants.js.map +1 -1
  78. package/lib/module/games/fruit-ninja/FruitNinjaService.js +1 -311
  79. package/lib/module/games/fruit-ninja/FruitNinjaStore.js +1 -191
  80. package/lib/module/games/fruit-ninja/FruitNinjaStore.js.map +1 -1
  81. package/lib/module/games/fruit-ninja/components/FruitComponent.js +1 -99
  82. package/lib/module/games/fruit-ninja/components/GameArea.js +1 -215
  83. package/lib/module/games/fruit-ninja/components/GameBackground.js +1 -1267
  84. package/lib/module/games/fruit-ninja/components/ScoreBoard.js +1 -92
  85. package/lib/module/games/fruit-ninja/components/ScoreBoard.js.map +1 -1
  86. package/lib/module/games/fruit-ninja/components/index.js +1 -7
  87. package/lib/module/games/game-2048/Game2048.js +1 -149
  88. package/lib/module/games/game-2048/Game2048.js.map +1 -1
  89. package/lib/module/games/game-2048/Game2048Constants.js +1 -263
  90. package/lib/module/games/game-2048/Game2048Constants.js.map +1 -1
  91. package/lib/module/games/game-2048/Game2048Service.js +1 -457
  92. package/lib/module/games/game-2048/Game2048Store.js +1 -236
  93. package/lib/module/games/game-2048/components/GameBackground.js +1 -247
  94. package/lib/module/games/game-2048/components/GameGrid.js +1 -139
  95. package/lib/module/games/game-2048/components/GameTile.js +1 -72
  96. package/lib/module/games/game-2048/components/ScoreBoard.js +1 -52
  97. package/lib/module/games/game-2048/components/index.js +1 -7
  98. package/lib/module/games/maze-runner/MazeRunner.js +1 -267
  99. package/lib/module/games/maze-runner/MazeRunner.js.map +1 -1
  100. package/lib/module/games/maze-runner/MazeRunnerConstants.js +1 -100
  101. package/lib/module/games/maze-runner/MazeRunnerConstants.js.map +1 -1
  102. package/lib/module/games/maze-runner/MazeRunnerService.js +1 -586
  103. package/lib/module/games/maze-runner/components/EnhancedBallComponent.js +1 -150
  104. package/lib/module/games/maze-runner/components/EnhancedGameArea.js +1 -370
  105. package/lib/module/games/maze-runner/components/GameBackground.js +1 -175
  106. package/lib/module/games/maze-runner/components/ScoreBoard.js +1 -61
  107. package/lib/module/games/maze-runner/components/SkiaPipeComponent.js +1 -209
  108. package/lib/module/games/maze-runner/components/StaticGameBackground.js +1 -169
  109. package/lib/module/games/maze-runner/components/WallComponent.js +1 -91
  110. package/lib/module/games/maze-runner/components/index.js +1 -8
  111. package/lib/module/games/popit-fidget/PopitFidget.js +1 -285
  112. package/lib/module/games/popit-fidget/PopitFidget.js.map +1 -1
  113. package/lib/module/games/popit-fidget/PopitFidgetConstants.js +1 -113
  114. package/lib/module/games/popit-fidget/PopitFidgetConstants.js.map +1 -1
  115. package/lib/module/games/popit-fidget/PopitFidgetService.js +1 -132
  116. package/lib/module/games/popit-fidget/PopitFidgetStore.js +1 -125
  117. package/lib/module/games/popit-fidget/components/BubbleComponent.js +1 -198
  118. package/lib/module/games/popit-fidget/components/FidgetGrid.js +1 -165
  119. package/lib/module/games/popit-fidget/components/GameBackground.js +1 -177
  120. package/lib/module/games/popit-fidget/components/ScoreBoard.js +1 -61
  121. package/lib/module/games/popit-fidget/components/index.js +1 -7
  122. package/lib/module/games/sliding-numbers/SlidingNumbers.js +1 -159
  123. package/lib/module/games/sliding-numbers/SlidingNumbers.js.map +1 -1
  124. package/lib/module/games/sliding-numbers/SlidingNumbersConstants.js +1 -207
  125. package/lib/module/games/sliding-numbers/SlidingNumbersConstants.js.map +1 -1
  126. package/lib/module/games/sliding-numbers/SlidingNumbersService.js +1 -248
  127. package/lib/module/games/sliding-numbers/SlidingNumbersStore.js +1 -274
  128. package/lib/module/games/sliding-numbers/components/GameBackground.js +1 -259
  129. package/lib/module/games/sliding-numbers/components/NumbersGrid.js +1 -174
  130. package/lib/module/games/sliding-numbers/components/NumbersTile.js +1 -116
  131. package/lib/module/games/sliding-numbers/components/ScoreBoard.js +1 -64
  132. package/lib/module/games/sliding-numbers/components/index.js +1 -7
  133. package/lib/module/games/snake/Snake.js +1 -189
  134. package/lib/module/games/snake/Snake.js.map +1 -1
  135. package/lib/module/games/snake/SnakeConstants.js +1 -138
  136. package/lib/module/games/snake/SnakeConstants.js.map +1 -1
  137. package/lib/module/games/snake/SnakeService.js +1 -148
  138. package/lib/module/games/snake/SnakeStore.js +1 -182
  139. package/lib/module/games/snake/components/GameBackground.js +1 -221
  140. package/lib/module/games/snake/components/GameGrid.js +1 -153
  141. package/lib/module/games/snake/components/ScoreBoard.js +1 -51
  142. package/lib/module/games/snake/components/index.js +1 -6
  143. package/lib/module/games/snake/index.js +1 -6
  144. package/lib/module/games/space-fighter/SpaceFighter.js +1 -165
  145. package/lib/module/games/space-fighter/SpaceFighter.js.map +1 -1
  146. package/lib/module/games/space-fighter/SpaceFighterConstants.js +1 -108
  147. package/lib/module/games/space-fighter/SpaceFighterConstants.js.map +1 -1
  148. package/lib/module/games/space-fighter/SpaceFighterService.js +1 -326
  149. package/lib/module/games/space-fighter/SpaceFighterStore.js +1 -209
  150. package/lib/module/games/space-fighter/components/AsteroidComponent.js +1 -113
  151. package/lib/module/games/space-fighter/components/GameArea.js +1 -289
  152. package/lib/module/games/space-fighter/components/GameBackground.js +1 -239
  153. package/lib/module/games/space-fighter/components/ScoreBoard.js +1 -136
  154. package/lib/module/games/space-fighter/components/Spacecraft3D.js +1 -202
  155. package/lib/module/games/space-fighter/components/SpacecraftPath.js +1 -52
  156. package/lib/module/games/space-fighter/components/index.js +1 -9
  157. package/lib/module/games/whack-a-mole/WhackAMole.js +1 -270
  158. package/lib/module/games/whack-a-mole/WhackAMole.js.map +1 -1
  159. package/lib/module/games/whack-a-mole/WhackAMoleConstants.js +1 -115
  160. package/lib/module/games/whack-a-mole/WhackAMoleConstants.js.map +1 -1
  161. package/lib/module/games/whack-a-mole/WhackAMoleService.js +1 -120
  162. package/lib/module/games/whack-a-mole/WhackAMoleStore.js +1 -172
  163. package/lib/module/games/whack-a-mole/components/GameBackground.js +1 -477
  164. package/lib/module/games/whack-a-mole/components/GameGrid.js +1 -97
  165. package/lib/module/games/whack-a-mole/components/GameHole.js +1 -196
  166. package/lib/module/games/whack-a-mole/components/MoleCharacter.js +1 -241
  167. package/lib/module/games/whack-a-mole/components/ScoreBoard.js +1 -67
  168. package/lib/module/games/whack-a-mole/components/ScoreBoard.js.map +1 -1
  169. package/lib/module/games/whack-a-mole/components/index.js +1 -8
  170. package/lib/module/helpers/AnimationFrame.js +1 -120
  171. package/lib/module/helpers/AnimationTracker.js +1 -89
  172. package/lib/module/helpers/ErrorHandler.js +1 -269
  173. package/lib/module/helpers/GameControlButton.js +1 -219
  174. package/lib/module/helpers/GameOverModal.js +1 -144
  175. package/lib/module/helpers/GameOverModal.js.map +1 -1
  176. package/lib/module/helpers/GameSettingsModal.js +1 -287
  177. package/lib/module/helpers/ParticleBlast.js +1 -134
  178. package/lib/module/helpers/ScoreBoardContainer.js +1 -34
  179. package/lib/module/helpers/index.js +1 -12
  180. package/lib/module/index.js +1 -22
  181. package/lib/module/services/GamesConstants.js +1 -178
  182. package/lib/module/services/GamesService.js +1 -112
  183. package/lib/module/services/GamesService.js.map +1 -1
  184. package/lib/module/services/HapticsService.js +1 -77
  185. package/lib/module/services/SoundsService.js +1 -302
  186. package/lib/module/services/UtilsService.js +1 -32
  187. package/lib/typescript/src/games/balloon-blaster/BalloonBlaster.d.ts.map +1 -1
  188. package/lib/typescript/src/games/balloon-blaster/BalloonBlasterConstants.d.ts +1 -1
  189. package/lib/typescript/src/games/balloon-blaster/components/ScoreBoard.d.ts.map +1 -1
  190. package/lib/typescript/src/games/candy-crush/CandyCrushConstants.d.ts +7 -7
  191. package/lib/typescript/src/games/colors-sort/ColorsSort.d.ts.map +1 -1
  192. package/lib/typescript/src/games/colors-sort/ColorsSortStore.d.ts.map +1 -1
  193. package/lib/typescript/src/games/dino-jump/DinoJump.d.ts.map +1 -1
  194. package/lib/typescript/src/games/dino-jump/components/DinoSprite.d.ts.map +1 -1
  195. package/lib/typescript/src/games/flappy-bird/FlappyBird.d.ts.map +1 -1
  196. package/lib/typescript/src/games/flappy-bird/FlappyBirdConstants.d.ts.map +1 -1
  197. package/lib/typescript/src/games/fruit-merger/FruitMerger.d.ts.map +1 -1
  198. package/lib/typescript/src/games/fruit-merger/FruitMergerConstants.d.ts.map +1 -1
  199. package/lib/typescript/src/games/fruit-ninja/FruitNinja.d.ts.map +1 -1
  200. package/lib/typescript/src/games/fruit-ninja/components/ScoreBoard.d.ts.map +1 -1
  201. package/lib/typescript/src/games/game-2048/Game2048.d.ts.map +1 -1
  202. package/lib/typescript/src/games/maze-runner/MazeRunner.d.ts.map +1 -1
  203. package/lib/typescript/src/games/popit-fidget/PopitFidget.d.ts.map +1 -1
  204. package/lib/typescript/src/games/sliding-numbers/SlidingNumbers.d.ts.map +1 -1
  205. package/lib/typescript/src/games/space-fighter/SpaceFighter.d.ts.map +1 -1
  206. package/lib/typescript/src/games/whack-a-mole/WhackAMole.d.ts.map +1 -1
  207. package/lib/typescript/src/games/whack-a-mole/WhackAMoleConstants.d.ts +1 -1
  208. package/lib/typescript/src/games/whack-a-mole/components/ScoreBoard.d.ts.map +1 -1
  209. package/lib/typescript/src/helpers/GameOverModal.d.ts +3 -0
  210. package/lib/typescript/src/helpers/GameOverModal.d.ts.map +1 -1
  211. package/lib/typescript/src/services/GamesConstants.d.ts +7 -7
  212. package/package.json +2 -2
@@ -1,270 +1 @@
1
- "use strict";
2
-
3
- import { DINO_JUMP_CONSTANTS, DINO_JUMP_GAME_CONFIG, getGroundY } from "./DinoJumpConstants.js";
4
- export class DinoJumpService {
5
- gameTimer = null;
6
- physicsAnimationId = null;
7
- obstacleTimer = null;
8
- cloudTimer = null;
9
- starTimer = null;
10
- lastFrameTime = 0;
11
- obstacleId = 0;
12
- cloudId = 0;
13
- starId = 0;
14
- isPhysicsRunning = false;
15
- constructor() {
16
- this.lastFrameTime = performance.now();
17
- }
18
-
19
- // Get difficulty settings
20
- getDifficultySettings(difficulty) {
21
- return {
22
- speed: DINO_JUMP_CONSTANTS.gameSpeed[difficulty],
23
- baseScore: DINO_JUMP_CONSTANTS.baseScore[difficulty],
24
- scoreMultiplier: DINO_JUMP_CONSTANTS.scoreMultiplier[difficulty],
25
- obstacleSpawnRate: difficulty === 'easy' ? 3000 : difficulty === 'medium' ? 2000 : 1500
26
- };
27
- }
28
-
29
- // Start game timer
30
- startTimer(decrementTimeCallback) {
31
- this.stopTimer();
32
- this.gameTimer = setInterval(() => {
33
- decrementTimeCallback();
34
- }, 1000);
35
- }
36
-
37
- // Stop game timer
38
- stopTimer() {
39
- if (this.gameTimer) {
40
- clearInterval(this.gameTimer);
41
- this.gameTimer = null;
42
- }
43
- }
44
-
45
- // Start physics loop
46
- startPhysicsLoop(updateDinosaur, updateObstacles, updateClouds, updateStars, updateGround, updateScore, updateSpeed, checkCollisions, stopGame) {
47
- this.stopPhysicsLoop();
48
- this.isPhysicsRunning = true;
49
- this.lastFrameTime = performance.now();
50
- const physicsLoop = currentTime => {
51
- if (!this.isPhysicsRunning) return;
52
- const deltaTime = Math.min((currentTime - this.lastFrameTime) / 1000, 0.016); // Cap at 60fps
53
- this.lastFrameTime = currentTime;
54
- try {
55
- // Update game objects
56
- updateDinosaur(deltaTime);
57
- updateObstacles(deltaTime);
58
- updateClouds(deltaTime);
59
- updateStars(deltaTime);
60
- updateGround(deltaTime);
61
-
62
- // Update score (distance-based)
63
- updateScore(1);
64
- updateSpeed();
65
-
66
- // Check for collisions (collision handler will stop game if lives reach 0)
67
- checkCollisions();
68
-
69
- // Continue loop using requestAnimationFrame for better performance
70
- if (this.isPhysicsRunning) {
71
- this.physicsAnimationId = requestAnimationFrame(physicsLoop);
72
- }
73
- } catch (error) {
74
- console.error('Physics loop error:', error);
75
- this.stopPhysicsLoop();
76
- stopGame();
77
- }
78
- };
79
- this.physicsAnimationId = requestAnimationFrame(physicsLoop);
80
- }
81
-
82
- // Stop physics loop
83
- stopPhysicsLoop() {
84
- this.isPhysicsRunning = false;
85
- if (this.physicsAnimationId) {
86
- cancelAnimationFrame(this.physicsAnimationId);
87
- this.physicsAnimationId = null;
88
- }
89
- }
90
-
91
- // Start obstacle spawning
92
- startObstacleSpawning(addObstacle, difficulty, getOffset) {
93
- this.stopObstacleSpawning();
94
- const settings = this.getDifficultySettings(difficulty);
95
- const spawnObstacle = () => {
96
- const offset = getOffset();
97
- const obstacle = this.createRandomObstacle(offset);
98
- addObstacle(obstacle);
99
-
100
- // Schedule next obstacle
101
- const nextSpawnTime = settings.obstacleSpawnRate + Math.random() * 1000; // Add randomness
102
- this.obstacleTimer = setTimeout(spawnObstacle, nextSpawnTime);
103
- };
104
-
105
- // Start spawning after initial delay
106
- this.obstacleTimer = setTimeout(spawnObstacle, 2000);
107
- }
108
-
109
- // Stop obstacle spawning
110
- stopObstacleSpawning() {
111
- if (this.obstacleTimer) {
112
- clearTimeout(this.obstacleTimer);
113
- this.obstacleTimer = null;
114
- }
115
- }
116
-
117
- // Start cloud spawning
118
- startCloudSpawning(addCloud) {
119
- this.stopCloudSpawning();
120
- const spawnCloud = () => {
121
- const cloud = this.createRandomCloud();
122
- addCloud(cloud);
123
-
124
- // Schedule next cloud (clouds spawn less frequently)
125
- const nextSpawnTime = 5000 + Math.random() * 5000; // 5-10 seconds
126
- this.cloudTimer = setTimeout(spawnCloud, nextSpawnTime);
127
- };
128
-
129
- // Start spawning clouds
130
- this.cloudTimer = setTimeout(spawnCloud, 3000);
131
- }
132
-
133
- // Stop cloud spawning
134
- stopCloudSpawning() {
135
- if (this.cloudTimer) {
136
- clearTimeout(this.cloudTimer);
137
- this.cloudTimer = null;
138
- }
139
- }
140
-
141
- // Start star spawning
142
- startStarSpawning(addStar, getOffset) {
143
- this.stopStarSpawning();
144
- const spawnStar = () => {
145
- const offset = getOffset();
146
- const star = this.createRandomStar(offset);
147
- addStar(star);
148
-
149
- // Schedule next star (stars spawn occasionally)
150
- const nextSpawnTime = 8000 + Math.random() * 7000; // 8-15 seconds
151
- this.starTimer = setTimeout(spawnStar, nextSpawnTime);
152
- };
153
-
154
- // Start spawning stars after initial delay
155
- this.starTimer = setTimeout(spawnStar, 10000);
156
- }
157
-
158
- // Stop star spawning
159
- stopStarSpawning() {
160
- if (this.starTimer) {
161
- clearTimeout(this.starTimer);
162
- this.starTimer = null;
163
- }
164
- }
165
-
166
- // Create random obstacle (needs offset parameter)
167
- createRandomObstacle(offset = 0) {
168
- const types = ['cactus_small', 'cactus_large'];
169
- const type = types[Math.floor(Math.random() * types.length)];
170
- let width, height, y;
171
- const groundY = getGroundY(offset);
172
- switch (type) {
173
- case 'cactus_small':
174
- width = 22;
175
- height = 45;
176
- y = groundY - height - 22; // Exactly on top of ground
177
- break;
178
- case 'cactus_large':
179
- width = 32;
180
- height = 65;
181
- y = groundY - height - 22; // Exactly on top of ground
182
- break;
183
- }
184
- return {
185
- id: `obstacle_${this.obstacleId++}`,
186
- type,
187
- x: DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,
188
- y,
189
- width,
190
- height,
191
- speed: 5 // Base speed, will be modified by game speed
192
- };
193
- }
194
-
195
- // Create random cloud
196
- createRandomCloud() {
197
- return {
198
- id: `cloud_${this.cloudId++}`,
199
- x: DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,
200
- y: 50 + Math.random() * 80,
201
- // Sky height
202
- width: 46 + Math.random() * 30,
203
- height: 14 + Math.random() * 10,
204
- speed: 1 + Math.random() * 2 // Slow moving
205
- };
206
- }
207
-
208
- // Create random star (mushroom) (needs offset parameter)
209
- createRandomStar(offset = 0) {
210
- const groundY = getGroundY(offset);
211
- const width = 45;
212
- const height = 45;
213
- return {
214
- id: `star_${this.starId++}`,
215
- x: DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,
216
- y: groundY - height - 5,
217
- // Same as obstacles - sits on ground
218
- width,
219
- height,
220
- speed: 5 // Same speed as obstacles
221
- };
222
- }
223
-
224
- // Format time for display
225
- formatTime(timeInSeconds) {
226
- const minutes = Math.floor(timeInSeconds / 60);
227
- const seconds = timeInSeconds % 60;
228
- return `${minutes}:${seconds.toString().padStart(2, '0')}`;
229
- }
230
-
231
- // Calculate final score
232
- calculateFinalScore(score, timeElapsed, difficulty) {
233
- const settings = this.getDifficultySettings(difficulty);
234
- const timeBonus = Math.max(0, 300 - timeElapsed) * settings.scoreMultiplier;
235
- return score + timeBonus;
236
- }
237
-
238
- // Check if new high score
239
- isNewHighScore(currentScore, previousHighScore) {
240
- return currentScore > previousHighScore;
241
- }
242
-
243
- // Generate random ground pattern for visual variety
244
- generateGroundPattern() {
245
- const pattern = [];
246
- for (let i = 0; i < 20; i++) {
247
- pattern.push(Math.random() * 3); // Random height variation
248
- }
249
- return pattern;
250
- }
251
-
252
- // Cleanup all timers and intervals
253
- cleanup() {
254
- this.stopTimer();
255
- this.stopPhysicsLoop();
256
- this.stopObstacleSpawning();
257
- this.stopCloudSpawning();
258
- this.stopStarSpawning();
259
- }
260
-
261
- // Reset service state
262
- reset() {
263
- this.cleanup();
264
- this.obstacleId = 0;
265
- this.cloudId = 0;
266
- this.starId = 0;
267
- this.lastFrameTime = performance.now();
268
- }
269
- }
270
- //# sourceMappingURL=DinoJumpService.js.map
1
+ "use strict";import{DINO_JUMP_CONSTANTS,DINO_JUMP_GAME_CONFIG,getGroundY}from "./DinoJumpConstants.js";export class DinoJumpService{gameTimer = null;physicsAnimationId = null;obstacleTimer = null;cloudTimer = null;starTimer = null;lastFrameTime = 0;obstacleId = 0;cloudId = 0;starId = 0;isPhysicsRunning = false;constructor(){this.lastFrameTime = performance.now();}getDifficultySettings(difficulty){return{speed:DINO_JUMP_CONSTANTS.gameSpeed[difficulty],baseScore:DINO_JUMP_CONSTANTS.baseScore[difficulty],scoreMultiplier:DINO_JUMP_CONSTANTS.scoreMultiplier[difficulty],obstacleSpawnRate:difficulty === 'easy' ? 3000:difficulty === 'medium' ? 2000:1500};}startTimer(decrementTimeCallback){this.stopTimer();this.gameTimer = setInterval(()=>{decrementTimeCallback();},1000);}stopTimer(){if(this.gameTimer){clearInterval(this.gameTimer);this.gameTimer = null;}}startPhysicsLoop(updateDinosaur,updateObstacles,updateClouds,updateStars,updateGround,updateScore,updateSpeed,checkCollisions,stopGame){this.stopPhysicsLoop();this.isPhysicsRunning = true;this.lastFrameTime = performance.now();const physicsLoop = currentTime =>{if(!this.isPhysicsRunning)return;const deltaTime = Math.min((currentTime - this.lastFrameTime)/ 1000,0.016);this.lastFrameTime = currentTime;try{updateDinosaur(deltaTime);updateObstacles(deltaTime);updateClouds(deltaTime);updateStars(deltaTime);updateGround(deltaTime);updateScore(1);updateSpeed();checkCollisions();if(this.isPhysicsRunning){this.physicsAnimationId = requestAnimationFrame(physicsLoop);}}catch(error){console.error('Physics loop error:',error);this.stopPhysicsLoop();stopGame();}};this.physicsAnimationId = requestAnimationFrame(physicsLoop);}stopPhysicsLoop(){this.isPhysicsRunning = false;if(this.physicsAnimationId){cancelAnimationFrame(this.physicsAnimationId);this.physicsAnimationId = null;}}startObstacleSpawning(addObstacle,difficulty,getOffset){this.stopObstacleSpawning();const settings = this.getDifficultySettings(difficulty);const spawnObstacle =()=>{const offset = getOffset();const obstacle = this.createRandomObstacle(offset);addObstacle(obstacle);const nextSpawnTime = settings.obstacleSpawnRate + Math.random()* 1000;this.obstacleTimer = setTimeout(spawnObstacle,nextSpawnTime);};this.obstacleTimer = setTimeout(spawnObstacle,2000);}stopObstacleSpawning(){if(this.obstacleTimer){clearTimeout(this.obstacleTimer);this.obstacleTimer = null;}}startCloudSpawning(addCloud){this.stopCloudSpawning();const spawnCloud =()=>{const cloud = this.createRandomCloud();addCloud(cloud);const nextSpawnTime = 5000 + Math.random()* 5000;this.cloudTimer = setTimeout(spawnCloud,nextSpawnTime);};this.cloudTimer = setTimeout(spawnCloud,3000);}stopCloudSpawning(){if(this.cloudTimer){clearTimeout(this.cloudTimer);this.cloudTimer = null;}}startStarSpawning(addStar,getOffset){this.stopStarSpawning();const spawnStar =()=>{const offset = getOffset();const star = this.createRandomStar(offset);addStar(star);const nextSpawnTime = 8000 + Math.random()* 7000;this.starTimer = setTimeout(spawnStar,nextSpawnTime);};this.starTimer = setTimeout(spawnStar,10000);}stopStarSpawning(){if(this.starTimer){clearTimeout(this.starTimer);this.starTimer = null;}}createRandomObstacle(offset = 0){const types = ['cactus_small','cactus_large'];const type = types[Math.floor(Math.random()* types.length)];let width,height,y;const groundY = getGroundY(offset);switch(type){case 'cactus_small':width = 22;height = 45;y = groundY - height - 22;break;case 'cactus_large':width = 32;height = 65;y = groundY - height - 22;break;}return{id:`obstacle_${this.obstacleId++}`,type,x:DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,y,width,height,speed:5};}createRandomCloud(){return{id:`cloud_${this.cloudId++}`,x:DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,y:50 + Math.random()* 80,width:46 + Math.random()* 30,height:14 + Math.random()* 10,speed:1 + Math.random()* 2};}createRandomStar(offset = 0){const groundY = getGroundY(offset);const width = 45;const height = 45;return{id:`star_${this.starId++}`,x:DINO_JUMP_GAME_CONFIG.SCREEN_WIDTH + 50,y:groundY - height - 5,width,height,speed:5};}formatTime(timeInSeconds){const minutes = Math.floor(timeInSeconds / 60);const seconds = timeInSeconds % 60;return `${minutes}:${seconds.toString().padStart(2,'0')}`;}calculateFinalScore(score,timeElapsed,difficulty){const settings = this.getDifficultySettings(difficulty);const timeBonus = Math.max(0,300 - timeElapsed)* settings.scoreMultiplier;return score + timeBonus;}isNewHighScore(currentScore,previousHighScore){return currentScore > previousHighScore;}generateGroundPattern(){const pattern = [];for(let i = 0;i < 20;i++){pattern.push(Math.random()* 3);}return pattern;}cleanup(){this.stopTimer();this.stopPhysicsLoop();this.stopObstacleSpawning();this.stopCloudSpawning();this.stopStarSpawning();}reset(){this.cleanup();this.obstacleId = 0;this.cloudId = 0;this.starId = 0;this.lastFrameTime = performance.now();}}
@@ -1,381 +1 @@
1
- "use strict";
2
-
3
- import { create } from 'zustand';
4
- import { subscribeWithSelector } from 'zustand/middleware';
5
- import { immerMiddleware } from "../../services/UtilsService.js";
6
- import { DINO_JUMP_CONSTANTS, DINO_JUMP_GAME_CONFIG, getGroundY } from "./DinoJumpConstants.js";
7
- import { playSound, GAME_SOUNDS } from "../../services/SoundsService.js";
8
- import { playHaptic, HapticType } from "../../services/HapticsService.js";
9
- export const useDinoJumpStore = create()(subscribeWithSelector(immerMiddleware((set, get) => ({
10
- // Initial state
11
- isPlaying: false,
12
- isGameOver: false,
13
- isPaused: false,
14
- // Dinosaur initial state
15
- dinosaurY: 47,
16
- // Ground level (dinosaur height)
17
- dinosaurVelocityY: 0,
18
- dinosaurState: 'running',
19
- isJumping: false,
20
- isDucking: false,
21
- // Game objects
22
- obstacles: [],
23
- clouds: [],
24
- stars: [],
25
- collisionBlasts: [],
26
- // Game metrics
27
- score: 0,
28
- distance: 0,
29
- speed: 3,
30
- // Initial speed
31
- timeLeft: 300,
32
- // 5 minutes
33
- timeElapsed: 0,
34
- startTime: null,
35
- lives: 3,
36
- // Start with 3 lives
37
-
38
- // Ground animation
39
- groundOffset: 0,
40
- // Device offset
41
- offset: 0,
42
- // Set offset
43
- setOffset: offset => {
44
- set(state => {
45
- state.offset = offset;
46
- });
47
- },
48
- // Start the game
49
- startGame: () => {
50
- const currentState = get();
51
- if (currentState.isPlaying) return; // Prevent multiple starts
52
-
53
- set(state => {
54
- state.isPlaying = true;
55
- state.isGameOver = false;
56
- state.isPaused = false;
57
- state.startTime = Date.now();
58
- state.dinosaurState = 'running';
59
- });
60
-
61
- // Auto-jump test removed - physics working correctly
62
- },
63
- // Stop the game
64
- stopGame: () => {
65
- const state = get();
66
- // Reset the game instead of showing game over modal
67
- state.resetGame();
68
- },
69
- // Reset the game
70
- resetGame: () => {
71
- set(state => {
72
- state.isPlaying = false;
73
- state.isGameOver = false;
74
- state.isPaused = false;
75
- state.dinosaurY = 47;
76
- state.dinosaurVelocityY = 0;
77
- state.dinosaurState = 'running';
78
- state.isJumping = false;
79
- state.isDucking = false;
80
- state.obstacles = [];
81
- state.clouds = [];
82
- state.score = 0;
83
- state.distance = 0;
84
- state.speed = 3;
85
- state.timeLeft = 300;
86
- state.timeElapsed = 0;
87
- state.startTime = null;
88
- state.lives = 3; // Reset lives to 3
89
- state.groundOffset = 0;
90
- });
91
- },
92
- // Pause the game
93
- pauseGame: () => {
94
- set(state => {
95
- state.isPaused = true;
96
- });
97
- },
98
- // Resume the game
99
- resumeGame: () => {
100
- set(state => {
101
- state.isPaused = false;
102
- });
103
- },
104
- // Dinosaur jump
105
- jump: () => {
106
- try {
107
- const state = get();
108
- if (!state || !state.isPlaying || state.isGameOver || state.isPaused || state.isJumping) {
109
- return;
110
- }
111
- set(state => {
112
- state.isJumping = true;
113
- state.dinosaurVelocityY = DINO_JUMP_CONSTANTS.jumpForce; // Chrome dino jump force
114
- state.dinosaurState = 'jumping';
115
- });
116
- } catch (error) {
117
- console.error('Jump action error:', error);
118
- }
119
- },
120
- // Chrome dino doesn't have ducking - removed duck functionality
121
-
122
- // Update dinosaur physics
123
- updateDinosaur: _deltaTime => {
124
- const state = get();
125
- if (!state.isPlaying || state.isGameOver) return;
126
- set(state => {
127
- if (state.isJumping) {
128
- // Apply Chrome dino gravity (positive gravity pulls down)
129
- state.dinosaurVelocityY += DINO_JUMP_CONSTANTS.gravity;
130
- state.dinosaurY += state.dinosaurVelocityY;
131
-
132
- // Check if landed (Y decreases when going up, increases when going down)
133
- if (state.dinosaurY >= 47) {
134
- // Ground level
135
- state.dinosaurY = 47;
136
- state.dinosaurVelocityY = 0;
137
- state.isJumping = false;
138
- state.dinosaurState = 'running'; // Chrome dino only runs or jumps
139
- }
140
- }
141
- });
142
- },
143
- // Add obstacle
144
- addObstacle: obstacle => {
145
- set(state => {
146
- // Limit obstacles to prevent memory issues and layout crashes
147
- if (state.obstacles.length < 8) {
148
- state.obstacles.push(obstacle);
149
- }
150
- });
151
- },
152
- // Remove obstacle
153
- removeObstacle: id => {
154
- set(state => {
155
- state.obstacles = state.obstacles.filter(obstacle => obstacle.id !== id);
156
- });
157
- },
158
- // Update obstacles
159
- updateObstacles: _deltaTime => {
160
- const state = get();
161
- if (!state.isPlaying || state.isGameOver) return;
162
- set(state => {
163
- state.obstacles.forEach(obstacle => {
164
- obstacle.x -= obstacle.speed;
165
- });
166
-
167
- // Remove obstacles that are off-screen
168
- state.obstacles = state.obstacles.filter(obstacle => obstacle.x > -obstacle.width);
169
- });
170
- },
171
- // Add cloud
172
- addCloud: cloud => {
173
- set(state => {
174
- state.clouds.push(cloud);
175
- });
176
- },
177
- // Add star
178
- addStar: star => {
179
- set(state => {
180
- state.stars.push(star);
181
- });
182
- },
183
- // Update stars
184
- updateStars: _deltaTime => {
185
- const state = get();
186
- if (!state.isPlaying || state.isGameOver) return;
187
- set(state => {
188
- state.stars.forEach(star => {
189
- star.x -= star.speed;
190
- });
191
-
192
- // Remove stars that are off-screen
193
- state.stars = state.stars.filter(star => star.x > -star.width);
194
- });
195
- },
196
- // Update clouds
197
- updateClouds: _deltaTime => {
198
- const state = get();
199
- if (!state.isPlaying || state.isGameOver) return;
200
- set(state => {
201
- state.clouds.forEach(cloud => {
202
- cloud.x -= cloud.speed;
203
- });
204
-
205
- // Remove clouds that are off-screen and add new ones
206
- state.clouds = state.clouds.filter(cloud => cloud.x > -cloud.width);
207
- });
208
- },
209
- // Remove collision blast after animation
210
- removeCollisionBlast: id => {
211
- set(state => {
212
- state.collisionBlasts = state.collisionBlasts.filter(blast => blast.id !== id);
213
- });
214
- },
215
- // Check collisions
216
- checkCollisions: settings => {
217
- const state = get();
218
- const dinosaurX = DINO_JUMP_GAME_CONFIG.DINOSAUR_X;
219
- const dinosaurWidth = DINO_JUMP_GAME_CONFIG.DINOSAUR_WIDTH;
220
- const dinosaurHeight = state.isDucking ? 30 : DINO_JUMP_GAME_CONFIG.DINOSAUR_HEIGHT;
221
-
222
- // Convert dinosaur game-space Y to screen-space Y
223
- // dinosaurY: 47 = ground, 0 = high in air
224
- // Screen Y: calculated from top of screen
225
- const groundY = getGroundY(state.offset);
226
- const dinosaurScreenY = groundY - dinosaurHeight - 2 - (47 - state.dinosaurY);
227
-
228
- // Check star collisions (collect stars for extra life)
229
- for (const star of state.stars) {
230
- if (dinosaurX < star.x + star.width && dinosaurX + dinosaurWidth > star.x && dinosaurScreenY < star.y + star.height && dinosaurScreenY + dinosaurHeight > star.y) {
231
- // Star collected - add life
232
- set(state => {
233
- state.lives = Math.min(state.lives + 1, 5); // Max 5 lives
234
- state.score += 50; // Bonus points
235
-
236
- // Remove the star that was collected
237
- state.stars = state.stars.filter(s => s.id !== star.id);
238
- });
239
-
240
- // Play collect sound and haptic
241
- playSound(GAME_SOUNDS.DINO_JUMP.COLLECT, settings.enableSounds);
242
- playHaptic(HapticType.SUCCESS, settings.enableHaptics);
243
- }
244
- }
245
-
246
- // Check obstacle collisions
247
- for (const obstacle of state.obstacles) {
248
- // Simple AABB collision detection with screen coordinates
249
- if (dinosaurX < obstacle.x + obstacle.width && dinosaurX + dinosaurWidth > obstacle.x && dinosaurScreenY < obstacle.y + obstacle.height && dinosaurScreenY + dinosaurHeight > obstacle.y) {
250
- // Collision detected - decrease life
251
- set(state => {
252
- state.lives -= 1;
253
-
254
- // Create collision blast marker at collision point
255
- const collisionX = obstacle.x + obstacle.width / 2;
256
- const collisionY = obstacle.y + obstacle.height / 2;
257
- state.collisionBlasts.push({
258
- id: `blast_${Date.now()}`,
259
- x: collisionX,
260
- y: collisionY
261
- });
262
-
263
- // Remove the obstacle that was hit
264
- state.obstacles = state.obstacles.filter(obs => obs.id !== obstacle.id);
265
-
266
- // Check if game over (no lives left)
267
- if (state.lives <= 0) {
268
- state.isGameOver = true;
269
- state.isPlaying = false;
270
- state.dinosaurState = 'dead';
271
-
272
- // Play game over sound
273
- playSound(GAME_SOUNDS.DINO_JUMP.GAME_OVER, settings.enableSounds);
274
- playHaptic(HapticType.ERROR, settings.enableHaptics);
275
- } else {
276
- // Play hit sound for losing a life
277
- playSound(GAME_SOUNDS.DINO_JUMP.HIT, settings.enableSounds);
278
- playHaptic(HapticType.HEAVY, settings.enableHaptics);
279
- }
280
- });
281
- return true; // Collision detected
282
- }
283
- }
284
- return false;
285
- },
286
- // Update score
287
- updateScore: points => {
288
- set(state => {
289
- state.score += points;
290
- state.distance += 1;
291
- });
292
- },
293
- // Update game speed
294
- updateSpeed: () => {
295
- set(state => {
296
- // Increase speed based on distance
297
- const speedIncrease = Math.floor(state.distance / 100) * 0.5;
298
- state.speed = Math.min(3 + speedIncrease, 10); // Cap at 10
299
- });
300
- },
301
- // Update ground animation
302
- updateGround: _deltaTime => {
303
- const state = get();
304
- if (!state.isPlaying || state.isGameOver) return;
305
- set(state => {
306
- state.groundOffset += state.speed;
307
- if (state.groundOffset >= 100) {
308
- state.groundOffset = 0;
309
- }
310
- });
311
- },
312
- // Decrement time
313
- decrementTime: () => {
314
- set(state => {
315
- if (state.timeLeft > 0) {
316
- state.timeLeft--;
317
- if (state.startTime) {
318
- state.timeElapsed = Math.floor((Date.now() - state.startTime) / 1000);
319
- }
320
- } else {
321
- state.isPlaying = false;
322
- state.isGameOver = true;
323
- state.startTime = null;
324
- }
325
- });
326
- },
327
- // Initialize game with difficulty
328
- initializeGame: difficulty => {
329
- set(state => {
330
- // Set initial speed based on difficulty
331
- const speeds = {
332
- easy: 3,
333
- medium: 5,
334
- hard: 7
335
- };
336
- state.speed = speeds[difficulty];
337
-
338
- // Set time limit based on difficulty
339
- const timeLimits = DINO_JUMP_CONSTANTS.timeLimit;
340
- const timeLimit = timeLimits[difficulty];
341
-
342
- // Reset all game state
343
- state.isPlaying = false;
344
- state.isGameOver = false;
345
- state.isPaused = false;
346
- state.dinosaurY = 47;
347
- state.dinosaurVelocityY = 0;
348
- state.dinosaurState = 'running';
349
- state.isJumping = false;
350
- state.isDucking = false;
351
- state.obstacles = [];
352
- state.clouds = [];
353
- state.score = 0;
354
- state.distance = 0;
355
- state.timeLeft = timeLimit;
356
- state.timeElapsed = 0;
357
- state.startTime = null;
358
- state.groundOffset = 0;
359
- });
360
- }
361
- }))));
362
-
363
- // Optimized selectors for performance - prevent unnecessary re-renders
364
- export const useIsPlaying = () => useDinoJumpStore(state => state.isPlaying);
365
- export const useIsGameOver = () => useDinoJumpStore(state => state.isGameOver);
366
- export const useIsPaused = () => useDinoJumpStore(state => state.isPaused);
367
- export const useDinosaurY = () => useDinoJumpStore(state => state.dinosaurY);
368
- export const useDinosaurVelocityY = () => useDinoJumpStore(state => state.dinosaurVelocityY);
369
- export const useDinosaurStateValue = () => useDinoJumpStore(state => state.dinosaurState);
370
- export const useIsJumping = () => useDinoJumpStore(state => state.isJumping);
371
- export const useIsDucking = () => useDinoJumpStore(state => state.isDucking);
372
- export const useScore = () => useDinoJumpStore(state => state.score);
373
- export const useTimeLeft = () => useDinoJumpStore(state => state.timeLeft);
374
- export const useLives = () => useDinoJumpStore(state => state.lives);
375
-
376
- // Return all obstacles - filtering happens in component for stability
377
- export const useObstacles = () => useDinoJumpStore(state => state.obstacles);
378
- export const useClouds = () => useDinoJumpStore(state => state.clouds);
379
- export const useGroundOffset = () => useDinoJumpStore(state => state.groundOffset);
380
- export const useStars = () => useDinoJumpStore(state => state.stars);
381
- //# sourceMappingURL=DinoJumpStore.js.map
1
+ "use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{immerMiddleware}from "../../services/UtilsService.js";import{DINO_JUMP_CONSTANTS,DINO_JUMP_GAME_CONFIG,getGroundY}from "./DinoJumpConstants.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";export const useDinoJumpStore = create()(subscribeWithSelector(immerMiddleware((set,get)=>({isPlaying:false,isGameOver:false,isPaused:false,dinosaurY:47,dinosaurVelocityY:0,dinosaurState:'running',isJumping:false,isDucking:false,obstacles:[],clouds:[],stars:[],collisionBlasts:[],score:0,distance:0,speed:3,timeLeft:300,timeElapsed:0,startTime:null,lives:3,groundOffset:0,offset:0,setOffset:offset =>{set(state =>{state.offset = offset;});},startGame:()=>{const currentState = get();if(currentState.isPlaying)return;set(state =>{state.isPlaying = true;state.isGameOver = false;state.isPaused = false;state.startTime = Date.now();state.dinosaurState = 'running';});},stopGame:()=>{const state = get();state.resetGame();},resetGame:()=>{set(state =>{state.isPlaying = false;state.isGameOver = false;state.isPaused = false;state.dinosaurY = 47;state.dinosaurVelocityY = 0;state.dinosaurState = 'running';state.isJumping = false;state.isDucking = false;state.obstacles = [];state.clouds = [];state.score = 0;state.distance = 0;state.speed = 3;state.timeLeft = 300;state.timeElapsed = 0;state.startTime = null;state.lives = 3;state.groundOffset = 0;});},pauseGame:()=>{set(state =>{state.isPaused = true;});},resumeGame:()=>{set(state =>{state.isPaused = false;});},jump:()=>{try{const state = get();if(!state || !state.isPlaying || state.isGameOver || state.isPaused || state.isJumping){return;}set(state =>{state.isJumping = true;state.dinosaurVelocityY = DINO_JUMP_CONSTANTS.jumpForce;state.dinosaurState = 'jumping';});}catch(error){console.error('Jump action error:',error);}},updateDinosaur:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{if(state.isJumping){state.dinosaurVelocityY += DINO_JUMP_CONSTANTS.gravity;state.dinosaurY += state.dinosaurVelocityY;if(state.dinosaurY >= 47){state.dinosaurY = 47;state.dinosaurVelocityY = 0;state.isJumping = false;state.dinosaurState = 'running';}}});},addObstacle:obstacle =>{set(state =>{if(state.obstacles.length < 8){state.obstacles.push(obstacle);}});},removeObstacle:id =>{set(state =>{state.obstacles = state.obstacles.filter(obstacle => obstacle.id !== id);});},updateObstacles:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.obstacles.forEach(obstacle =>{obstacle.x -= obstacle.speed;});state.obstacles = state.obstacles.filter(obstacle => obstacle.x > -obstacle.width);});},addCloud:cloud =>{set(state =>{state.clouds.push(cloud);});},addStar:star =>{set(state =>{state.stars.push(star);});},updateStars:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.stars.forEach(star =>{star.x -= star.speed;});state.stars = state.stars.filter(star => star.x > -star.width);});},updateClouds:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.clouds.forEach(cloud =>{cloud.x -= cloud.speed;});state.clouds = state.clouds.filter(cloud => cloud.x > -cloud.width);});},removeCollisionBlast:id =>{set(state =>{state.collisionBlasts = state.collisionBlasts.filter(blast => blast.id !== id);});},checkCollisions:settings =>{const state = get();const dinosaurX = DINO_JUMP_GAME_CONFIG.DINOSAUR_X;const dinosaurWidth = DINO_JUMP_GAME_CONFIG.DINOSAUR_WIDTH;const dinosaurHeight = state.isDucking ? 30:DINO_JUMP_GAME_CONFIG.DINOSAUR_HEIGHT;const groundY = getGroundY(state.offset);const dinosaurScreenY = groundY - dinosaurHeight - 2 -(47 - state.dinosaurY);for(const star of state.stars){if(dinosaurX < star.x + star.width && dinosaurX + dinosaurWidth > star.x && dinosaurScreenY < star.y + star.height && dinosaurScreenY + dinosaurHeight > star.y){set(state =>{state.lives = Math.min(state.lives + 1,5);state.score += 50;state.stars = state.stars.filter(s => s.id !== star.id);});playSound(GAME_SOUNDS.DINO_JUMP.COLLECT,settings.enableSounds);playHaptic(HapticType.SUCCESS,settings.enableHaptics);}}for(const obstacle of state.obstacles){if(dinosaurX < obstacle.x + obstacle.width && dinosaurX + dinosaurWidth > obstacle.x && dinosaurScreenY < obstacle.y + obstacle.height && dinosaurScreenY + dinosaurHeight > obstacle.y){set(state =>{state.lives -= 1;const collisionX = obstacle.x + obstacle.width / 2;const collisionY = obstacle.y + obstacle.height / 2;state.collisionBlasts.push({id:`blast_${Date.now()}`,x:collisionX,y:collisionY});state.obstacles = state.obstacles.filter(obs => obs.id !== obstacle.id);if(state.lives <= 0){state.isGameOver = true;state.isPlaying = false;state.dinosaurState = 'dead';playSound(GAME_SOUNDS.DINO_JUMP.GAME_OVER,settings.enableSounds);playHaptic(HapticType.ERROR,settings.enableHaptics);}else{playSound(GAME_SOUNDS.DINO_JUMP.HIT,settings.enableSounds);playHaptic(HapticType.HEAVY,settings.enableHaptics);}});return true;}}return false;},updateScore:points =>{set(state =>{state.score += points;state.distance += 1;});},updateSpeed:()=>{set(state =>{const speedIncrease = Math.floor(state.distance / 100)* 0.5;state.speed = Math.min(3 + speedIncrease,10);});},updateGround:_deltaTime =>{const state = get();if(!state.isPlaying || state.isGameOver)return;set(state =>{state.groundOffset += state.speed;if(state.groundOffset >= 100){state.groundOffset = 0;}});},decrementTime:()=>{set(state =>{if(state.timeLeft > 0){state.timeLeft--;if(state.startTime){state.timeElapsed = Math.floor((Date.now()- state.startTime)/ 1000);}}else{state.isPlaying = false;state.isGameOver = true;state.startTime = null;}});},initializeGame:difficulty =>{set(state =>{const speeds ={easy:3,medium:5,hard:7};state.speed = speeds[difficulty];const timeLimits = DINO_JUMP_CONSTANTS.timeLimit;const timeLimit = timeLimits[difficulty];state.isPlaying = false;state.isGameOver = false;state.isPaused = false;state.dinosaurY = 47;state.dinosaurVelocityY = 0;state.dinosaurState = 'running';state.isJumping = false;state.isDucking = false;state.obstacles = [];state.clouds = [];state.score = 0;state.distance = 0;state.timeLeft = timeLimit;state.timeElapsed = 0;state.startTime = null;state.groundOffset = 0;});}}))));export const useIsPlaying =()=> useDinoJumpStore(state => state.isPlaying);export const useIsGameOver =()=> useDinoJumpStore(state => state.isGameOver);export const useIsPaused =()=> useDinoJumpStore(state => state.isPaused);export const useDinosaurY =()=> useDinoJumpStore(state => state.dinosaurY);export const useDinosaurVelocityY =()=> useDinoJumpStore(state => state.dinosaurVelocityY);export const useDinosaurStateValue =()=> useDinoJumpStore(state => state.dinosaurState);export const useIsJumping =()=> useDinoJumpStore(state => state.isJumping);export const useIsDucking =()=> useDinoJumpStore(state => state.isDucking);export const useScore =()=> useDinoJumpStore(state => state.score);export const useTimeLeft =()=> useDinoJumpStore(state => state.timeLeft);export const useLives =()=> useDinoJumpStore(state => state.lives);export const useObstacles =()=> useDinoJumpStore(state => state.obstacles);export const useClouds =()=> useDinoJumpStore(state => state.clouds);export const useGroundOffset =()=> useDinoJumpStore(state => state.groundOffset);export const useStars =()=> useDinoJumpStore(state => state.stars);