2024-09-01 02:30:44 +00:00
|
|
|
const canvas = document.getElementById('gameCanvas');
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
|
2024-09-06 23:53:24 +00:00
|
|
|
// Set canvas size to match the container
|
|
|
|
canvas.width = 540;
|
|
|
|
canvas.height = 675;
|
|
|
|
|
|
|
|
// Make sure the canvas is visible
|
|
|
|
canvas.style.display = 'block';
|
|
|
|
|
2024-09-06 22:02:34 +00:00
|
|
|
// Load background image once, outside of any function
|
|
|
|
const backgroundImage = new Image();
|
|
|
|
backgroundImage.src = '/assets/images/background.png';
|
|
|
|
|
2024-09-01 02:30:44 +00:00
|
|
|
let bricks = [];
|
|
|
|
let paddle = { x: 175, y: 510, width: 75, height: 15 };
|
|
|
|
let ball = { x: 200, y: 370, dx: 4, dy: -4, radius: 8 };
|
|
|
|
const floorY = 525; // Define the floor position
|
|
|
|
|
2024-09-07 22:19:15 +00:00
|
|
|
let isPaused = true;
|
2024-09-01 02:30:44 +00:00
|
|
|
|
|
|
|
function togglePause() {
|
|
|
|
isPaused = !isPaused;
|
|
|
|
if (!isPaused) {
|
|
|
|
requestAnimationFrame(update);
|
|
|
|
}
|
2024-09-07 22:19:15 +00:00
|
|
|
updatePauseButton(); // We'll add this function
|
|
|
|
}
|
|
|
|
|
|
|
|
function updatePauseButton() {
|
|
|
|
pauseButton.textContent = isPaused ? 'Démarrer' : 'Pause';
|
2024-09-01 02:30:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function drawBricks() {
|
|
|
|
bricks.forEach(brick => {
|
|
|
|
ctx.fillStyle = brick.color;
|
|
|
|
ctx.fillRect(brick.x, brick.y, 90, 30);
|
|
|
|
ctx.fillStyle = brick.textColor;
|
|
|
|
ctx.font = '14px Arial';
|
|
|
|
ctx.fillText(brick.text, brick.x + 10, brick.y + 20);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawPaddle() {
|
|
|
|
ctx.fillStyle = '#003333';
|
|
|
|
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawBall() {
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
|
|
|
|
ctx.fillStyle = '#003333';
|
|
|
|
ctx.fill();
|
|
|
|
ctx.closePath();
|
|
|
|
}
|
|
|
|
|
|
|
|
function movePaddle(e) {
|
|
|
|
if (!isPaused) {
|
2024-09-06 23:53:24 +00:00
|
|
|
let rect = canvas.getBoundingClientRect();
|
|
|
|
let root = document.documentElement;
|
|
|
|
let mouseX = e.clientX - rect.left - root.scrollLeft;
|
|
|
|
|
|
|
|
// Ensure the paddle stays within the canvas
|
|
|
|
paddle.x = Math.max(0, Math.min(canvas.width - paddle.width, mouseX - paddle.width / 2));
|
2024-09-01 02:30:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function collisionDetection() {
|
|
|
|
bricks.forEach((brick, index) => {
|
|
|
|
if (
|
|
|
|
ball.x > brick.x &&
|
|
|
|
ball.x < brick.x + 90 && // Changed from 50 to 90
|
|
|
|
ball.y > brick.y &&
|
|
|
|
ball.y < brick.y + 30 // Changed from 20 to 30
|
|
|
|
) {
|
|
|
|
ball.dy = -ball.dy;
|
|
|
|
bricks.splice(index, 1);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawPauseScreen() {
|
|
|
|
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
|
|
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
ctx.fillStyle = 'white';
|
|
|
|
ctx.font = '30px Arial';
|
2024-09-07 22:19:15 +00:00
|
|
|
if (bricks.length === 0) {
|
|
|
|
ctx.fillText('PAUSE', canvas.width / 2 - 50, canvas.height / 2);
|
|
|
|
} else {
|
|
|
|
ctx.fillText("Clique 'Démarrer' pour jouer", canvas.width / 2 - 175, canvas.height / 2);
|
|
|
|
}
|
2024-09-01 02:30:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function update() {
|
|
|
|
|
|
|
|
if (isPaused) {
|
|
|
|
drawPauseScreen();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
|
|
|
|
|
// Draw background image
|
2024-09-06 22:02:34 +00:00
|
|
|
ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
|
2024-09-01 02:30:44 +00:00
|
|
|
|
|
|
|
// Draw floor line
|
|
|
|
ctx.beginPath();
|
|
|
|
ctx.moveTo(0, floorY);
|
|
|
|
ctx.lineTo(canvas.width, floorY);
|
|
|
|
ctx.strokeStyle = 'white';
|
|
|
|
ctx.stroke();
|
|
|
|
|
|
|
|
drawBricks();
|
|
|
|
drawPaddle();
|
|
|
|
drawBall();
|
|
|
|
|
|
|
|
collisionDetection();
|
|
|
|
|
|
|
|
if (bricks.length === 0) {
|
2024-09-01 03:44:06 +00:00
|
|
|
// Gagné !!
|
2024-09-01 02:30:44 +00:00
|
|
|
document.location.reload();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bounce off side walls
|
|
|
|
if (ball.x + ball.dx > canvas.width - ball.radius || ball.x + ball.dx < ball.radius) {
|
|
|
|
ball.dx = -ball.dx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bounce off top wall
|
|
|
|
if (ball.y + ball.dy < ball.radius) {
|
|
|
|
ball.dy = -ball.dy;
|
2024-09-01 05:10:57 +00:00
|
|
|
} else if (ball.y + ball.dy > floorY - paddle.height) { // Changed to use floorY
|
2024-09-01 05:54:46 +00:00
|
|
|
if (ball.x > paddle.x-ball.radius && ball.x < paddle.x + paddle.width+ball.radius) {
|
|
|
|
|
|
|
|
// Limit the angle to a maximum of 60 degrees (pi/3 radians) from vertical
|
|
|
|
const maxAngle = Math.PI*2/3;
|
2024-09-01 02:30:44 +00:00
|
|
|
// Calculate where the ball hit the paddle
|
2024-09-01 05:54:46 +00:00
|
|
|
let hitPos = Math.max(0.1, Math.min(0.9, (ball.x - paddle.x) / paddle.width)) ;
|
|
|
|
|
|
|
|
console.log('Hit position:', hitPos); // Debugging purposes
|
2024-09-01 02:30:44 +00:00
|
|
|
|
|
|
|
// Change angle based on where the ball hit the paddle
|
|
|
|
let angle = hitPos * Math.PI - Math.PI/2;
|
2024-09-01 05:54:46 +00:00
|
|
|
console.log('Angle brut:', angle); // Debugging purposes
|
2024-09-01 05:10:57 +00:00
|
|
|
|
|
|
|
// Add some randomness to the angle (within the limited range)
|
|
|
|
angle += (Math.random() - 0.5) * Math.PI/12;
|
|
|
|
|
|
|
|
// Ensure the angle stays within the maximum limits after randomness
|
2024-09-01 05:54:46 +00:00
|
|
|
if (Math.abs(angle) < maxAngle) {
|
|
|
|
angle = Math.sign(angle) * maxAngle;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('Angle ajusté:', angle); // Debugging purposes
|
2024-09-01 02:30:44 +00:00
|
|
|
|
|
|
|
// Set new velocity based on this angle
|
|
|
|
let speed = Math.sqrt(ball.dx * ball.dx + ball.dy * ball.dy);
|
2024-09-01 05:54:46 +00:00
|
|
|
ball.dx = Math.cos(angle) * speed * Math.sign(angle);
|
2024-09-01 02:30:44 +00:00
|
|
|
ball.dy = -Math.abs(Math.sin(angle) * speed); // Ensure the ball always goes up
|
|
|
|
} else {
|
2024-09-01 03:44:06 +00:00
|
|
|
// Game over!
|
2024-09-01 02:30:44 +00:00
|
|
|
document.location.reload();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ball.x += ball.dx;
|
|
|
|
ball.y += ball.dy;
|
|
|
|
|
|
|
|
requestAnimationFrame(update);
|
|
|
|
}
|
|
|
|
|
|
|
|
document.addEventListener('keydown', function(e) {
|
|
|
|
if (e.key === 'p' || e.key === 'P') {
|
|
|
|
togglePause();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Create pause button
|
|
|
|
const pauseButton = document.createElement('button');
|
2024-09-07 22:19:15 +00:00
|
|
|
pauseButton.textContent = 'Démarrer'; // Changed from 'Pause' to 'Démarrer'
|
2024-09-01 02:30:44 +00:00
|
|
|
pauseButton.style.position = 'absolute';
|
|
|
|
pauseButton.style.top = '10px';
|
|
|
|
pauseButton.style.left = '10px';
|
2024-09-06 23:53:24 +00:00
|
|
|
pauseButton.style.zIndex = '20';
|
|
|
|
document.getElementById('gameContainer').appendChild(pauseButton);
|
2024-09-01 02:30:44 +00:00
|
|
|
pauseButton.addEventListener('click', togglePause);
|
|
|
|
|
2024-09-06 23:53:24 +00:00
|
|
|
// Load bricks from JSON file
|
|
|
|
|
|
|
|
function updateThemeHeader(theme) {
|
|
|
|
const themeHeader = document.getElementById('themeHeader');
|
|
|
|
if (themeHeader) {
|
2024-09-08 00:02:12 +00:00
|
|
|
themeHeader.textContent = `DéconstruIT - Le jeu ! Thème: ${theme}`;
|
2024-09-06 23:53:24 +00:00
|
|
|
themeHeader.style.position = 'absolute';
|
|
|
|
themeHeader.style.top = '10px';
|
|
|
|
themeHeader.style.left = '0';
|
|
|
|
themeHeader.style.right = '0';
|
|
|
|
themeHeader.style.zIndex = '10';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-09-08 00:03:51 +00:00
|
|
|
// Create exit button
|
|
|
|
const exitButton = document.createElement('button');
|
|
|
|
exitButton.textContent = 'Quitter';
|
|
|
|
exitButton.style.position = 'absolute';
|
|
|
|
exitButton.style.top = '10px';
|
|
|
|
exitButton.style.right = '10px';
|
|
|
|
exitButton.style.zIndex = '20';
|
|
|
|
document.getElementById('gameContainer').appendChild(exitButton);
|
|
|
|
exitButton.addEventListener('click', function() {
|
|
|
|
window.location.href = 'https://jevalide.ca/deconstruit';
|
|
|
|
});
|
|
|
|
|
2024-09-06 23:53:24 +00:00
|
|
|
const brickFiles = [
|
|
|
|
'bricks-productivite.json',
|
|
|
|
'bricks-developpement.json',
|
2024-09-07 23:22:33 +00:00
|
|
|
'bricks-reseaux.json',
|
2024-09-06 23:53:24 +00:00
|
|
|
'bricks-marketing.json',
|
|
|
|
'bricks-coaching.json',
|
2024-09-07 23:22:33 +00:00
|
|
|
'bricks-techbro.json',
|
|
|
|
'bricks-cybersec.json',
|
|
|
|
'bricks-gafam.json'
|
2024-09-06 23:53:24 +00:00
|
|
|
];
|
|
|
|
const randomFile = brickFiles[Math.floor(Math.random() * brickFiles.length)];
|
|
|
|
|
|
|
|
// Extract theme from filename
|
|
|
|
const theme = randomFile.split('-')[1].split('.')[0];
|
|
|
|
|
|
|
|
fetch(`/bricks?file=${randomFile}`)
|
2024-09-01 02:30:44 +00:00
|
|
|
.then(response => response.json())
|
|
|
|
.then(data => {
|
|
|
|
bricks = data;
|
2024-09-06 23:53:24 +00:00
|
|
|
updateThemeHeader(theme);
|
2024-09-07 22:19:15 +00:00
|
|
|
drawPauseScreen(); // Draw the pause screen instead of starting the game
|
|
|
|
updatePauseButton();
|
2024-09-06 23:53:24 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
document.addEventListener('mousemove', movePaddle, true);
|