UNPKG

advanced-games-library

Version:

Advanced Gaming Library for React Native - Four Complete Games with iOS Compatibility Fixes

578 lines (517 loc) 16.9 kB
/** * Reaction Time Game Component * Version 3.3.0 - Organized Code Structure */ // Import React safely let React; try { React = require('react'); console.log('✅ React loaded successfully for ReactionTimeGame'); } catch (error) { console.error('❌ Failed to load React:', error); } const { View, Text, TouchableOpacity, StyleSheet, Alert, Dimensions } = require('react-native'); // =========================================== // REAL REACTION TIME GAME - CLASS COMPONENT! // =========================================== class ReactionTimeGameComponent extends React.Component { constructor(props) { super(props); console.log('⚡ ReactionTimeGameComponent - REAL GAME initializing...'); const totalRounds = props.totalRounds || 5; this.state = { currentScreen: props.showMenu !== false ? 'menu' : 'game', // Game progress currentRound: 0, totalRounds: totalRounds, reactionTimes: [], // Current round state gamePhase: 'waiting', // 'waiting', 'ready', 'go', 'reacted', 'tooEarly' phaseStartTime: null, roundStartTime: null, lastReactionTime: null, // Game settings difficulty: props.difficulty || 'normal', isGameStarted: false, isComplete: false, // Statistics averageTime: 0, bestTime: 0 }; this.initializeGame = this.initializeGame.bind(this); this.startGame = this.startGame.bind(this); this.startRound = this.startRound.bind(this); this.handleReaction = this.handleReaction.bind(this); this.checkGameComplete = this.checkGameComplete.bind(this); this.resetGame = this.resetGame.bind(this); this.goToMenu = this.goToMenu.bind(this); } initializeGame() { console.log('🔄 Initializing reaction time game...'); this.setState({ currentRound: 0, reactionTimes: [], gamePhase: 'waiting', phaseStartTime: null, roundStartTime: null, lastReactionTime: null, isGameStarted: true, isComplete: false, averageTime: 0, bestTime: 0 }); } startGame() { console.log('🚀 Starting reaction time game...'); this.setState({ currentScreen: 'game' }); this.initializeGame(); if (this.props.onGameStart) { this.props.onGameStart(); } // Start first round setTimeout(() => { this.startRound(); }, 1000); } startRound() { if (this.state.currentRound >= this.state.totalRounds) { this.checkGameComplete(); return; } console.log(`🎯 Starting round ${this.state.currentRound + 1}`); this.setState({ gamePhase: 'ready', phaseStartTime: Date.now() }); // Random delay between 1-4 seconds based on difficulty let delayRange; switch (this.state.difficulty) { case 'easy': delayRange = [2000, 4000]; // 2-4 seconds break; case 'hard': delayRange = [500, 2000]; // 0.5-2 seconds break; default: // normal delayRange = [1000, 3000]; // 1-3 seconds } const delay = Math.random() * (delayRange[1] - delayRange[0]) + delayRange[0]; this.roundTimer = setTimeout(() => { this.setState({ gamePhase: 'go', roundStartTime: Date.now() }); }, delay); } handleReaction() { const now = Date.now(); if (this.state.gamePhase === 'ready') { // Too early! console.log('❌ Too early reaction!'); if (this.roundTimer) { clearTimeout(this.roundTimer); } this.setState({ gamePhase: 'tooEarly', lastReactionTime: null }); setTimeout(() => { this.startRound(); }, 1500); } else if (this.state.gamePhase === 'go') { // Perfect timing! const reactionTime = now - this.state.roundStartTime; console.log(`✅ Good reaction! ${reactionTime}ms`); const newReactionTimes = [...this.state.reactionTimes, reactionTime]; const newAverage = newReactionTimes.reduce((a, b) => a + b, 0) / newReactionTimes.length; const newBest = Math.min(...newReactionTimes); this.setState({ gamePhase: 'reacted', lastReactionTime: reactionTime, reactionTimes: newReactionTimes, currentRound: this.state.currentRound + 1, averageTime: newAverage, bestTime: newBest }); setTimeout(() => { if (this.state.currentRound >= this.state.totalRounds) { this.checkGameComplete(); } else { this.startRound(); } }, 1500); } } checkGameComplete() { console.log('🎉 Reaction time game completed!'); const { reactionTimes, averageTime, bestTime } = this.state; const score = Math.max(2000 - averageTime, 100); this.setState({ isComplete: true }); const result = { score: Math.round(score), averageTime: averageTime, bestTime: bestTime, reactionTimes: reactionTimes, totalRounds: this.state.totalRounds, completed: true }; if (this.props.onGameComplete) { this.props.onGameComplete(result); } setTimeout(() => { Alert.alert( '⚡ סיימת!', `השלמת את משחק זמן התגובה!\n\n` + `⚡ זמן ממוצע: ${averageTime.toFixed(0)}ms\n` + `🏆 זמן הטוב ביותר: ${bestTime.toFixed(0)}ms\n` + `🎯 סיבובים מוצלחים: ${reactionTimes.length}/${this.state.totalRounds}\n` + `🎊 ניקוד: ${Math.round(score)}`, [ { text: 'משחק חדש', onPress: this.resetGame }, { text: 'תפריט', onPress: this.goToMenu } ] ); }, 500); } resetGame() { console.log('🔄 Resetting reaction time game...'); if (this.roundTimer) { clearTimeout(this.roundTimer); } this.initializeGame(); setTimeout(() => { this.startRound(); }, 1000); } goToMenu() { console.log('🏠 Going to reaction menu...'); if (this.roundTimer) { clearTimeout(this.roundTimer); } this.setState({ currentScreen: 'menu' }); } componentWillUnmount() { if (this.roundTimer) { clearTimeout(this.roundTimer); } } renderMenu() { const styles = this.getReactionStyles(); const { totalRounds, difficulty } = this.state; return React.createElement(View, { style: styles.menuContainer }, React.createElement(Text, { style: styles.title }, '⚡ משחק זמן תגובה'), React.createElement(Text, { style: styles.subtitle }, 'בדקו את מהירות התגובה שלכם!'), React.createElement(View, { style: styles.gameInfo }, React.createElement(Text, { style: styles.infoText }, `⚡ סיבובים: ${totalRounds}`), React.createElement(Text, { style: styles.infoText }, `⚙️ רמת קושי: ${difficulty}`), React.createElement(Text, { style: styles.infoText }, `🎯 מטרה: תגובה מהירה לאות ירוק`) ), React.createElement(View, { style: styles.instructionsBox }, React.createElement(Text, { style: styles.instructionTitle }, 'איך לשחק:'), React.createElement(Text, { style: styles.instructionText }, '1. המתינו לעיגול האדום'), React.createElement(Text, { style: styles.instructionText }, '2. כשהוא הופך ירוק - הקישו מיד!'), React.createElement(Text, { style: styles.instructionText }, '3. אל תקישו מוקדם - זה יאפס את הסיבוב') ), React.createElement(TouchableOpacity, { style: styles.startButton, onPress: this.startGame }, React.createElement(Text, { style: styles.buttonText }, '⚡ התחל משחק') ) ); } renderGame() { const styles = this.getReactionStyles(); const { currentRound, totalRounds, gamePhase, lastReactionTime, averageTime, bestTime, reactionTimes, isComplete } = this.state; let circleColor = '#95a5a6'; // Default gray let circleText = '●'; let instructionText = 'התכונן...'; let isClickable = false; switch (gamePhase) { case 'waiting': circleColor = '#95a5a6'; instructionText = 'התכונן לסיבוב הבא...'; break; case 'ready': circleColor = '#e74c3c'; // Red instructionText = 'המתן... אל תקיש עדיין!'; isClickable = true; break; case 'go': circleColor = '#2ecc71'; // Green instructionText = '⚡ הקש עכשיו!'; isClickable = true; break; case 'reacted': circleColor = '#3498db'; // Blue instructionText = `מעולה! ${lastReactionTime}ms`; break; case 'tooEarly': circleColor = '#f39c12'; // Orange instructionText = 'מוקדם מדי! נסה שוב...'; break; } if (isComplete) { circleColor = '#9b59b6'; // Purple instructionText = '🎉 המשחק הושלם!'; } return React.createElement(View, { style: styles.gameContainer }, React.createElement(View, { style: styles.header }, React.createElement(Text, { style: styles.gameTitle }, '⚡ זמן תגובה'), React.createElement(View, { style: styles.stats }, React.createElement(Text, { style: styles.statText }, `סיבוב: ${currentRound}/${totalRounds}`), React.createElement(Text, { style: styles.statText }, `ממוצע: ${averageTime.toFixed(0)}ms`), React.createElement(Text, { style: styles.statText }, `הטוב ביותר: ${bestTime.toFixed(0)}ms`) ) ), React.createElement(View, { style: styles.gameArea }, React.createElement(TouchableOpacity, { style: [styles.reactionCircle, { backgroundColor: circleColor }], onPress: isClickable ? this.handleReaction : null, disabled: !isClickable, activeOpacity: 0.8 }, React.createElement(Text, { style: styles.circleText }, circleText) ), React.createElement(Text, { style: styles.instructionText }, instructionText) ), reactionTimes.length > 0 && React.createElement(View, { style: styles.timesDisplay }, React.createElement(Text, { style: styles.timesTitle }, 'זמני תגובה:'), React.createElement(View, { style: styles.timesList }, ...reactionTimes.map((time, index) => React.createElement(Text, { key: index, style: styles.timeItem }, `${index + 1}. ${time.toFixed(0)}ms`) ) ) ), isComplete && React.createElement(View, { style: styles.completeIndicator }, React.createElement(Text, { style: styles.completeText }, '⚡ המשחק הושלם!') ), React.createElement(View, { style: styles.controls }, React.createElement(TouchableOpacity, { style: styles.controlButton, onPress: this.resetGame }, React.createElement(Text, { style: styles.controlButtonText }, '🔄 משחק חדש') ), React.createElement(TouchableOpacity, { style: [styles.controlButton, styles.menuButton], onPress: this.goToMenu }, React.createElement(Text, { style: styles.controlButtonText }, '🏠 תפריט') ) ) ); } getReactionStyles() { const { width } = Dimensions.get('window'); const circleSize = Math.min(width * 0.6, 250); return StyleSheet.create({ menuContainer: { backgroundColor: '#f8f9fa', flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20, minHeight: 400 }, title: { fontSize: 28, fontWeight: 'bold', color: '#2c3e50', textAlign: 'center', marginBottom: 10, }, subtitle: { fontSize: 16, color: '#7f8c8d', textAlign: 'center', marginBottom: 30, }, gameInfo: { backgroundColor: 'white', padding: 20, borderRadius: 15, marginBottom: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, }, infoText: { fontSize: 16, color: '#2c3e50', textAlign: 'center', marginBottom: 8, }, instructionsBox: { backgroundColor: '#ecf0f1', padding: 15, borderRadius: 10, marginBottom: 30, alignSelf: 'stretch', }, instructionTitle: { fontSize: 16, fontWeight: 'bold', color: '#2c3e50', marginBottom: 8, textAlign: 'center', }, instructionText: { fontSize: 14, color: '#2c3e50', marginBottom: 4, textAlign: 'right', }, startButton: { backgroundColor: '#e74c3c', paddingVertical: 15, paddingHorizontal: 30, borderRadius: 25, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.2, shadowRadius: 4, elevation: 5, }, buttonText: { color: 'white', fontSize: 18, fontWeight: 'bold', textAlign: 'center', }, gameContainer: { backgroundColor: '#f8f9fa', flex: 1, padding: 15, }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 30, backgroundColor: 'white', padding: 15, borderRadius: 10, shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.1, shadowRadius: 2, elevation: 2, }, gameTitle: { fontSize: 20, fontWeight: 'bold', color: '#2c3e50', }, stats: { alignItems: 'flex-end', }, statText: { fontSize: 14, color: '#7f8c8d', marginBottom: 2, }, gameArea: { flex: 1, justifyContent: 'center', alignItems: 'center', marginBottom: 20, }, reactionCircle: { width: circleSize, height: circleSize, borderRadius: circleSize / 2, justifyContent: 'center', alignItems: 'center', marginBottom: 30, shadowColor: '#000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 8, elevation: 8, }, circleText: { fontSize: 48, color: 'white', fontWeight: 'bold', }, instructionText: { fontSize: 20, fontWeight: 'bold', color: '#2c3e50', textAlign: 'center', marginBottom: 20, }, timesDisplay: { backgroundColor: 'white', padding: 15, borderRadius: 10, marginBottom: 15, shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.1, shadowRadius: 2, elevation: 2, }, timesTitle: { fontSize: 16, fontWeight: 'bold', color: '#2c3e50', textAlign: 'center', marginBottom: 10, }, timesList: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'center', }, timeItem: { fontSize: 14, color: '#7f8c8d', marginHorizontal: 8, marginVertical: 2, }, completeIndicator: { backgroundColor: '#e74c3c', padding: 12, borderRadius: 10, alignItems: 'center', marginBottom: 15, }, completeText: { color: 'white', fontSize: 18, fontWeight: 'bold', }, controls: { flexDirection: 'row', justifyContent: 'space-around', marginTop: 10, }, controlButton: { backgroundColor: '#e74c3c', paddingVertical: 12, paddingHorizontal: 20, borderRadius: 20, minWidth: 120, alignItems: 'center', }, menuButton: { backgroundColor: '#95a5a6', }, controlButtonText: { color: 'white', fontSize: 14, fontWeight: 'bold', }, }); } render() { console.log('🎨 ReactionTimeGameComponent rendering...', this.state.currentScreen); return this.state.currentScreen === 'menu' ? this.renderMenu() : this.renderGame(); } } module.exports = ReactionTimeGameComponent; console.log('✅ ReactionTimeGameComponent loaded successfully');