File size: 5,046 Bytes
a3b97ad
 
 
 
a4b6ccc
 
a3b97ad
ae20685
 
 
 
 
 
a4b6ccc
 
ae20685
a3b97ad
 
5994a14
 
ae20685
5994a14
 
 
ae20685
5994a14
 
 
ae20685
a4b6ccc
 
 
 
5994a14
 
a3b97ad
ae20685
b00bf58
ae20685
b00bf58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25cc5de
8d12a80
 
a3b97ad
a4b6ccc
ae20685
a4b6ccc
 
 
 
 
 
 
a3b97ad
ae20685
 
a3b97ad
ae20685
 
 
 
a4b6ccc
 
 
 
 
 
 
 
 
a3b97ad
 
ae20685
 
fc7647d
ae20685
fc7647d
ae20685
fc7647d
 
 
ae20685
fc7647d
a3b97ad
 
 
 
 
 
 
 
a4b6ccc
ae20685
a4b6ccc
 
ae20685
a4b6ccc
ae20685
 
 
a4b6ccc
ae20685
a4b6ccc
 
ae20685
a3b97ad
 
5994a14
a3b97ad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
const gameArea = document.getElementById('gameArea');
const paddleLeft = document.getElementById('paddleLeft');
const paddleRight = document.getElementById('paddleRight');
const ball = document.getElementById('ball');
const playerScoreDisplay = document.getElementById('playerScore');
const botScoreDisplay = document.getElementById('botScore');

let paddleLeftY = window.innerHeight / 2 - 40;
let paddleRightY = window.innerHeight / 2 - 40;
let ballX = window.innerWidth / 2;
let ballY = window.innerHeight / 2;
let ballSpeedX = 3;
let ballSpeedY = 0;
let playerScore = 0;
let botScore = 0;
let isGamePaused = true;

const paddleHeight = 80;
const paddleWidth = 10;
const ballSize = 15;
const maxAngle = 45;

gameArea.addEventListener('touchmove', (e) => {
    e.preventDefault();
    let touchY = e.touches[0].clientY;

    if (e.touches[0].clientX < window.innerWidth / 2) {
        paddleLeftY = touchY - paddleHeight / 2;
        paddleLeftY = Math.max(0, Math.min(paddleLeftY, window.innerHeight - paddleHeight));

        if (isGamePaused) {
            isGamePaused = false;
        }
    }
});

function handlePaddleCollision(paddleY, paddleX, isLeftPaddle) {
    const ballRadius = ballSize / 2;

    if (isLeftPaddle && ballSpeedX < 0) {
        // Collision X position for left paddle
        let collisionX = paddleX + paddleWidth + ballRadius;
        let t = (collisionX - ballX) / ballSpeedX;
        if (t >= 0 && t <= 1) {
            let collisionY = ballY + ballSpeedY * t;
            if (collisionY >= paddleY && collisionY <= paddleY + paddleHeight) {
                // Collision detected with left paddle
                let hitPosition = collisionY - (paddleY + paddleHeight / 2);
                let angle = hitPosition / (paddleHeight / 2) * maxAngle * (Math.PI / 180);
                // Update ball's velocity
                ballSpeedX = Math.abs(ballSpeedX); // Reverse X direction for left paddle
                ballSpeedY = Math.sin(angle) * ballSpeedX;
                // Reposition ball outside the paddle
                ballX = collisionX + ballRadius;
                ballY = collisionY;
            }
        }
    } else if (!isLeftPaddle && ballSpeedX > 0) {
        // Collision X position for right paddle
        let collisionX = paddleX - ballRadius;
        let t = (collisionX - ballX) / ballSpeedX;
        if (t >= 0 && t <= 1) {
            let collisionY = ballY + ballSpeedY * t;
            if (collisionY >= paddleY && collisionY <= paddleY + paddleHeight) {
                // Collision detected with right paddle
                let hitPosition = collisionY - (paddleY + paddleHeight / 2);
                let angle = hitPosition / (paddleHeight / 2) * maxAngle * (Math.PI / 180);
                // Update ball's velocity
                ballSpeedX = -Math.abs(ballSpeedX); // Reverse X direction for right paddle
                ballSpeedY = Math.sin(angle) * Math.abs(ballSpeedX);
                // Reposition ball outside the paddle
                ballX = collisionX - ballRadius;
                ballY = collisionY;
            }
        }
    }
}

function update() {
    if (!isGamePaused) {
        let previousBallX = ballX;
        ballX += ballSpeedX;
        ballY += ballSpeedY;

        // Ball collision with top and bottom walls
        if (ballY <= 0 || ballY >= window.innerHeight - ballSize) {
            ballSpeedY = -ballSpeedY;
        }

        // Check collision with left paddle using swept collision detection
        handlePaddleCollision(paddleLeftY, paddleWidth, true);

        // Check collision with right paddle using swept collision detection
        handlePaddleCollision(paddleRightY, window.innerWidth - paddleWidth - 25, false);

        // Ball out of bounds
        if (ballX <= 0) {
            botScore++;
            botScoreDisplay.textContent = botScore;
            resetBall('right');
        } else if (ballX >= window.innerWidth) {
            playerScore++;
            playerScoreDisplay.textContent = playerScore;
            resetBall('left');
        }
    }

    // Bot AI movement
    if (ballSpeedX > 0) {
        if (paddleRightY + paddleHeight / 2 < ballY) {
            paddleRightY += 3;
        } else if (paddleRightY + paddleHeight / 2 > ballY) {
            paddleRightY -= 3;
        }
    }

    paddleRightY = Math.max(0, Math.min(paddleRightY, window.innerHeight - paddleHeight));

    ball.style.left = ballX + 'px';
    ball.style.top = ballY + 'px';
    paddleLeft.style.top = paddleLeftY + 'px';
    paddleRight.style.top = paddleRightY + 'px';

    requestAnimationFrame(update);
}

function resetBall(side) {
    isGamePaused = true;

    if (side === 'left') {
        ballX = paddleWidth + 10;
        ballY = paddleLeftY + paddleHeight / 2;
        ballSpeedX = Math.abs(ballSpeedX);
    } else {
        ballX = window.innerWidth - paddleWidth - 25;
        ballY = paddleRightY + paddleHeight / 2;
        ballSpeedX = -Math.abs(ballSpeedX);
    }

    ballSpeedY = 0;
}

// Start the game loop
update();