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,289 +1 @@
1
- "use strict";
2
-
3
- import React, { useRef, useEffect, useCallback, useState, useMemo } from 'react';
4
- import { View, Text, StyleSheet, Dimensions } from 'react-native';
5
- import { Gesture, GestureDetector } from 'react-native-gesture-handler';
6
- import { useSpaceFighterStore } from "../SpaceFighterStore.js";
7
- import { createSpaceFighterService } from "../SpaceFighterService.js";
8
- import { playSound, GAME_SOUNDS } from "../../../services/SoundsService.js";
9
- import { playHaptic, HapticType } from "../../../services/HapticsService.js";
10
- import { ParticleBlast } from "../../../helpers/index.js";
11
- import { AsteroidComponent } from "./AsteroidComponent.js";
12
- import { Spacecraft3D } from "./Spacecraft3D.js";
13
- import { SpacecraftPath } from "./SpacecraftPath.js";
14
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
- const {
16
- width,
17
- height
18
- } = Dimensions.get('window');
19
-
20
- // Self-contained GameArea component following FruitNinja pattern with performance optimizations
21
- export const GameArea = /*#__PURE__*/React.memo(() => {
22
- // Optimized store subscriptions - read only what's needed for rendering
23
- const asteroids = useSpaceFighterStore(state => state.asteroids);
24
- const spacecraft = useSpaceFighterStore(state => state.spacecraft);
25
- const spacecraftPath = useSpaceFighterStore(state => state.spacecraftPath);
26
- const isControllingSpacecraft = useSpaceFighterStore(state => state.isControllingSpacecraft);
27
- const isPlaying = useSpaceFighterStore(state => state.isPlaying);
28
-
29
- // Get store actions independently (these don't cause re-renders)
30
- const updateSpacecraft = useSpaceFighterStore(state => state.updateSpacecraft);
31
- const setSpacecraftPath = useSpaceFighterStore(state => state.setSpacecraftPath);
32
- const setIsControllingSpacecraft = useSpaceFighterStore(state => state.setIsControllingSpacecraft);
33
- const markAsteroidPassed = useSpaceFighterStore(state => state.markAsteroidPassed);
34
- const loseLife = useSpaceFighterStore(state => state.loseLife);
35
-
36
- // Self-contained component - no external settings needed
37
-
38
- // Game service ref
39
- const gameService = useRef(createSpaceFighterService(width, height)).current;
40
-
41
- // Spacecraft control refs
42
- const currentSpacecraftPath = useRef([]);
43
- const initialSpacecraftPosition = useRef(null);
44
- const initialTouchPosition = useRef(null);
45
- const pendingSpacecraftUpdate = useRef(null);
46
- const animationFrameId = useRef(null);
47
- const lastCollisionTime = useRef(0);
48
-
49
- // State for managing active particle blasts
50
- const [activeBlasts, setActiveBlasts] = useState([]);
51
-
52
- // Memoized particle blast colors for performance
53
- const particleColors = useMemo(() => ['#ff6b6b', '#ff8e53', '#ff6b35'], []);
54
-
55
- // Sound and haptic feedback functions (using default enabled state)
56
- const playSuccessSound = useCallback(() => {
57
- playSound(GAME_SOUNDS.SPACE_FIGHTER.SUCCESS, true);
58
- playHaptic(HapticType.LIGHT, true);
59
- }, []);
60
- const playCollisionSound = useCallback(() => {
61
- playSound(GAME_SOUNDS.SPACE_FIGHTER.COLLISION, true);
62
- playHaptic(HapticType.HEAVY, true);
63
- }, []);
64
-
65
- // Spacecraft control functions
66
- const handleSpacecraftControlStart = useCallback((x, y) => {
67
- const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;
68
- const controlledSpacecraft = gameService.controlSpacecraft({
69
- ...currentSpacecraft
70
- }, x, y);
71
- updateSpacecraft(controlledSpacecraft);
72
- setIsControllingSpacecraft(true);
73
- currentSpacecraftPath.current = [{
74
- x,
75
- y
76
- }];
77
- setSpacecraftPath([{
78
- x,
79
- y
80
- }]);
81
- }, [gameService, updateSpacecraft, setIsControllingSpacecraft, setSpacecraftPath]);
82
- const processPendingSpacecraftUpdate = useCallback(() => {
83
- if (pendingSpacecraftUpdate.current) {
84
- const {
85
- x,
86
- y
87
- } = pendingSpacecraftUpdate.current;
88
- const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;
89
- const controlledSpacecraft = gameService.controlSpacecraft({
90
- ...currentSpacecraft
91
- }, x, y);
92
- updateSpacecraft(controlledSpacecraft);
93
-
94
- // Throttle path updates to reduce re-renders
95
- currentSpacecraftPath.current.push({
96
- x,
97
- y
98
- });
99
- if (currentSpacecraftPath.current.length > 8) {
100
- currentSpacecraftPath.current.shift();
101
- }
102
-
103
- // Only update path every 3rd update to reduce re-renders
104
- if (currentSpacecraftPath.current.length % 3 === 0) {
105
- setSpacecraftPath([...currentSpacecraftPath.current]);
106
- }
107
- pendingSpacecraftUpdate.current = null;
108
- }
109
- animationFrameId.current = null;
110
- }, [gameService, updateSpacecraft, setSpacecraftPath]);
111
- const handleSpacecraftControlMove = useCallback((x, y) => {
112
- pendingSpacecraftUpdate.current = {
113
- x,
114
- y
115
- };
116
- if (animationFrameId.current === null) {
117
- animationFrameId.current = requestAnimationFrame(processPendingSpacecraftUpdate);
118
- }
119
- }, [processPendingSpacecraftUpdate]);
120
- const handleSpacecraftControlEnd = useCallback(() => {
121
- if (animationFrameId.current !== null) {
122
- cancelAnimationFrame(animationFrameId.current);
123
- animationFrameId.current = null;
124
- }
125
- if (pendingSpacecraftUpdate.current) {
126
- processPendingSpacecraftUpdate();
127
- }
128
- const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;
129
- const releasedSpacecraft = gameService.releaseSpacecraft({
130
- ...currentSpacecraft
131
- });
132
- updateSpacecraft(releasedSpacecraft);
133
- setIsControllingSpacecraft(false);
134
- setTimeout(() => {
135
- currentSpacecraftPath.current = [];
136
- setSpacecraftPath([]);
137
- }, 300);
138
- }, [gameService, updateSpacecraft, setIsControllingSpacecraft, setSpacecraftPath, processPendingSpacecraftUpdate]);
139
-
140
- // Optimized collision detection with reduced store access
141
- useEffect(() => {
142
- if (!isPlaying) return;
143
- const interval = setInterval(() => {
144
- // Single store access for better performance
145
- const state = useSpaceFighterStore.getState();
146
- const currentSpacecraft = state.spacecraft;
147
- const currentAsteroids = state.asteroids;
148
-
149
- // Skip if no asteroids to check
150
- if (currentAsteroids.length === 0) return;
151
- const collision = gameService.checkCollision(currentSpacecraft, currentAsteroids);
152
- const now = Date.now();
153
- if (collision.collision && now - lastCollisionTime.current > 1000) {
154
- lastCollisionTime.current = now;
155
- playCollisionSound();
156
-
157
- // Create particle blast at collision point
158
- const blastId = `blast-${now}`;
159
- setActiveBlasts(prev => [...prev, {
160
- id: blastId,
161
- x: currentSpacecraft.x,
162
- y: currentSpacecraft.y
163
- }]);
164
-
165
- // Remove blast after animation
166
- setTimeout(() => {
167
- setActiveBlasts(prev => prev.filter(blast => blast.id !== blastId));
168
- }, 800);
169
- loseLife(); // This now handles spacecraft position reset internally
170
- return;
171
- }
172
-
173
- // Check asteroid passes for scoring
174
- const passedAsteroids = gameService.checkAsteroidPass(currentSpacecraft, currentAsteroids);
175
- if (passedAsteroids.length > 0) {
176
- passedAsteroids.forEach(pairId => {
177
- markAsteroidPassed(pairId);
178
- playSuccessSound();
179
- });
180
- }
181
- }, 100); // Slightly increased interval for better performance (was 80ms)
182
-
183
- return () => clearInterval(interval);
184
- }, [isPlaying, gameService, playCollisionSound, loseLife, updateSpacecraft, markAsteroidPassed, playSuccessSound]);
185
-
186
- // Memoized gesture handling for better performance
187
- const panGesture = useMemo(() => Gesture.Pan().onStart(event => {
188
- const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;
189
- initialSpacecraftPosition.current = {
190
- x: currentSpacecraft.x,
191
- y: currentSpacecraft.y
192
- };
193
- initialTouchPosition.current = {
194
- x: event.absoluteX,
195
- y: event.absoluteY
196
- };
197
- handleSpacecraftControlStart(currentSpacecraft.x, currentSpacecraft.y);
198
- }).onUpdate(event => {
199
- if (!initialSpacecraftPosition.current || !initialTouchPosition.current) {
200
- return;
201
- }
202
- const dx = event.absoluteX - initialTouchPosition.current.x;
203
- const newX = initialSpacecraftPosition.current.x + dx;
204
- const newY = initialSpacecraftPosition.current.y;
205
- handleSpacecraftControlMove(newX, newY);
206
- }).onEnd(() => {
207
- initialTouchPosition.current = null;
208
- handleSpacecraftControlEnd();
209
- }).onFinalize(() => {
210
- initialTouchPosition.current = null;
211
- handleSpacecraftControlEnd();
212
- }).runOnJS(true), [handleSpacecraftControlStart, handleSpacecraftControlMove, handleSpacecraftControlEnd]);
213
- return /*#__PURE__*/_jsxs(View, {
214
- style: [styles.gameArea],
215
- children: [/*#__PURE__*/_jsx(SpacecraftPath, {
216
- path: spacecraftPath
217
- }), asteroids.map(asteroid => /*#__PURE__*/_jsx(AsteroidComponent, {
218
- asteroid: asteroid
219
- }, asteroid.id)), activeBlasts.map(blast => /*#__PURE__*/_jsx(ParticleBlast, {
220
- x: blast.x,
221
- y: blast.y,
222
- colors: particleColors,
223
- particleCount: 12,
224
- duration: 800
225
- }, blast.id)), /*#__PURE__*/_jsx(Spacecraft3D, {
226
- spacecraft: spacecraft,
227
- isControlled: isControllingSpacecraft
228
- }), /*#__PURE__*/_jsx(GestureDetector, {
229
- gesture: panGesture,
230
- children: /*#__PURE__*/_jsx(View, {
231
- style: styles.gestureOverlay
232
- })
233
- }), asteroids.length === 0 && /*#__PURE__*/_jsxs(View, {
234
- style: styles.instructionsContainer,
235
- children: [/*#__PURE__*/_jsx(Text, {
236
- style: styles.instructionsEmoji,
237
- children: "\uD83D\uDE80"
238
- }), /*#__PURE__*/_jsx(Text, {
239
- style: styles.instructionsTitle,
240
- children: "Navigate your spacecraft through the space!"
241
- }), /*#__PURE__*/_jsx(Text, {
242
- style: styles.instructionsSubtitle,
243
- children: "Touch and drag to control your spacecraft"
244
- })]
245
- })]
246
- });
247
- });
248
- const styles = StyleSheet.create({
249
- gameArea: {
250
- flex: 1,
251
- position: 'relative'
252
- },
253
- gestureOverlay: {
254
- position: 'absolute',
255
- top: 0,
256
- left: 0,
257
- right: 0,
258
- bottom: 0,
259
- backgroundColor: 'transparent',
260
- zIndex: 10
261
- },
262
- instructionsContainer: {
263
- position: 'absolute',
264
- top: '33%',
265
- left: 0,
266
- right: 0,
267
- opacity: 0.6,
268
- alignItems: 'center',
269
- justifyContent: 'center'
270
- },
271
- instructionsEmoji: {
272
- textAlign: 'center',
273
- fontSize: 24,
274
- marginBottom: 12
275
- },
276
- instructionsTitle: {
277
- color: '#ffffff',
278
- textAlign: 'center',
279
- fontSize: 18,
280
- fontWeight: 'bold',
281
- marginBottom: 8
282
- },
283
- instructionsSubtitle: {
284
- color: '#ffffff',
285
- textAlign: 'center',
286
- marginTop: 8
287
- }
288
- });
289
- //# sourceMappingURL=GameArea.js.map
1
+ "use strict";import React,{useRef,useEffect,useCallback,useState,useMemo}from 'react';import{View,Text,StyleSheet,Dimensions}from 'react-native';import{Gesture,GestureDetector}from 'react-native-gesture-handler';import{useSpaceFighterStore}from "../SpaceFighterStore.js";import{createSpaceFighterService}from "../SpaceFighterService.js";import{playSound,GAME_SOUNDS}from "../../../services/SoundsService.js";import{playHaptic,HapticType}from "../../../services/HapticsService.js";import{ParticleBlast}from "../../../helpers/index.js";import{AsteroidComponent}from "./AsteroidComponent.js";import{Spacecraft3D}from "./Spacecraft3D.js";import{SpacecraftPath}from "./SpacecraftPath.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');export const GameArea = React.memo(()=>{const asteroids = useSpaceFighterStore(state => state.asteroids);const spacecraft = useSpaceFighterStore(state => state.spacecraft);const spacecraftPath = useSpaceFighterStore(state => state.spacecraftPath);const isControllingSpacecraft = useSpaceFighterStore(state => state.isControllingSpacecraft);const isPlaying = useSpaceFighterStore(state => state.isPlaying);const updateSpacecraft = useSpaceFighterStore(state => state.updateSpacecraft);const setSpacecraftPath = useSpaceFighterStore(state => state.setSpacecraftPath);const setIsControllingSpacecraft = useSpaceFighterStore(state => state.setIsControllingSpacecraft);const markAsteroidPassed = useSpaceFighterStore(state => state.markAsteroidPassed);const loseLife = useSpaceFighterStore(state => state.loseLife);const gameService = useRef(createSpaceFighterService(width,height)).current;const currentSpacecraftPath = useRef([]);const initialSpacecraftPosition = useRef(null);const initialTouchPosition = useRef(null);const pendingSpacecraftUpdate = useRef(null);const animationFrameId = useRef(null);const lastCollisionTime = useRef(0);const [activeBlasts,setActiveBlasts] = useState([]);const particleColors = useMemo(()=> ['#ff6b6b','#ff8e53','#ff6b35'],[]);const playSuccessSound = useCallback(()=>{playSound(GAME_SOUNDS.SPACE_FIGHTER.SUCCESS,true);playHaptic(HapticType.LIGHT,true);},[]);const playCollisionSound = useCallback(()=>{playSound(GAME_SOUNDS.SPACE_FIGHTER.COLLISION,true);playHaptic(HapticType.HEAVY,true);},[]);const handleSpacecraftControlStart = useCallback((x,y)=>{const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;const controlledSpacecraft = gameService.controlSpacecraft({...currentSpacecraft},x,y);updateSpacecraft(controlledSpacecraft);setIsControllingSpacecraft(true);currentSpacecraftPath.current = [{x,y}];setSpacecraftPath([{x,y}]);},[gameService,updateSpacecraft,setIsControllingSpacecraft,setSpacecraftPath]);const processPendingSpacecraftUpdate = useCallback(()=>{if(pendingSpacecraftUpdate.current){const{x,y}= pendingSpacecraftUpdate.current;const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;const controlledSpacecraft = gameService.controlSpacecraft({...currentSpacecraft},x,y);updateSpacecraft(controlledSpacecraft);currentSpacecraftPath.current.push({x,y});if(currentSpacecraftPath.current.length > 8){currentSpacecraftPath.current.shift();}if(currentSpacecraftPath.current.length % 3 === 0){setSpacecraftPath([...currentSpacecraftPath.current]);}pendingSpacecraftUpdate.current = null;}animationFrameId.current = null;},[gameService,updateSpacecraft,setSpacecraftPath]);const handleSpacecraftControlMove = useCallback((x,y)=>{pendingSpacecraftUpdate.current ={x,y};if(animationFrameId.current === null){animationFrameId.current = requestAnimationFrame(processPendingSpacecraftUpdate);}},[processPendingSpacecraftUpdate]);const handleSpacecraftControlEnd = useCallback(()=>{if(animationFrameId.current !== null){cancelAnimationFrame(animationFrameId.current);animationFrameId.current = null;}if(pendingSpacecraftUpdate.current){processPendingSpacecraftUpdate();}const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;const releasedSpacecraft = gameService.releaseSpacecraft({...currentSpacecraft});updateSpacecraft(releasedSpacecraft);setIsControllingSpacecraft(false);setTimeout(()=>{currentSpacecraftPath.current = [];setSpacecraftPath([]);},300);},[gameService,updateSpacecraft,setIsControllingSpacecraft,setSpacecraftPath,processPendingSpacecraftUpdate]);useEffect(()=>{if(!isPlaying)return;const interval = setInterval(()=>{const state = useSpaceFighterStore.getState();const currentSpacecraft = state.spacecraft;const currentAsteroids = state.asteroids;if(currentAsteroids.length === 0)return;const collision = gameService.checkCollision(currentSpacecraft,currentAsteroids);const now = Date.now();if(collision.collision && now - lastCollisionTime.current > 1000){lastCollisionTime.current = now;playCollisionSound();const blastId = `blast-${now}`;setActiveBlasts(prev => [...prev,{id:blastId,x:currentSpacecraft.x,y:currentSpacecraft.y}]);setTimeout(()=>{setActiveBlasts(prev => prev.filter(blast => blast.id !== blastId));},800);loseLife();return;}const passedAsteroids = gameService.checkAsteroidPass(currentSpacecraft,currentAsteroids);if(passedAsteroids.length > 0){passedAsteroids.forEach(pairId =>{markAsteroidPassed(pairId);playSuccessSound();});}},100);return()=> clearInterval(interval);},[isPlaying,gameService,playCollisionSound,loseLife,updateSpacecraft,markAsteroidPassed,playSuccessSound]);const panGesture = useMemo(()=> Gesture.Pan().onStart(event =>{const currentSpacecraft = useSpaceFighterStore.getState().spacecraft;initialSpacecraftPosition.current ={x:currentSpacecraft.x,y:currentSpacecraft.y};initialTouchPosition.current ={x:event.absoluteX,y:event.absoluteY};handleSpacecraftControlStart(currentSpacecraft.x,currentSpacecraft.y);}).onUpdate(event =>{if(!initialSpacecraftPosition.current || !initialTouchPosition.current){return;}const dx = event.absoluteX - initialTouchPosition.current.x;const newX = initialSpacecraftPosition.current.x + dx;const newY = initialSpacecraftPosition.current.y;handleSpacecraftControlMove(newX,newY);}).onEnd(()=>{initialTouchPosition.current = null;handleSpacecraftControlEnd();}).onFinalize(()=>{initialTouchPosition.current = null;handleSpacecraftControlEnd();}).runOnJS(true),[handleSpacecraftControlStart,handleSpacecraftControlMove,handleSpacecraftControlEnd]);return _jsxs(View,{style:[styles.gameArea],children:[_jsx(SpacecraftPath,{path:spacecraftPath}),asteroids.map(asteroid => _jsx(AsteroidComponent,{asteroid:asteroid},asteroid.id)),activeBlasts.map(blast => _jsx(ParticleBlast,{x:blast.x,y:blast.y,colors:particleColors,particleCount:12,duration:800},blast.id)),_jsx(Spacecraft3D,{spacecraft:spacecraft,isControlled:isControllingSpacecraft}),_jsx(GestureDetector,{gesture:panGesture,children:_jsx(View,{style:styles.gestureOverlay})}),asteroids.length === 0 && _jsxs(View,{style:styles.instructionsContainer,children:[_jsx(Text,{style:styles.instructionsEmoji,children:"\uD83D\uDE80"}),_jsx(Text,{style:styles.instructionsTitle,children:"Navigate your spacecraft through the space!"}),_jsx(Text,{style:styles.instructionsSubtitle,children:"Touch and drag to control your spacecraft"})]})]});});const styles = StyleSheet.create({gameArea:{flex:1,position:'relative'},gestureOverlay:{position:'absolute',top:0,left:0,right:0,bottom:0,backgroundColor:'transparent',zIndex:10},instructionsContainer:{position:'absolute',top:'33%',left:0,right:0,opacity:0.6,alignItems:'center',justifyContent:'center'},instructionsEmoji:{textAlign:'center',fontSize:24,marginBottom:12},instructionsTitle:{color:'#ffffff',textAlign:'center',fontSize:18,fontWeight:'bold',marginBottom:8},instructionsSubtitle:{color:'#ffffff',textAlign:'center',marginTop:8}});
@@ -1,239 +1 @@
1
- "use strict";
2
-
3
- import React from 'react';
4
- import { View, Dimensions } from 'react-native';
5
- import { Canvas, LinearGradient, Rect, Circle, Group, Shadow, vec } from '@shopify/react-native-skia';
6
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
- const {
8
- width,
9
- height
10
- } = Dimensions.get('window');
11
- export const GameBackground = /*#__PURE__*/React.memo(({
12
- children
13
- }) => {
14
- return /*#__PURE__*/_jsxs(View, {
15
- style: {
16
- flex: 1
17
- },
18
- children: [/*#__PURE__*/_jsxs(Canvas, {
19
- style: {
20
- position: 'absolute',
21
- top: 0,
22
- left: 0,
23
- right: 0,
24
- bottom: 0,
25
- width,
26
- height
27
- },
28
- children: [/*#__PURE__*/_jsx(Rect, {
29
- x: 0,
30
- y: 0,
31
- width: width,
32
- height: height,
33
- children: /*#__PURE__*/_jsx(LinearGradient, {
34
- start: vec(0, 0),
35
- end: vec(0, height),
36
- colors: ['#0c0a1f', '#1a1b3a', '#2d1b69', '#1e1b4b', '#0c0a1f']
37
- })
38
- }), /*#__PURE__*/_jsx(Group, {
39
- children: Array.from({
40
- length: 40
41
- }, (_, i) => {
42
- const x = width / 8 * (i % 8) + i % 5 * 25;
43
- const y = height / 5 * Math.floor(i / 8) + i % 3 * 40;
44
- const size = 1 + i % 3 * 0.4;
45
- return /*#__PURE__*/_jsx(Circle, {
46
- cx: x,
47
- cy: y,
48
- r: size,
49
- color: "#ffffff",
50
- opacity: 0.6
51
- }, `star-${i}`);
52
- })
53
- }), /*#__PURE__*/_jsx(Group, {
54
- children: Array.from({
55
- length: 8
56
- }, (_, i) => {
57
- const positions = [{
58
- x: width * 0.15,
59
- y: height * 0.2
60
- }, {
61
- x: width * 0.8,
62
- y: height * 0.3
63
- }, {
64
- x: width * 0.3,
65
- y: height * 0.5
66
- }, {
67
- x: width * 0.7,
68
- y: height * 0.6
69
- }, {
70
- x: width * 0.2,
71
- y: height * 0.7
72
- }, {
73
- x: width * 0.85,
74
- y: height * 0.8
75
- }, {
76
- x: width * 0.5,
77
- y: height * 0.15
78
- }, {
79
- x: width * 0.6,
80
- y: height * 0.85
81
- }];
82
- const pos = positions[i];
83
- if (!pos) return null;
84
- const size = 2.5 + i % 2 * 0.5;
85
- return /*#__PURE__*/_jsx(Group, {
86
- children: /*#__PURE__*/_jsx(Circle, {
87
- cx: pos.x,
88
- cy: pos.y,
89
- r: size,
90
- color: "#ffffff",
91
- opacity: 0.8,
92
- children: /*#__PURE__*/_jsx(Shadow, {
93
- dx: 0,
94
- dy: 0,
95
- blur: 10,
96
- color: "#ffffff"
97
- })
98
- })
99
- }, `bright-star-${i}`);
100
- })
101
- }), /*#__PURE__*/_jsxs(Group, {
102
- children: [/*#__PURE__*/_jsx(Circle, {
103
- cx: width * 0.85,
104
- cy: height * 0.2,
105
- r: 32,
106
- color: "#4c1d95",
107
- opacity: 0.8,
108
- children: /*#__PURE__*/_jsx(Shadow, {
109
- dx: -2,
110
- dy: 2,
111
- blur: 8,
112
- color: "rgba(0,0,0,0.5)"
113
- })
114
- }), /*#__PURE__*/_jsx(Circle, {
115
- cx: width * 0.85 - 6,
116
- cy: height * 0.2 - 4,
117
- r: 10,
118
- color: "#5b21b6",
119
- opacity: 0.6
120
- }), /*#__PURE__*/_jsx(Circle, {
121
- cx: width * 0.85 + 4,
122
- cy: height * 0.2 + 6,
123
- r: 6,
124
- color: "#6d28d9",
125
- opacity: 0.5
126
- }), /*#__PURE__*/_jsx(Circle, {
127
- cx: width * 0.85 - 8,
128
- cy: height * 0.2 - 8,
129
- r: 6,
130
- color: "#a855f7",
131
- opacity: 0.3
132
- })]
133
- }), /*#__PURE__*/_jsxs(Group, {
134
- children: [/*#__PURE__*/_jsxs(Group, {
135
- children: [/*#__PURE__*/_jsx(Circle, {
136
- cx: width * 0.2,
137
- cy: height * 0.6,
138
- r: 40,
139
- color: "#7c3aed",
140
- opacity: 0.12,
141
- children: /*#__PURE__*/_jsx(Shadow, {
142
- dx: 0,
143
- dy: 0,
144
- blur: 15,
145
- color: "#7c3aed"
146
- })
147
- }), /*#__PURE__*/_jsx(Circle, {
148
- cx: width * 0.24,
149
- cy: height * 0.58,
150
- r: 28,
151
- color: "#a855f7",
152
- opacity: 0.1
153
- })]
154
- }), /*#__PURE__*/_jsxs(Group, {
155
- children: [/*#__PURE__*/_jsx(Circle, {
156
- cx: width * 0.7,
157
- cy: height * 0.4,
158
- r: 30,
159
- color: "#3b82f6",
160
- opacity: 0.1,
161
- children: /*#__PURE__*/_jsx(Shadow, {
162
- dx: 0,
163
- dy: 0,
164
- blur: 12,
165
- color: "#3b82f6"
166
- })
167
- }), /*#__PURE__*/_jsx(Circle, {
168
- cx: width * 0.72,
169
- cy: height * 0.38,
170
- r: 20,
171
- color: "#60a5fa",
172
- opacity: 0.08
173
- })]
174
- })]
175
- }), /*#__PURE__*/_jsx(Group, {
176
- children: Array.from({
177
- length: 5
178
- }, (_, i) => {
179
- const positions = [{
180
- x: width * 0.15,
181
- y: height * 0.3
182
- }, {
183
- x: width * 0.85,
184
- y: height * 0.5
185
- }, {
186
- x: width * 0.3,
187
- y: height * 0.75
188
- }, {
189
- x: width * 0.75,
190
- y: height * 0.2
191
- }, {
192
- x: width * 0.5,
193
- y: height * 0.85
194
- }];
195
- const pos = positions[i];
196
- if (!pos) return null;
197
- const size = 3 + i % 3;
198
- return /*#__PURE__*/_jsxs(Group, {
199
- children: [/*#__PURE__*/_jsx(Circle, {
200
- cx: pos.x,
201
- cy: pos.y,
202
- r: size,
203
- color: "#6b7280",
204
- opacity: 0.5,
205
- children: /*#__PURE__*/_jsx(Shadow, {
206
- dx: 1,
207
- dy: 1,
208
- blur: 2,
209
- color: "rgba(0,0,0,0.3)"
210
- })
211
- }), /*#__PURE__*/_jsx(Circle, {
212
- cx: pos.x - size * 0.25,
213
- cy: pos.y - size * 0.25,
214
- r: size * 0.3,
215
- color: "#9ca3af",
216
- opacity: 0.3
217
- })]
218
- }, `asteroid-${i}`);
219
- })
220
- }), /*#__PURE__*/_jsx(Group, {
221
- children: Array.from({
222
- length: 15
223
- }, (_, i) => {
224
- const x = width / 5 * (i % 5) + i % 3 * 20;
225
- const y = height / 3 * Math.floor(i / 5) + i % 4 * 30;
226
- const size = 0.5 + i % 2 * 0.2;
227
- return /*#__PURE__*/_jsx(Circle, {
228
- cx: x,
229
- cy: y,
230
- r: size,
231
- color: "#e5e7eb",
232
- opacity: 0.25
233
- }, `dust-${i}`);
234
- })
235
- })]
236
- }), children]
237
- });
238
- });
239
- //# sourceMappingURL=GameBackground.js.map
1
+ "use strict";import React from 'react';import{View,Dimensions}from 'react-native';import{Canvas,LinearGradient,Rect,Circle,Group,Shadow,vec}from '@shopify/react-native-skia';import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');export const GameBackground = React.memo(({children})=>{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(0,height),colors:['#0c0a1f','#1a1b3a','#2d1b69','#1e1b4b','#0c0a1f']})}),_jsx(Group,{children:Array.from({length:40},(_,i)=>{const x = width / 8 *(i % 8)+ i % 5 * 25;const y = height / 5 * Math.floor(i / 8)+ i % 3 * 40;const size = 1 + i % 3 * 0.4;return _jsx(Circle,{cx:x,cy:y,r:size,color:"#ffffff",opacity:0.6},`star-${i}`);})}),_jsx(Group,{children:Array.from({length:8},(_,i)=>{const positions = [{x:width * 0.15,y:height * 0.2},{x:width * 0.8,y:height * 0.3},{x:width * 0.3,y:height * 0.5},{x:width * 0.7,y:height * 0.6},{x:width * 0.2,y:height * 0.7},{x:width * 0.85,y:height * 0.8},{x:width * 0.5,y:height * 0.15},{x:width * 0.6,y:height * 0.85}];const pos = positions[i];if(!pos)return null;const size = 2.5 + i % 2 * 0.5;return _jsx(Group,{children:_jsx(Circle,{cx:pos.x,cy:pos.y,r:size,color:"#ffffff",opacity:0.8,children:_jsx(Shadow,{dx:0,dy:0,blur:10,color:"#ffffff"})})},`bright-star-${i}`);})}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.85,cy:height * 0.2,r:32,color:"#4c1d95",opacity:0.8,children:_jsx(Shadow,{dx:-2,dy:2,blur:8,color:"rgba(0,0,0,0.5)"})}),_jsx(Circle,{cx:width * 0.85 - 6,cy:height * 0.2 - 4,r:10,color:"#5b21b6",opacity:0.6}),_jsx(Circle,{cx:width * 0.85 + 4,cy:height * 0.2 + 6,r:6,color:"#6d28d9",opacity:0.5}),_jsx(Circle,{cx:width * 0.85 - 8,cy:height * 0.2 - 8,r:6,color:"#a855f7",opacity:0.3})]}),_jsxs(Group,{children:[_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.2,cy:height * 0.6,r:40,color:"#7c3aed",opacity:0.12,children:_jsx(Shadow,{dx:0,dy:0,blur:15,color:"#7c3aed"})}),_jsx(Circle,{cx:width * 0.24,cy:height * 0.58,r:28,color:"#a855f7",opacity:0.1})]}),_jsxs(Group,{children:[_jsx(Circle,{cx:width * 0.7,cy:height * 0.4,r:30,color:"#3b82f6",opacity:0.1,children:_jsx(Shadow,{dx:0,dy:0,blur:12,color:"#3b82f6"})}),_jsx(Circle,{cx:width * 0.72,cy:height * 0.38,r:20,color:"#60a5fa",opacity:0.08})]})]}),_jsx(Group,{children:Array.from({length:5},(_,i)=>{const positions = [{x:width * 0.15,y:height * 0.3},{x:width * 0.85,y:height * 0.5},{x:width * 0.3,y:height * 0.75},{x:width * 0.75,y:height * 0.2},{x:width * 0.5,y:height * 0.85}];const pos = positions[i];if(!pos)return null;const size = 3 + i % 3;return _jsxs(Group,{children:[_jsx(Circle,{cx:pos.x,cy:pos.y,r:size,color:"#6b7280",opacity:0.5,children:_jsx(Shadow,{dx:1,dy:1,blur:2,color:"rgba(0,0,0,0.3)"})}),_jsx(Circle,{cx:pos.x - size * 0.25,cy:pos.y - size * 0.25,r:size * 0.3,color:"#9ca3af",opacity:0.3})]},`asteroid-${i}`);})}),_jsx(Group,{children:Array.from({length:15},(_,i)=>{const x = width / 5 *(i % 5)+ i % 3 * 20;const y = height / 3 * Math.floor(i / 5)+ i % 4 * 30;const size = 0.5 + i % 2 * 0.2;return _jsx(Circle,{cx:x,cy:y,r:size,color:"#e5e7eb",opacity:0.25},`dust-${i}`);})})]}),children]});});
@@ -1,136 +1 @@
1
- "use strict";
2
-
3
- import React from 'react';
4
- import { View, Text, StyleSheet } from 'react-native';
5
- import { useSpaceFighterStore } from "../SpaceFighterStore.js";
6
- import { ScoreBoardContainer } from "../../../helpers/index.js";
7
-
8
- // Self-contained ScoreBoard component that reads directly from store
9
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
- export const ScoreBoard = /*#__PURE__*/React.memo(({
11
- offset = 0
12
- }) => {
13
- // Read state directly from store to minimize re-renders
14
- const score = useSpaceFighterStore(state => state.score);
15
- const timeLeft = useSpaceFighterStore(state => state.timeLeft);
16
- const currentLives = useSpaceFighterStore(state => state.lives);
17
- const maxLives = 3;
18
- return /*#__PURE__*/_jsx(ScoreBoardContainer, {
19
- offset: offset,
20
- backgroundColor: "rgba(147, 112, 219, 0.4)",
21
- borderColor: "rgba(139, 92, 246, 0.3)",
22
- children: /*#__PURE__*/_jsxs(View, {
23
- style: styles.scoreBoard,
24
- children: [/*#__PURE__*/_jsxs(View, {
25
- style: styles.scoreItem,
26
- children: [/*#__PURE__*/_jsx(Text, {
27
- style: styles.scoreLabel,
28
- children: "Score"
29
- }), /*#__PURE__*/_jsx(Text, {
30
- style: styles.scoreValue,
31
- children: score
32
- })]
33
- }), /*#__PURE__*/_jsxs(View, {
34
- style: styles.scoreItem,
35
- children: [/*#__PURE__*/_jsx(Text, {
36
- style: styles.scoreLabel,
37
- children: "Time"
38
- }), /*#__PURE__*/_jsx(Text, {
39
- style: styles.timeValue,
40
- children: timeLeft
41
- })]
42
- }), /*#__PURE__*/_jsxs(View, {
43
- style: styles.scoreItem,
44
- children: [/*#__PURE__*/_jsx(Text, {
45
- style: styles.scoreLabel,
46
- children: "Lives"
47
- }), /*#__PURE__*/_jsx(View, {
48
- style: styles.livesContainer,
49
- children: Array.from({
50
- length: maxLives
51
- }, (_, i) => /*#__PURE__*/_jsx(Text, {
52
- style: [styles.lifeIcon, i < currentLives ? styles.lifeActive : styles.lifeInactive],
53
- children: i < currentLives ? '❤️' : '🖤'
54
- }, i))
55
- })]
56
- })]
57
- })
58
- });
59
- });
60
- const styles = StyleSheet.create({
61
- scoreBoard: {
62
- flexDirection: 'row',
63
- justifyContent: 'space-between',
64
- alignItems: 'center'
65
- },
66
- scoreItem: {
67
- alignItems: 'center',
68
- flex: 1
69
- },
70
- scoreLabel: {
71
- fontSize: 18,
72
- fontWeight: 'bold',
73
- color: '#e2e8f0',
74
- // Light space gray
75
- marginBottom: 6,
76
- textShadowColor: 'rgba(0,0,0,0.5)',
77
- textShadowOffset: {
78
- width: 1,
79
- height: 1
80
- },
81
- textShadowRadius: 2
82
- },
83
- scoreValue: {
84
- fontSize: 30,
85
- fontWeight: 'bold',
86
- color: '#fbbf24',
87
- // Bright yellow for score
88
- textShadowColor: 'rgba(0,0,0,0.5)',
89
- textShadowOffset: {
90
- width: 1,
91
- height: 1
92
- },
93
- textShadowRadius: 2
94
- },
95
- timeValue: {
96
- fontSize: 30,
97
- fontWeight: 'bold',
98
- color: '#34d399',
99
- // Bright green for time
100
- textShadowColor: 'rgba(0,0,0,0.5)',
101
- textShadowOffset: {
102
- width: 1,
103
- height: 1
104
- },
105
- textShadowRadius: 2
106
- },
107
- livesContainer: {
108
- flexDirection: 'row',
109
- justifyContent: 'center'
110
- },
111
- lifeIcon: {
112
- fontSize: 22,
113
- marginHorizontal: 2
114
- },
115
- lifeActive: {
116
- color: '#ef4444',
117
- // Bright red for active lives
118
- textShadowColor: 'rgba(0,0,0,0.5)',
119
- textShadowOffset: {
120
- width: 1,
121
- height: 1
122
- },
123
- textShadowRadius: 2
124
- },
125
- lifeInactive: {
126
- color: '#374151',
127
- // Dark gray for lost lives
128
- textShadowColor: 'rgba(255,255,255,0.2)',
129
- textShadowOffset: {
130
- width: 1,
131
- height: 1
132
- },
133
- textShadowRadius: 1
134
- }
135
- });
136
- //# sourceMappingURL=ScoreBoard.js.map
1
+ "use strict";import React from 'react';import{View,Text,StyleSheet}from 'react-native';import{useSpaceFighterStore}from "../SpaceFighterStore.js";import{ScoreBoardContainer}from "../../../helpers/index.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const ScoreBoard = React.memo(({offset = 0})=>{const score = useSpaceFighterStore(state => state.score);const timeLeft = useSpaceFighterStore(state => state.timeLeft);const currentLives = useSpaceFighterStore(state => state.lives);const maxLives = 3;return _jsx(ScoreBoardContainer,{offset:offset,backgroundColor:"rgba(147,112,219,0.4)",borderColor:"rgba(139,92,246,0.3)",children:_jsxs(View,{style:styles.scoreBoard,children:[_jsxs(View,{style:styles.scoreItem,children:[_jsx(Text,{style:styles.scoreLabel,children:"Score"}),_jsx(Text,{style:styles.scoreValue,children:score})]}),_jsxs(View,{style:styles.scoreItem,children:[_jsx(Text,{style:styles.scoreLabel,children:"Time"}),_jsx(Text,{style:styles.timeValue,children:timeLeft})]}),_jsxs(View,{style:styles.scoreItem,children:[_jsx(Text,{style:styles.scoreLabel,children:"Lives"}),_jsx(View,{style:styles.livesContainer,children:Array.from({length:maxLives},(_,i)=> _jsx(Text,{style:[styles.lifeIcon,i < currentLives ? styles.lifeActive:styles.lifeInactive],children:i < currentLives ? '❤️':'🖤'},i))})]})]})});});const styles = StyleSheet.create({scoreBoard:{flexDirection:'row',justifyContent:'space-between',alignItems:'center'},scoreItem:{alignItems:'center',flex:1},scoreLabel:{fontSize:16,fontWeight:'bold',color:'#e2e8f0',marginBottom:6,textShadowColor:'rgba(0,0,0,0.5)',textShadowOffset:{width:1,height:1},textShadowRadius:2},scoreValue:{fontSize:25,fontWeight:'bold',color:'#fbbf24',textShadowColor:'rgba(0,0,0,0.5)',textShadowOffset:{width:1,height:1},textShadowRadius:2},timeValue:{fontSize:25,fontWeight:'bold',color:'#34d399',textShadowColor:'rgba(0,0,0,0.5)',textShadowOffset:{width:1,height:1},textShadowRadius:2},livesContainer:{flexDirection:'row',justifyContent:'center'},lifeIcon:{fontSize:22,marginHorizontal:2},lifeActive:{color:'#ef4444',textShadowColor:'rgba(0,0,0,0.5)',textShadowOffset:{width:1,height:1},textShadowRadius:2},lifeInactive:{color:'#374151',textShadowColor:'rgba(255,255,255,0.2)',textShadowOffset:{width:1,height:1},textShadowRadius:1}});