返回

精简版吃豆人小游戏:用 348 字节代码实现经典的街机游戏

前端

极简主义的艺术:用 348 字节代码实现吃豆人小游戏

引言

在现代快节奏的世界中,我们往往习惯了复杂庞大的软件和应用程序。然而,有时,用最少的代码实现一个项目反而能带来更纯粹的快乐和成就感。这种极简主义的艺术不仅是编程的挑战,更是对创造力的考验。

用 348 字节代码实现吃豆人小游戏

吃豆人是电子游戏史上最经典的游戏之一,它的简单易懂的游戏规则和可爱的像素图形吸引了无数玩家。而现在,我们将用不到 400 个字节的代码来实现一个精简版吃豆人小游戏。

代码分析

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

const map = [
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
  [1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1],
  [1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1],
  [1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1],
  [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
];

const pac = {
  x: 10,
  y: 10,
  d: 'right'
};

const ghosts = [
  {x: 5, y: 5, d: 'right'},
  {x: 10, y: 5, d: 'left'},
  {x: 15, y: 5, d: 'right'}
];

let score = 0;

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Draw the map
  for (let i = 0; i < map.length; i++) {
    for (let j = 0; j < map[i].length; j++) {
      if (map[i][j] === 1) {
        ctx.fillRect(j * 10, i * 10, 10, 10);
      }
    }
  }

  // Draw Pac-Man
  ctx.fillStyle = 'yellow';
  ctx.beginPath();
  ctx.arc(pac.x * 10 + 5, pac.y * 10 + 5, 5, 0, 2 * Math.PI);
  ctx.fill();

  // Draw ghosts
  ctx.fillStyle = 'red';
  for (let i = 0; i < ghosts.length; i++) {
    ctx.beginPath();
    ctx.arc(ghosts[i].x * 10 + 5, ghosts[i].y * 10 + 5, 5, 0, 2 * Math.PI);
    ctx.fill();
  }

  // Draw score
  ctx.fillStyle = 'white';
  ctx.font = '10px Arial';
  ctx.fillText(`Score: ${score}`, 10, 10);

  requestAnimationFrame(draw);
}

function movePac(e) {
  switch (e.keyCode) {
    case 37:
      pac.d = 'left';
      break;
    case 38:
      pac.d = 'up';
      break;
    case 39:
      pac.d = 'right';
      break;
    case 40:
      pac.d = 'down';
      break;
  }
}

function update() {
  // Move Pac-Man
  switch (pac.d) {
    case 'left':
      pac.x -= 1;
      if (pac.x < 0) {
        pac.x = 19;
      }
      break;
    case 'up':
      pac.y -= 1;
      if (pac.y < 0) {
        pac.y = 14;
      }
      break;
    case 'right':
      pac.x += 1;
      if (pac.x > 19) {
        pac.x = 0;
      }
      break;
    case 'down':
      pac.y += 1;
      if (pac.y > 14) {
        pac.y = 0;
      }
      break;
  }

  // Move ghosts
  for (let i = 0; i < ghosts.length; i++) {
    switch (g】