📜  设计蛇游戏(1)

📅  最后修改于: 2023-12-03 14:57:40.375000             🧑  作者: Mango

设计蛇游戏

蛇游戏是一种经典的街机游戏,目的是使蛇“吃”到食物,尽可能多地增加身体长度,同时避免撞到蛇身体或游戏边缘。

游戏规则
  • 初始状态有一条由三个方块组成的蛇,随机生成一些食物
  • 操作方式为上下左右箭头键控制蛇的移动方向
  • 当蛇头位置与食物位置重合时,蛇增加一个方块长度,随机生成一个新的食物
  • 当蛇头位置与蛇身体或边缘重合时,游戏失败,弹出游戏结束提示框
设计思路
数据结构
  • 蛇:由一个存放每个方块位置的数组表示,数组头即为蛇头,每次移动时更新数组元素位置
  • 食物:随机在游戏区域生成一个坐标,通过判断坐标是否与蛇重合来判断是否被吃掉
游戏主循环

游戏主循环中,先检测用户操作,根据用户操作更新蛇的位置,再根据蛇的位置更新游戏画面。

伪代码如下:

while 游戏未结束:
    获取用户操作
    根据用户操作更新蛇的位置
    判断是否吃到食物
    更新游戏画面
    判断是否结束游戏
代码片段

以下是一个简单的 JavaScript 蛇游戏实现。

// 蛇类
class Snake {
  constructor() {
    this.body = [[5, 5], [4, 5], [3, 5]];
    this.direction = "right";
  }

  // 向上移动
  moveUp() {
    this.direction = "up";
  }
  
  // 向下移动
  moveDown() {
    this.direction = "down";
  }

  // 向左移动
  moveLeft() {
    this.direction = "left";
  }

  // 向右移动
  moveRight() {
    this.direction = "right";
  }

  // 移动
  move() {
    const head = this.body[0];
    
    // 根据方向更新头部位置
    switch (this.direction) {
      case "up":
        this.body.unshift([head[0], head[1] - 1]);
        break;
      case "down":
        this.body.unshift([head[0], head[1] + 1]);
        break;
      case "left":
        this.body.unshift([head[0] - 1, head[1]]);
        break;
      case "right":
        this.body.unshift([head[0] + 1, head[1]]);
        break;
      default:
        break;
    }
    // 删除尾部元素
    this.body.pop();
  }
}

// 游戏类
class Game {
  constructor() {      
  }

  // 初始化游戏
  init(snake) {
    this.snake = snake;
    this.food = this.generateFood();
    this.score = 0;
  }

  // 随机生成食物
  generateFood() {
    const x = Math.floor(Math.random() * 20);
    const y = Math.floor(Math.random() * 20);
    return [x, y];
  }

  // 判断是否吃到食物
  checkIfEatFood() {
    const head = this.snake.body[0];
    if (head[0] === this.food[0] && head[1] === this.food[1]) {
      this.snake.body.push(this.snake.body[this.snake.body.length - 1]);
      this.food = this.generateFood();
      this.score++;
    }
  }

  // 游戏主循环
  loop() {
    // 判断是否结束游戏
    if (this.checkIfGameOver()) {
      // 游戏结束
      return;
    }

    // 检测用户操作
    document.addEventListener("keydown", (e) => {
      switch (e.key) {
        case "ArrowUp":
          this.snake.moveUp();
          break;
        case "ArrowDown":
          this.snake.moveDown();
          break;
        case "ArrowLeft":
          this.snake.moveLeft();
          break;
        case "ArrowRight":
          this.snake.moveRight();
          break;
        default:
          break;
      }
    });

    // 更新蛇的位置
    this.snake.move();

    // 判断是否吃到食物
    this.checkIfEatFood();

    // 更新游戏画面
    this.updateScreen();

    // 下一帧
    setTimeout(() => {
      this.loop();
    }, 100);
  }

  // 判断是否结束游戏
  checkIfGameOver() {
    const head = this.snake.body[0];

    // 判断是否撞到蛇身
    for (let i = 1; i < this.snake.body.length; i++) {
      if (head[0] === this.snake.body[i][0] && head[1] === this.snake.body[i][1]) {
        return true;
      }
    }

    // 判断是否撞到游戏边界
    if (head[0] < 0 || head[0] > 19 || head[1] < 0 || head[1] > 19) {
      return true;
    }

    return false;
  }

  // 更新画面
  updateScreen() {
    const board = document.querySelector("#board");
    board.innerHTML = "";

    // 添加蛇的元素
    this.snake.body.forEach((segment) => {
      const div = document.createElement("div");
      div.classList.add("segment");
      div.style.left = `${segment[0] * 20}px`;
      div.style.top = `${segment[1] * 20}px`;
      board.appendChild(div);
    });

    // 添加食物
    const foodDiv = document.createElement("div");
    foodDiv.classList.add("food");
    foodDiv.style.left = `${this.food[0] * 20}px`;
    foodDiv.style.top = `${this.food[1] * 20}px`;
    board.appendChild(foodDiv);

    // 更新得分
    const scoreDiv = document.querySelector("#score");
    scoreDiv.innerText = `Score: ${this.score}`;
  }
}

// 启动游戏
const snake = new Snake();
const game = new Game();
game.init(snake);
game.loop();
结束语

以上是一个简单的蛇游戏实现,可以根据需求进行定制,例如添加声音效果、在特定条件下开始加速等等。