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