UNPKG

react-native-games

Version:

Free games for your react native projects.

1 lines 6.27 kB
"use strict";import React,{useEffect,useRef,useCallback,useMemo}from 'react';import{View,StyleSheet,Dimensions}from 'react-native';import{GestureHandlerRootView}from 'react-native-gesture-handler';import{usePopitFidgetStore}from "./PopitFidgetStore.js";import{PopitFidgetService}from "./PopitFidgetService.js";import{GAME_IDS,DEFAULT_GAME_SETTINGS}from "../../services/UtilsService.js";import{playSound,GAME_SOUNDS}from "../../services/SoundsService.js";import{playHaptic,HapticType}from "../../services/HapticsService.js";import{GameBackground,FidgetGrid as FidgetGridComponent,ScoreBoard}from "./components/index.js";import{GameControlButton,GameOverModal}from "../../helpers/index.js";import{GameSettingsModal}from "../../helpers/index.js";import{jsx as _jsx,jsxs as _jsxs}from "react/jsx-runtime";const{width,height}= Dimensions.get('window');const PopitFidget =({settings,onSettingsChange})=>{const fidgetGrid = usePopitFidgetStore(state => state.fidgetGrid);const timeElapsed = usePopitFidgetStore(state => state.timeElapsed);const isPlaying = usePopitFidgetStore(state => state.isPlaying);const gameOver = usePopitFidgetStore(state => state.gameOver);const gameWon = usePopitFidgetStore(state => state.gameWon);const startGame = usePopitFidgetStore(state => state.startGame);const resetGame = usePopitFidgetStore(state => state.resetGame);const setFidgetGrid = usePopitFidgetStore(state => state.setFidgetGrid);const popBubble = usePopitFidgetStore(state => state.popBubble);const incrementTime = usePopitFidgetStore(state => state.incrementTime);const serviceRef = useRef(null);const{difficulty = 'medium',enableSounds = true,enableHaptics = true}= settings ||{};useEffect(()=>{if(!serviceRef.current){serviceRef.current = new PopitFidgetService();}if(serviceRef.current && !fidgetGrid){const grid = serviceRef.current.generateFidgetGrid(difficulty);setFidgetGrid(grid);}},[fidgetGrid,setFidgetGrid,difficulty]);useEffect(()=>{return()=>{try{serviceRef.current?.stopGameTimer();}catch{}try{resetGame();}catch{}try{serviceRef.current?.cleanup();}catch{}};},[]);const service = useMemo(()=>{if(!serviceRef.current){serviceRef.current = new PopitFidgetService();}return serviceRef.current;},[]);const generateNewFidget = useCallback(()=>{const grid = service.generateFidgetGrid(difficulty);setFidgetGrid(grid);},[service,setFidgetGrid,difficulty]);const prevDifficultyRef = React.useRef(difficulty);const handleDifficultyChange = useCallback(()=>{if(prevDifficultyRef.current !== difficulty){if(!isPlaying){generateNewFidget();}prevDifficultyRef.current = difficulty;}},[difficulty,isPlaying,generateNewFidget]);useEffect(()=>{handleDifficultyChange();},[handleDifficultyChange]);React.useEffect(()=>{if(gameOver && !isPlaying){if(gameWon){playSound(GAME_SOUNDS.BUBBLE_POPPER.COMPLETE,enableSounds);}else{playSound(GAME_SOUNDS.TIME_UP,enableSounds);}}},[gameOver,gameWon,isPlaying,enableSounds]);useEffect(()=>{let timerInterval = null;if(isPlaying){timerInterval = setInterval(()=>{incrementTime();},1000);}return()=>{if(timerInterval){clearInterval(timerInterval);}};},[isPlaying,incrementTime]);const startGameHandler = useCallback(()=>{generateNewFidget();playSound(GAME_SOUNDS.BUBBLE_POPPER.START,enableSounds);startGame();playHaptic(HapticType.MEDIUM,enableHaptics);},[startGame,enableSounds,enableHaptics,generateNewFidget]);const stopGameHandler = useCallback(()=>{service.stopGameTimer();resetGame();generateNewFidget();},[service,resetGame,generateNewFidget]);const resetGameHandler = useCallback(()=>{service.stopGameTimer();resetGame();generateNewFidget();},[service,resetGame,generateNewFidget]);const handleBubblePop = useCallback((row,col)=>{if(!fidgetGrid)return;const bubble = fidgetGrid.bubbles[row]?.[col];if(!bubble || bubble.isPopped)return;playSound(GAME_SOUNDS.BUBBLE_POPPER.POP,enableSounds);popBubble(row,col);playHaptic(HapticType.LIGHT,enableHaptics);},[fidgetGrid,popBubble,enableSounds,enableHaptics]);const screenDimensions = useMemo(()=>({width,height}),[]);const bubbleSize = useMemo(()=>{if(!fidgetGrid)return 60;const availableWidth = screenDimensions.width * 0.85;const availableHeight = screenDimensions.height * 0.6;const maxSize = Math.min(availableWidth / fidgetGrid.size,availableHeight / fidgetGrid.size);return Math.max(45,Math.min(80,maxSize * 0.9));},[fidgetGrid,screenDimensions]);const gameControlButtonProps = useMemo(()=>({isPlaying,gameOver,onStartGame:startGameHandler,onStopGame:stopGameHandler,startButtonText:"START POPPING",stopButtonText:"STOP GAME",startButtonSubtext:"Pop bubbles to relax!",stopButtonSubtext:"End current game",startButtonColor:"#9c27b0",stopButtonColor:"#dc2626",startButtonBorderColor:"#ce93d8",stopButtonBorderColor:"#f87171"}),[isPlaying,gameOver,startGameHandler,stopGameHandler]);const gameOverModalProps = useMemo(()=>({isVisible:gameOver,score:timeElapsed,onPlayAgain:resetGameHandler,buttonText:"Pop Again!",primaryColor:"rgba(156,39,176,0.5)",borderColor:"rgba(156,39,176,0.5)",buttonColor:"#ffffff",buttonBorderColor:"#ffffff",buttonTextColor:"#9c27b0",scoreFormatter:time =>{const mins = Math.floor(time / 60);const secs = time % 60;return `${mins.toString().padStart(2,'0')}:${secs.toString().padStart(2,'0')}`;},scoreLabel:"Time Elapsed"}),[gameOver,timeElapsed,resetGameHandler]);const offset = settings?.offset ?? 0;return _jsx(View,{style:styles.container,children:_jsx(GestureHandlerRootView,{children:_jsxs(View,{style:[styles.gameContainer,{paddingTop:offset}],children:[_jsx(GameBackground,{width:screenDimensions.width,height:screenDimensions.height,isPlaying:isPlaying}),_jsx(ScoreBoard,{timeElapsed:timeElapsed,offset:offset}),_jsx(View,{style:styles.gameArea,children:fidgetGrid && _jsx(FidgetGridComponent,{grid:fidgetGrid,bubbleSize:bubbleSize,onBubblePop:handleBubblePop,hapticEnabled:enableHaptics,isPlaying:isPlaying})}),_jsx(GameControlButton,{...gameControlButtonProps}),_jsx(GameOverModal,{...gameOverModalProps}),_jsx(GameSettingsModal,{gameId:GAME_IDS.POPIT_FIDGET,settings:settings || DEFAULT_GAME_SETTINGS,onSettingsChange:onSettingsChange})]})})});};const styles = StyleSheet.create({container:{flex:1},gameContainer:{flex:1,backgroundColor:'#fef7ff'},gameArea:{flex:1,justifyContent:'center',alignItems:'center',paddingHorizontal:20}});export{PopitFidget};