344 lines
9.5 KiB
JavaScript
Executable File
344 lines
9.5 KiB
JavaScript
Executable File
// Configuration du jeu
|
|
const config = {
|
|
boardWidth: 800,
|
|
boardHeight: 500,
|
|
playerWidth: 10,
|
|
playerHeight: 80,
|
|
ballSize: 12,
|
|
winningScore: 5
|
|
};
|
|
|
|
// Éléments du DOM
|
|
let board, context;
|
|
let startScreen, gameContainer, gameOverScreen;
|
|
let scoreElement, player1ScoreElement, player2ScoreElement, winnerText;
|
|
|
|
// État du jeu
|
|
let score1 = 0;
|
|
let score2 = 0;
|
|
let gameRunning = false;
|
|
let animationId = null;
|
|
|
|
// Joueurs
|
|
let player1 = {
|
|
x: 30,
|
|
y: config.boardHeight / 2 - config.playerHeight / 2,
|
|
width: config.playerWidth,
|
|
height: config.playerHeight,
|
|
velocityY: 0,
|
|
speed: 8
|
|
};
|
|
|
|
let player2 = {
|
|
x: config.boardWidth - 30 - config.playerWidth,
|
|
y: config.boardHeight / 2 - config.playerHeight / 2,
|
|
width: config.playerWidth,
|
|
height: config.playerHeight,
|
|
velocityY: 0,
|
|
speed: 8
|
|
};
|
|
|
|
// Balle
|
|
let ball = {
|
|
x: config.boardWidth / 2,
|
|
y: config.boardHeight / 2,
|
|
width: config.ballSize,
|
|
height: config.ballSize,
|
|
velocityX: 5,
|
|
velocityY: 0
|
|
};
|
|
|
|
// Initialisation du jeu
|
|
window.onload = function() {
|
|
// Initialisation des éléments du DOM
|
|
board = document.getElementById("board");
|
|
context = board.getContext("2d");
|
|
|
|
// Configuration du canvas
|
|
board.width = config.boardWidth;
|
|
board.height = config.boardHeight;
|
|
|
|
// Récupération des éléments d'interface
|
|
startScreen = document.getElementById("start-screen");
|
|
gameContainer = document.getElementById("game-container");
|
|
gameOverScreen = document.getElementById("game-over");
|
|
player1ScoreElement = document.getElementById("player1-score");
|
|
player2ScoreElement = document.getElementById("player2-score");
|
|
winnerText = document.getElementById("winner-text");
|
|
|
|
// Configuration des écouteurs d'événements
|
|
document.getElementById("start-button").addEventListener("click", startGame);
|
|
document.getElementById("restart-button").addEventListener("click", resetGame);
|
|
document.addEventListener("keydown", handleKeyDown);
|
|
document.addEventListener("keyup", handleKeyUp);
|
|
|
|
// Afficher l'écran de démarrage
|
|
showScreen("start");
|
|
};
|
|
|
|
// Gestion des écrans
|
|
function showScreen(screen) {
|
|
startScreen.style.display = screen === "start" ? "flex" : "none";
|
|
gameContainer.style.display = screen === "game" ? "block" : "none";
|
|
gameOverScreen.style.display = screen === "gameOver" ? "flex" : "none";
|
|
}
|
|
|
|
// Démarrer une nouvelle partie
|
|
function startGame() {
|
|
resetGame();
|
|
showScreen("game");
|
|
gameRunning = true;
|
|
update();
|
|
}
|
|
|
|
// Réinitialiser le jeu
|
|
function resetGame() {
|
|
// Réinitialiser les scores
|
|
score1 = 0;
|
|
score2 = 0;
|
|
updateScore();
|
|
|
|
// Réinitialiser les positions des joueurs
|
|
player1.y = config.boardHeight / 2 - player1.height / 2;
|
|
player2.y = config.boardHeight / 2 - player2.height / 2;
|
|
|
|
// Réinitialiser la balle
|
|
resetBall();
|
|
}
|
|
|
|
// Réinitialiser la balle au centre
|
|
function resetBall() {
|
|
ball.x = config.boardWidth / 2 - ball.width / 2;
|
|
ball.y = config.boardHeight / 2 - ball.height / 2;
|
|
ball.velocityX = Math.random() > 0.5 ? 5 : -5;
|
|
ball.velocityY = (Math.random() * 6) - 3;
|
|
}
|
|
|
|
// Mettre à jour l'affichage des scores
|
|
function updateScore() {
|
|
player1ScoreElement.textContent = score1;
|
|
player2ScoreElement.textContent = score2;
|
|
|
|
// Vérifier si un joueur a gagné
|
|
if (score1 >= config.winningScore || score2 >= config.winningScore) {
|
|
endGame();
|
|
}
|
|
}
|
|
|
|
// Fin de la partie
|
|
function endGame() {
|
|
gameRunning = false;
|
|
cancelAnimationFrame(animationId);
|
|
|
|
// Déterminer le gagnant
|
|
const winner = score1 > score2 ? "Joueur 1" : "Joueur 2";
|
|
winnerText.textContent = `${winner} a gagné !`;
|
|
|
|
// Afficher l'écran de fin de partie
|
|
showScreen("gameOver");
|
|
}
|
|
|
|
// Boucle de jeu principale
|
|
function update() {
|
|
if (!gameRunning) return;
|
|
|
|
// Effacer le canvas
|
|
context.clearRect(0, 0, config.boardWidth, config.boardHeight);
|
|
|
|
// Dessiner le terrain
|
|
drawField();
|
|
|
|
// Mettre à jour et dessiner les joueurs
|
|
updatePlayer(player1);
|
|
updatePlayer(player2);
|
|
drawPlayer(player1);
|
|
drawPlayer(player2);
|
|
|
|
// Mettre à jour et dessiner la balle
|
|
updateBall();
|
|
drawBall();
|
|
|
|
// Vérifier les collisions
|
|
checkCollisions();
|
|
|
|
// Continuer la boucle d'animation
|
|
animationId = requestAnimationFrame(update);
|
|
}
|
|
|
|
// Dessiner le terrain
|
|
function drawField() {
|
|
// Fond
|
|
context.fillStyle = "#0d1b2a";
|
|
context.fillRect(0, 0, config.boardWidth, config.boardHeight);
|
|
|
|
// Ligne médiane en pointillés
|
|
context.strokeStyle = "rgba(255, 255, 255, 0.2)";
|
|
context.setLineDash([10, 10]);
|
|
context.beginPath();
|
|
context.moveTo(config.boardWidth / 2, 0);
|
|
context.lineTo(config.boardWidth / 2, config.boardHeight);
|
|
context.stroke();
|
|
context.setLineDash([]);
|
|
}
|
|
|
|
// Mettre à jour la position d'un joueur
|
|
function updatePlayer(player) {
|
|
// Mettre à jour la position
|
|
player.y += player.velocityY;
|
|
|
|
// Limites du terrain
|
|
if (player.y < 0) player.y = 0;
|
|
if (player.y + player.height > config.boardHeight) {
|
|
player.y = config.boardHeight - player.height;
|
|
}
|
|
}
|
|
|
|
// Dessiner un joueur
|
|
function drawPlayer(player) {
|
|
context.fillStyle = "#00b4d8";
|
|
context.fillRect(player.x, player.y, player.width, player.height);
|
|
|
|
// Effet de brillance
|
|
const gradient = context.createLinearGradient(player.x, 0, player.x + player.width, 0);
|
|
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');
|
|
gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
|
|
context.fillStyle = gradient;
|
|
context.fillRect(player.x, player.y, player.width / 2, player.height);
|
|
}
|
|
|
|
// Mettre à jour la position de la balle
|
|
function updateBall() {
|
|
ball.x += ball.velocityX;
|
|
ball.y += ball.velocityY;
|
|
|
|
// Rebond sur les bords haut et bas
|
|
if (ball.y <= 0 || ball.y + ball.height >= config.boardHeight) {
|
|
ball.velocityY *= -1;
|
|
}
|
|
|
|
// Vérifier si un joueur marque un point
|
|
if (ball.x < 0) {
|
|
// Joueur 2 marque un point
|
|
score2++;
|
|
updateScore();
|
|
resetBall();
|
|
} else if (ball.x > config.boardWidth) {
|
|
// Joueur 1 marque un point
|
|
score1++;
|
|
updateScore();
|
|
resetBall();
|
|
}
|
|
}
|
|
|
|
// Dessiner la balle
|
|
function drawBall() {
|
|
// Effet de brillance
|
|
const gradient = context.createRadialGradient(
|
|
ball.x + ball.width / 2,
|
|
ball.y + ball.height / 2,
|
|
0,
|
|
ball.x + ball.width / 2,
|
|
ball.y + ball.height / 2,
|
|
ball.width / 2
|
|
);
|
|
gradient.addColorStop(0, '#ffffff');
|
|
gradient.addColorStop(1, '#90e0ef');
|
|
|
|
context.fillStyle = gradient;
|
|
context.beginPath();
|
|
context.arc(
|
|
ball.x + ball.width / 2,
|
|
ball.y + ball.height / 2,
|
|
ball.width / 2,
|
|
0,
|
|
Math.PI * 2
|
|
);
|
|
context.fill();
|
|
|
|
// Effet de lueur
|
|
context.shadowColor = '#00b4d8';
|
|
context.shadowBlur = 15;
|
|
context.fill();
|
|
context.shadowBlur = 0;
|
|
}
|
|
|
|
// Vérifier les collisions
|
|
function checkCollisions() {
|
|
// Collision avec le joueur 1 (gauche)
|
|
if (ball.x <= player1.x + player1.width &&
|
|
ball.x + ball.width >= player1.x &&
|
|
ball.y + ball.height >= player1.y &&
|
|
ball.y <= player1.y + player1.height) {
|
|
|
|
// Inverser la direction horizontale
|
|
ball.velocityX = Math.abs(ball.velocityX);
|
|
|
|
// Ajuster la direction verticale en fonction de l'endroit où la balle touche la raquette
|
|
const hitPosition = (ball.y - (player1.y + player1.height / 2)) / (player1.height / 2);
|
|
ball.velocityY = hitPosition * 8;
|
|
|
|
// Augmenter légèrement la vitesse
|
|
ball.velocityX *= 1.05;
|
|
ball.velocityY *= 1.05;
|
|
}
|
|
|
|
// Collision avec le joueur 2 (droite)
|
|
if (ball.x + ball.width >= player2.x &&
|
|
ball.x <= player2.x + player2.width &&
|
|
ball.y + ball.height >= player2.y &&
|
|
ball.y <= player2.y + player2.height) {
|
|
|
|
// Inverser la direction horizontale
|
|
ball.velocityX = -Math.abs(ball.velocityX);
|
|
|
|
// Ajuster la direction verticale
|
|
const hitPosition = (ball.y - (player2.y + player2.height / 2)) / (player2.height / 2);
|
|
ball.velocityY = hitPosition * 8;
|
|
|
|
// Augmenter légèrement la vitesse
|
|
ball.velocityX *= 1.05;
|
|
ball.velocityY *= 1.05;
|
|
}
|
|
}
|
|
|
|
// Gestion des touches enfoncées
|
|
function handleKeyDown(e) {
|
|
// Joueur 1 (W/S)
|
|
if (e.key.toLowerCase() === 'w') {
|
|
player1.velocityY = -player1.speed;
|
|
} else if (e.key.toLowerCase() === 's') {
|
|
player1.velocityY = player1.speed;
|
|
}
|
|
|
|
// Joueur 2 (Flèches)
|
|
if (e.key === 'ArrowUp') {
|
|
player2.velocityY = -player2.speed;
|
|
} else if (e.key === 'ArrowDown') {
|
|
player2.velocityY = player2.speed;
|
|
}
|
|
|
|
// Touche Espace pour démarrer/redémarrer
|
|
if (e.code === 'Space' && !gameRunning) {
|
|
if (startScreen.style.display === 'flex') {
|
|
startGame();
|
|
} else if (gameOverScreen.style.display === 'flex') {
|
|
resetGame();
|
|
startGame();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Gestion du relâchement des touches
|
|
function handleKeyUp(e) {
|
|
// Joueur 1 (W/S)
|
|
if ((e.key.toLowerCase() === 'w' && player1.velocityY < 0) ||
|
|
(e.key.toLowerCase() === 's' && player1.velocityY > 0)) {
|
|
player1.velocityY = 0;
|
|
}
|
|
|
|
// Joueur 2 (Flèches)
|
|
if ((e.key === 'ArrowUp' && player2.velocityY < 0) ||
|
|
(e.key === 'ArrowDown' && player2.velocityY > 0)) {
|
|
player2.velocityY = 0;
|
|
}
|
|
} |