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.
- package/README.md +80 -368
- package/lib/module/games/balloon-blaster/BalloonBlaster.js +1 -167
- package/lib/module/games/balloon-blaster/BalloonBlaster.js.map +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterConstants.js +1 -182
- package/lib/module/games/balloon-blaster/BalloonBlasterConstants.js.map +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterService.js +1 -318
- package/lib/module/games/balloon-blaster/BalloonBlasterStore.js +1 -183
- package/lib/module/games/balloon-blaster/components/BalloonComponent.js +1 -237
- package/lib/module/games/balloon-blaster/components/GameArea.js +1 -156
- package/lib/module/games/balloon-blaster/components/GameBackground.js +1 -476
- package/lib/module/games/balloon-blaster/components/ScoreBoard.js +1 -112
- package/lib/module/games/balloon-blaster/components/ScoreBoard.js.map +1 -1
- package/lib/module/games/balloon-blaster/components/index.js +1 -7
- package/lib/module/games/candy-crush/CandyCrush.js +1 -131
- package/lib/module/games/candy-crush/CandyCrush.js.map +1 -1
- package/lib/module/games/candy-crush/CandyCrushConstants.js +1 -125
- package/lib/module/games/candy-crush/CandyCrushConstants.js.map +1 -1
- package/lib/module/games/candy-crush/CandyCrushService.js +1 -370
- package/lib/module/games/candy-crush/CandyCrushStore.js +1 -303
- package/lib/module/games/candy-crush/components/CandyItem.js +1 -191
- package/lib/module/games/candy-crush/components/GameBackground.js +1 -85
- package/lib/module/games/candy-crush/components/GameGrid.js +1 -314
- package/lib/module/games/candy-crush/components/ScoreBoard.js +1 -79
- package/lib/module/games/candy-crush/components/index.js +1 -7
- package/lib/module/games/candy-crush/index.js +1 -6
- package/lib/module/games/colors-sort/ColorsSort.js +1 -143
- package/lib/module/games/colors-sort/ColorsSort.js.map +1 -1
- package/lib/module/games/colors-sort/ColorsSortConstants.js +1 -72
- package/lib/module/games/colors-sort/ColorsSortConstants.js.map +1 -1
- package/lib/module/games/colors-sort/ColorsSortService.js +1 -255
- package/lib/module/games/colors-sort/ColorsSortStore.js +1 -257
- package/lib/module/games/colors-sort/ColorsSortStore.js.map +1 -1
- package/lib/module/games/colors-sort/components/ColorContainer.js +1 -140
- package/lib/module/games/colors-sort/components/GameBackground.js +1 -135
- package/lib/module/games/colors-sort/components/ScoreBoard.js +1 -70
- package/lib/module/games/colors-sort/components/index.js +1 -6
- package/lib/module/games/dino-jump/DinoJump.js +1 -209
- package/lib/module/games/dino-jump/DinoJump.js.map +1 -1
- package/lib/module/games/dino-jump/DinoJumpConstants.js +1 -189
- package/lib/module/games/dino-jump/DinoJumpConstants.js.map +1 -1
- package/lib/module/games/dino-jump/DinoJumpService.js +1 -270
- package/lib/module/games/dino-jump/DinoJumpStore.js +1 -381
- package/lib/module/games/dino-jump/components/DinoSprite.js +1 -418
- package/lib/module/games/dino-jump/components/DinoSprite.js.map +1 -1
- package/lib/module/games/dino-jump/components/GameArea.js +1 -68
- package/lib/module/games/dino-jump/components/GameBackground.js +1 -444
- package/lib/module/games/dino-jump/components/ObstacleSprite.js +1 -306
- package/lib/module/games/dino-jump/components/ScoreBoard.js +1 -105
- package/lib/module/games/dino-jump/components/ScoreBoard.js.map +1 -1
- package/lib/module/games/dino-jump/components/StarSprite.js +1 -45
- package/lib/module/games/dino-jump/components/index.js +1 -9
- package/lib/module/games/flappy-bird/FlappyBird.js +1 -126
- package/lib/module/games/flappy-bird/FlappyBird.js.map +1 -1
- package/lib/module/games/flappy-bird/FlappyBirdConstants.js +1 -90
- package/lib/module/games/flappy-bird/FlappyBirdConstants.js.map +1 -1
- package/lib/module/games/flappy-bird/FlappyBirdStore.js +1 -300
- package/lib/module/games/flappy-bird/components/Bird.js +1 -87
- package/lib/module/games/flappy-bird/components/GameArea.js +1 -87
- package/lib/module/games/flappy-bird/components/GameBackground.js +1 -79
- package/lib/module/games/flappy-bird/components/Pipes.js +1 -172
- package/lib/module/games/flappy-bird/components/ScoreBoard.js +1 -73
- package/lib/module/games/flappy-bird/components/index.js +1 -8
- package/lib/module/games/fruit-merger/FruitMerger.js +1 -120
- package/lib/module/games/fruit-merger/FruitMerger.js.map +1 -1
- package/lib/module/games/fruit-merger/FruitMergerConstants.js +1 -119
- package/lib/module/games/fruit-merger/FruitMergerConstants.js.map +1 -1
- package/lib/module/games/fruit-merger/FruitMergerService.js +1 -13
- package/lib/module/games/fruit-merger/FruitMergerStore.js +1 -315
- package/lib/module/games/fruit-merger/components/FruitItem.js +1 -102
- package/lib/module/games/fruit-merger/components/GameArea.js +1 -103
- package/lib/module/games/fruit-merger/components/GameBackground.js +1 -498
- package/lib/module/games/fruit-merger/components/ScoreBoard.js +1 -58
- package/lib/module/games/fruit-merger/components/index.js +1 -7
- package/lib/module/games/fruit-ninja/FruitNinja.js +1 -134
- package/lib/module/games/fruit-ninja/FruitNinja.js.map +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaConstants.js +1 -148
- package/lib/module/games/fruit-ninja/FruitNinjaConstants.js.map +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaService.js +1 -311
- package/lib/module/games/fruit-ninja/FruitNinjaStore.js +1 -191
- package/lib/module/games/fruit-ninja/FruitNinjaStore.js.map +1 -1
- package/lib/module/games/fruit-ninja/components/FruitComponent.js +1 -99
- package/lib/module/games/fruit-ninja/components/GameArea.js +1 -215
- package/lib/module/games/fruit-ninja/components/GameBackground.js +1 -1267
- package/lib/module/games/fruit-ninja/components/ScoreBoard.js +1 -92
- package/lib/module/games/fruit-ninja/components/ScoreBoard.js.map +1 -1
- package/lib/module/games/fruit-ninja/components/index.js +1 -7
- package/lib/module/games/game-2048/Game2048.js +1 -149
- package/lib/module/games/game-2048/Game2048.js.map +1 -1
- package/lib/module/games/game-2048/Game2048Constants.js +1 -263
- package/lib/module/games/game-2048/Game2048Constants.js.map +1 -1
- package/lib/module/games/game-2048/Game2048Service.js +1 -457
- package/lib/module/games/game-2048/Game2048Store.js +1 -236
- package/lib/module/games/game-2048/components/GameBackground.js +1 -247
- package/lib/module/games/game-2048/components/GameGrid.js +1 -139
- package/lib/module/games/game-2048/components/GameTile.js +1 -72
- package/lib/module/games/game-2048/components/ScoreBoard.js +1 -52
- package/lib/module/games/game-2048/components/index.js +1 -7
- package/lib/module/games/maze-runner/MazeRunner.js +1 -267
- package/lib/module/games/maze-runner/MazeRunner.js.map +1 -1
- package/lib/module/games/maze-runner/MazeRunnerConstants.js +1 -100
- package/lib/module/games/maze-runner/MazeRunnerConstants.js.map +1 -1
- package/lib/module/games/maze-runner/MazeRunnerService.js +1 -586
- package/lib/module/games/maze-runner/components/EnhancedBallComponent.js +1 -150
- package/lib/module/games/maze-runner/components/EnhancedGameArea.js +1 -370
- package/lib/module/games/maze-runner/components/GameBackground.js +1 -175
- package/lib/module/games/maze-runner/components/ScoreBoard.js +1 -61
- package/lib/module/games/maze-runner/components/SkiaPipeComponent.js +1 -209
- package/lib/module/games/maze-runner/components/StaticGameBackground.js +1 -169
- package/lib/module/games/maze-runner/components/WallComponent.js +1 -91
- package/lib/module/games/maze-runner/components/index.js +1 -8
- package/lib/module/games/popit-fidget/PopitFidget.js +1 -285
- package/lib/module/games/popit-fidget/PopitFidget.js.map +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetConstants.js +1 -113
- package/lib/module/games/popit-fidget/PopitFidgetConstants.js.map +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetService.js +1 -132
- package/lib/module/games/popit-fidget/PopitFidgetStore.js +1 -125
- package/lib/module/games/popit-fidget/components/BubbleComponent.js +1 -198
- package/lib/module/games/popit-fidget/components/FidgetGrid.js +1 -165
- package/lib/module/games/popit-fidget/components/GameBackground.js +1 -177
- package/lib/module/games/popit-fidget/components/ScoreBoard.js +1 -61
- package/lib/module/games/popit-fidget/components/index.js +1 -7
- package/lib/module/games/sliding-numbers/SlidingNumbers.js +1 -159
- package/lib/module/games/sliding-numbers/SlidingNumbers.js.map +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersConstants.js +1 -207
- package/lib/module/games/sliding-numbers/SlidingNumbersConstants.js.map +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersService.js +1 -248
- package/lib/module/games/sliding-numbers/SlidingNumbersStore.js +1 -274
- package/lib/module/games/sliding-numbers/components/GameBackground.js +1 -259
- package/lib/module/games/sliding-numbers/components/NumbersGrid.js +1 -174
- package/lib/module/games/sliding-numbers/components/NumbersTile.js +1 -116
- package/lib/module/games/sliding-numbers/components/ScoreBoard.js +1 -64
- package/lib/module/games/sliding-numbers/components/index.js +1 -7
- package/lib/module/games/snake/Snake.js +1 -189
- package/lib/module/games/snake/Snake.js.map +1 -1
- package/lib/module/games/snake/SnakeConstants.js +1 -138
- package/lib/module/games/snake/SnakeConstants.js.map +1 -1
- package/lib/module/games/snake/SnakeService.js +1 -148
- package/lib/module/games/snake/SnakeStore.js +1 -182
- package/lib/module/games/snake/components/GameBackground.js +1 -221
- package/lib/module/games/snake/components/GameGrid.js +1 -153
- package/lib/module/games/snake/components/ScoreBoard.js +1 -51
- package/lib/module/games/snake/components/index.js +1 -6
- package/lib/module/games/snake/index.js +1 -6
- package/lib/module/games/space-fighter/SpaceFighter.js +1 -165
- package/lib/module/games/space-fighter/SpaceFighter.js.map +1 -1
- package/lib/module/games/space-fighter/SpaceFighterConstants.js +1 -108
- package/lib/module/games/space-fighter/SpaceFighterConstants.js.map +1 -1
- package/lib/module/games/space-fighter/SpaceFighterService.js +1 -326
- package/lib/module/games/space-fighter/SpaceFighterStore.js +1 -209
- package/lib/module/games/space-fighter/components/AsteroidComponent.js +1 -113
- package/lib/module/games/space-fighter/components/GameArea.js +1 -289
- package/lib/module/games/space-fighter/components/GameBackground.js +1 -239
- package/lib/module/games/space-fighter/components/ScoreBoard.js +1 -136
- package/lib/module/games/space-fighter/components/Spacecraft3D.js +1 -202
- package/lib/module/games/space-fighter/components/SpacecraftPath.js +1 -52
- package/lib/module/games/space-fighter/components/index.js +1 -9
- package/lib/module/games/whack-a-mole/WhackAMole.js +1 -270
- package/lib/module/games/whack-a-mole/WhackAMole.js.map +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleConstants.js +1 -115
- package/lib/module/games/whack-a-mole/WhackAMoleConstants.js.map +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleService.js +1 -120
- package/lib/module/games/whack-a-mole/WhackAMoleStore.js +1 -172
- package/lib/module/games/whack-a-mole/components/GameBackground.js +1 -477
- package/lib/module/games/whack-a-mole/components/GameGrid.js +1 -97
- package/lib/module/games/whack-a-mole/components/GameHole.js +1 -196
- package/lib/module/games/whack-a-mole/components/MoleCharacter.js +1 -241
- package/lib/module/games/whack-a-mole/components/ScoreBoard.js +1 -67
- package/lib/module/games/whack-a-mole/components/ScoreBoard.js.map +1 -1
- package/lib/module/games/whack-a-mole/components/index.js +1 -8
- package/lib/module/helpers/AnimationFrame.js +1 -120
- package/lib/module/helpers/AnimationTracker.js +1 -89
- package/lib/module/helpers/ErrorHandler.js +1 -269
- package/lib/module/helpers/GameControlButton.js +1 -219
- package/lib/module/helpers/GameOverModal.js +1 -144
- package/lib/module/helpers/GameOverModal.js.map +1 -1
- package/lib/module/helpers/GameSettingsModal.js +1 -287
- package/lib/module/helpers/ParticleBlast.js +1 -134
- package/lib/module/helpers/ScoreBoardContainer.js +1 -34
- package/lib/module/helpers/index.js +1 -12
- package/lib/module/index.js +1 -22
- package/lib/module/services/GamesConstants.js +1 -178
- package/lib/module/services/GamesService.js +1 -112
- package/lib/module/services/GamesService.js.map +1 -1
- package/lib/module/services/HapticsService.js +1 -77
- package/lib/module/services/SoundsService.js +1 -302
- package/lib/module/services/UtilsService.js +1 -32
- package/lib/typescript/src/games/balloon-blaster/BalloonBlaster.d.ts.map +1 -1
- package/lib/typescript/src/games/balloon-blaster/BalloonBlasterConstants.d.ts +1 -1
- package/lib/typescript/src/games/balloon-blaster/components/ScoreBoard.d.ts.map +1 -1
- package/lib/typescript/src/games/candy-crush/CandyCrushConstants.d.ts +7 -7
- package/lib/typescript/src/games/colors-sort/ColorsSort.d.ts.map +1 -1
- package/lib/typescript/src/games/colors-sort/ColorsSortStore.d.ts.map +1 -1
- package/lib/typescript/src/games/dino-jump/DinoJump.d.ts.map +1 -1
- package/lib/typescript/src/games/dino-jump/components/DinoSprite.d.ts.map +1 -1
- package/lib/typescript/src/games/flappy-bird/FlappyBird.d.ts.map +1 -1
- package/lib/typescript/src/games/flappy-bird/FlappyBirdConstants.d.ts.map +1 -1
- package/lib/typescript/src/games/fruit-merger/FruitMerger.d.ts.map +1 -1
- package/lib/typescript/src/games/fruit-merger/FruitMergerConstants.d.ts.map +1 -1
- package/lib/typescript/src/games/fruit-ninja/FruitNinja.d.ts.map +1 -1
- package/lib/typescript/src/games/fruit-ninja/components/ScoreBoard.d.ts.map +1 -1
- package/lib/typescript/src/games/game-2048/Game2048.d.ts.map +1 -1
- package/lib/typescript/src/games/maze-runner/MazeRunner.d.ts.map +1 -1
- package/lib/typescript/src/games/popit-fidget/PopitFidget.d.ts.map +1 -1
- package/lib/typescript/src/games/sliding-numbers/SlidingNumbers.d.ts.map +1 -1
- package/lib/typescript/src/games/space-fighter/SpaceFighter.d.ts.map +1 -1
- package/lib/typescript/src/games/whack-a-mole/WhackAMole.d.ts.map +1 -1
- package/lib/typescript/src/games/whack-a-mole/WhackAMoleConstants.d.ts +1 -1
- package/lib/typescript/src/games/whack-a-mole/components/ScoreBoard.d.ts.map +1 -1
- package/lib/typescript/src/helpers/GameOverModal.d.ts +3 -0
- package/lib/typescript/src/helpers/GameOverModal.d.ts.map +1 -1
- package/lib/typescript/src/services/GamesConstants.d.ts +7 -7
- package/package.json +2 -2
|
@@ -1,326 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { SPACE_FIGHTER_GAME_CONFIG as GAME_CONFIG, SPACE_FIGHTER_COLORS as COLORS } from "./SpaceFighterConstants.js";
|
|
4
|
-
|
|
5
|
-
// Constants now imported from SpaceFighterConstants.ts
|
|
6
|
-
// Re-export for backward compatibility
|
|
7
|
-
export { GAME_CONFIG, COLORS };
|
|
8
|
-
|
|
9
|
-
// Asteroid Types (space obstacles)
|
|
10
|
-
|
|
11
|
-
// Game Service Class
|
|
12
|
-
class SpaceFighterGameService {
|
|
13
|
-
gameTimer = null;
|
|
14
|
-
asteroidSpawnTimer = null;
|
|
15
|
-
physicsTimer = null;
|
|
16
|
-
particles = [];
|
|
17
|
-
lastCollisionTime = 0;
|
|
18
|
-
currentAsteroidSpeed = GAME_CONFIG.ASTEROID_SPEED;
|
|
19
|
-
currentSpawnInterval = GAME_CONFIG.ASTEROID_SPAWN_INTERVAL;
|
|
20
|
-
constructor(screenWidth, screenHeight) {
|
|
21
|
-
this.width = screenWidth;
|
|
22
|
-
this.height = screenHeight;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Game Control
|
|
26
|
-
startGame() {
|
|
27
|
-
this.cleanup();
|
|
28
|
-
}
|
|
29
|
-
cleanup() {
|
|
30
|
-
if (this.gameTimer) {
|
|
31
|
-
clearInterval(this.gameTimer);
|
|
32
|
-
this.gameTimer = null;
|
|
33
|
-
}
|
|
34
|
-
if (this.asteroidSpawnTimer) {
|
|
35
|
-
clearInterval(this.asteroidSpawnTimer);
|
|
36
|
-
this.asteroidSpawnTimer = null;
|
|
37
|
-
}
|
|
38
|
-
if (this.physicsTimer) {
|
|
39
|
-
clearInterval(this.physicsTimer);
|
|
40
|
-
this.physicsTimer = null;
|
|
41
|
-
}
|
|
42
|
-
this.particles = [];
|
|
43
|
-
this.lastCollisionTime = 0; // Reset collision cooldown
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Timer Management
|
|
47
|
-
startGameTimer(decrementTime) {
|
|
48
|
-
this.gameTimer = setInterval(decrementTime, 1000);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Method to update difficulty settings
|
|
52
|
-
updateDifficultySettings(asteroidSpeed, spawnInterval) {
|
|
53
|
-
this.currentAsteroidSpeed = asteroidSpeed;
|
|
54
|
-
this.currentSpawnInterval = spawnInterval;
|
|
55
|
-
}
|
|
56
|
-
startAsteroidSpawning(spawnAsteroid) {
|
|
57
|
-
// Spawn first asteroid pair immediately
|
|
58
|
-
const initialAsteroids = this.generateAsteroidPair();
|
|
59
|
-
spawnAsteroid(initialAsteroids);
|
|
60
|
-
|
|
61
|
-
// Then continue spawning at regular intervals using dynamic spawn interval
|
|
62
|
-
this.asteroidSpawnTimer = setInterval(() => {
|
|
63
|
-
const asteroids = this.generateAsteroidPair();
|
|
64
|
-
spawnAsteroid(asteroids);
|
|
65
|
-
}, this.currentSpawnInterval);
|
|
66
|
-
}
|
|
67
|
-
startPhysicsLoop(updateSpacecraft, updateAsteroid, removeAsteroid, getSpacecraft, getAsteroids) {
|
|
68
|
-
this.physicsTimer = setInterval(() => {
|
|
69
|
-
this.updatePhysics(updateSpacecraft, updateAsteroid, removeAsteroid, getSpacecraft, getAsteroids);
|
|
70
|
-
}, 16); // ~60 FPS
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Asteroid Generation - Horizontal asteroids for portrait mode
|
|
74
|
-
generateAsteroidPair() {
|
|
75
|
-
const pairId = `asteroid_pair_${Date.now()}_${Math.random()}`;
|
|
76
|
-
// Make gap position truly random across 80% of screen width for better gameplay
|
|
77
|
-
const minGapX = this.width * 0.1; // 10% from left edge
|
|
78
|
-
const maxGapX = this.width * 0.9 - GAME_CONFIG.ASTEROID_GAP; // 10% from right edge
|
|
79
|
-
const gapX = Math.random() * (maxGapX - minGapX) + minGapX;
|
|
80
|
-
const leftAsteroid = {
|
|
81
|
-
id: `${pairId}_left`,
|
|
82
|
-
x: 0,
|
|
83
|
-
y: -250,
|
|
84
|
-
// Start well above screen (200px above)
|
|
85
|
-
width: gapX,
|
|
86
|
-
height: GAME_CONFIG.ASTEROID_WIDTH,
|
|
87
|
-
type: 'left',
|
|
88
|
-
pairId,
|
|
89
|
-
passed: false,
|
|
90
|
-
spawnTime: Date.now()
|
|
91
|
-
};
|
|
92
|
-
const rightAsteroid = {
|
|
93
|
-
id: `${pairId}_right`,
|
|
94
|
-
x: gapX + GAME_CONFIG.ASTEROID_GAP,
|
|
95
|
-
y: -250,
|
|
96
|
-
// Start well above screen (200px above)
|
|
97
|
-
width: this.width - (gapX + GAME_CONFIG.ASTEROID_GAP),
|
|
98
|
-
height: GAME_CONFIG.ASTEROID_WIDTH,
|
|
99
|
-
type: 'right',
|
|
100
|
-
pairId,
|
|
101
|
-
passed: false,
|
|
102
|
-
spawnTime: Date.now()
|
|
103
|
-
};
|
|
104
|
-
return [leftAsteroid, rightAsteroid];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Physics Update
|
|
108
|
-
updatePhysics(updateSpacecraft, updateAsteroid, removeAsteroid, getSpacecraft, getAsteroids) {
|
|
109
|
-
const spacecraft = getSpacecraft();
|
|
110
|
-
const asteroids = getAsteroids();
|
|
111
|
-
|
|
112
|
-
// Update spacecraft physics - Horizontal movement only, Y position locked
|
|
113
|
-
let newSpacecraft = {
|
|
114
|
-
...spacecraft
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
// Spacecraft never moves vertically - Y position is always locked to current position
|
|
118
|
-
// The store manages the Y position based on offset, so we just maintain it
|
|
119
|
-
newSpacecraft.y = spacecraft.y; // Keep Y position as set by store
|
|
120
|
-
newSpacecraft.velocityY = 0;
|
|
121
|
-
|
|
122
|
-
// Only allow horizontal movement when being controlled
|
|
123
|
-
if (!newSpacecraft.isControlled) {
|
|
124
|
-
// Stop horizontal movement when not being controlled
|
|
125
|
-
newSpacecraft.velocityX = 0;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Horizontal boundary constraints only
|
|
129
|
-
if (newSpacecraft.x <= newSpacecraft.size / 2) {
|
|
130
|
-
newSpacecraft.x = newSpacecraft.size / 2;
|
|
131
|
-
newSpacecraft.velocityX = 0;
|
|
132
|
-
}
|
|
133
|
-
if (newSpacecraft.x >= this.width - newSpacecraft.size / 2) {
|
|
134
|
-
newSpacecraft.x = this.width - newSpacecraft.size / 2;
|
|
135
|
-
newSpacecraft.velocityX = 0;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Y position is always forced to correct position - never changes
|
|
139
|
-
|
|
140
|
-
updateSpacecraft(newSpacecraft);
|
|
141
|
-
|
|
142
|
-
// Update asteroids - move vertically from top to bottom using dynamic speed
|
|
143
|
-
// Optimized: Use for-loop instead of forEach for better performance
|
|
144
|
-
for (let i = 0; i < asteroids.length; i++) {
|
|
145
|
-
const asteroid = asteroids[i];
|
|
146
|
-
if (!asteroid) continue; // Safety check for undefined asteroid
|
|
147
|
-
|
|
148
|
-
const newY = asteroid.y + this.currentAsteroidSpeed;
|
|
149
|
-
if (newY > this.height) {
|
|
150
|
-
removeAsteroid(asteroid.id);
|
|
151
|
-
} else {
|
|
152
|
-
updateAsteroid(asteroid.id, {
|
|
153
|
-
y: newY
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Update particles
|
|
159
|
-
this.updateParticles();
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Spacecraft Control - Direct horizontal drag movement
|
|
163
|
-
controlSpacecraft(spacecraft, targetX, _targetY) {
|
|
164
|
-
// Direct movement - spacecraft follows finger immediately for responsive drag
|
|
165
|
-
// Constrain X position to screen bounds
|
|
166
|
-
const minX = spacecraft.size / 2;
|
|
167
|
-
const maxX = this.width - spacecraft.size / 2;
|
|
168
|
-
const constrainedX = Math.max(minX, Math.min(maxX, targetX));
|
|
169
|
-
return {
|
|
170
|
-
...spacecraft,
|
|
171
|
-
x: constrainedX,
|
|
172
|
-
y: spacecraft.y,
|
|
173
|
-
// Explicitly maintain Y position - no vertical movement
|
|
174
|
-
velocityX: 0,
|
|
175
|
-
velocityY: 0,
|
|
176
|
-
isControlled: true
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
releaseSpacecraft(spacecraft) {
|
|
180
|
-
// Return a new spacecraft object instead of mutating
|
|
181
|
-
return {
|
|
182
|
-
...spacecraft,
|
|
183
|
-
isControlled: false
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Collision Detection with 5-second cooldown
|
|
188
|
-
checkCollision(spacecraft, asteroids) {
|
|
189
|
-
const currentTime = Date.now();
|
|
190
|
-
|
|
191
|
-
// Check if we're still in collision cooldown period
|
|
192
|
-
if (currentTime - this.lastCollisionTime < GAME_CONFIG.COLLISION_COOLDOWN) {
|
|
193
|
-
return {
|
|
194
|
-
collision: false
|
|
195
|
-
}; // Immunity period - no collision detected
|
|
196
|
-
}
|
|
197
|
-
for (const asteroid of asteroids) {
|
|
198
|
-
if (this.spacecraftAsteroidCollision(spacecraft, asteroid)) {
|
|
199
|
-
this.lastCollisionTime = currentTime; // Record collision time
|
|
200
|
-
return {
|
|
201
|
-
collision: true,
|
|
202
|
-
asteroidId: asteroid.id
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return {
|
|
207
|
-
collision: false
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
spacecraftAsteroidCollision(spacecraft, asteroid) {
|
|
211
|
-
const spacecraftLeft = spacecraft.x - spacecraft.size / 2;
|
|
212
|
-
const spacecraftRight = spacecraft.x + spacecraft.size / 2;
|
|
213
|
-
const spacecraftTop = spacecraft.y - spacecraft.size / 2;
|
|
214
|
-
const spacecraftBottom = spacecraft.y + spacecraft.size / 2;
|
|
215
|
-
const asteroidLeft = asteroid.x;
|
|
216
|
-
const asteroidRight = asteroid.x + asteroid.width;
|
|
217
|
-
const asteroidTop = asteroid.y;
|
|
218
|
-
const asteroidBottom = asteroid.y + asteroid.height;
|
|
219
|
-
return spacecraftRight > asteroidLeft && spacecraftLeft < asteroidRight && spacecraftBottom > asteroidTop && spacecraftTop < asteroidBottom;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Scoring - Updated for horizontal asteroids moving vertically
|
|
223
|
-
checkAsteroidPass(spacecraft, asteroids) {
|
|
224
|
-
const passedAsteroids = [];
|
|
225
|
-
|
|
226
|
-
// Optimized: Use for-loop instead of forEach for better performance
|
|
227
|
-
for (let i = 0; i < asteroids.length; i++) {
|
|
228
|
-
const asteroid = asteroids[i];
|
|
229
|
-
if (!asteroid) continue; // Safety check for undefined asteroid
|
|
230
|
-
|
|
231
|
-
if (!asteroid.passed && spacecraft.y > asteroid.y + asteroid.height) {
|
|
232
|
-
passedAsteroids.push(asteroid.pairId);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return passedAsteroids;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Particles - Enhanced collision particles for dramatic effect
|
|
239
|
-
createCollisionParticles(x, y) {
|
|
240
|
-
// Create more particles for bigger explosion effect
|
|
241
|
-
for (let i = 0; i < 15; i++) {
|
|
242
|
-
const particle = {
|
|
243
|
-
id: `particle_${Date.now()}_${i}`,
|
|
244
|
-
x,
|
|
245
|
-
y,
|
|
246
|
-
velocityX: (Math.random() - 0.5) * 15,
|
|
247
|
-
// Increased velocity spread
|
|
248
|
-
velocityY: (Math.random() - 0.5) * 15,
|
|
249
|
-
color: i < 5 ? '#ff6600' : i < 10 ? COLORS.SPACECRAFT : '#ffff00',
|
|
250
|
-
// Mix of colors
|
|
251
|
-
life: 1200,
|
|
252
|
-
// Longer life for better visibility
|
|
253
|
-
maxLife: 1200,
|
|
254
|
-
size: 8 + Math.random() * 12 // Much bigger particles (8-20px)
|
|
255
|
-
};
|
|
256
|
-
this.particles.push(particle);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Add some extra large explosion particles
|
|
260
|
-
for (let i = 0; i < 5; i++) {
|
|
261
|
-
const bigParticle = {
|
|
262
|
-
id: `big_particle_${Date.now()}_${i}`,
|
|
263
|
-
x: x + (Math.random() - 0.5) * 20,
|
|
264
|
-
y: y + (Math.random() - 0.5) * 20,
|
|
265
|
-
velocityX: (Math.random() - 0.5) * 8,
|
|
266
|
-
velocityY: (Math.random() - 0.5) * 8,
|
|
267
|
-
color: '#ff0000',
|
|
268
|
-
// Red explosion particles
|
|
269
|
-
life: 1500,
|
|
270
|
-
maxLife: 1500,
|
|
271
|
-
size: 15 + Math.random() * 10 // Very large particles (15-25px)
|
|
272
|
-
};
|
|
273
|
-
this.particles.push(bigParticle);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
updateParticles() {
|
|
277
|
-
// Optimized: Use for-loop with manual filtering for better performance
|
|
278
|
-
const activeParticles = [];
|
|
279
|
-
for (let i = 0; i < this.particles.length; i++) {
|
|
280
|
-
const particle = this.particles[i];
|
|
281
|
-
if (!particle) continue; // Safety check for undefined particle
|
|
282
|
-
|
|
283
|
-
particle.x += particle.velocityX;
|
|
284
|
-
particle.y += particle.velocityY;
|
|
285
|
-
particle.velocityY += 0.2; // gravity
|
|
286
|
-
particle.life -= 16;
|
|
287
|
-
if (particle.life > 0) {
|
|
288
|
-
activeParticles.push(particle);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
this.particles = activeParticles;
|
|
292
|
-
}
|
|
293
|
-
getParticles() {
|
|
294
|
-
return this.particles;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Check if spacecraft is currently immune to collisions
|
|
298
|
-
isInCollisionImmunity() {
|
|
299
|
-
const currentTime = Date.now();
|
|
300
|
-
return currentTime - this.lastCollisionTime < GAME_CONFIG.COLLISION_COOLDOWN;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Get remaining immunity time in milliseconds
|
|
304
|
-
getRemainingImmunityTime() {
|
|
305
|
-
const currentTime = Date.now();
|
|
306
|
-
const elapsed = currentTime - this.lastCollisionTime;
|
|
307
|
-
return Math.max(0, GAME_CONFIG.COLLISION_COOLDOWN - elapsed);
|
|
308
|
-
}
|
|
309
|
-
// Initial Spacecraft Position - Centered horizontally, positioned at bottom above start button
|
|
310
|
-
getInitialSpacecraft() {
|
|
311
|
-
return {
|
|
312
|
-
x: this.width / 2,
|
|
313
|
-
// Ensure exact center
|
|
314
|
-
y: this.height * 0.77,
|
|
315
|
-
// Fixed position at 77% from top
|
|
316
|
-
velocityX: 0,
|
|
317
|
-
velocityY: 0,
|
|
318
|
-
size: GAME_CONFIG.SPACECRAFT_SIZE,
|
|
319
|
-
isControlled: false
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
export const createSpaceFighterService = (width, height) => {
|
|
324
|
-
return new SpaceFighterGameService(width, height);
|
|
325
|
-
};
|
|
326
|
-
//# sourceMappingURL=SpaceFighterService.js.map
|
|
1
|
+
"use strict";import{SPACE_FIGHTER_GAME_CONFIG as GAME_CONFIG,SPACE_FIGHTER_COLORS as COLORS}from "./SpaceFighterConstants.js";export{GAME_CONFIG,COLORS};class SpaceFighterGameService{gameTimer = null;asteroidSpawnTimer = null;physicsTimer = null;particles = [];lastCollisionTime = 0;currentAsteroidSpeed = GAME_CONFIG.ASTEROID_SPEED;currentSpawnInterval = GAME_CONFIG.ASTEROID_SPAWN_INTERVAL;constructor(screenWidth,screenHeight){this.width = screenWidth;this.height = screenHeight;}startGame(){this.cleanup();}cleanup(){if(this.gameTimer){clearInterval(this.gameTimer);this.gameTimer = null;}if(this.asteroidSpawnTimer){clearInterval(this.asteroidSpawnTimer);this.asteroidSpawnTimer = null;}if(this.physicsTimer){clearInterval(this.physicsTimer);this.physicsTimer = null;}this.particles = [];this.lastCollisionTime = 0;}startGameTimer(decrementTime){this.gameTimer = setInterval(decrementTime,1000);}updateDifficultySettings(asteroidSpeed,spawnInterval){this.currentAsteroidSpeed = asteroidSpeed;this.currentSpawnInterval = spawnInterval;}startAsteroidSpawning(spawnAsteroid){const initialAsteroids = this.generateAsteroidPair();spawnAsteroid(initialAsteroids);this.asteroidSpawnTimer = setInterval(()=>{const asteroids = this.generateAsteroidPair();spawnAsteroid(asteroids);},this.currentSpawnInterval);}startPhysicsLoop(updateSpacecraft,updateAsteroid,removeAsteroid,getSpacecraft,getAsteroids){this.physicsTimer = setInterval(()=>{this.updatePhysics(updateSpacecraft,updateAsteroid,removeAsteroid,getSpacecraft,getAsteroids);},16);}generateAsteroidPair(){const pairId = `asteroid_pair_${Date.now()}_${Math.random()}`;const minGapX = this.width * 0.1;const maxGapX = this.width * 0.9 - GAME_CONFIG.ASTEROID_GAP;const gapX = Math.random()*(maxGapX - minGapX)+ minGapX;const leftAsteroid ={id:`${pairId}_left`,x:0,y:-250,width:gapX,height:GAME_CONFIG.ASTEROID_WIDTH,type:'left',pairId,passed:false,spawnTime:Date.now()};const rightAsteroid ={id:`${pairId}_right`,x:gapX + GAME_CONFIG.ASTEROID_GAP,y:-250,width:this.width -(gapX + GAME_CONFIG.ASTEROID_GAP),height:GAME_CONFIG.ASTEROID_WIDTH,type:'right',pairId,passed:false,spawnTime:Date.now()};return [leftAsteroid,rightAsteroid];}updatePhysics(updateSpacecraft,updateAsteroid,removeAsteroid,getSpacecraft,getAsteroids){const spacecraft = getSpacecraft();const asteroids = getAsteroids();let newSpacecraft ={...spacecraft};newSpacecraft.y = spacecraft.y;newSpacecraft.velocityY = 0;if(!newSpacecraft.isControlled){newSpacecraft.velocityX = 0;}if(newSpacecraft.x <= newSpacecraft.size / 2){newSpacecraft.x = newSpacecraft.size / 2;newSpacecraft.velocityX = 0;}if(newSpacecraft.x >= this.width - newSpacecraft.size / 2){newSpacecraft.x = this.width - newSpacecraft.size / 2;newSpacecraft.velocityX = 0;}updateSpacecraft(newSpacecraft);for(let i = 0;i < asteroids.length;i++){const asteroid = asteroids[i];if(!asteroid)continue;const newY = asteroid.y + this.currentAsteroidSpeed;if(newY > this.height){removeAsteroid(asteroid.id);}else{updateAsteroid(asteroid.id,{y:newY});}}this.updateParticles();}controlSpacecraft(spacecraft,targetX,_targetY){const minX = spacecraft.size / 2;const maxX = this.width - spacecraft.size / 2;const constrainedX = Math.max(minX,Math.min(maxX,targetX));return{...spacecraft,x:constrainedX,y:spacecraft.y,velocityX:0,velocityY:0,isControlled:true};}releaseSpacecraft(spacecraft){return{...spacecraft,isControlled:false};}checkCollision(spacecraft,asteroids){const currentTime = Date.now();if(currentTime - this.lastCollisionTime < GAME_CONFIG.COLLISION_COOLDOWN){return{collision:false};}for(const asteroid of asteroids){if(this.spacecraftAsteroidCollision(spacecraft,asteroid)){this.lastCollisionTime = currentTime;return{collision:true,asteroidId:asteroid.id};}}return{collision:false};}spacecraftAsteroidCollision(spacecraft,asteroid){const spacecraftLeft = spacecraft.x - spacecraft.size / 2;const spacecraftRight = spacecraft.x + spacecraft.size / 2;const spacecraftTop = spacecraft.y - spacecraft.size / 2;const spacecraftBottom = spacecraft.y + spacecraft.size / 2;const asteroidLeft = asteroid.x;const asteroidRight = asteroid.x + asteroid.width;const asteroidTop = asteroid.y;const asteroidBottom = asteroid.y + asteroid.height;return spacecraftRight > asteroidLeft && spacecraftLeft < asteroidRight && spacecraftBottom > asteroidTop && spacecraftTop < asteroidBottom;}checkAsteroidPass(spacecraft,asteroids){const passedAsteroids = [];for(let i = 0;i < asteroids.length;i++){const asteroid = asteroids[i];if(!asteroid)continue;if(!asteroid.passed && spacecraft.y > asteroid.y + asteroid.height){passedAsteroids.push(asteroid.pairId);}}return passedAsteroids;}createCollisionParticles(x,y){for(let i = 0;i < 15;i++){const particle ={id:`particle_${Date.now()}_${i}`,x,y,velocityX:(Math.random()- 0.5)* 15,velocityY:(Math.random()- 0.5)* 15,color:i < 5 ? '#ff6600':i < 10 ? COLORS.SPACECRAFT:'#ffff00',life:1200,maxLife:1200,size:8 + Math.random()* 12};this.particles.push(particle);}for(let i = 0;i < 5;i++){const bigParticle ={id:`big_particle_${Date.now()}_${i}`,x:x +(Math.random()- 0.5)* 20,y:y +(Math.random()- 0.5)* 20,velocityX:(Math.random()- 0.5)* 8,velocityY:(Math.random()- 0.5)* 8,color:'#ff0000',life:1500,maxLife:1500,size:15 + Math.random()* 10};this.particles.push(bigParticle);}}updateParticles(){const activeParticles = [];for(let i = 0;i < this.particles.length;i++){const particle = this.particles[i];if(!particle)continue;particle.x += particle.velocityX;particle.y += particle.velocityY;particle.velocityY += 0.2;particle.life -= 16;if(particle.life > 0){activeParticles.push(particle);}}this.particles = activeParticles;}getParticles(){return this.particles;}isInCollisionImmunity(){const currentTime = Date.now();return currentTime - this.lastCollisionTime < GAME_CONFIG.COLLISION_COOLDOWN;}getRemainingImmunityTime(){const currentTime = Date.now();const elapsed = currentTime - this.lastCollisionTime;return Math.max(0,GAME_CONFIG.COLLISION_COOLDOWN - elapsed);}getInitialSpacecraft(){return{x:this.width / 2,y:this.height * 0.77,velocityX:0,velocityY:0,size:GAME_CONFIG.SPACECRAFT_SIZE,isControlled:false};}}export const createSpaceFighterService =(width,height)=>{return new SpaceFighterGameService(width,height);};
|
|
@@ -1,209 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import { create } from 'zustand';
|
|
4
|
-
import { subscribeWithSelector } from 'zustand/middleware';
|
|
5
|
-
import { Dimensions } from 'react-native';
|
|
6
|
-
import { GAME_CONFIG } from "./SpaceFighterService.js";
|
|
7
|
-
import { immerMiddleware } from "../../services/UtilsService.js";
|
|
8
|
-
const {
|
|
9
|
-
width,
|
|
10
|
-
height
|
|
11
|
-
} = Dimensions.get('window');
|
|
12
|
-
|
|
13
|
-
// Helper function to get spacecraft Y position based on offset
|
|
14
|
-
const getSpacecraftYPosition = (offset = 0) => {
|
|
15
|
-
const yPercent = offset > 0 ? 0.77 : 0.68;
|
|
16
|
-
return height * yPercent;
|
|
17
|
-
};
|
|
18
|
-
// Optimized store with selective subscriptions for low-end devices
|
|
19
|
-
export const useSpaceFighterStore = create()(subscribeWithSelector(immerMiddleware((set, _get) => ({
|
|
20
|
-
// Initial state
|
|
21
|
-
score: 0,
|
|
22
|
-
timeLeft: 60,
|
|
23
|
-
// Fixed 60 seconds regardless of difficulty
|
|
24
|
-
isPlaying: false,
|
|
25
|
-
gameOver: false,
|
|
26
|
-
lives: 3,
|
|
27
|
-
asteroids: [],
|
|
28
|
-
spacecraft: {
|
|
29
|
-
x: width / 2,
|
|
30
|
-
// Center horizontally
|
|
31
|
-
y: getSpacecraftYPosition(0),
|
|
32
|
-
// Dynamic position based on offset
|
|
33
|
-
velocityX: 0,
|
|
34
|
-
velocityY: 0,
|
|
35
|
-
size: GAME_CONFIG.SPACECRAFT_SIZE,
|
|
36
|
-
isControlled: false
|
|
37
|
-
},
|
|
38
|
-
spacecraftPath: [],
|
|
39
|
-
isControllingSpacecraft: false,
|
|
40
|
-
offset: 0,
|
|
41
|
-
// Actions
|
|
42
|
-
setOffset: offset => {
|
|
43
|
-
set(draft => {
|
|
44
|
-
draft.offset = offset;
|
|
45
|
-
// Update spacecraft Y position when offset changes
|
|
46
|
-
draft.spacecraft.y = getSpacecraftYPosition(offset);
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
startGame: _gameDuration => {
|
|
50
|
-
// Always use fixed duration regardless of difficulty or passed duration
|
|
51
|
-
const duration = 60;
|
|
52
|
-
set(draft => {
|
|
53
|
-
draft.score = 0;
|
|
54
|
-
draft.timeLeft = duration;
|
|
55
|
-
draft.isPlaying = true;
|
|
56
|
-
draft.gameOver = false;
|
|
57
|
-
draft.lives = 3;
|
|
58
|
-
draft.asteroids = [];
|
|
59
|
-
draft.spacecraftPath = [];
|
|
60
|
-
draft.isControllingSpacecraft = false;
|
|
61
|
-
// Reset spacecraft to initial position
|
|
62
|
-
draft.spacecraft = {
|
|
63
|
-
x: width / 2,
|
|
64
|
-
// Center horizontally
|
|
65
|
-
y: getSpacecraftYPosition(draft.offset),
|
|
66
|
-
// Dynamic position based on offset
|
|
67
|
-
velocityX: 0,
|
|
68
|
-
velocityY: 0,
|
|
69
|
-
size: GAME_CONFIG.SPACECRAFT_SIZE,
|
|
70
|
-
isControlled: false
|
|
71
|
-
};
|
|
72
|
-
});
|
|
73
|
-
},
|
|
74
|
-
stopGame: () => {
|
|
75
|
-
set(draft => {
|
|
76
|
-
draft.score = 0;
|
|
77
|
-
draft.timeLeft = 60; // Fixed 60 seconds
|
|
78
|
-
draft.isPlaying = false;
|
|
79
|
-
draft.gameOver = false;
|
|
80
|
-
draft.lives = 3;
|
|
81
|
-
draft.asteroids = [];
|
|
82
|
-
draft.spacecraftPath = [];
|
|
83
|
-
draft.isControllingSpacecraft = false;
|
|
84
|
-
// Reset spacecraft to initial position
|
|
85
|
-
draft.spacecraft = {
|
|
86
|
-
x: width / 2,
|
|
87
|
-
// Center horizontally
|
|
88
|
-
y: getSpacecraftYPosition(draft.offset),
|
|
89
|
-
// Dynamic position based on offset
|
|
90
|
-
velocityX: 0,
|
|
91
|
-
velocityY: 0,
|
|
92
|
-
size: GAME_CONFIG.SPACECRAFT_SIZE,
|
|
93
|
-
isControlled: false
|
|
94
|
-
};
|
|
95
|
-
});
|
|
96
|
-
},
|
|
97
|
-
resetGame: () => {
|
|
98
|
-
set(draft => {
|
|
99
|
-
draft.score = 0;
|
|
100
|
-
draft.timeLeft = 60; // Fixed 60 seconds
|
|
101
|
-
draft.isPlaying = false;
|
|
102
|
-
draft.gameOver = false;
|
|
103
|
-
draft.lives = 3;
|
|
104
|
-
draft.asteroids = [];
|
|
105
|
-
draft.spacecraftPath = [];
|
|
106
|
-
draft.isControllingSpacecraft = false;
|
|
107
|
-
// Reset spacecraft to initial position
|
|
108
|
-
draft.spacecraft = {
|
|
109
|
-
x: width / 2,
|
|
110
|
-
// Center horizontally
|
|
111
|
-
y: getSpacecraftYPosition(draft.offset),
|
|
112
|
-
// Dynamic position based on offset
|
|
113
|
-
velocityX: 0,
|
|
114
|
-
velocityY: 0,
|
|
115
|
-
size: GAME_CONFIG.SPACECRAFT_SIZE,
|
|
116
|
-
isControlled: false
|
|
117
|
-
};
|
|
118
|
-
});
|
|
119
|
-
},
|
|
120
|
-
updateScore: points => {
|
|
121
|
-
set(draft => {
|
|
122
|
-
draft.score = draft.score + points;
|
|
123
|
-
});
|
|
124
|
-
},
|
|
125
|
-
decrementTime: () => {
|
|
126
|
-
set(draft => {
|
|
127
|
-
const newTimeLeft = draft.timeLeft - 1;
|
|
128
|
-
if (newTimeLeft <= 0) {
|
|
129
|
-
draft.timeLeft = 0;
|
|
130
|
-
draft.isPlaying = false;
|
|
131
|
-
draft.gameOver = true;
|
|
132
|
-
} else {
|
|
133
|
-
draft.timeLeft = newTimeLeft;
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
},
|
|
137
|
-
addAsteroids: asteroids => {
|
|
138
|
-
set(draft => {
|
|
139
|
-
draft.asteroids.push(...asteroids);
|
|
140
|
-
});
|
|
141
|
-
},
|
|
142
|
-
removeAsteroid: asteroidId => {
|
|
143
|
-
set(draft => {
|
|
144
|
-
draft.asteroids = draft.asteroids.filter(a => a.id !== asteroidId);
|
|
145
|
-
});
|
|
146
|
-
},
|
|
147
|
-
updateAsteroid: (asteroidId, updates) => {
|
|
148
|
-
set(draft => {
|
|
149
|
-
// Optimized: Use for-loop instead of find for better performance
|
|
150
|
-
for (let i = 0; i < draft.asteroids.length; i++) {
|
|
151
|
-
if (draft.asteroids[i].id === asteroidId) {
|
|
152
|
-
Object.assign(draft.asteroids[i], updates);
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
},
|
|
158
|
-
updateSpacecraft: spacecraft => {
|
|
159
|
-
set(draft => {
|
|
160
|
-
draft.spacecraft = spacecraft;
|
|
161
|
-
});
|
|
162
|
-
},
|
|
163
|
-
setSpacecraftPath: path => {
|
|
164
|
-
set(draft => {
|
|
165
|
-
draft.spacecraftPath = path;
|
|
166
|
-
});
|
|
167
|
-
},
|
|
168
|
-
setIsControllingSpacecraft: isControlling => {
|
|
169
|
-
set(draft => {
|
|
170
|
-
draft.isControllingSpacecraft = isControlling;
|
|
171
|
-
});
|
|
172
|
-
},
|
|
173
|
-
markAsteroidPassed: pairId => {
|
|
174
|
-
set(draft => {
|
|
175
|
-
// Optimized: Use for-loop instead of forEach for better performance
|
|
176
|
-
for (let i = 0; i < draft.asteroids.length; i++) {
|
|
177
|
-
if (draft.asteroids[i].pairId === pairId) {
|
|
178
|
-
draft.asteroids[i].passed = true;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
draft.score = draft.score + 10; // 10 points per asteroid pair passed
|
|
182
|
-
});
|
|
183
|
-
},
|
|
184
|
-
loseLife: () => {
|
|
185
|
-
set(draft => {
|
|
186
|
-
const newLives = draft.lives - 1;
|
|
187
|
-
|
|
188
|
-
// Reset spacecraft to initial position after collision
|
|
189
|
-
draft.spacecraft = {
|
|
190
|
-
x: width / 2,
|
|
191
|
-
// Center horizontally
|
|
192
|
-
y: getSpacecraftYPosition(draft.offset),
|
|
193
|
-
// Dynamic position based on offset
|
|
194
|
-
velocityX: 0,
|
|
195
|
-
velocityY: 0,
|
|
196
|
-
size: GAME_CONFIG.SPACECRAFT_SIZE,
|
|
197
|
-
isControlled: false
|
|
198
|
-
};
|
|
199
|
-
if (newLives <= 0) {
|
|
200
|
-
draft.lives = 0;
|
|
201
|
-
draft.isPlaying = false;
|
|
202
|
-
draft.gameOver = true;
|
|
203
|
-
} else {
|
|
204
|
-
draft.lives = newLives;
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
}))));
|
|
209
|
-
//# sourceMappingURL=SpaceFighterStore.js.map
|
|
1
|
+
"use strict";import{create}from 'zustand';import{subscribeWithSelector}from 'zustand/middleware';import{Dimensions}from 'react-native';import{GAME_CONFIG}from "./SpaceFighterService.js";import{immerMiddleware}from "../../services/UtilsService.js";const{width,height}= Dimensions.get('window');const getSpacecraftYPosition =(offset = 0)=>{const yPercent = offset > 0 ? 0.77:0.68;return height * yPercent;};export const useSpaceFighterStore = create()(subscribeWithSelector(immerMiddleware((set,_get)=>({score:0,timeLeft:60,isPlaying:false,gameOver:false,lives:3,asteroids:[],spacecraft:{x:width / 2,y:getSpacecraftYPosition(0),velocityX:0,velocityY:0,size:GAME_CONFIG.SPACECRAFT_SIZE,isControlled:false},spacecraftPath:[],isControllingSpacecraft:false,offset:0,setOffset:offset =>{set(draft =>{draft.offset = offset;draft.spacecraft.y = getSpacecraftYPosition(offset);});},startGame:_gameDuration =>{const duration = 60;set(draft =>{draft.score = 0;draft.timeLeft = duration;draft.isPlaying = true;draft.gameOver = false;draft.lives = 3;draft.asteroids = [];draft.spacecraftPath = [];draft.isControllingSpacecraft = false;draft.spacecraft ={x:width / 2,y:getSpacecraftYPosition(draft.offset),velocityX:0,velocityY:0,size:GAME_CONFIG.SPACECRAFT_SIZE,isControlled:false};});},stopGame:()=>{set(draft =>{draft.score = 0;draft.timeLeft = 60;draft.isPlaying = false;draft.gameOver = false;draft.lives = 3;draft.asteroids = [];draft.spacecraftPath = [];draft.isControllingSpacecraft = false;draft.spacecraft ={x:width / 2,y:getSpacecraftYPosition(draft.offset),velocityX:0,velocityY:0,size:GAME_CONFIG.SPACECRAFT_SIZE,isControlled:false};});},resetGame:()=>{set(draft =>{draft.score = 0;draft.timeLeft = 60;draft.isPlaying = false;draft.gameOver = false;draft.lives = 3;draft.asteroids = [];draft.spacecraftPath = [];draft.isControllingSpacecraft = false;draft.spacecraft ={x:width / 2,y:getSpacecraftYPosition(draft.offset),velocityX:0,velocityY:0,size:GAME_CONFIG.SPACECRAFT_SIZE,isControlled:false};});},updateScore:points =>{set(draft =>{draft.score = draft.score + points;});},decrementTime:()=>{set(draft =>{const newTimeLeft = draft.timeLeft - 1;if(newTimeLeft <= 0){draft.timeLeft = 0;draft.isPlaying = false;draft.gameOver = true;}else{draft.timeLeft = newTimeLeft;}});},addAsteroids:asteroids =>{set(draft =>{draft.asteroids.push(...asteroids);});},removeAsteroid:asteroidId =>{set(draft =>{draft.asteroids = draft.asteroids.filter(a => a.id !== asteroidId);});},updateAsteroid:(asteroidId,updates)=>{set(draft =>{for(let i = 0;i < draft.asteroids.length;i++){if(draft.asteroids[i].id === asteroidId){Object.assign(draft.asteroids[i],updates);break;}}});},updateSpacecraft:spacecraft =>{set(draft =>{draft.spacecraft = spacecraft;});},setSpacecraftPath:path =>{set(draft =>{draft.spacecraftPath = path;});},setIsControllingSpacecraft:isControlling =>{set(draft =>{draft.isControllingSpacecraft = isControlling;});},markAsteroidPassed:pairId =>{set(draft =>{for(let i = 0;i < draft.asteroids.length;i++){if(draft.asteroids[i].pairId === pairId){draft.asteroids[i].passed = true;}}draft.score = draft.score + 10;});},loseLife:()=>{set(draft =>{const newLives = draft.lives - 1;draft.spacecraft ={x:width / 2,y:getSpacecraftYPosition(draft.offset),velocityX:0,velocityY:0,size:GAME_CONFIG.SPACECRAFT_SIZE,isControlled:false};if(newLives <= 0){draft.lives = 0;draft.isPlaying = false;draft.gameOver = true;}else{draft.lives = newLives;}});}}))));
|
|
@@ -1,113 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { View } from 'react-native';
|
|
5
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
-
export const AsteroidComponent = /*#__PURE__*/React.memo(({
|
|
7
|
-
asteroid
|
|
8
|
-
}) => {
|
|
9
|
-
// Use regular View instead of Animated.View to avoid worklet issues
|
|
10
|
-
return /*#__PURE__*/_jsxs(View, {
|
|
11
|
-
style: {
|
|
12
|
-
position: 'absolute',
|
|
13
|
-
left: asteroid.x,
|
|
14
|
-
top: asteroid.y,
|
|
15
|
-
width: asteroid.width,
|
|
16
|
-
height: asteroid.height,
|
|
17
|
-
backgroundColor: '#6B4423',
|
|
18
|
-
// Darker brown for more realistic asteroid
|
|
19
|
-
borderRadius: 15,
|
|
20
|
-
// More rounded for organic look
|
|
21
|
-
shadowColor: '#2F1B14',
|
|
22
|
-
shadowOffset: {
|
|
23
|
-
width: 3,
|
|
24
|
-
height: 4
|
|
25
|
-
},
|
|
26
|
-
shadowOpacity: 0.7,
|
|
27
|
-
shadowRadius: 10,
|
|
28
|
-
// Add some texture with border
|
|
29
|
-
borderWidth: 1,
|
|
30
|
-
borderColor: 'rgba(139, 69, 19, 0.8)'
|
|
31
|
-
},
|
|
32
|
-
children: [/*#__PURE__*/_jsx(View, {
|
|
33
|
-
style: {
|
|
34
|
-
position: 'absolute',
|
|
35
|
-
left: 2,
|
|
36
|
-
top: 2,
|
|
37
|
-
width: asteroid.width - 4,
|
|
38
|
-
height: Math.max(0, asteroid.height - 4),
|
|
39
|
-
backgroundColor: 'rgba(160, 82, 45, 0.4)',
|
|
40
|
-
// Lighter brown highlight
|
|
41
|
-
borderRadius: 12
|
|
42
|
-
}
|
|
43
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
44
|
-
style: {
|
|
45
|
-
position: 'absolute',
|
|
46
|
-
left: asteroid.width * 0.25,
|
|
47
|
-
top: asteroid.height * 0.3,
|
|
48
|
-
width: 12,
|
|
49
|
-
height: 8,
|
|
50
|
-
backgroundColor: 'rgba(47, 27, 20, 0.8)',
|
|
51
|
-
// Dark crater
|
|
52
|
-
borderRadius: 6
|
|
53
|
-
}
|
|
54
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
55
|
-
style: {
|
|
56
|
-
position: 'absolute',
|
|
57
|
-
left: asteroid.width * 0.65,
|
|
58
|
-
top: asteroid.height * 0.6,
|
|
59
|
-
width: 8,
|
|
60
|
-
height: 6,
|
|
61
|
-
backgroundColor: 'rgba(47, 27, 20, 0.9)',
|
|
62
|
-
borderRadius: 4
|
|
63
|
-
}
|
|
64
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
65
|
-
style: {
|
|
66
|
-
position: 'absolute',
|
|
67
|
-
left: asteroid.width * 0.15,
|
|
68
|
-
top: asteroid.height * 0.7,
|
|
69
|
-
width: 5,
|
|
70
|
-
height: 4,
|
|
71
|
-
backgroundColor: 'rgba(47, 27, 20, 0.7)',
|
|
72
|
-
borderRadius: 2
|
|
73
|
-
}
|
|
74
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
75
|
-
style: {
|
|
76
|
-
position: 'absolute',
|
|
77
|
-
left: asteroid.width * 0.45,
|
|
78
|
-
top: asteroid.height * 0.2,
|
|
79
|
-
width: 4,
|
|
80
|
-
height: 4,
|
|
81
|
-
backgroundColor: 'rgba(101, 67, 33, 0.8)',
|
|
82
|
-
borderRadius: 2
|
|
83
|
-
}
|
|
84
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
85
|
-
style: {
|
|
86
|
-
position: 'absolute',
|
|
87
|
-
left: asteroid.width * 0.8,
|
|
88
|
-
top: asteroid.height * 0.4,
|
|
89
|
-
width: 3,
|
|
90
|
-
height: 3,
|
|
91
|
-
backgroundColor: 'rgba(139, 69, 19, 0.9)',
|
|
92
|
-
borderRadius: 1.5
|
|
93
|
-
}
|
|
94
|
-
}), /*#__PURE__*/_jsx(View, {
|
|
95
|
-
style: {
|
|
96
|
-
position: 'absolute',
|
|
97
|
-
left: asteroid.width * 0.1,
|
|
98
|
-
top: asteroid.height * 0.1,
|
|
99
|
-
width: asteroid.width * 0.3,
|
|
100
|
-
height: asteroid.height * 0.2,
|
|
101
|
-
backgroundColor: 'rgba(205, 133, 63, 0.3)',
|
|
102
|
-
// Light brown highlight
|
|
103
|
-
borderRadius: 8
|
|
104
|
-
}
|
|
105
|
-
})]
|
|
106
|
-
});
|
|
107
|
-
}, (prevProps, nextProps) => {
|
|
108
|
-
// Custom comparison for better performance
|
|
109
|
-
const prev = prevProps.asteroid;
|
|
110
|
-
const next = nextProps.asteroid;
|
|
111
|
-
return prev.id === next.id && prev.x === next.x && prev.y === next.y && prev.width === next.width && prev.height === next.height;
|
|
112
|
-
});
|
|
113
|
-
//# sourceMappingURL=AsteroidComponent.js.map
|
|
1
|
+
"use strict";import React from 'react';import{View}from 'react-native';import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";export const AsteroidComponent = React.memo(({asteroid})=>{return _jsxs(View,{style:{position:'absolute',left:asteroid.x,top:asteroid.y,width:asteroid.width,height:asteroid.height,backgroundColor:'#6B4423',borderRadius:15,shadowColor:'#2F1B14',shadowOffset:{width:3,height:4},shadowOpacity:0.7,shadowRadius:10,borderWidth:1,borderColor:'rgba(139,69,19,0.8)'},children:[_jsx(View,{style:{position:'absolute',left:2,top:2,width:asteroid.width - 4,height:Math.max(0,asteroid.height - 4),backgroundColor:'rgba(160,82,45,0.4)',borderRadius:12}}),_jsx(View,{style:{position:'absolute',left:asteroid.width * 0.25,top:asteroid.height * 0.3,width:12,height:8,backgroundColor:'rgba(47,27,20,0.8)',borderRadius:6}}),_jsx(View,{style:{position:'absolute',left:asteroid.width * 0.65,top:asteroid.height * 0.6,width:8,height:6,backgroundColor:'rgba(47,27,20,0.9)',borderRadius:4}}),_jsx(View,{style:{position:'absolute',left:asteroid.width * 0.15,top:asteroid.height * 0.7,width:5,height:4,backgroundColor:'rgba(47,27,20,0.7)',borderRadius:2}}),_jsx(View,{style:{position:'absolute',left:asteroid.width * 0.45,top:asteroid.height * 0.2,width:4,height:4,backgroundColor:'rgba(101,67,33,0.8)',borderRadius:2}}),_jsx(View,{style:{position:'absolute',left:asteroid.width * 0.8,top:asteroid.height * 0.4,width:3,height:3,backgroundColor:'rgba(139,69,19,0.9)',borderRadius:1.5}}),_jsx(View,{style:{position:'absolute',left:asteroid.width * 0.1,top:asteroid.height * 0.1,width:asteroid.width * 0.3,height:asteroid.height * 0.2,backgroundColor:'rgba(205,133,63,0.3)',borderRadius:8}})]});},(prevProps,nextProps)=>{const prev = prevProps.asteroid;const next = nextProps.asteroid;return prev.id === next.id && prev.x === next.x && prev.y === next.y && prev.width === next.width && prev.height === next.height;});
|