react-native-games 1.0.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 +80 -368
  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,457 +1 @@
1
- "use strict";
2
-
3
- import { Animated } from 'react-native';
4
- import { GAME_2048_SETTINGS, GAME_2048_GESTURES, GAME_CONFIG } from "./Game2048Constants.js";
5
-
6
- // Types
7
-
8
- export class Game2048Service {
9
- // Get difficulty settings
10
- getDifficultySettings(difficulty) {
11
- return GAME_2048_SETTINGS.DIFFICULTY_SETTINGS[difficulty];
12
- }
13
-
14
- // Calculate score based on tile value and difficulty
15
- calculateMergeScore(tileValue, difficulty) {
16
- const multiplier = GAME_2048_SETTINGS.SCORE_MULTIPLIER[difficulty];
17
- return tileValue * multiplier;
18
- }
19
-
20
- // Format time for display
21
- formatTime(seconds) {
22
- const minutes = Math.floor(seconds / 60);
23
- const remainingSeconds = seconds % 60;
24
- return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
25
- }
26
-
27
- // Detect swipe direction from gesture data
28
- detectSwipeDirection(startX, startY, endX, endY, velocity) {
29
- const deltaX = endX - startX;
30
- const deltaY = endY - startY;
31
- const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
32
-
33
- // Check minimum distance
34
- if (distance < GAME_2048_GESTURES.MIN_SWIPE_DISTANCE) {
35
- return null;
36
- }
37
-
38
- // Check velocity if provided
39
- if (velocity) {
40
- const velocityMagnitude = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
41
- if (velocityMagnitude < GAME_2048_GESTURES.MIN_VELOCITY) {
42
- return null;
43
- }
44
- }
45
-
46
- // Determine primary direction
47
- const absDeltaX = Math.abs(deltaX);
48
- const absDeltaY = Math.abs(deltaY);
49
- if (absDeltaX > absDeltaY) {
50
- // Horizontal swipe
51
- return deltaX > 0 ? 'right' : 'left';
52
- } else {
53
- // Vertical swipe
54
- return deltaY > 0 ? 'down' : 'up';
55
- }
56
- }
57
-
58
- // Calculate tile position for animations
59
- calculateTilePosition(row, col, gridSize, containerSize) {
60
- const tileSize = GAME_2048_SETTINGS.TILE_SIZE;
61
- const margin = GAME_2048_SETTINGS.TILE_MARGIN;
62
-
63
- // Calculate total grid size
64
- const totalGridSize = tileSize * gridSize + margin * (gridSize + 1);
65
-
66
- // Calculate starting position to center the grid
67
- const startX = (containerSize - totalGridSize) / 2;
68
- const startY = (containerSize - totalGridSize) / 2;
69
- const x = startX + margin + col * (tileSize + margin);
70
- const y = startY + margin + row * (tileSize + margin);
71
- return {
72
- x,
73
- y
74
- };
75
- }
76
-
77
- // Generate haptic feedback patterns
78
- generateHapticFeedback(type) {
79
- // This would integrate with react-native-haptic-feedback
80
- const patterns = {
81
- move: 'impactLight',
82
- merge: 'impactMedium',
83
- win: 'notificationSuccess',
84
- gameOver: 'notificationError'
85
- };
86
- return patterns[type];
87
- }
88
-
89
- // Generate sound effects
90
- generateSoundEffect(type) {
91
- // This would integrate with react-native-sound
92
- const sounds = {
93
- move: 'tile_move.mp3',
94
- merge: 'tile_merge.mp3',
95
- win: 'game_win.mp3',
96
- gameOver: 'game_over.mp3',
97
- newTile: 'new_tile.mp3'
98
- };
99
- return sounds[type];
100
- }
101
-
102
- // Animate tile movement
103
- animateTileMovement(fromPosition, toPosition, duration = GAME_2048_SETTINGS.ANIMATION_DURATION) {
104
- return {
105
- from: fromPosition,
106
- to: toPosition,
107
- duration,
108
- easing: 'easeOutCubic'
109
- };
110
- }
111
-
112
- // Animate tile merge
113
- animateTileMerge(position, duration = GAME_2048_SETTINGS.MERGE_ANIMATION_DURATION) {
114
- return {
115
- position,
116
- duration,
117
- scaleFrom: 1,
118
- scaleTo: 1.1,
119
- scaleBack: 1,
120
- easing: 'easeInOutCubic'
121
- };
122
- }
123
-
124
- // Animate new tile spawn
125
- animateNewTileSpawn(position, duration = GAME_2048_SETTINGS.SPAWN_ANIMATION_DURATION) {
126
- return {
127
- position,
128
- duration,
129
- scaleFrom: 0,
130
- scaleTo: 1,
131
- easing: 'easeOutBack'
132
- };
133
- }
134
-
135
- // Check if position is within grid bounds
136
- isValidPosition(row, col, gridSize) {
137
- return row >= 0 && row < gridSize && col >= 0 && col < gridSize;
138
- }
139
-
140
- // Get adjacent positions
141
- getAdjacentPositions(row, col, gridSize) {
142
- const directions = [{
143
- row: -1,
144
- col: 0,
145
- direction: 'up'
146
- }, {
147
- row: 1,
148
- col: 0,
149
- direction: 'down'
150
- }, {
151
- row: 0,
152
- col: -1,
153
- direction: 'left'
154
- }, {
155
- row: 0,
156
- col: 1,
157
- direction: 'right'
158
- }];
159
- return directions.map(dir => ({
160
- row: row + dir.row,
161
- col: col + dir.col,
162
- direction: dir.direction
163
- })).filter(pos => this.isValidPosition(pos.row, pos.col, gridSize));
164
- }
165
-
166
- // Calculate game statistics
167
- calculateGameStats(score, moves, timeElapsed) {
168
- const averageScorePerMove = moves > 0 ? Math.round(score / moves) : 0;
169
- const scorePerSecond = timeElapsed > 0 ? Math.round(score / timeElapsed) : 0;
170
- return {
171
- averageScorePerMove,
172
- scorePerSecond,
173
- efficiency: moves > 0 ? Math.round(score / moves * 100) / 100 : 0
174
- };
175
- }
176
-
177
- // Save game state to storage
178
- async saveGameState(gameState) {
179
- try {
180
- // This would integrate with AsyncStorage
181
- JSON.stringify(gameState); // Validate JSON serialization
182
- return true;
183
- } catch (error) {
184
- console.error('Failed to save game state:', error);
185
- return false;
186
- }
187
- }
188
-
189
- // Load game state from storage
190
- async loadGameState() {
191
- try {
192
- // This would integrate with AsyncStorage
193
- // const stateString = await AsyncStorage.getItem('game2048_state');
194
- // return stateString ? JSON.parse(stateString) : null;
195
- return null;
196
- } catch (error) {
197
- console.error('Failed to load game state:', error);
198
- return null;
199
- }
200
- }
201
-
202
- // Cleanup resources
203
- cleanup() {
204
- // No timers to cleanup - memory safe
205
- }
206
-
207
- // Create empty grid
208
- createGrid() {
209
- return Array(GAME_CONFIG.GRID_SIZE).fill(null).map(() => Array(GAME_CONFIG.GRID_SIZE).fill(null));
210
- }
211
-
212
- // Add random tile (2 or 4)
213
- addRandomTile(grid, tileId) {
214
- const emptyCells = [];
215
- for (let row = 0; row < GAME_CONFIG.GRID_SIZE; row++) {
216
- for (let col = 0; col < GAME_CONFIG.GRID_SIZE; col++) {
217
- const gridRow = grid[row];
218
- if (gridRow && !gridRow[col]) {
219
- emptyCells.push({
220
- row,
221
- col
222
- });
223
- }
224
- }
225
- }
226
- if (emptyCells.length === 0) return null;
227
- const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
228
- if (!randomCell) return null;
229
- const newTile = {
230
- id: tileId,
231
- value: Math.random() < GAME_CONFIG.NEW_TILE_PROBABILITY_4 ? 4 : 2,
232
- row: randomCell.row,
233
- col: randomCell.col,
234
- animatedValue: new Animated.Value(0),
235
- scaleValue: new Animated.Value(0)
236
- };
237
- const targetRow = grid[randomCell.row];
238
- if (targetRow) {
239
- targetRow[randomCell.col] = newTile;
240
- }
241
- return newTile;
242
- }
243
-
244
- // Move tiles in direction - Optimized for performance
245
- moveTiles(grid, direction) {
246
- let moved = false;
247
- let score = 0;
248
-
249
- // Pre-calculate direction constants for better performance
250
- const isHorizontal = direction === 'left' || direction === 'right';
251
- const isReverse = direction === 'right' || direction === 'down';
252
- const gridSize = GAME_CONFIG.GRID_SIZE;
253
-
254
- // Create a temporary grid to avoid multiple allocations
255
- const newGrid = this.createGrid();
256
-
257
- // Process each row/column
258
- for (let i = 0; i < gridSize; i++) {
259
- // Extract non-null tiles efficiently
260
- const tiles = [];
261
- for (let j = 0; j < gridSize; j++) {
262
- const index = isReverse ? gridSize - 1 - j : j;
263
- const row = isHorizontal ? grid[i] : grid[index];
264
- const tile = row ? isHorizontal ? row[index] : row[i] : null;
265
- if (tile) tiles.push(tile);
266
- }
267
-
268
- // Merge tiles in-place for better performance
269
- const merged = [];
270
- let j = 0;
271
- while (j < tiles.length) {
272
- const currentTile = tiles[j];
273
- const nextTile = tiles[j + 1];
274
- if (currentTile && nextTile && j < tiles.length - 1 && currentTile.value === nextTile.value) {
275
- // Reuse existing tile object for better memory performance
276
- const mergedTile = {
277
- ...currentTile,
278
- value: currentTile.value * 2,
279
- scaleValue: currentTile.scaleValue || new Animated.Value(1)
280
- };
281
- merged.push(mergedTile);
282
- score += mergedTile.value;
283
- j += 2;
284
- } else {
285
- const tile = tiles[j];
286
- merged.push(tile || null);
287
- j++;
288
- }
289
- }
290
-
291
- // Fill remaining positions with nulls
292
- while (merged.length < gridSize) {
293
- merged.push(null);
294
- }
295
-
296
- // Place tiles back and check for movement
297
- for (let j = 0; j < gridSize; j++) {
298
- const tile = merged[j];
299
- const index = isReverse ? gridSize - 1 - j : j;
300
- const newRow = isHorizontal ? i : index;
301
- const newCol = isHorizontal ? index : i;
302
-
303
- // Check if position changed
304
- const originalRow = isHorizontal ? grid[i] : grid[index];
305
- const originalTile = originalRow ? isHorizontal ? originalRow[index] : originalRow[i] : null;
306
- if (tile !== originalTile || tile && (tile.row !== newRow || tile.col !== newCol)) {
307
- moved = true;
308
- }
309
- if (tile) {
310
- // Create new tile with updated position to avoid read-only property issues
311
- const updatedTile = {
312
- ...tile,
313
- row: newRow,
314
- col: newCol
315
- };
316
- const targetRow = newGrid[newRow];
317
- if (targetRow) {
318
- targetRow[newCol] = updatedTile;
319
- }
320
- } else {
321
- const targetRow = newGrid[newRow];
322
- if (targetRow) {
323
- targetRow[newCol] = null;
324
- }
325
- }
326
- }
327
- }
328
-
329
- // Copy new grid back efficiently
330
- for (let row = 0; row < gridSize; row++) {
331
- for (let col = 0; col < gridSize; col++) {
332
- const sourceRow = newGrid[row];
333
- const targetRow = grid[row];
334
- if (sourceRow && targetRow) {
335
- targetRow[col] = sourceRow[col] || null;
336
- }
337
- }
338
- }
339
- return {
340
- moved,
341
- score
342
- };
343
- }
344
-
345
- // Check if game is over - Optimized
346
- checkGameOver(grid) {
347
- const gridSize = GAME_CONFIG.GRID_SIZE;
348
-
349
- // Single pass to check empty cells and possible merges
350
- for (let row = 0; row < gridSize; row++) {
351
- for (let col = 0; col < gridSize; col++) {
352
- const currentRow = grid[row];
353
- if (!currentRow) continue;
354
- const tile = currentRow[col];
355
-
356
- // If empty cell found, game is not over
357
- if (!tile) return false;
358
-
359
- // Check right and down neighbors only (avoid duplicate checks)
360
- if (col < gridSize - 1) {
361
- const rightTile = currentRow[col + 1];
362
- if (rightTile && rightTile.value === tile.value) return false;
363
- }
364
- if (row < gridSize - 1) {
365
- const nextRow = grid[row + 1];
366
- const downTile = nextRow ? nextRow[col] : null;
367
- if (downTile && downTile.value === tile.value) return false;
368
- }
369
- }
370
- }
371
- return true;
372
- }
373
-
374
- // Check if won (reached target value)
375
- hasWon(grid, targetValue) {
376
- for (let row = 0; row < GAME_CONFIG.GRID_SIZE; row++) {
377
- const currentRow = grid[row];
378
- if (!currentRow) continue;
379
- for (let col = 0; col < GAME_CONFIG.GRID_SIZE; col++) {
380
- const tile = currentRow[col];
381
- if (tile && tile.value >= targetValue) return true;
382
- }
383
- }
384
- return false;
385
- }
386
-
387
- // Get tile colors for rendering
388
- getTileBackgroundColor(value) {
389
- const colors = {
390
- 2: '#eee4da',
391
- 4: '#ede0c8',
392
- 8: '#f2b179',
393
- 16: '#f59563',
394
- 32: '#f67c5f',
395
- 64: '#f65e3b',
396
- 128: '#edcf72',
397
- 256: '#edcc61',
398
- 512: '#edc850',
399
- 1024: '#edc53f',
400
- 2048: '#edc22e',
401
- 4096: '#ff6b6b',
402
- 8192: '#ee5a52'
403
- };
404
- if (value > 8192) return '#ff4757';
405
- return colors[value] || '#3c3a32';
406
- }
407
- getTileTextColor(value) {
408
- return value <= 4 ? '#776e65' : '#f9f6f2';
409
- }
410
-
411
- // Get tile text size based on value
412
- getTileTextSize(value) {
413
- if (value < 100) return 28;
414
- if (value < 1000) return 24;
415
- if (value < 10000) return 20;
416
- return 16;
417
- }
418
-
419
- // Get tile animation delay for staggered animations
420
- getTileAnimationDelay(row, col, direction) {
421
- const baseDelay = 50; // Base delay in milliseconds
422
-
423
- switch (direction) {
424
- case 'up':
425
- return row * baseDelay;
426
- case 'down':
427
- return (3 - row) * baseDelay;
428
- // Assuming 4x4 grid
429
- case 'left':
430
- return col * baseDelay;
431
- case 'right':
432
- return (3 - col) * baseDelay;
433
- // Assuming 4x4 grid
434
- default:
435
- return 0;
436
- }
437
- }
438
-
439
- // Interpolate between two values for animations
440
- interpolate(from, to, progress) {
441
- return from + (to - from) * progress;
442
- }
443
-
444
- // Easing functions for animations
445
- easeOutCubic(t) {
446
- return 1 - Math.pow(1 - t, 3);
447
- }
448
- easeInOutCubic(t) {
449
- return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
450
- }
451
- easeOutBack(t) {
452
- const c1 = 1.70158;
453
- const c3 = c1 + 1;
454
- return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
455
- }
456
- }
457
- //# sourceMappingURL=Game2048Service.js.map
1
+ "use strict";import{Animated}from 'react-native';import{GAME_2048_SETTINGS,GAME_2048_GESTURES,GAME_CONFIG}from "./Game2048Constants.js";export class Game2048Service{getDifficultySettings(difficulty){return GAME_2048_SETTINGS.DIFFICULTY_SETTINGS[difficulty];}calculateMergeScore(tileValue,difficulty){const multiplier = GAME_2048_SETTINGS.SCORE_MULTIPLIER[difficulty];return tileValue * multiplier;}formatTime(seconds){const minutes = Math.floor(seconds / 60);const remainingSeconds = seconds % 60;return `${minutes.toString().padStart(2,'0')}:${remainingSeconds.toString().padStart(2,'0')}`;}detectSwipeDirection(startX,startY,endX,endY,velocity){const deltaX = endX - startX;const deltaY = endY - startY;const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);if(distance < GAME_2048_GESTURES.MIN_SWIPE_DISTANCE){return null;}if(velocity){const velocityMagnitude = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);if(velocityMagnitude < GAME_2048_GESTURES.MIN_VELOCITY){return null;}}const absDeltaX = Math.abs(deltaX);const absDeltaY = Math.abs(deltaY);if(absDeltaX > absDeltaY){return deltaX > 0 ? 'right':'left';}else{return deltaY > 0 ? 'down':'up';}}calculateTilePosition(row,col,gridSize,containerSize){const tileSize = GAME_2048_SETTINGS.TILE_SIZE;const margin = GAME_2048_SETTINGS.TILE_MARGIN;const totalGridSize = tileSize * gridSize + margin *(gridSize + 1);const startX =(containerSize - totalGridSize)/ 2;const startY =(containerSize - totalGridSize)/ 2;const x = startX + margin + col *(tileSize + margin);const y = startY + margin + row *(tileSize + margin);return{x,y};}generateHapticFeedback(type){const patterns ={move:'impactLight',merge:'impactMedium',win:'notificationSuccess',gameOver:'notificationError'};return patterns[type];}generateSoundEffect(type){const sounds ={move:'tile_move.mp3',merge:'tile_merge.mp3',win:'game_win.mp3',gameOver:'game_over.mp3',newTile:'new_tile.mp3'};return sounds[type];}animateTileMovement(fromPosition,toPosition,duration = GAME_2048_SETTINGS.ANIMATION_DURATION){return{from:fromPosition,to:toPosition,duration,easing:'easeOutCubic'};}animateTileMerge(position,duration = GAME_2048_SETTINGS.MERGE_ANIMATION_DURATION){return{position,duration,scaleFrom:1,scaleTo:1.1,scaleBack:1,easing:'easeInOutCubic'};}animateNewTileSpawn(position,duration = GAME_2048_SETTINGS.SPAWN_ANIMATION_DURATION){return{position,duration,scaleFrom:0,scaleTo:1,easing:'easeOutBack'};}isValidPosition(row,col,gridSize){return row >= 0 && row < gridSize && col >= 0 && col < gridSize;}getAdjacentPositions(row,col,gridSize){const directions = [{row:-1,col:0,direction:'up'},{row:1,col:0,direction:'down'},{row:0,col:-1,direction:'left'},{row:0,col:1,direction:'right'}];return directions.map(dir =>({row:row + dir.row,col:col + dir.col,direction:dir.direction})).filter(pos => this.isValidPosition(pos.row,pos.col,gridSize));}calculateGameStats(score,moves,timeElapsed){const averageScorePerMove = moves > 0 ? Math.round(score / moves):0;const scorePerSecond = timeElapsed > 0 ? Math.round(score / timeElapsed):0;return{averageScorePerMove,scorePerSecond,efficiency:moves > 0 ? Math.round(score / moves * 100)/ 100:0};}async saveGameState(gameState){try{JSON.stringify(gameState);return true;}catch(error){console.error('Failed to save game state:',error);return false;}}async loadGameState(){try{return null;}catch(error){console.error('Failed to load game state:',error);return null;}}cleanup(){}createGrid(){return Array(GAME_CONFIG.GRID_SIZE).fill(null).map(()=> Array(GAME_CONFIG.GRID_SIZE).fill(null));}addRandomTile(grid,tileId){const emptyCells = [];for(let row = 0;row < GAME_CONFIG.GRID_SIZE;row++){for(let col = 0;col < GAME_CONFIG.GRID_SIZE;col++){const gridRow = grid[row];if(gridRow && !gridRow[col]){emptyCells.push({row,col});}}}if(emptyCells.length === 0)return null;const randomCell = emptyCells[Math.floor(Math.random()* emptyCells.length)];if(!randomCell)return null;const newTile ={id:tileId,value:Math.random()< GAME_CONFIG.NEW_TILE_PROBABILITY_4 ? 4:2,row:randomCell.row,col:randomCell.col,animatedValue:new Animated.Value(0),scaleValue:new Animated.Value(0)};const targetRow = grid[randomCell.row];if(targetRow){targetRow[randomCell.col] = newTile;}return newTile;}moveTiles(grid,direction){let moved = false;let score = 0;const isHorizontal = direction === 'left' || direction === 'right';const isReverse = direction === 'right' || direction === 'down';const gridSize = GAME_CONFIG.GRID_SIZE;const newGrid = this.createGrid();for(let i = 0;i < gridSize;i++){const tiles = [];for(let j = 0;j < gridSize;j++){const index = isReverse ? gridSize - 1 - j:j;const row = isHorizontal ? grid[i]:grid[index];const tile = row ? isHorizontal ? row[index]:row[i]:null;if(tile)tiles.push(tile);}const merged = [];let j = 0;while(j < tiles.length){const currentTile = tiles[j];const nextTile = tiles[j + 1];if(currentTile && nextTile && j < tiles.length - 1 && currentTile.value === nextTile.value){const mergedTile ={...currentTile,value:currentTile.value * 2,scaleValue:currentTile.scaleValue || new Animated.Value(1)};merged.push(mergedTile);score += mergedTile.value;j += 2;}else{const tile = tiles[j];merged.push(tile || null);j++;}}while(merged.length < gridSize){merged.push(null);}for(let j = 0;j < gridSize;j++){const tile = merged[j];const index = isReverse ? gridSize - 1 - j:j;const newRow = isHorizontal ? i:index;const newCol = isHorizontal ? index:i;const originalRow = isHorizontal ? grid[i]:grid[index];const originalTile = originalRow ? isHorizontal ? originalRow[index]:originalRow[i]:null;if(tile !== originalTile || tile &&(tile.row !== newRow || tile.col !== newCol)){moved = true;}if(tile){const updatedTile ={...tile,row:newRow,col:newCol};const targetRow = newGrid[newRow];if(targetRow){targetRow[newCol] = updatedTile;}}else{const targetRow = newGrid[newRow];if(targetRow){targetRow[newCol] = null;}}}}for(let row = 0;row < gridSize;row++){for(let col = 0;col < gridSize;col++){const sourceRow = newGrid[row];const targetRow = grid[row];if(sourceRow && targetRow){targetRow[col] = sourceRow[col] || null;}}}return{moved,score};}checkGameOver(grid){const gridSize = GAME_CONFIG.GRID_SIZE;for(let row = 0;row < gridSize;row++){for(let col = 0;col < gridSize;col++){const currentRow = grid[row];if(!currentRow)continue;const tile = currentRow[col];if(!tile)return false;if(col < gridSize - 1){const rightTile = currentRow[col + 1];if(rightTile && rightTile.value === tile.value)return false;}if(row < gridSize - 1){const nextRow = grid[row + 1];const downTile = nextRow ? nextRow[col]:null;if(downTile && downTile.value === tile.value)return false;}}}return true;}hasWon(grid,targetValue){for(let row = 0;row < GAME_CONFIG.GRID_SIZE;row++){const currentRow = grid[row];if(!currentRow)continue;for(let col = 0;col < GAME_CONFIG.GRID_SIZE;col++){const tile = currentRow[col];if(tile && tile.value >= targetValue)return true;}}return false;}getTileBackgroundColor(value){const colors ={2:'#eee4da',4:'#ede0c8',8:'#f2b179',16:'#f59563',32:'#f67c5f',64:'#f65e3b',128:'#edcf72',256:'#edcc61',512:'#edc850',1024:'#edc53f',2048:'#edc22e',4096:'#ff6b6b',8192:'#ee5a52'};if(value > 8192)return '#ff4757';return colors[value] || '#3c3a32';}getTileTextColor(value){return value <= 4 ? '#776e65':'#f9f6f2';}getTileTextSize(value){if(value < 100)return 28;if(value < 1000)return 24;if(value < 10000)return 20;return 16;}getTileAnimationDelay(row,col,direction){const baseDelay = 50;switch(direction){case 'up':return row * baseDelay;case 'down':return(3 - row)* baseDelay;case 'left':return col * baseDelay;case 'right':return(3 - col)* baseDelay;default:return 0;}}interpolate(from,to,progress){return from +(to - from)* progress;}easeOutCubic(t){return 1 - Math.pow(1 - t,3);}easeInOutCubic(t){return t < 0.5 ? 4 * t * t * t:1 - Math.pow(-2 * t + 2,3)/ 2;}easeOutBack(t){const c1 = 1.70158;const c3 = c1 + 1;return 1 + c3 * Math.pow(t - 1,3)+ c1 * Math.pow(t - 1,2);}}