I am currently working on react native project where i need to build pong game, but i ran in to a bug. I need to get ball to bounce of the blue platform byt right now it just flys thrue the platform.
Can someone explain how fix the problem?
import React, { useState, useRef, useEffect } from 'react';
import { View, PanResponder, Animated, Text, TouchableOpacity, StyleSheet } from 'react-native';
const BLUE_ISLAND_WIDTH = 150;
const BLUE_ISLAND_HEIGHT = 50;
const BALL_SIZE = 30;
const FALLING_SPEED = 9.2;
const BOUNCE_VELOCITY_MULTIPLIER = 0.8;
export default function Canvas() {
const [blueIslandPosition] = useState(new Animated.ValueXY({ x: 0, y: 600 }));
const [ballPosition] = useState(new Animated.ValueXY({ x: 180, y: 400 })); // Position of the small black square
const [selectedLevel, setSelectedLevel] = useState(null);
const [gameStarted, setGameStarted] = useState(false);
const fallingSpeedRef = useRef(null);
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (event, gestureState) => {
const newX = parseFloat(blueIslandPosition.x) || 0;
Animated.event(
[null, { dx: newX }],
{ useNativeDriver: false }
)(event, gestureState);
},
onPanResponderRelease: () => {
// No need for release action in this version
},
});
const CustomButton = ({ title, onPress, style }) => (
<TouchableOpacity onPress={onPress} style={style}>
<Text style={{ color: 'black' }}>{title}</Text>
</TouchableOpacity>
);
const handleLevelPress = (level) => {
setSelectedLevel(level);
};
const handleStartPress = () => {
if (selectedLevel) {
let fallingSpeed = FALLING_SPEED;
switch (selectedLevel) {
case 'Medium':
fallingSpeed *= 1.5;
break;
case 'Hard':
fallingSpeed *= 2;
break;
default:
break;
}
console.log('Starting game with level:', selectedLevel, 'and falling speed:', fallingSpeed);
setGameStarted(true);
fallingSpeedRef.current = setInterval(() => {
const newY = ballPosition.y._value + fallingSpeed;
ballPosition.y.setValue(newY);
}, 1000 / 60);
} else {
console.log('Please select a level before starting the game.');
}
};
useEffect(() => {
return () => {
if (fallingSpeedRef.current) {
clearInterval(fallingSpeedRef.current);
}
};
}, []);
const handleCollision = () => {
const ballX = ballPosition.x._value;
const ballY = ballPosition.y._value;
const islandX = blueIslandPosition.x._value;
const islandY = blueIslandPosition.y._value;
if (
ballX >= islandX && ballX <= islandX + BLUE_ISLAND_WIDTH &&
ballY >= islandY && ballY <= islandY + BLUE_ISLAND_HEIGHT
) {
const newXVelocity = -BOUNCE_VELOCITY_MULTIPLIER * (ballX - (islandX + BLUE_ISLAND_WIDTH / 2));
const newYVelocity = -BOUNCE_VELOCITY_MULTIPLIER * (ballY - (islandY + BLUE_ISLAND_HEIGHT / 2));
ballPosition.x.setValue(ballX + newXVelocity);
ballPosition.y.setValue(ballY + newYVelocity);
}
};
useEffect(() => {
const animationLoop =() => {
const newY = ballPosition.y._value + (gameStarted? FALLING_SPEED : 0);
ballPosition.y.setValue(newY);
handleCollision();
requestAnimationFrame(animationLoop);
};
animationLoop();
return () => {
cancelAnimationFrame(animationLoop);
};
}, [ballPosition, blueIslandPosition, gameStarted]);
return (
<View style={styles.container}>
<View style={{ width: BLUE_ISLAND_WIDTH, height: BLUE_ISLAND_HEIGHT, backgroundColor: "#e52441", position: "absolute", top: 100, left: 120, borderRadius: 100 }}>
<Animated.View {...panResponder.panHandlers} style={{ width: BLUE_ISLAND_WIDTH, height: BLUE_ISLAND_HEIGHT, backgroundColor: "#1875FF", position: "absolute", marginTop: -10, transform: [{ translateX: blueIslandPosition.x }, { translateY: blueIslandPosition.y }], borderRadius: 100 }} />
</View>
<Animated.View style={{ position: "absolute", top: ballPosition.y, left: ballPosition.x, borderRadius: BALL_SIZE, width: BALL_SIZE, height: BALL_SIZE, backgroundColor: "black" }} />
{!gameStarted && (
<View style={styles.difficultyPanel}>
<Text style={styles.panelText}>Paddle Dash</Text>
<Text style={styles.panelText}>Level</Text>
<View style={styles.levelButtons}>
<CustomButton title="Easy" onPress={() => handleLevelPress('Easy')} style={[styles.button, { backgroundColor: selectedLevel === 'Easy' ? "#1875FF" : "white" }]} />
<CustomButton title="Medium" onPress={() => handleLevelPress('Medium')} style={[styles.button, { backgroundColor: selectedLevel === 'Medium' ? "#1875FF" : "white" }]} />
<CustomButton title="Hard" onPress={() => handleLevelPress('Hard')} style={[styles.button, { backgroundColor: selectedLevel === 'Hard' ? "#1875FF" : "white" }]} />
</View>
<CustomButton title="Start" onPress={handleStartPress} style={styles.startButton} />
</View>
)}
</View>
);
}
I have tried to ask chat gpt, but it just give me bad answers. And i can’t find information somewhere else.