File size: 3,851 Bytes
a3b97ad
 
 
 
a4b6ccc
 
a3b97ad
ae20685
 
 
 
 
 
a4b6ccc
 
ae20685
a3b97ad
 
5994a14
 
ae20685
5994a14
 
 
ae20685
5994a14
 
 
ae20685
a4b6ccc
 
 
 
5994a14
 
a3b97ad
ae20685
 
8d12a80
ae20685
25cc5de
ae20685
 
 
 
25cc5de
ae20685
 
 
 
 
 
 
 
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
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) {
    let previousBallX = ballX - ballSpeedX;
    
    // Swept collision detection: Check if the ball crossed the paddle between frames
    if (
        previousBallX < paddleX + paddleWidth &&
        ballX > paddleX &&
        ballY + ballSize > paddleY &&
        ballY < paddleY + paddleHeight
    ) {
        const hitPosition = (ballY - (paddleY + paddleHeight / 2)) / (paddleHeight / 2);
        const angle = hitPosition * maxAngle * (Math.PI / 180);

        ballSpeedX = (isLeftPaddle ? 1 : -1) * Math.abs(ballSpeedX);
        ballSpeedY = Math.sin(angle) * Math.abs(ballSpeedX);

        // Reposition the ball outside the paddle to avoid clipping
        ballX = isLeftPaddle ? paddleX + paddleWidth + 1 : paddleX - ballSize - 1;
    }
}

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();