// Variables globales let game; let canvas; let ctx; class Game { constructor() { this.canvas = document.getElementById('gameCanvas'); this.ctx = this.canvas.getContext('2d'); this.width = this.canvas.width; this.height = this.canvas.height; // État du jeu this.score = 0; this.lives = 3; this.level = 1; this.gameRunning = false; this.paused = false; // Entités du jeu this.player = null; this.enemies = []; this.bubbles = []; this.platforms = []; // Contrôles this.keys = {}; } init() { // Créer le joueur this.player = new Player(100, this.height - 100, this); // Créer quelques plateformes this.createPlatforms(); // Créer quelques ennemis this.createEnemies(); // Écouter les événements clavier this.setupControls(); // Démarrer la boucle du jeu this.gameRunning = true; this.gameLoop(); } createPlatforms() { this.platforms = []; // Plateforme du sol this.platforms.push({ x: 0, y: this.height - 40, width: this.width, height: 40 }); // Plateformes flottantes this.platforms.push({ x: 100, y: this.height - 150, width: 200, height: 20 }); this.platforms.push({ x: 400, y: this.height - 250, width: 200, height: 20 }); this.platforms.push({ x: 200, y: this.height - 350, width: 200, height: 20 }); } createEnemies() { this.enemies = []; // Créer quelques ennemis this.enemies.push(new Enemy(300, this.height - 100, this)); this.enemies.push(new Enemy(500, this.height - 200, this)); } setupControls() { document.addEventListener('keydown', (e) => { this.keys[e.key] = true; // Sauter avec espace if (e.key === ' ' && this.gameRunning && !this.paused) { if (this.player) { this.player.jump(); } } // Tirer une bulle avec Ctrl if ((e.key === 'Control' || e.key === 'ControlLeft') && this.gameRunning && !this.paused) { if (this.player) { this.player.shootBubble(); } } }); document.addEventListener('keyup', (e) => { this.keys[e.key] = false; }); } update() { if (!this.gameRunning || this.paused) return; // Mettre à jour le joueur if (this.player) { this.player.update(); } // Mettre à jour les ennemis for (let i = 0; i < this.enemies.length; i++) { this.enemies[i].update(); // Vérifier si l'ennemi est hors jeu if (this.enemies[i].y > this.height) { this.enemies.splice(i, 1); i--; } } // Mettre à jour les bulles for (let i = 0; i < this.bubbles.length; i++) { this.bubbles[i].update(); // Vérifier si la bulle est hors jeu if (this.bubbles[i].y < -50 || this.bubbles[i].x > this.width + 50 || this.bubbles[i].x < -50) { this.bubbles.splice(i, 1); i--; continue; } // Vérifier les collisions entre bulles et ennemis for (let j = 0; j < this.enemies.length; j++) { if (j < this.enemies.length && this.checkCollision(this.bubbles[i], this.enemies[j])) { // Ennemi capturé dans une bulle this.score += 100; this.updateUI(); this.bubbles.splice(i, 1); this.enemies.splice(j, 1); i--; break; } } } // Vérifier les collisions entre joueur et ennemis if (this.player) { for (let i = 0; i < this.enemies.length; i++) { if (this.checkCollision(this.player, this.enemies[i])) { this.playerHit(); break; } } } // Vérifier si tous les ennemis sont éliminés if (this.enemies.length === 0) { this.nextLevel(); } } draw() { // Effacer le canvas this.ctx.clearRect(0, 0, this.width, this.height); // Dessiner le fond this.ctx.fillStyle = '#00008B'; this.ctx.fillRect(0, 0, this.width, this.height); // Dessiner les plateformes this.ctx.fillStyle = '#8B4513'; for (let platform of this.platforms) { this.ctx.fillRect(platform.x, platform.y, platform.width, platform.height); } // Dessiner le joueur if (this.player) { this.player.draw(); } // Dessiner les ennemis for (let enemy of this.enemies) { enemy.draw(); } // Dessiner les bulles for (let bubble of this.bubbles) { bubble.draw(); } } checkCollision(obj1, obj2) { return obj1.x < obj2.x + obj2.width && obj1.x + obj1.width > obj2.x && obj1.y < obj2.y + obj2.height && obj1.y + obj1.height > obj2.y; } playerHit() { this.lives--; this.updateUI(); if (this.lives <= 0) { this.gameOver(); } else { // Réinitialiser la position du joueur if (this.player) { this.player.x = 100; this.player.y = this.height - 100; this.player.velocityY = 0; this.player.velocityX = 0; } } } nextLevel() { this.level++; this.updateUI(); // Réinitialiser les ennemis this.createEnemies(); // Réinitialiser le joueur if (this.player) { this.player.x = 100; this.player.y = this.height - 100; this.player.velocityY = 0; this.player.velocityX = 0; } } gameOver() { this.gameRunning = false; setTimeout(() => { alert(`Game Over! Score final: ${this.score}`); }, 100); } updateUI() { document.getElementById('score').textContent = this.score; document.getElementById('lives').textContent = this.lives; document.getElementById('level').textContent = this.level; } gameLoop() { this.update(); this.draw(); if (this.gameRunning) { requestAnimationFrame(() => this.gameLoop()); } } } class Player { constructor(x, y, game) { this.x = x; this.y = y; this.width = 30; this.height = 30; this.velocityX = 0; this.velocityY = 0; this.speed = 5; this.jumpPower = 12; this.gravity = 0.5; this.onGround = false; this.game = game; } update() { // Gestion des contrôles this.velocityX = 0; if (this.game.keys['ArrowLeft']) { this.velocityX = -this.speed; } if (this.game.keys['ArrowRight']) { this.velocityX = this.speed; } // Appliquer la gravité this.velocityY += this.gravity; // Mettre à jour la position this.x += this.velocityX; this.y += this.velocityY; // Empêcher le joueur de sortir de l'écran if (this.x < 0) this.x = 0; if (this.x + this.width > this.game.width) this.x = this.game.width - this.width; // Vérifier les collisions avec les plateformes this.onGround = false; for (let platform of this.game.platforms) { if (this.x < platform.x + platform.width && this.x + this.width > platform.x && this.y + this.height <= platform.y + 10 && this.y + this.height + this.velocityY >= platform.y) { this.y = platform.y - this.height; this.velocityY = 0; this.onGround = true; } } // Empêcher le joueur de tomber sous l'écran if (this.y > this.game.height) { this.game.playerHit(); } } jump() { if (this.onGround) { this.velocityY = -this.jumpPower; this.onGround = false; } } shootBubble() { // Créer une nouvelle bulle let direction = 1; if (this.game.keys['ArrowLeft']) direction = -1; this.game.bubbles.push(new Bubble(this.x + this.width/2, this.y + this.height/2, direction, this.game)); } draw() { // Dessiner le joueur (cercle vert) this.game.ctx.fillStyle = '#00FF00'; this.game.ctx.beginPath(); this.game.ctx.arc(this.x + this.width/2, this.y + this.height/2, this.width/2, 0, Math.PI * 2); this.game.ctx.fill(); // Dessiner les yeux this.game.ctx.fillStyle = '#000000'; let eyeOffset = this.game.keys['ArrowLeft'] ? -5 : (this.game.keys['ArrowRight'] ? 5 : 0); this.game.ctx.beginPath(); this.game.ctx.arc(this.x + this.width/2 - 5 + eyeOffset, this.y + this.height/2 - 5, 3, 0, Math.PI * 2); this.game.ctx.arc(this.x + this.width/2 + 5 + eyeOffset, this.y + this.height/2 - 5, 3, 0, Math.PI * 2); this.game.ctx.fill(); } } class Enemy { constructor(x, y, game) { this.x = x; this.y = y; this.width = 25; this.height = 25; this.velocityX = 2; this.velocityY = 0; this.gravity = 0.5; this.game = game; } update() { // Déplacement horizontal this.x += this.velocityX; // Appliquer la gravité this.velocityY += this.gravity; this.y += this.velocityY; // Vérifier les collisions avec les plateformes let onPlatform = false; for (let platform of this.game.platforms) { if (this.x < platform.x + platform.width && this.x + this.width > platform.x && this.y + this.height <= platform.y + 10 && this.y + this.height + this.velocityY >= platform.y) { this.y = platform.y - this.height; this.velocityY = 0; onPlatform = true; // Changer de direction si on arrive au bord de la plateforme if (this.x <= platform.x || this.x + this.width >= platform.x + platform.width) { this.velocityX *= -1; } } } // Rebondir sur les murs if (this.x <= 0 || this.x + this.width >= this.game.width) { this.velocityX *= -1; } } draw() { // Dessiner l'ennemi (cercle rouge) this.game.ctx.fillStyle = '#FF0000'; this.game.ctx.beginPath(); this.game.ctx.arc(this.x + this.width/2, this.y + this.height/2, this.width/2, 0, Math.PI * 2); this.game.ctx.fill(); // Dessiner les yeux this.game.ctx.fillStyle = '#000000'; let eyeOffset = this.velocityX < 0 ? -5 : 5; this.game.ctx.beginPath(); this.game.ctx.arc(this.x + this.width/2 - 5 + eyeOffset, this.y + this.height/2 - 5, 3, 0, Math.PI * 2); this.game.ctx.arc(this.x + this.width/2 + 5 + eyeOffset, this.y + this.height/2 - 5, 3, 0, Math.PI * 2); this.game.ctx.fill(); } } class Bubble { constructor(x, y, direction, game) { this.x = x; this.y = y; this.radius = 10; this.velocityX = direction * 4; this.velocityY = -3; this.game = game; } update() { this.x += this.velocityX; this.y += this.velocityY; // La bulle monte légèrement this.velocityY -= 0.1; // Limiter la vitesse verticale if (this.velocityY < -5) this.velocityY = -5; } draw() { // Dessiner la bulle (cercle transparent avec bordure) this.game.ctx.strokeStyle = '#FFFFFF'; this.game.ctx.lineWidth = 2; this.game.ctx.beginPath(); this.game.ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); this.game.ctx.stroke(); // Ajouter un reflet this.game.ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; this.game.ctx.beginPath(); this.game.ctx.arc(this.x - this.radius/3, this.y - this.radius/3, this.radius/4, 0, Math.PI * 2); this.game.ctx.fill(); } } // Fonctions globales function startGame() { if (game) { // Réinitialiser le jeu game.score = 0; game.lives = 3; game.level = 1; game.updateUI(); game.createPlatforms(); game.createEnemies(); if (game.player) { game.player.x = 100; game.player.y = game.height - 100; game.player.velocityY = 0; game.player.velocityX = 0; } game.bubbles = []; game.gameRunning = true; game.gameLoop(); } else { // Créer un nouveau jeu game = new Game(); game.init(); } game.gameRunning = true; game.paused = false; } function pauseGame() { if (game && game.gameRunning) { game.paused = !game.paused; }