react-native-games 1.3.0 → 1.5.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/lib/module/games/balloon-blaster/BalloonBlaster.js +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterConstants.js +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterService.js +1 -1
- package/lib/module/games/balloon-blaster/BalloonBlasterStore.js +1 -1
- package/lib/module/games/balloon-blaster/components/BalloonComponent.js +1 -1
- package/lib/module/games/balloon-blaster/components/GameArea.js +1 -1
- package/lib/module/games/balloon-blaster/components/GameBackground.js +1 -1
- package/lib/module/games/balloon-blaster/components/ScoreBoard.js +1 -1
- package/lib/module/games/balloon-blaster/components/index.js +1 -1
- package/lib/module/games/bike-racing/BikeRacing.js +1 -1
- package/lib/module/games/bike-racing/BikeRacingConstants.js +1 -1
- package/lib/module/games/bike-racing/BikeRacingService.js +1 -1
- package/lib/module/games/bike-racing/BikeRacingStore.js +1 -1
- package/lib/module/games/bike-racing/components/BikeComponent.js +1 -1
- package/lib/module/games/bike-racing/components/GameBackground.js +1 -1
- package/lib/module/games/bike-racing/components/ScoreBoard.js +1 -1
- package/lib/module/games/bike-racing/components/index.js +1 -1
- package/lib/module/games/bike-racing/index.js +1 -1
- package/lib/module/games/block-blast/BlockBlast.js +1 -1
- package/lib/module/games/block-blast/BlockBlastConstants.js +1 -1
- package/lib/module/games/block-blast/BlockBlastService.js +1 -1
- package/lib/module/games/block-blast/BlockBlastStore.js +1 -1
- package/lib/module/games/block-blast/components/BlockPieceComponent.js +1 -1
- package/lib/module/games/block-blast/components/GameArea.js +1 -1
- package/lib/module/games/block-blast/components/GameBackground.js +1 -1
- package/lib/module/games/block-blast/components/GridComponent.js +1 -1
- package/lib/module/games/block-blast/components/ScoreBoard.js +1 -1
- package/lib/module/games/block-blast/components/index.js +1 -1
- package/lib/module/games/block-blast/index.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooter.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooterConstants.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooterService.js +1 -1
- package/lib/module/games/bubble-shooter/BubbleShooterStore.js +1 -1
- package/lib/module/games/bubble-shooter/components/GameArea.js +1 -1
- package/lib/module/games/bubble-shooter/components/GameBackground.js +1 -1
- package/lib/module/games/bubble-shooter/components/ScoreBoard.js +1 -1
- package/lib/module/games/bubble-shooter/components/index.js +1 -1
- package/lib/module/games/bubble-shooter/index.js +1 -1
- package/lib/module/games/candy-crush/CandyCrush.js +1 -1
- package/lib/module/games/candy-crush/CandyCrushConstants.js +1 -1
- package/lib/module/games/candy-crush/CandyCrushService.js +1 -1
- package/lib/module/games/candy-crush/CandyCrushStore.js +1 -1
- package/lib/module/games/candy-crush/components/CandyItem.js +1 -1
- package/lib/module/games/candy-crush/components/GameBackground.js +1 -1
- package/lib/module/games/candy-crush/components/GameGrid.js +1 -1
- package/lib/module/games/candy-crush/components/ScoreBoard.js +1 -1
- package/lib/module/games/candy-crush/components/index.js +1 -1
- package/lib/module/games/candy-crush/index.js +1 -1
- package/lib/module/games/car-racing/CarRacing.js +1 -1
- package/lib/module/games/car-racing/CarRacingConstants.js +1 -1
- package/lib/module/games/car-racing/CarRacingService.js +1 -1
- package/lib/module/games/car-racing/CarRacingStore.js +1 -1
- package/lib/module/games/car-racing/components/CarComponent.js +1 -1
- package/lib/module/games/car-racing/components/GameBackground.js +1 -1
- package/lib/module/games/car-racing/components/ScoreBoard.js +1 -1
- package/lib/module/games/car-racing/components/index.js +1 -1
- package/lib/module/games/colors-sort/ColorsSort.js +1 -1
- package/lib/module/games/colors-sort/ColorsSortConstants.js +1 -1
- package/lib/module/games/colors-sort/ColorsSortService.js +1 -1
- package/lib/module/games/colors-sort/ColorsSortStore.js +1 -1
- package/lib/module/games/colors-sort/components/ColorContainer.js +1 -1
- package/lib/module/games/colors-sort/components/GameBackground.js +1 -1
- package/lib/module/games/colors-sort/components/ScoreBoard.js +1 -1
- package/lib/module/games/colors-sort/components/index.js +1 -1
- package/lib/module/games/dino-jump/DinoJump.js +1 -1
- package/lib/module/games/dino-jump/DinoJumpConstants.js +1 -1
- package/lib/module/games/dino-jump/DinoJumpService.js +1 -1
- package/lib/module/games/dino-jump/DinoJumpStore.js +1 -1
- package/lib/module/games/dino-jump/components/DinoSprite.js +1 -1
- package/lib/module/games/dino-jump/components/GameArea.js +1 -1
- package/lib/module/games/dino-jump/components/GameBackground.js +1 -1
- package/lib/module/games/dino-jump/components/ObstacleSprite.js +1 -1
- package/lib/module/games/dino-jump/components/ScoreBoard.js +1 -1
- package/lib/module/games/dino-jump/components/StarSprite.js +1 -1
- package/lib/module/games/dino-jump/components/index.js +1 -1
- package/lib/module/games/flappy-bird/FlappyBird.js +1 -1
- package/lib/module/games/flappy-bird/FlappyBirdConstants.js +1 -1
- package/lib/module/games/flappy-bird/FlappyBirdStore.js +1 -1
- package/lib/module/games/flappy-bird/components/Bird.js +1 -1
- package/lib/module/games/flappy-bird/components/GameArea.js +1 -1
- package/lib/module/games/flappy-bird/components/GameBackground.js +1 -1
- package/lib/module/games/flappy-bird/components/Pipes.js +1 -1
- package/lib/module/games/flappy-bird/components/ScoreBoard.js +1 -1
- package/lib/module/games/flappy-bird/components/index.js +1 -1
- package/lib/module/games/fruit-merger/FruitMerger.js +1 -1
- package/lib/module/games/fruit-merger/FruitMergerConstants.js +1 -1
- package/lib/module/games/fruit-merger/FruitMergerService.js +1 -1
- package/lib/module/games/fruit-merger/FruitMergerStore.js +1 -1
- package/lib/module/games/fruit-merger/components/FruitItem.js +1 -1
- package/lib/module/games/fruit-merger/components/GameArea.js +1 -1
- package/lib/module/games/fruit-merger/components/GameBackground.js +1 -1
- package/lib/module/games/fruit-merger/components/ScoreBoard.js +1 -1
- package/lib/module/games/fruit-merger/components/index.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinja.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaConstants.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaService.js +1 -1
- package/lib/module/games/fruit-ninja/FruitNinjaStore.js +1 -1
- package/lib/module/games/fruit-ninja/components/FruitComponent.js +1 -1
- package/lib/module/games/fruit-ninja/components/GameArea.js +1 -1
- package/lib/module/games/fruit-ninja/components/GameBackground.js +1 -1
- package/lib/module/games/fruit-ninja/components/ScoreBoard.js +1 -1
- package/lib/module/games/fruit-ninja/components/index.js +1 -1
- package/lib/module/games/game-2048/Game2048.js +1 -1
- package/lib/module/games/game-2048/Game2048Constants.js +1 -1
- package/lib/module/games/game-2048/Game2048Service.js +1 -1
- package/lib/module/games/game-2048/Game2048Store.js +1 -1
- package/lib/module/games/game-2048/components/GameBackground.js +1 -1
- package/lib/module/games/game-2048/components/GameGrid.js +1 -1
- package/lib/module/games/game-2048/components/GameTile.js +1 -1
- package/lib/module/games/game-2048/components/ScoreBoard.js +1 -1
- package/lib/module/games/game-2048/components/index.js +1 -1
- package/lib/module/games/maze-runner/MazeRunner.js +1 -1
- package/lib/module/games/maze-runner/MazeRunnerConstants.js +1 -1
- package/lib/module/games/maze-runner/MazeRunnerService.js +1 -1
- package/lib/module/games/maze-runner/components/EnhancedBallComponent.js +1 -1
- package/lib/module/games/maze-runner/components/EnhancedGameArea.js +1 -1
- package/lib/module/games/maze-runner/components/GameBackground.js +1 -1
- package/lib/module/games/maze-runner/components/ScoreBoard.js +1 -1
- package/lib/module/games/maze-runner/components/SkiaPipeComponent.js +1 -1
- package/lib/module/games/maze-runner/components/StaticGameBackground.js +1 -1
- package/lib/module/games/maze-runner/components/WallComponent.js +1 -1
- package/lib/module/games/maze-runner/components/index.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircle.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircleConstants.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircleService.js +1 -1
- package/lib/module/games/perfect-circle/PerfectCircleStore.js +1 -1
- package/lib/module/games/perfect-circle/components/DrawingCanvas.js +1 -1
- package/lib/module/games/perfect-circle/components/GameBackground.js +1 -1
- package/lib/module/games/perfect-circle/components/ScoreBoard.js +1 -1
- package/lib/module/games/perfect-circle/index.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidget.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetConstants.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetService.js +1 -1
- package/lib/module/games/popit-fidget/PopitFidgetStore.js +1 -1
- package/lib/module/games/popit-fidget/components/BubbleComponent.js +1 -1
- package/lib/module/games/popit-fidget/components/FidgetGrid.js +1 -1
- package/lib/module/games/popit-fidget/components/GameBackground.js +1 -1
- package/lib/module/games/popit-fidget/components/ScoreBoard.js +1 -1
- package/lib/module/games/popit-fidget/components/index.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbers.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersConstants.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersService.js +1 -1
- package/lib/module/games/sliding-numbers/SlidingNumbersStore.js +1 -1
- package/lib/module/games/sliding-numbers/components/GameBackground.js +1 -1
- package/lib/module/games/sliding-numbers/components/NumbersGrid.js +1 -1
- package/lib/module/games/sliding-numbers/components/NumbersTile.js +1 -1
- package/lib/module/games/sliding-numbers/components/ScoreBoard.js +1 -1
- package/lib/module/games/sliding-numbers/components/index.js +1 -1
- package/lib/module/games/snake/Snake.js +1 -1
- package/lib/module/games/snake/SnakeConstants.js +1 -1
- package/lib/module/games/snake/SnakeService.js +1 -1
- package/lib/module/games/snake/SnakeStore.js +1 -1
- package/lib/module/games/snake/components/GameBackground.js +1 -1
- package/lib/module/games/snake/components/GameGrid.js +1 -1
- package/lib/module/games/snake/components/ScoreBoard.js +1 -1
- package/lib/module/games/snake/components/index.js +1 -1
- package/lib/module/games/snake/index.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighter.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighterConstants.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighterService.js +1 -1
- package/lib/module/games/space-fighter/SpaceFighterStore.js +1 -1
- package/lib/module/games/space-fighter/components/AsteroidComponent.js +1 -1
- package/lib/module/games/space-fighter/components/GameArea.js +1 -1
- package/lib/module/games/space-fighter/components/GameBackground.js +1 -1
- package/lib/module/games/space-fighter/components/ScoreBoard.js +1 -1
- package/lib/module/games/space-fighter/components/Spacecraft3D.js +1 -1
- package/lib/module/games/space-fighter/components/SpacecraftPath.js +1 -1
- package/lib/module/games/space-fighter/components/index.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMole.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleConstants.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleService.js +1 -1
- package/lib/module/games/whack-a-mole/WhackAMoleStore.js +1 -1
- package/lib/module/games/whack-a-mole/components/GameBackground.js +1 -1
- package/lib/module/games/whack-a-mole/components/GameGrid.js +1 -1
- package/lib/module/games/whack-a-mole/components/GameHole.js +1 -1
- package/lib/module/games/whack-a-mole/components/MoleCharacter.js +1 -1
- package/lib/module/games/whack-a-mole/components/ScoreBoard.js +1 -1
- package/lib/module/games/whack-a-mole/components/index.js +1 -1
- package/lib/module/helpers/AnimationFrame.js +1 -1
- package/lib/module/helpers/AnimationTracker.js +1 -1
- package/lib/module/helpers/ErrorHandler.js +1 -1
- package/lib/module/helpers/GameControlButton.js +1 -1
- package/lib/module/helpers/GameOverModal.js +1 -1
- package/lib/module/helpers/GameSettingsModal.js +1 -1
- package/lib/module/helpers/ParticleBlast.js +1 -1
- package/lib/module/helpers/ScoreBoardContainer.js +1 -1
- package/lib/module/helpers/index.js +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/services/GamesConstants.js +1 -1
- package/lib/module/services/GamesService.js +1 -1
- package/lib/module/services/HapticsService.js +1 -1
- package/lib/module/services/ScoringService.js +1 -1
- package/lib/module/services/SoundsService.js +1 -1
- package/lib/module/services/UtilsService.js +1 -1
- package/package.json +5 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{Dimensions}from
|
|
1
|
+
"use strict";import{Dimensions as e}from"react-native";const{width:t}=e.get("window");export const SLIDING_NUMBERS_CONSTANTS={gridSize:{easy:3,medium:4,hard:5},maxNumbers:{easy:8,medium:15,hard:24},baseScore:{easy:1e3,medium:2e3,hard:3e3},scoreMultiplier:{easy:5,medium:10,hard:15}};export const SLIDING_NUMBERS_GAME_CONFIG={TILE_SIZE:Math.min(.16*t,70),TILE_GAP:4,GRID_PADDING:20,GAME_DURATION:600,SHUFFLE_MOVES:100,ANIMATION_DURATION:200};export const SLIDING_NUMBERS_ANIMATION_CONFIG={TILE_SLIDE:{damping:25,stiffness:400,mass:1,restDisplacementThreshold:.01,restSpeedThreshold:.01},TILE_PRESS:{damping:15,stiffness:200},GESTURE:{activeScale:1.05,snapThreshold:.3,velocityThreshold:500},COMPLETION_CELEBRATION:{duration:500}};export const SLIDING_NUMBERS_COLORS={BACKGROUND:"#F5F5DC",GRID_BACKGROUND:"#FFFFFF",GRID_BORDER:"#E0E0E0",TILE_COLORS:["#FFB3D9","#B3E5FC","#C8E6C9","#FFF9C4","#E1BEE7","#FFCDD2","#B2DFDB","#F8BBD9","#A5D6A7","#FFECB3","#D1C4E9","#B3E5FC","#FFE0B2","#C8E6C9","#F8BBD9","#E0F2F1","#FCE4EC","#E8F5E8","#FFF3E0","#F3E5F5","#E1F5FE","#F9FBE7","#FFF8E1","#EFEBE9"],TILE_BORDER:"#D0D0D0",TILE_SHADOW:"rgba(0,0,0,0.1)",NUMBER_TEXT:"#333333",WORD_TEXT:"#666666",EMPTY_TILE:"#F8F8F8",SCORE_BOARD:"#f59e0b",SCORE_TEXT:"#FFFFFF",TIMER_TEXT:"#f59e0b",UI:"#f59e0b",BUTTON_ACTIVE:"#f59e0b",BUTTON_INACTIVE:"#fbbf24",TEXT_PRIMARY:"#FFFFFF",TEXT_SECONDARY:"#fef3c7",WHITE:"#FFFFFF",START_BUTTON:"#f59e0b",COMPLETION_OVERLAY:"rgba(245, 158, 11, 0.9)",BUTTON_BORDER:"#fbbf24"};export const NUMBER_WORDS={1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine",10:"ten",11:"eleven",12:"twelve",13:"thirteen",14:"fourteen",15:"fifteen",16:"sixteen",17:"seventeen",18:"eighteen",19:"nineteen",20:"twenty",21:"twenty-one",22:"twenty-two",23:"twenty-three",24:"twenty-four"};export const SLIDING_NUMBERS_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#f59e0b",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(245, 158, 11, 0.15)",sectionTitleColor:"#f59e0b",buttonSelectedColor:"#f59e0b",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(245, 158, 11, 0.3)",switchTrackColorTrue:"#f59e0b",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const SLIDING_NUMBERS_DIFFICULTY_DESCRIPTIONS={easy:"3x3 grid with numbers 1-8, perfect for beginners",medium:"4x4 grid with numbers 1-15, moderate challenge",hard:"5x5 grid with numbers 1-24, expert level puzzle"};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{SLIDING_NUMBERS_CONSTANTS}from
|
|
1
|
+
"use strict";import{SLIDING_NUMBERS_CONSTANTS as t}from"./SlidingNumbersConstants.js";export class SlidingNumbersService{gameTimer=null;createSolvedPuzzle(t){const e=[],r=t*t;for(let s=0;r>s;s++){const l=Math.floor(s/t),o=s%t,n=s===r-1?0:s+1;e.push({id:s,value:n,position:{row:l,col:o},isCorrect:!0})}return e}canMoveTile(t,e){const r=Math.abs(t.position.row-e.row),s=Math.abs(t.position.col-e.col);return 1===r&&0===s||0===r&&1===s}getMovableTiles(t,e){return t.filter(t=>0!==t.value&&this.canMoveTile(t,e))}isPuzzleSolvable(t,e){const r=[];let s=0;for(let l=0;e>l;l++)for(let o=0;e>o;o++){const e=t.find(t=>t.position.row===l&&t.position.col===o);e&&(0===e.value?s=l:r.push(e.value))}let l=0;for(let t=0;t<r.length-1;t++)for(let e=t+1;e<r.length;e++)(r[t]||0)>(r[e]||0)&&l++;return e%2==1?l%2==0:(e-s)%2==0?l%2==1:l%2==0}shufflePuzzle(t,e){const r=[...t];let s=0;do{const t=[];for(let r=0;e>r;r++)for(let s=0;e>s;s++)t.push({row:r,col:s});for(let e=t.length-1;e>0;e--){const r=Math.floor(Math.random()*(e+1)),s=t[e],l=t[r];s&&l&&([t[e],t[r]]=[l,s])}r.forEach((e,r)=>{const s=t[r];s&&(e.position=s)}),s++}while(!this.isPuzzleSolvable(r,e)&&100>s);return 100>s?(r.forEach((t,r)=>{const s=Math.floor(r/e),l=r%e;t.isCorrect=t.position.row===s&&t.position.col===l}),r):this.shuffleWithValidMoves(t,e)}shuffleWithValidMoves(t,e){const r=[...t];let s={row:e-1,col:e-1};for(let t=0;1e3>t;t++){const t=this.getMovableTiles(r,s);if(t.length>0){const e=t[Math.floor(Math.random()*t.length)],l=r.find(t=>0===t.value);if(l&&e){const t=e.position;e.position=s,l.position=t,s=t}}}return r.forEach((t,r)=>{const s=Math.floor(r/e),l=r%e;t.isCorrect=t.position.row===s&&t.position.col===l}),r}isPuzzleCompleted(t,e){return t.every((t,r)=>{const s=Math.floor(r/e),l=r%e;return t.position.row===s&&t.position.col===l})}calculateScore(e,r){const s=t.baseScore[r],l=t.scoreMultiplier[r];return Math.max(0,s-e*l)}getOptimalMoveCount(t){switch(t){case"easy":default:return 50;case"medium":return 100;case"hard":return 200}}startTimer(t){this.stopTimer(),this.gameTimer=setInterval(t,1e3)}stopTimer(){this.gameTimer&&(clearInterval(this.gameTimer),this.gameTimer=null)}getHint(t,e){const r=this.getMovableTiles(t,e),s=r.filter(t=>!t.isCorrect);return s.length>0?s[0]||null:r.length>0&&r[0]||null}formatTime(t){return`${Math.floor(t/60)}:${(""+t%60).padStart(2,"0")}`}getDifficultySettings(e){return{gridSize:t.gridSize[e],maxNumbers:t.maxNumbers[e],baseScore:t.baseScore[e],scoreMultiplier:t.scoreMultiplier[e]}}cleanup(){this.stopTimer()}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{create}from
|
|
1
|
+
"use strict";import{create as e}from"zustand";import{subscribeWithSelector as t}from"zustand/middleware";import{immerMiddleware as o}from"../../services/UtilsService.js";export const useSlidingNumbersStore=e()(t(o((e,t)=>({isPlaying:!1,isCompleted:!1,tiles:[],gridSize:3,emptyPosition:{row:2,col:2},score:0,timeLeft:600,timeElapsed:0,startTime:null,initializePuzzle:o=>{e(e=>{const t=[],s=o*o;for(let e=0;s>e;e++){const r=Math.floor(e/o),i=e%o,n=e===s-1?0:e+1;t.push({id:e,value:n,position:{row:r,col:i},isCorrect:!0})}e.tiles=t,e.gridSize=o,e.emptyPosition={row:o-1,col:o-1},e.score=0,e.timeLeft=600,e.timeElapsed=0,e.isCompleted=!1,e.isPlaying=!1,e.startTime=null}),t().shufflePuzzle()},moveTile:o=>{const s=t();if(!s.isPlaying||s.isCompleted)return!1;const r=s.tiles[o],i=s.emptyPosition,n=Math.abs(r.position.row-i.row),c=Math.abs(r.position.col-i.col);return(1===n&&0===c||0===n&&1===c)&&(e(e=>{const t=e.tiles[o];if(!t)return;const s=t.position,r=e.tiles.findIndex(e=>0===e.value),i=e.tiles[r];i&&(t.position=e.emptyPosition,i.position=s,e.emptyPosition=s,e.startTime&&(e.timeElapsed=Math.floor((Date.now()-e.startTime)/1e3)),e.tiles.forEach((t,o)=>{const s=Math.floor(o/e.gridSize),r=o%e.gridSize;t.isCorrect=t.position.row===s&&t.position.col===r}))}),!0)},moveTileInDirection:(e,o)=>{const s=t();if(!s.isPlaying||s.isCompleted)return!1;const r=s.tiles[e];if(!r)return!1;const i=s.emptyPosition;let n;switch(o){case"up":n={row:r.position.row-1,col:r.position.col};break;case"down":n={row:r.position.row+1,col:r.position.col};break;case"left":n={row:r.position.row,col:r.position.col-1};break;case"right":n={row:r.position.row,col:r.position.col+1}}return i.row===n.row&&i.col===n.col&&t().moveTile(e)},shufflePuzzle:()=>{e(e=>{for(let t=0;100>t;t++){const t=e.emptyPosition,o=[];if(e.tiles.forEach((e,s)=>{if(0===e.value)return;const r=Math.abs(e.position.row-t.row),i=Math.abs(e.position.col-t.col);(1===r&&0===i||0===r&&1===i)&&o.push(s)}),o.length>0){const t=Math.floor(Math.random()*o.length),s=o[t];if(void 0!==s){const t=e.tiles[s],o=e.tiles.findIndex(e=>0===e.value),r=e.tiles[o];if(t&&r){const o=t.position;t.position=e.emptyPosition,r.position=o,e.emptyPosition=o}}}}e.tiles.forEach((t,o)=>{const s=Math.floor(o/e.gridSize),r=o%e.gridSize;t.isCorrect=t.position.row===s&&t.position.col===r}),e.score=0,e.timeElapsed=0})},startGame:()=>{e(e=>{e.isPlaying=!0,e.isCompleted=!1,e.startTime=Date.now()})},stopGame:()=>{t().resetGame()},resetGame:()=>{e(e=>{e.isPlaying=!1,e.isCompleted=!1,e.score=0,e.timeLeft=600,e.timeElapsed=0,e.startTime=null})},decrementTime:()=>{e(e=>{e.timeLeft>0?(e.timeLeft--,e.startTime&&(e.timeElapsed=Math.floor((Date.now()-e.startTime)/1e3))):(e.isPlaying=!1,e.startTime=null)})},checkCompletion:o=>{const s=t();s.tiles.every(e=>e.isCorrect)&&s.isPlaying&&e(e=>{e.isCompleted=!0,e.isPlaying=!1;const t="easy"===o?5:"medium"===o?10:15,s=Math.max(0,("easy"===o?1e3:"medium"===o?2e3:3e3)-e.timeElapsed*t),r=e.timeLeft*t;e.score=s+r})},updateScore:t=>{e(e=>{e.score+=t})}}))));export const useGameState=()=>useSlidingNumbersStore(e=>({isPlaying:e.isPlaying,isCompleted:e.isCompleted}));export const useScore=()=>useSlidingNumbersStore(e=>e.score);export const useTimeLeft=()=>useSlidingNumbersStore(e=>e.timeLeft);export const useTimeElapsed=()=>useSlidingNumbersStore(e=>e.timeElapsed);export const useTiles=()=>useSlidingNumbersStore(e=>e.tiles);export const useGridSize=()=>useSlidingNumbersStore(e=>e.gridSize);export const useEmptyPosition=()=>useSlidingNumbersStore(e=>e.emptyPosition);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import t from"react";import{View as r,Dimensions as h}from"react-native";import{Canvas as o,LinearGradient as i,Rect as e,vec as a,Circle as c,RoundedRect as l}from"@shopify/react-native-skia";import{jsx as n,jsxs as d}from"react/jsx-runtime";const{width:s,height:g}=h.get("window"),x=["#E91E63","#F44336","#FF5722","#FF9800","#FFC107","#CDDC39","#4CAF50","#009688","#00BCD4","#2196F3","#3F51B5","#9C27B0"];export const GameBackground=t.memo(({children:h})=>{const y=t.useMemo(()=>{const t=[];for(let r=0;25>r;r++){const h=g/25*r,o=s/25*r+50*Math.sin(.5*r)+100*Math.random(),i=h+60*Math.cos(.7*r)+120*Math.random(),e=20+20*Math.random(),a=r%12,d=.3+.15*Math.sin(r),y=Math.max(e/2,Math.min(s-e,o)),w=Math.max(e/2,Math.min(g-e,i));r%4==0?t.push(n(l,{x:y,y:w,width:e,height:e,r:.2*e,color:`${x[a]}${Math.floor(255*d).toString(16).padStart(2,"0")}`},"square-tile-"+r)):r%4==1?t.push(n(l,{x:y,y:w,width:.6*e,height:e,r:.15*e,color:`${x[a]}${Math.floor(255*d).toString(16).padStart(2,"0")}`},"rect-tile-"+r)):r%4==2?t.push(n(l,{x:y,y:w,width:1.2*e,height:.8*e,r:.1*e,color:`${x[a]}${Math.floor(255*d).toString(16).padStart(2,"0")}`},"wide-tile-"+r)):t.push(n(c,{cx:y+e/2,cy:w+e/2,r:e/2,color:`${x[a]}${Math.floor(255*d).toString(16).padStart(2,"0")}`},"circle-tile-"+r))}return t},[s,g]);return d(r,{style:{flex:1},children:[d(o,{style:{position:"absolute",top:0,left:0,right:0,bottom:0,width:s,height:g},children:[n(e,{x:0,y:0,width:s,height:g,children:n(i,{start:a(0,0),end:a(s,g),colors:[x[0]+"30",x[3]+"25",x[6]+"30",x[9]+"25",x[11]+"30"]})}),n(e,{x:0,y:0,width:s,height:g,children:n(i,{start:a(0,0),end:a(s/2,g/2),colors:[x[1]+"20","transparent",x[4]+"20","transparent",x[7]+"20","transparent"]})}),n(e,{x:0,y:0,width:s,height:g,children:n(i,{start:a(s,0),end:a(0,g),colors:[x[2]+"15","transparent",x[5]+"15","transparent",x[8]+"15","transparent"]})}),y,n(l,{x:.08*s,y:.12*g,width:50,height:50,r:8,color:x[0]+"50"}),n(l,{x:.85*s,y:.82*g,width:45,height:45,r:7,color:x[3]+"50"}),n(l,{x:.82*s,y:.18*g,width:40,height:40,r:6,color:x[6]+"50"}),n(l,{x:.12*s,y:.75*g,width:55,height:55,r:9,color:x[9]+"50"}),n(l,{x:.47*s,y:.08*g,width:35,height:35,r:5,color:x[11]+"50"}),n(l,{x:.15*s,y:.47*g,width:42,height:42,r:6,color:x[5]+"50"}),n(l,{x:.75*s,y:.57*g,width:38,height:38,r:6,color:x[8]+"50"}),n(l,{x:.57*s,y:.87*g,width:32,height:32,r:5,color:x[1]+"50"}),n(c,{cx:.25*s,cy:.25*g,r:18,color:x[4]+"45"}),n(c,{cx:.65*s,cy:.35*g,r:22,color:x[7]+"45"}),n(c,{cx:.35*s,cy:.65*g,r:16,color:x[10]+"45"}),Array.from({length:Math.floor(s/60)},(t,r)=>n(e,{x:60*r,y:0,width:1,height:g,color:"rgba(255, 255, 255, 0.05)"},"grid-v-"+r)),Array.from({length:Math.floor(g/60)},(t,r)=>n(e,{x:0,y:60*r,width:s,height:1,color:"rgba(255, 255, 255, 0.05)"},"grid-h-"+r))]}),h]})});GameBackground.displayName="GameBackground";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import t,{useMemo as e}from"react";import{View as r,StyleSheet as i,Dimensions as o}from"react-native";import n,{useAnimatedStyle as s,withSpring as a,useSharedValue as c,withSequence as l}from"react-native-reanimated";import{NumbersTile as d}from"./NumbersTile.js";import{useTiles as h,useGridSize as m,useEmptyPosition as u,useSlidingNumbersStore as f}from"../SlidingNumbersStore.js";import{SLIDING_NUMBERS_GAME_CONFIG as g,SLIDING_NUMBERS_ANIMATION_CONFIG as w}from"../SlidingNumbersConstants.js";import{jsx as p}from"react/jsx-runtime";export const NumbersGrid=t.memo(({difficulty:i})=>{const j=h(),y=m(),S=u(),C=f(t=>t.isPlaying),F=f(t=>t.isCompleted),M=f(t=>t.moveTile),N=f(t=>t.checkCompletion),v=c(1),x=e(()=>{const t=g.TILE_GAP,e=2*(t+8),{width:r}=o.get("window"),i=Math.max(45,Math.min(80,Math.floor((r-e-40-t*(y-1))/y))),n=i*y+t*(y-1),s=n+e;return{width:s,height:s,contentWidth:n,contentHeight:n,tileSize:i,gap:t}},[y]),G=e(()=>{const t=[];for(let e=0;y>e;e++){t[e]=[];for(let r=0;y>r;r++){const i=t[e];i&&(i[r]=null)}}return j.forEach(e=>{const{row:r,col:i}=e.position;r>=0&&y>r&&i>=0&&y>i&&t[r]&&(t[r][i]=e)}),t},[j,y]),z=t.useCallback(t=>{C&&!F&&M(t)&&N(i)},[C,F,M,N,i]),I=t.useCallback(t=>{if(!t||0===t.value||!C||F)return!1;const e=S,r=Math.abs(t.position.row-e.row),i=Math.abs(t.position.col-e.col);return 1===r&&0===i||0===r&&1===i},[S,C,F]),O=s(()=>({transform:[{scale:v.value}]}));t.useEffect(()=>{F&&(v.value=l(a(1.1,w.COMPLETION_CELEBRATION),a(1,w.COMPLETION_CELEBRATION)))},[F]);const R=e(()=>[b.gridContainer,{width:x.width,height:x.height},O],[x.width,x.height,O]),$=t.useCallback(t=>[b.tileSlot,{width:t,height:t}],[]);return p(n.View,{style:R,children:G.map((t,e)=>p(r,{style:b.row,children:t.map((t,i)=>p(r,{style:$(x.tileSize),children:t&&0!==t.value&&p(d,{tile:t,onPress:z,isMovable:I(t),tileSize:x.tileSize})},`${e}-${i}`))},e))})});const b=i.create({gridContainer:{backgroundColor:"#FFFFFF",borderRadius:20,padding:g.TILE_GAP+8,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.1,shadowRadius:8,elevation:8,alignSelf:"center"},row:{flexDirection:"row",justifyContent:"center",alignItems:"center"},tileSlot:{justifyContent:"center",alignItems:"center",margin:g.TILE_GAP/2}});NumbersGrid.displayName="NumbersGrid";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import t from"react";import{StyleSheet as e,TouchableOpacity as r,Text as o}from"react-native";import i,{useSharedValue as n,useAnimatedStyle as s,withSpring as a,runOnJS as l}from"react-native-reanimated";import{SLIDING_NUMBERS_COLORS as m,SLIDING_NUMBERS_GAME_CONFIG as c,SLIDING_NUMBERS_ANIMATION_CONFIG as d,NUMBER_WORDS as u}from"../SlidingNumbersConstants.js";import{jsx as h,jsxs as b}from"react/jsx-runtime";const f=i.createAnimatedComponent(r);export const NumbersTile=t.memo(({tile:e,onPress:r,isMovable:i,tileSize:c})=>{const p=n(1),w=n(0===e.value?0:1),S=t.useCallback(()=>{0!==e.value&&i&&(p.value=a(.95,d.TILE_PRESS,()=>{p.value=a(1,d.TILE_PRESS)}),l(r)(e.id))},[e.value,e.id,i,r,p]),y=s(()=>({transform:[{scale:p.value}],opacity:w.value}));if(0===e.value)return null;const{tileColor:z,numberWord:C}=t.useMemo(()=>{const t=(e.value-1)%m.TILE_COLORS.length;return{tileColor:m.TILE_COLORS[t]||m.TILE_COLORS[0],numberWord:u[e.value]||""}},[e.value]),{numberFontSize:x,wordFontSize:F}=t.useMemo(()=>({numberFontSize:Math.max(16,.4*c),wordFontSize:Math.max(8,.15*c)}),[c]);return b(f,{style:[g.tile,{width:c,height:c,backgroundColor:z,borderColor:e.isCorrect?"transparent":"#FF4444",borderWidth:e.isCorrect?0:2},y],onPress:S,activeOpacity:.8,disabled:!i||0===e.value,children:[h(o,{style:[g.number,{fontSize:x}],children:e.value}),h(o,{style:[g.word,{fontSize:F}],children:C})]})},(t,e)=>t.tile.id===e.tile.id&&t.tile.value===e.tile.value&&t.tile.isCorrect===e.tile.isCorrect&&t.tile.position.row===e.tile.position.row&&t.tile.position.col===e.tile.position.col&&t.isMovable===e.isMovable&&t.tileSize===e.tileSize);const g=e.create({tile:{margin:c.TILE_GAP/2,justifyContent:"center",alignItems:"center",borderRadius:16,shadowColor:"#000",shadowOffset:{width:0,height:3},shadowOpacity:.15,shadowRadius:6,elevation:6},number:{fontWeight:"bold",color:"#000000",textAlign:"center",marginBottom:2},word:{fontWeight:"normal",color:"#000000",textAlign:"center"}});NumbersTile.displayName="NumbersTile";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import e,{useMemo as o}from"react";import{View as r,Text as t,StyleSheet as i}from"react-native";import{useTimeElapsed as n}from"../SlidingNumbersStore.js";import{SlidingNumbersService as s}from"../SlidingNumbersService.js";import{ScoreBoardContainer as c}from"../../../helpers/index.js";import{jsx as l,jsxs as a}from"react/jsx-runtime";export const ScoreBoard=e.memo(({offset:e=0})=>{const i=o(()=>new s,[]),f=n(),d=o(()=>i.formatTime(f),[i,f]);return l(c,{offset:e,backgroundColor:"rgba(245, 245, 220, 0.6)",borderColor:"rgba(255, 255, 255, 0.3)",children:l(r,{style:m.scoreBoard,children:a(r,{style:m.scoreSection,children:[l(t,{style:m.scoreLabel,children:"Time Elapsed"}),l(t,{style:[m.timeValue,{color:"#3b82f6"}],children:d})]})})})});const m=i.create({scoreBoard:{flexDirection:"row",justifyContent:"space-between",alignItems:"center"},scoreSection:{alignItems:"center",flex:1},scoreLabel:{fontSize:16,fontWeight:"bold",color:"#4a5568",marginBottom:4},timeValue:{fontSize:25,fontWeight:"bold"},hintText:{fontSize:18,fontWeight:"600",color:"#10b981"}});ScoreBoard.displayName="ScoreBoard";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export{NumbersTile}from
|
|
1
|
+
"use strict";export{NumbersTile}from"./NumbersTile.js";export{NumbersGrid}from"./NumbersGrid.js";export{ScoreBoard}from"./ScoreBoard.js";export{GameBackground}from"./GameBackground.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import t from"react";import{View as e,StyleSheet as r}from"react-native";import{GestureHandlerRootView as o,Gesture as n,GestureDetector as a}from"react-native-gesture-handler";import{runOnJS as s}from"react-native-reanimated";import{GameControlButton as i,GameOverModal as c,GameSettingsModal as m}from"../../helpers/index.js";import{DEFAULT_GAME_SETTINGS as l,GAME_IDS as f}from"../../services/UtilsService.js";import{GameBackground as u,GameGrid as p,ScoreBoard as d}from"./components/index.js";import{useSnakeStore as g,useScore as S,useIsPlaying as h,useIsGameOver as b}from"./SnakeStore.js";import{SNAKE_COLORS as x}from"./SnakeConstants.js";import{jsx as y,jsxs as C}from"react/jsx-runtime";export const Snake=t.memo(({settings:r,onSettingsChange:v,onEndGame:B})=>{const T=S(),k=h(),G=b(),P=t.useRef(!1),A=t.useCallback(t=>{B&&!P.current&&(B({status:t,score:T.toString()}),P.current=!0)},[B,T]),F=g(t=>t.startGame),H=g(t=>t.stopGame),I=g(t=>t.resetGame),E=g(t=>t.initializeGame),M=g(t=>t.updateSettings),O=g(t=>t.changeDirection),R=t.useRef({enableSounds:!0,enableHaptics:!0}),U=t.useRef("easy");t.useEffect(()=>{const t=r?.enableSounds??!0,e=r?.enableHaptics??!0;R.current.enableSounds===t&&R.current.enableHaptics===e||(R.current={enableSounds:t,enableHaptics:e},M(t,e))},[M,r?.enableSounds,r?.enableHaptics]),t.useEffect(()=>{const t=r?.difficulty||"easy";U.current!==t&&(U.current=t,E(t))},[E,r?.difficulty]),t.useEffect(()=>{G&&!P.current&&A("lose"),G||(P.current=!1)},[G,A]);const q=t.useCallback(()=>{P.current=!1,F()},[F]),w=t.useCallback(()=>{I()},[I]),D=t.useCallback(()=>{A("cancel"),H()},[H,A]),L=t.useCallback(t=>{try{if(!k)return;requestAnimationFrame(()=>{try{O(t)}catch(t){}})}catch(t){}},[k,O]),N=t.useMemo(()=>n.Pan().onEnd(t=>{const e=Math.abs(t.translationX),r=Math.abs(t.translationY);(e>30||r>30)&&(e>r?t.translationX>0?s(L)("RIGHT"):s(L)("LEFT"):t.translationY>0?s(L)("DOWN"):s(L)("UP"))}),[L]),V=t.useMemo(()=>({isPlaying:k,gameOver:G,onStartGame:q,onStopGame:D,onResetGame:w,startButtonText:"Start Slithering!",startButtonSubtext:"Swipe to move or turn.",startButtonColor:x.BUTTON_PRIMARY,startButtonBorderColor:x.BUTTON_SECONDARY}),[k,G,q,D,w]),W=t.useMemo(()=>({isVisible:G,score:T,onPlayAgain:w,buttonText:"Play Again!",primaryColor:"rgba(0, 204, 106, 0.5)",borderColor:"rgba(0, 204, 106, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#00cc6a",scoreFormatter:t=>""+t}),[G,T,w]),z=t.useMemo(()=>({gameId:f.SNAKE,settings:r||l,onSettingsChange:v}),[r,v]),J=r?.offset??0;return y(u,{children:C(o,{style:j.container,children:[y(a,{gesture:N,children:y(e,{style:j.container,children:y(e,{style:[j.gridContainer,{paddingTop:J}],children:y(p,{})})})}),y(d,{offset:J}),y(i,{...V}),y(c,{...W}),y(m,{...z})]})})});Snake.displayName="Snake";const j=r.create({container:{flex:1},gridContainer:{flex:1,justifyContent:"center",alignItems:"center"}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{Dimensions}from
|
|
1
|
+
"use strict";import{Dimensions as e}from"react-native";const{width:t}=e.get("window");export const SNAKE_GAME_CONFIG={GRID_SIZE:20,CELL_SIZE:Math.floor((t-40)/20),GAME_SPEED:{easy:400,medium:300,hard:200},POINTS_PER_FOOD:10,POINTS_PER_SPECIAL_FOOD:25,DIFFICULTY_MULTIPLIER:{easy:1,medium:2,hard:3},SPECIAL_FOOD_CHANCE:.15,SPECIAL_FOOD_DURATION:5e3,INITIAL_SNAKE_LENGTH:3};export const SNAKE_COLORS={BACKGROUND:"#252541",GRID_LINE:"rgba(255, 255, 255, 0.15)",SNAKE_HEAD:"#00ff88",SNAKE_BODY:"#00cc6a",SNAKE_TAIL:"#00994d",SNAKE_OUTLINE:"#004d26",FOOD_NORMAL:"#ff4757",FOOD_SPECIAL:"#ffa502",FOOD_GLOW:"rgba(255, 71, 87, 0.5)",SCORE_TEXT:"#ffffff",SCORE_BACKGROUND:"rgba(0, 255, 136, 0.2)",BUTTON_PRIMARY:"#00cc6a",BUTTON_SECONDARY:"#00994d",MODAL_PRIMARY:"rgba(0, 255, 136, 0.95)",MODAL_BORDER:"rgba(0, 204, 106, 0.9)",MODAL_BUTTON:"#00ff88",MODAL_BUTTON_BORDER:"#00cc6a",COLLISION_COLOR:"#ff4757"};export const DIRECTIONS={UP:{x:0,y:-1},DOWN:{x:0,y:1},LEFT:{x:-1,y:0},RIGHT:{x:1,y:0}};export const SNAKE_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#00cc6a",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(0, 204, 106, 0.15)",sectionTitleColor:"#00cc6a",buttonSelectedColor:"#00cc6a",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(0, 204, 106, 0.3)",switchTrackColorTrue:"#00cc6a",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const SNAKE_DIFFICULTY_DESCRIPTIONS={easy:"Slow speed \u2022 1x points \u2022 Perfect for beginners",medium:"Medium speed \u2022 2x points \u2022 Balanced challenge",hard:"Fast speed \u2022 3x points \u2022 Expert level"};export const SNAKE_SOUNDS={EAT:{text:"Nom!",pitch:1.2,rate:1.5},SPECIAL:{text:"Bonus!",pitch:1.5,rate:2},COLLISION:{text:"Ouch!",pitch:.8,rate:1.2},WIN:{text:"Victory!",pitch:1.6,rate:1.8},LOSE:{text:"Game Over",pitch:.8,rate:1.2}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{SNAKE_GAME_CONFIG,DIRECTIONS}from
|
|
1
|
+
"use strict";import{SNAKE_GAME_CONFIG as t,DIRECTIONS as e}from"./SnakeConstants.js";export class SnakeService{nextId=1;initializeSnake(){const e=Math.floor(t.GRID_SIZE/2),r=Math.floor(t.GRID_SIZE/2),n=[];for(let i=0;i<t.INITIAL_SNAKE_LENGTH;i++)n.push({id:this.nextId++,x:e-i,y:r});return n}generateFood(e,r=!1){let n,i=0;do{n={x:Math.floor(Math.random()*t.GRID_SIZE),y:Math.floor(Math.random()*t.GRID_SIZE)},i++}while(100>i&&this.isPositionOnSnake(n,e));const o={id:this.nextId++,x:n.x,y:n.y,isSpecial:r};return r&&(o.expiresAt=Date.now()+t.SPECIAL_FOOD_DURATION),o}isPositionOnSnake(t,e){return e.some(e=>e.x===t.x&&e.y===t.y)}moveSnake(t,r){const n=t[0];if(!n)return t;const i=e[r],o=[{id:this.nextId++,x:n.x+i.x,y:n.y+i.y},...t];return o.pop(),o}checkWallCollision(e){return 0>e.x||e.x>=t.GRID_SIZE||0>e.y||e.y>=t.GRID_SIZE}checkSelfCollision(t){const e=t[0];if(!e)return!1;for(let r=1;r<t.length;r++){const n=t[r];if(n&&e.x===n.x&&e.y===n.y)return!0}return!1}checkFoodCollision(t,e){return t.x===e.x&&t.y===e.y}growSnake(t){const e=t[t.length-1];if(!e)return t;const r={id:this.nextId++,x:e.x,y:e.y};return[...t,r]}isValidDirectionChange(t,e){return{UP:"DOWN",DOWN:"UP",LEFT:"RIGHT",RIGHT:"LEFT"}[t]!==e}getOppositeDirection(t){return{UP:"DOWN",DOWN:"UP",LEFT:"RIGHT",RIGHT:"LEFT"}[t]}resetIdCounter(){this.nextId=1}isSpecialFoodExpired(t){return!(!t.isSpecial||!t.expiresAt)&&Date.now()>t.expiresAt}calculateScore(e,r){return(e?t.POINTS_PER_SPECIAL_FOOD:t.POINTS_PER_FOOD)*t.DIFFICULTY_MULTIPLIER[r]}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{create}from
|
|
1
|
+
"use strict";import{create as e}from"zustand";import{subscribeWithSelector as t}from"zustand/middleware";import{immerMiddleware as n}from"../../services/UtilsService.js";import{SnakeService as s}from"./SnakeService.js";import{SNAKE_GAME_CONFIG as r,SNAKE_SOUNDS as o}from"./SnakeConstants.js";import{playSound as a}from"../../services/SoundsService.js";import{playHaptic as l,HapticType as c}from"../../services/HapticsService.js";const i=new s;export const useSnakeStore=e()(t(n((e,t)=>({snake:i.initializeSnake(),food:null,direction:"RIGHT",nextDirection:"RIGHT",score:0,timeLeft:300,isPlaying:!1,isGameOver:!1,isPaused:!1,difficulty:"easy",enableSounds:!0,enableHaptics:!0,moveTimer:null,countdownTimer:null,startGame:()=>{const n=t();n.moveTimer&&clearInterval(n.moveTimer),n.countdownTimer&&clearInterval(n.countdownTimer);const s=i.generateFood(n.snake,!1),o=r.GAME_SPEED[n.difficulty],a=setInterval(()=>{const e=t();e.isPlaying&&!e.isPaused&&e.gameLoop()},o),l=setInterval(()=>{const e=t();e.isPlaying&&!e.isPaused&&e.decrementTime()},1e3);e(e=>{e.isPlaying=!0,e.isPaused=!1,e.food=s,e.moveTimer=a,e.countdownTimer=l})},stopGame:()=>{const e=t();e.moveTimer&&clearInterval(e.moveTimer),e.countdownTimer&&clearInterval(e.countdownTimer),a(o.LOSE,e.enableSounds),l(c.MEDIUM,e.enableHaptics),e.initializeGame(e.difficulty)},pauseGame:()=>{e(e=>{e.isPaused=!0})},resumeGame:()=>{e(e=>{e.isPaused=!1})},resetGame:()=>{const e=t();e.initializeGame(e.difficulty)},initializeGame:(n="easy")=>{const s=t();s.moveTimer&&clearInterval(s.moveTimer),s.countdownTimer&&clearInterval(s.countdownTimer),i.resetIdCounter();const r=i.initializeSnake(),o="easy"===n?300:600;e(e=>{e.snake=r,e.food=null,e.direction="RIGHT",e.nextDirection="RIGHT",e.score=0,e.timeLeft=o,e.isPlaying=!1,e.isGameOver=!1,e.isPaused=!1,e.difficulty=n,e.moveTimer=null,e.countdownTimer=null})},changeDirection:n=>{const s=t();s.isPlaying&&!s.isPaused&&i.isValidDirectionChange(s.direction,n)&&e(e=>{e.nextDirection=n})},gameLoop:()=>{const n=t();!n.isPlaying||n.isPaused||n.isGameOver||e(e=>{e.direction=e.nextDirection;const t=i.moveSnake(e.snake,e.direction),n=t[0];if(n){if(i.checkWallCollision(n))return e.isGameOver=!0,e.isPlaying=!1,e.moveTimer&&(clearInterval(e.moveTimer),e.moveTimer=null),e.countdownTimer&&(clearInterval(e.countdownTimer),e.countdownTimer=null),a(o.COLLISION,e.enableSounds),void l(c.HEAVY,e.enableHaptics);if(i.checkSelfCollision(t))return e.isGameOver=!0,e.isPlaying=!1,e.moveTimer&&(clearInterval(e.moveTimer),e.moveTimer=null),e.countdownTimer&&(clearInterval(e.countdownTimer),e.countdownTimer=null),a(o.COLLISION,e.enableSounds),void l(c.HEAVY,e.enableHaptics);if(e.food&&i.checkFoodCollision(n,e.food)){const n=i.growSnake(t);e.snake=n;const s=i.calculateScore(e.food.isSpecial,e.difficulty);e.score+=s;const u=e.food.isSpecial?o.SPECIAL:o.EAT;a(u,e.enableSounds),l(e.food.isSpecial?c.HEAVY:c.MEDIUM,e.enableHaptics);const m=Math.random()<r.SPECIAL_FOOD_CHANCE;e.food=i.generateFood(n,m)}else e.snake=t;e.food&&i.isSpecialFoodExpired(e.food)&&(e.food=i.generateFood(e.snake,!1))}})},updateSettings:(t,n)=>{e(e=>{e.enableSounds=t,e.enableHaptics=n})},decrementTime:()=>{e(e=>{e.timeLeft>0?e.timeLeft--:(e.isGameOver=!0,e.isPlaying=!1,e.moveTimer&&(clearInterval(e.moveTimer),e.moveTimer=null),e.countdownTimer&&(clearInterval(e.countdownTimer),e.countdownTimer=null))})}}))));export const useSnake=()=>useSnakeStore(e=>e.snake);export const useFood=()=>useSnakeStore(e=>e.food);export const useScore=()=>useSnakeStore(e=>e.score);export const useTimeLeft=()=>useSnakeStore(e=>e.timeLeft);export const useIsPlaying=()=>useSnakeStore(e=>e.isPlaying);export const useIsGameOver=()=>useSnakeStore(e=>e.isGameOver);export const useIsPaused=()=>useSnakeStore(e=>e.isPaused);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import t from"react";import{Canvas as r,Rect as a,LinearGradient as o,vec as h,Circle as c,RoundedRect as e}from"@shopify/react-native-skia";import{Dimensions as i,View as n}from"react-native";import{jsx as l,jsxs as s}from"react/jsx-runtime";const{width:d,height:x}=i.get("window"),y=["#00ff88","#00ffaa","#00cc6a","#00dd77","#00ff99","#00ee77","#00bb55","#00aa44"];export const GameBackground=t.memo(({children:i})=>{const g=t.useMemo(()=>{const t=[];for(let r=0;20>r;r++){const a=x/20*r,o=d/20*r+60*Math.sin(.5*r)+80*Math.random(),h=a+70*Math.cos(.7*r)+100*Math.random(),i=15+25*Math.random(),n=r%8,s=.15+.1*Math.sin(r),g=Math.max(i/2,Math.min(d-i,o)),f=Math.max(i/2,Math.min(x-i,h));r%3==0?t.push(l(c,{cx:g+i/2,cy:f+i/2,r:i/2,color:`${y[n]}${Math.floor(255*s).toString(16).padStart(2,"0")}`},"circle-"+r)):t.push(l(e,{x:g,y:f,width:i,height:i,r:.3*i,color:`${y[n]}${Math.floor(255*s).toString(16).padStart(2,"0")}`},"rect-"+r))}return t},[]);return s(n,{style:{flex:1},children:[s(r,{style:{position:"absolute",top:0,left:0,right:0,bottom:0,width:d,height:x},children:[l(a,{x:0,y:0,width:d,height:x,children:l(o,{start:h(0,0),end:h(d,x),colors:["#1a1a2e","#252541","#1e3a3a","#1a2e1a","#1a1a2e"]})}),l(a,{x:0,y:0,width:d,height:x,children:l(o,{start:h(0,0),end:h(d/2,x/2),colors:[y[0]+"15","transparent",y[1]+"10","transparent",y[4]+"15","transparent"]})}),l(a,{x:0,y:0,width:d,height:x,children:l(o,{start:h(d,0),end:h(0,x),colors:[y[2]+"12","transparent",y[5]+"10","transparent",y[3]+"12","transparent"]})}),g,l(c,{cx:.12*d,cy:.15*x,r:35,color:y[0]+"30"}),l(e,{x:.82*d,y:.78*x,width:45,height:45,r:12,color:y[1]+"35"}),l(c,{cx:.85*d,cy:.2*x,r:28,color:y[2]+"30"}),l(e,{x:.08*d,y:.75*x,width:50,height:50,r:15,color:y[3]+"35"}),l(c,{cx:.5*d,cy:.1*x,r:25,color:y[4]+"28"}),l(e,{x:.1*d,y:.45*x,width:40,height:40,r:10,color:y[5]+"32"}),l(c,{cx:.88*d,cy:.55*x,r:30,color:y[6]+"30"}),l(e,{x:.55*d,y:.85*x,width:35,height:35,r:8,color:y[7]+"33"}),l(c,{cx:.3*d,cy:.3*x,r:20,color:y[0]+"25"}),l(c,{cx:.7*d,cy:.4*x,r:24,color:y[1]+"28"}),l(c,{cx:.4*d,cy:.65*x,r:18,color:y[2]+"26"}),Array.from({length:Math.floor(d/70)},(t,r)=>l(a,{x:70*r,y:0,width:1,height:x,color:"rgba(0, 255, 136, 0.04)"},"grid-v-"+r)),Array.from({length:Math.floor(x/70)},(t,r)=>l(a,{x:0,y:70*r,width:d,height:1,color:"rgba(0, 255, 136, 0.04)"},"grid-h-"+r))]}),i]})});GameBackground.displayName="GameBackground";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import r from"react";import{View as t,StyleSheet as o}from"react-native";import{Canvas as e,RoundedRect as c,Circle as i,Group as n,Shadow as h}from"@shopify/react-native-skia";import{useSnake as l,useFood as d}from"../SnakeStore.js";import{SNAKE_GAME_CONFIG as a,SNAKE_COLORS as s}from"../SnakeConstants.js";import{jsx as m,jsxs as x,Fragment as y}from"react/jsx-runtime";export const GameGrid=r.memo(()=>{const o=l(),f=d(),b=a.CELL_SIZE,u=a.GRID_SIZE,p=b*u,w=r.useMemo(()=>{const r=[];for(let t=0;u>=t;t++)r.push(t);return r},[u]);return m(t,{style:g.container,children:m(t,{style:[g.gridContainer,{width:p,height:p}],children:m(e,{style:{width:p,height:p},children:x(n,{children:[m(c,{x:0,y:0,width:p,height:p,r:15,color:s.BACKGROUND,children:m(h,{dx:0,dy:4,blur:8,color:"rgba(0, 0, 0, 0.3)"})}),w.map(r=>m(c,{x:r===u?p-2:r*b,y:0,width:0===r||r===u?2:1,height:p,r:0,color:s.GRID_LINE},"v-"+r)),w.map(r=>m(c,{x:0,y:r===u?p-2:r*b,width:p,height:0===r||r===u?2:1,r:0,color:s.GRID_LINE},"h-"+r)),f&&x(n,{children:[m(i,{cx:f.x*b+b/2,cy:f.y*b+b/2,r:.6*b,color:f.isSpecial?"rgba(255, 165, 2, 0.3)":s.FOOD_GLOW}),m(i,{cx:f.x*b+b/2,cy:f.y*b+b/2,r:.4*b,color:f.isSpecial?s.FOOD_SPECIAL:s.FOOD_NORMAL,children:m(h,{dx:0,dy:2,blur:4,color:"rgba(0, 0, 0, 0.4)"})}),m(i,{cx:f.x*b+b/2-.1*b,cy:f.y*b+b/2-.1*b,r:.15*b,color:"rgba(255, 255, 255, 0.6)"})]}),o.map((r,t)=>{const e=0===t,l=t===o.length-1,d=e?s.SNAKE_HEAD:l?s.SNAKE_TAIL:s.SNAKE_BODY;return x(n,{children:[m(c,{x:r.x*b+2,y:r.y*b+2,width:b-4,height:b-4,r:e?8:6,color:d,children:m(h,{dx:0,dy:2,blur:4,color:"rgba(0, 0, 0, 0.3)"})}),m(c,{x:r.x*b+.2*b,y:r.y*b+.2*b,width:.3*b,height:.3*b,r:4,color:"rgba(255, 255, 255, 0.3)"}),e&&x(y,{children:[m(i,{cx:r.x*b+.35*b,cy:r.y*b+.4*b,r:.08*b,color:"#000000"}),m(i,{cx:r.x*b+.65*b,cy:r.y*b+.4*b,r:.08*b,color:"#000000"})]})]},r.id)})]})})})})});GameGrid.displayName="GameGrid";const g=o.create({container:{flex:1,justifyContent:"center",alignItems:"center"},gridContainer:{}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import e from"react";import{View as r,Text as o,StyleSheet as t}from"react-native";import{useScore as n,useTimeLeft as s}from"../SnakeStore.js";import{SNAKE_COLORS as i}from"../SnakeConstants.js";import{ScoreBoardContainer as c}from"../../../helpers/index.js";import{jsx as l,jsxs as a}from"react/jsx-runtime";export const ScoreBoard=e.memo(({offset:t=0})=>{const d=n(),f=s(),h=e.useMemo(()=>`${Math.floor(f/60)}:${(""+f%60).padStart(2,"0")}`,[f]);return l(c,{offset:t,backgroundColor:i.SCORE_BACKGROUND,borderColor:i.SCORE_BACKGROUND,children:a(r,{style:m.scoreContainer,children:[a(r,{style:m.scoreItem,children:[l(o,{style:m.label,children:"Score"}),l(o,{style:m.value,children:d})]}),a(r,{style:m.scoreItem,children:[l(o,{style:m.label,children:"Time"}),l(o,{style:m.value,children:h})]})]})})});ScoreBoard.displayName="ScoreBoard";const m=t.create({scoreContainer:{flex:1,flexDirection:"row",justifyContent:"space-around",alignItems:"center"},scoreItem:{alignItems:"center"},label:{fontSize:16,color:"rgba(255, 255, 255, 0.7)",marginBottom:4},value:{fontSize:25,color:i.SCORE_TEXT,fontWeight:"bold"}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export{GameBackground}from
|
|
1
|
+
"use strict";export{GameBackground}from"./GameBackground.js";export{GameGrid}from"./GameGrid.js";export{ScoreBoard}from"./ScoreBoard.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export{Snake}from
|
|
1
|
+
"use strict";export{Snake}from"./Snake.js";export{useSnakeStore}from"./SnakeStore.js";export*from"./SnakeConstants.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import
|
|
1
|
+
"use strict";import t,{useEffect as o,useCallback as r,useMemo as e}from"react";import{View as n,StyleSheet as s,Dimensions as i}from"react-native";import{GestureHandlerRootView as a}from"react-native-gesture-handler";import{useSpaceFighterStore as c}from"./SpaceFighterStore.js";import{createSpaceFighterService as f}from"./SpaceFighterService.js";import{getDifficultySettings as m}from"./SpaceFighterConstants.js";import{ScoreBoard as p,GameArea as l,GameBackground as u}from"./components/index.js";import{GameControlButton as g,GameOverModal as d,useGameErrorHandler as h,GameErrorType as x}from"../../helpers/index.js";import{GameSettingsModal as S}from"../../helpers/index.js";import{GAME_IDS as b,DEFAULT_GAME_SETTINGS as C}from"../../services/UtilsService.js";import{jsx as B,jsxs as j}from"react/jsx-runtime";const{width:v,height:F}=i.get("window");export const SpaceFighter=({settings:s=C,onSettingsChange:i,onEndGame:y})=>{const{difficulty:w}=e(()=>s||C,[s]),G=c(t=>t.isPlaying),A=c(t=>t.gameOver),E=c(t=>t.score),P=t.useRef(!1),I=r(t=>{if(y&&!P.current){const o=c.getState();y({status:t,score:o.score.toString()}),P.current=!0}},[y]),N=c(t=>t.setOffset),O=c(t=>t.startGame),L=c(t=>t.stopGame),M=c(t=>t.resetGame),R=c(t=>t.decrementTime),U=c(t=>t.addAsteroids),V=c(t=>t.removeAsteroid),Y=c(t=>t.updateAsteroid),k=c(t=>t.updateSpacecraft),q=s?.offset??0;o(()=>{N(q)},[q,N]);const{wrapFunction:z,safeExecute:D}=h(b.SPACE_FIGHTER),H=e(()=>D(()=>f(v,F),f(v,F),x.INITIALIZATION_ERROR),[D]);o(()=>()=>{W(),H&&H.cleanup()},[H]),o(()=>{if(A&&!P.current){const t=c.getState().lives>0?"win":"lose";I(t)}A||(P.current=!1)},[A,I]),o(()=>{A&&H&&H.cleanup()},[A,H]);const J=e(()=>m(w),[w]),K=r(()=>z(()=>{P.current=!1,O(),H&&(H.updateDifficultySettings(J.asteroidSpeed,J.asteroidSpawnInterval),H.startGameTimer(R),H.startAsteroidSpawning(U),H.startPhysicsLoop(k,Y,V,()=>c.getState().spacecraft,()=>c.getState().asteroids))},x.INITIALIZATION_ERROR)(),[z,O,H,J,k,R,U,Y,V]),Q=r(()=>z(()=>{I("cancel"),L(),H&&H.cleanup()},x.UNKNOWN_ERROR)(),[z,L,H,I]),W=r(()=>z(()=>{if(H&&H.cleanup(),M(),H){const t=H.getInitialSpacecraft();k(t)}},x.UNKNOWN_ERROR)(),[z,H,M,k]),X=e(()=>({isPlaying:G,gameOver:A,onStartGame:K,onStopGame:Q,startButtonText:"START FLYING",stopButtonText:"STOP GAME",startButtonSubtext:"Navigate through space!",stopButtonSubtext:"End current game",startButtonColor:"#9370db",stopButtonColor:"#dc2626",startButtonBorderColor:"#ba68c8",stopButtonBorderColor:"#f87171"}),[G,A,K,Q]),Z=e(()=>({isVisible:A,score:E,onPlayAgain:W,buttonText:"Fly Again!",primaryColor:"rgba(147, 112, 219, 0.5)",borderColor:"rgba(147, 112, 219, 0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#9370db"}),[A,E,W]),$=e(()=>({gameId:b.SPACE_FIGHTER,settings:s||C,onSettingsChange:i}),[s,i]);return B(n,{style:T.container,children:B(a,{children:j(u,{children:[B(l,{}),B(p,{offset:q}),B(g,{...X}),B(d,{...Z}),B(S,{...$})]})})})};const T=s.create({container:{flex:1}});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";export const SPACE_FIGHTER_DIFFICULTY_CONFIG
|
|
1
|
+
"use strict";export const SPACE_FIGHTER_DIFFICULTY_CONFIG={easy:{gameDuration:60,asteroidSpawnInterval:4e3,asteroidSpeed:1.5},medium:{gameDuration:60,asteroidSpawnInterval:3e3,asteroidSpeed:2},hard:{gameDuration:60,asteroidSpawnInterval:2e3,asteroidSpeed:3}};export const getDifficultySettings=e=>SPACE_FIGHTER_DIFFICULTY_CONFIG[e];export const DEFAULT_SPACE_FIGHTER_SETTINGS={difficulty:"medium",soundEnabled:!0,hapticEnabled:!0,gameDuration:SPACE_FIGHTER_DIFFICULTY_CONFIG.medium.gameDuration,asteroidSpawnInterval:SPACE_FIGHTER_DIFFICULTY_CONFIG.medium.asteroidSpawnInterval,asteroidSpeed:SPACE_FIGHTER_DIFFICULTY_CONFIG.medium.asteroidSpeed};export const SPACE_FIGHTER_GAME_CONFIG={GAME_DURATION:120,SPACECRAFT_SIZE:28,SPACECRAFT_SPEED:3,ASTEROID_WIDTH:80,ASTEROID_GAP:120,ASTEROID_SPAWN_INTERVAL:3e3,ASTEROID_SPEED:2,GRAVITY:.3,BOUNCE_DAMPING:.7,FRICTION:.98,MAX_VELOCITY:8,COLLISION_TOLERANCE:2,COLLISION_COOLDOWN:2e3};export const SPACE_FIGHTER_COLORS={BACKGROUND:"#0a0a1a",SPACECRAFT:"#00d4ff",ASTEROID:"#8b4513",ASTEROID_SHADOW:"#654321",SCORE:"#ffd700",UI:"#9370db",STARS:"#ffffff"};export const SPACE_FIGHTER_THEME={backgroundColor:"rgba(0, 0, 0, 0.7)",headerBackgroundColor:"#9370db",headerTextColor:"#ffffff",sectionBackgroundColor:"rgba(147, 112, 219, 0.15)",sectionTitleColor:"#9370db",buttonSelectedColor:"#9370db",buttonUnselectedColor:"rgba(255, 255, 255, 0.2)",buttonSelectedTextColor:"#ffffff",buttonUnselectedTextColor:"rgba(255, 255, 255, 0.7)",switchTrackColorFalse:"rgba(147, 112, 219, 0.3)",switchTrackColorTrue:"#9370db",switchThumbColor:"#ffffff",infoTextColor:"rgba(255, 255, 255, 0.9)"};export const SPACE_FIGHTER_DIFFICULTY_DESCRIPTIONS={easy:"Slow asteroids, relaxed gameplay",medium:"Normal asteroid speed, balanced challenge",hard:"Fast asteroids, quick reflexes needed!"};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{SPACE_FIGHTER_GAME_CONFIG as
|
|
1
|
+
"use strict";import{SPACE_FIGHTER_GAME_CONFIG as t,SPACE_FIGHTER_COLORS as i}from"./SpaceFighterConstants.js";export{t as GAME_CONFIG,i as COLORS};class e{gameTimer=null;asteroidSpawnTimer=null;physicsTimer=null;particles=[];lastCollisionTime=0;currentAsteroidSpeed=t.ASTEROID_SPEED;currentSpawnInterval=t.ASTEROID_SPAWN_INTERVAL;constructor(t,i){this.width=t,this.height=i}startGame(){this.cleanup()}cleanup(){this.gameTimer&&(clearInterval(this.gameTimer),this.gameTimer=null),this.asteroidSpawnTimer&&(clearInterval(this.asteroidSpawnTimer),this.asteroidSpawnTimer=null),this.physicsTimer&&(clearInterval(this.physicsTimer),this.physicsTimer=null),this.particles=[],this.lastCollisionTime=0}startGameTimer(t){this.gameTimer=setInterval(t,1e3)}updateDifficultySettings(t,i){this.currentAsteroidSpeed=t,this.currentSpawnInterval=i}startAsteroidSpawning(t){const i=this.generateAsteroidPair();t(i),this.asteroidSpawnTimer=setInterval(()=>{const i=this.generateAsteroidPair();t(i)},this.currentSpawnInterval)}startPhysicsLoop(t,i,e,s,r){this.physicsTimer=setInterval(()=>{this.updatePhysics(t,i,e,s,r)},16)}generateAsteroidPair(){const i=`asteroid_pair_${Date.now()}_${Math.random()}`,e=.1*this.width,s=.9*this.width-t.ASTEROID_GAP,r=Math.random()*(s-e)+e;return[{id:i+"_left",x:0,y:-250,width:r,height:t.ASTEROID_WIDTH,type:"left",pairId:i,passed:!1,spawnTime:Date.now()},{id:i+"_right",x:r+t.ASTEROID_GAP,y:-250,width:this.width-(r+t.ASTEROID_GAP),height:t.ASTEROID_WIDTH,type:"right",pairId:i,passed:!1,spawnTime:Date.now()}]}updatePhysics(t,i,e,s,r){const a=s(),o=r();let n={...a};n.y=a.y,n.velocityY=0,n.isControlled||(n.velocityX=0),n.x>n.size/2||(n.x=n.size/2,n.velocityX=0),n.x<this.width-n.size/2||(n.x=this.width-n.size/2,n.velocityX=0),t(n);for(let t=0;t<o.length;t++){const s=o[t];if(!s)continue;const r=s.y+this.currentAsteroidSpeed;r>this.height?e(s.id):i(s.id,{y:r})}this.updateParticles()}controlSpacecraft(t,i,e){const s=t.size/2,r=this.width-t.size/2,a=Math.max(s,Math.min(r,i));return{...t,x:a,y:t.y,velocityX:0,velocityY:0,isControlled:!0}}releaseSpacecraft(t){return{...t,isControlled:!1}}checkCollision(i,e){const s=Date.now();if(s-this.lastCollisionTime<t.COLLISION_COOLDOWN)return{collision:!1};for(const t of e)if(this.spacecraftAsteroidCollision(i,t))return this.lastCollisionTime=s,{collision:!0,asteroidId:t.id};return{collision:!1}}spacecraftAsteroidCollision(t,i){const e=t.x-t.size/2,s=t.x+t.size/2,r=t.y-t.size/2,a=t.y+t.size/2,o=i.x,n=i.x+i.width,l=i.y,h=i.y+i.height;return s>o&&n>e&&a>l&&h>r}checkAsteroidPass(t,i){const e=[];for(let s=0;s<i.length;s++){const r=i[s];r&&!r.passed&&t.y>r.y+r.height&&e.push(r.pairId)}return e}createCollisionParticles(t,e){for(let s=0;15>s;s++){const r={id:`particle_${Date.now()}_${s}`,x:t,y:e,velocityX:15*(Math.random()-.5),velocityY:15*(Math.random()-.5),color:5>s?"#ff6600":10>s?i.SPACECRAFT:"#ffff00",life:1200,maxLife:1200,size:8+12*Math.random()};this.particles.push(r)}for(let i=0;5>i;i++){const s={id:`big_particle_${Date.now()}_${i}`,x:t+20*(Math.random()-.5),y:e+20*(Math.random()-.5),velocityX:8*(Math.random()-.5),velocityY:8*(Math.random()-.5),color:"#ff0000",life:1500,maxLife:1500,size:15+10*Math.random()};this.particles.push(s)}}updateParticles(){const t=[];for(let i=0;i<this.particles.length;i++){const e=this.particles[i];e&&(e.x+=e.velocityX,e.y+=e.velocityY,e.velocityY+=.2,e.life-=16,e.life>0&&t.push(e))}this.particles=t}getParticles(){return this.particles}isInCollisionImmunity(){return Date.now()-this.lastCollisionTime<t.COLLISION_COOLDOWN}getRemainingImmunityTime(){const i=Date.now()-this.lastCollisionTime;return Math.max(0,t.COLLISION_COOLDOWN-i)}getInitialSpacecraft(){return{x:this.width/2,y:.77*this.height,velocityX:0,velocityY:0,size:t.SPACECRAFT_SIZE,isControlled:!1}}}export const createSpaceFighterService=(t,i)=>new e(t,i);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{create}from
|
|
1
|
+
"use strict";import{create as e}from"zustand";import{subscribeWithSelector as t}from"zustand/middleware";import{Dimensions as o}from"react-native";import{GAME_CONFIG as i}from"./SpaceFighterService.js";import{immerMiddleware as r}from"../../services/UtilsService.js";const{width:s,height:c}=o.get("window"),a=(e=0)=>c*(e>0?.77:.68);export const useSpaceFighterStore=e()(t(r((e,t)=>({score:0,timeLeft:60,isPlaying:!1,gameOver:!1,lives:3,asteroids:[],spacecraft:{x:s/2,y:a(0),velocityX:0,velocityY:0,size:i.SPACECRAFT_SIZE,isControlled:!1},spacecraftPath:[],isControllingSpacecraft:!1,offset:0,setOffset:t=>{e(e=>{e.offset=t,e.spacecraft.y=a(t)})},startGame:t=>{e(e=>{e.score=0,e.timeLeft=60,e.isPlaying=!0,e.gameOver=!1,e.lives=3,e.asteroids=[],e.spacecraftPath=[],e.isControllingSpacecraft=!1,e.spacecraft={x:s/2,y:a(e.offset),velocityX:0,velocityY:0,size:i.SPACECRAFT_SIZE,isControlled:!1}})},stopGame:()=>{e(e=>{e.score=0,e.timeLeft=60,e.isPlaying=!1,e.gameOver=!1,e.lives=3,e.asteroids=[],e.spacecraftPath=[],e.isControllingSpacecraft=!1,e.spacecraft={x:s/2,y:a(e.offset),velocityX:0,velocityY:0,size:i.SPACECRAFT_SIZE,isControlled:!1}})},resetGame:()=>{e(e=>{e.score=0,e.timeLeft=60,e.isPlaying=!1,e.gameOver=!1,e.lives=3,e.asteroids=[],e.spacecraftPath=[],e.isControllingSpacecraft=!1,e.spacecraft={x:s/2,y:a(e.offset),velocityX:0,velocityY:0,size:i.SPACECRAFT_SIZE,isControlled:!1}})},updateScore:t=>{e(e=>{e.score=e.score+t})},decrementTime:()=>{e(e=>{const t=e.timeLeft-1;t>0?e.timeLeft=t:(e.timeLeft=0,e.isPlaying=!1,e.gameOver=!0)})},addAsteroids:t=>{e(e=>{e.asteroids.push(...t)})},removeAsteroid:t=>{e(e=>{e.asteroids=e.asteroids.filter(e=>e.id!==t)})},updateAsteroid:(t,o)=>{e(e=>{for(let i=0;i<e.asteroids.length;i++)if(e.asteroids[i].id===t){Object.assign(e.asteroids[i],o);break}})},updateSpacecraft:t=>{e(e=>{e.spacecraft=t})},setSpacecraftPath:t=>{e(e=>{e.spacecraftPath=t})},setIsControllingSpacecraft:t=>{e(e=>{e.isControllingSpacecraft=t})},markAsteroidPassed:t=>{e(e=>{for(let o=0;o<e.asteroids.length;o++)e.asteroids[o].pairId===t&&(e.asteroids[o].passed=!0);e.score=e.score+10})},loseLife:()=>{e(e=>{const t=e.lives-1;e.spacecraft={x:s/2,y:a(e.offset),velocityX:0,velocityY:0,size:i.SPACECRAFT_SIZE,isControlled:!1},t>0?e.lives=t:(e.lives=0,e.isPlaying=!1,e.gameOver=!0)})}}))));
|