first commit
This commit is contained in:
Executable
+35
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Pong de Caleb</title>
|
||||
<link rel="stylesheet" href="pong.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="start-screen" class="screen">
|
||||
<h1>PONG</h1>
|
||||
<button id="start-button">Jouer</button>
|
||||
<div class="controls">
|
||||
<h3>Contrôles :</h3>
|
||||
<p>Joueur 1 (Gauche) : W (haut) et S (bas)</p>
|
||||
<p>Joueur 2 (Droite) : Flèches Haut/Bas</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="game-container" style="display: none;">
|
||||
<div id="score">
|
||||
<span id="player1-score">0</span> - <span id="player2-score">0</span>
|
||||
</div>
|
||||
<canvas id="board"></canvas>
|
||||
</div>
|
||||
|
||||
<div id="game-over" class="screen" style="display: none;">
|
||||
<h1>Fin de la partie !</h1>
|
||||
<h2 id="winner-text"></h2>
|
||||
<button id="restart-button">Rejouer</button>
|
||||
</div>
|
||||
|
||||
<script src="pong.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+138
@@ -0,0 +1,138 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: 'Arial', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #1a1a2e, #16213e);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.screen {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
z-index: 10;
|
||||
transition: opacity 0.5s ease;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 4rem;
|
||||
margin-bottom: 2rem;
|
||||
color: #00b4d8;
|
||||
text-shadow: 0 0 10px rgba(0, 180, 216, 0.5);
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #90e0ef;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 12px 30px;
|
||||
font-size: 1.2rem;
|
||||
background: #00b4d8;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
margin: 10px;
|
||||
box-shadow: 0 4px 15px rgba(0, 180, 216, 0.3);
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #0096c7;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0, 180, 216, 0.4);
|
||||
}
|
||||
|
||||
button:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
#game-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#score {
|
||||
font-size: 2.5rem;
|
||||
color: #fff;
|
||||
margin-bottom: 20px;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
#board {
|
||||
background-color: #0d1b2a;
|
||||
border: 3px solid #00b4d8;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 30px rgba(0, 180, 216, 0.3);
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin-top: 2rem;
|
||||
background: rgba(13, 27, 42, 0.8);
|
||||
padding: 1.5rem;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #1b4965;
|
||||
}
|
||||
|
||||
.controls h3 {
|
||||
color: #90e0ef;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.controls p {
|
||||
margin: 0.5rem 0;
|
||||
color: #caf0f8;
|
||||
}
|
||||
|
||||
/* Animation pour le bouton de démarrage */
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(1); }
|
||||
50% { transform: scale(1.05); }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
|
||||
#start-button {
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
/* Style pour l'écran de fin de jeu */
|
||||
#game-over {
|
||||
background: rgba(13, 27, 42, 0.95);
|
||||
}
|
||||
|
||||
/* Style pour le score en jeu */
|
||||
#score {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 2rem;
|
||||
color: #fff;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Style pour le canvas */
|
||||
canvas {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Pong Game</title>
|
||||
<style>
|
||||
body {
|
||||
background: #111;
|
||||
color: #fff;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
}
|
||||
canvas {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
background: #222;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
h1 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Pong 🏓</h1>
|
||||
<canvas id="game" width="600" height="400"></canvas>
|
||||
<p>Joueur à gauche, utilisez W/S pour jouer.</p>
|
||||
<script>
|
||||
const canvas = document.getElementById("game");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const paddleWidth = 10, paddleHeight = 80, ballSize = 10;
|
||||
let player = { x: 0, y: canvas.height/2 - paddleHeight/2, dy: 0, score: 0 };
|
||||
let ai = { x: canvas.width - paddleWidth, y: canvas.height/2 - paddleHeight/2, dy: 2, score: 0 };
|
||||
let ball = { x: canvas.width/2, y: canvas.height/2, dx: 4, dy: 4 };
|
||||
|
||||
function drawRect(x, y, w, h, color) {
|
||||
ctx.fillStyle = color;
|
||||
ctx.fillRect(x, y, w, h);
|
||||
}
|
||||
|
||||
function drawCircle(x, y, r, color) {
|
||||
ctx.fillStyle = color;
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, r, 0, Math.PI*2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
function draw() {
|
||||
drawRect(0, 0, canvas.width, canvas.height, "#222");
|
||||
drawRect(player.x, player.y, paddleWidth, paddleHeight, "lime");
|
||||
drawRect(ai.x, ai.y, paddleWidth, paddleHeight, "red");
|
||||
drawCircle(ball.x, ball.y, ballSize, "white");
|
||||
ctx.fillStyle = "white";
|
||||
ctx.font = "20px sans-serif";
|
||||
ctx.fillText(`${player.score} : ${ai.score}`, canvas.width/2 - 20, 30);
|
||||
}
|
||||
|
||||
function update() {
|
||||
ball.x += ball.dx;
|
||||
ball.y += ball.dy;
|
||||
|
||||
// Ball collision with top/bottom
|
||||
if (ball.y < 0 || ball.y > canvas.height) ball.dy *= -1;
|
||||
|
||||
// Ball collision with player paddle
|
||||
if (ball.x < player.x + paddleWidth && ball.x > player.x &&
|
||||
ball.y > player.y && ball.y < player.y + paddleHeight) {
|
||||
ball.dx *= -1;
|
||||
ball.x = player.x + paddleWidth;
|
||||
}
|
||||
|
||||
// Ball collision with AI paddle
|
||||
if (ball.x > ai.x - ballSize && ball.x < ai.x + paddleWidth &&
|
||||
ball.y > ai.y && ball.y < ai.y + paddleHeight) {
|
||||
ball.dx *= -1;
|
||||
ball.x = ai.x - ballSize;
|
||||
}
|
||||
|
||||
// Score
|
||||
if (ball.x < 0) { ai.score++; resetBall(); }
|
||||
if (ball.x > canvas.width) { player.score++; resetBall(); }
|
||||
|
||||
// Move AI
|
||||
if (ball.y < ai.y + paddleHeight/2) ai.y -= ai.dy;
|
||||
else ai.y += ai.dy;
|
||||
if (ai.y < 0) ai.y = 0;
|
||||
if (ai.y + paddleHeight > canvas.height) ai.y = canvas.height - paddleHeight;
|
||||
|
||||
// Move player
|
||||
player.y += player.dy;
|
||||
if (player.y < 0) player.y = 0;
|
||||
if (player.y + paddleHeight > canvas.height) player.y = canvas.height - paddleHeight;
|
||||
}
|
||||
|
||||
function resetBall() {
|
||||
ball.x = canvas.width/2;
|
||||
ball.y = canvas.height/2;
|
||||
ball.dx *= -1;
|
||||
ball.dy = 4 * (Math.random() > 0.5 ? 1 : -1);
|
||||
}
|
||||
|
||||
function gameLoop() {
|
||||
update();
|
||||
draw();
|
||||
requestAnimationFrame(gameLoop);
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", e => {
|
||||
if (e.key === "w") player.dy = -4;
|
||||
if (e.key === "s") player.dy = 4;
|
||||
});
|
||||
document.addEventListener("keyup", e => {
|
||||
if (e.key === "w" || e.key === "s") player.dy = 0;
|
||||
});
|
||||
|
||||
requestAnimationFrame(gameLoop);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Executable
+344
@@ -0,0 +1,344 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user