advanced-games-library
Version:
Advanced Gaming Library for React Native - Four Complete Games with iOS Compatibility Fixes
578 lines (517 loc) • 16.9 kB
JavaScript
/**
* 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');