JSFiddle - React, Tailwind, and code Playground

by Oski Krawczyk

HTML

<canvas id="gameCanvas" width="400" height="600"></canvas>
<button id="playAgainBtn" style="display: none; margin: 20px auto; display: block;">Play Again</button>
<div id="score">Score: 0</div>

CSS

canvas {
  background: #111;
  display: block;
  margin: 20px auto;
}
button {
  padding: 10px 20px;
  font-size: 16px;
  cursor: pointer;
}

JavaScript

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');

let player = { x: 200, y: 550, width: 32, height: 32, speed: 5 };
let enemies = [];
let score = 0;
let gameOver = false;

function createEnemy() {
  return {
    x: Math.random() * (canvas.width - 32),
    y: -Math.random() * 400,
    width: 32,
    height: 32,
    speed: 2 + Math.random() * 2
  };
}

function initEnemies() {
  enemies = [];
  for (let i = 0; i < 5; i++) enemies.push(createEnemy());
}
initEnemies();

// Load ảnh và âm thanh
let playerImg = new Image();
playerImg.src = 'https://i.pinimg.com/736x/17/b1/af/17b1afb45e279e800b9a0557a46a0abb.jpg';

let deathSound = new Audio('https://cdn.pixabay.com/audio/2022/03/28/audio_b9b4d54922.mp3'); // tiếng nổ
let pointSound = new Audio('https://cdn.pixabay.com/audio/2022/03/15/audio_1b476c5d47.mp3'); // tiếng xu

playerImg.onload = () => gameLoop();

function drawPlayer() {
  ctx.drawImage(playerImg, player.x, player.y, player.width, player.height);
}

function drawEnemies() {
  ctx.fillStyle = 'red';
  enemies.forEach(e => ctx.fillRect(e.x, e.y, e.width, e.height));
}

function moveEnemies() {
  enemies.forEach(e => e.y += e.speed);
}

function checkCollisions() {
  enemies.forEach((e, i) => {
    if (
      player.x < e.x + e.width &&
      player.x + player.width > e.x &&
      player.y < e.y + e.height &&
      player.y + player.height > e.y
    ) {
      gameOver = true;
      deathSound.play(); // phát âm thanh chết
    }

    if (e.y > canvas.height) {
      e.y = -32;
      e.x = Math.random() * (canvas.width - 32);
      score++;
      document.getElementById("score").textContent = "Score: " + score;
      pointSound.play(); // phát âm thanh ghi điểm
    }
  });
}

function clearCanvas() {
  ctx.fillStyle = '#111';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
}

function gameLoop() {
  if (gameOver) {
   ...