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