当前位置:首页 > VUE

vue实现贪吃蛇

2026-01-20 10:00:50VUE

vue实现贪吃蛇

vue实现贪吃蛇

实现思路

Vue实现贪吃蛇游戏的核心在于数据驱动DOM渲染。通过维护蛇身坐标、食物位置和移动方向等状态,结合Vue的响应式特性实现游戏逻辑。

核心代码结构

<template>
  <div class="game-container">
    <div class="grid" :style="gridStyle">
      <div 
        v-for="(cell, index) in grid" 
        :key="index"
        :class="['cell', 
          { 'snake': cell.isSnake, 'food': cell.isFood }]"
      ></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      gridSize: 20,
      snake: [{x: 10, y: 10}],
      food: {},
      direction: 'right',
      gameSpeed: 200
    }
  }
}
</script>

初始化游戏

methods: {
  initGame() {
    this.generateFood();
    this.gameInterval = setInterval(this.moveSnake, this.gameSpeed);
    window.addEventListener('keydown', this.handleKeyPress);
  },

  generateFood() {
    this.food = {
      x: Math.floor(Math.random() * this.gridSize),
      y: Math.floor(Math.random() * this.gridSize)
    };
  }
}

蛇移动逻辑

moveSnake() {
  const head = {...this.snake[0]};

  switch(this.direction) {
    case 'up': head.y--; break;
    case 'down': head.y++; break;
    case 'left': head.x--; break;
    case 'right': head.x++; break;
  }

  if (this.checkCollision(head)) {
    this.gameOver();
    return;
  }

  this.snake.unshift(head);

  if (head.x === this.food.x && head.y === this.food.y) {
    this.generateFood();
  } else {
    this.snake.pop();
  }
}

碰撞检测

checkCollision(head) {
  // 边界检测
  if (head.x < 0 || head.x >= this.gridSize || 
      head.y < 0 || head.y >= this.gridSize) {
    return true;
  }

  // 自碰撞检测
  return this.snake.some(segment => 
    segment.x === head.x && segment.y === head.y
  );
}

键盘控制

handleKeyPress(e) {
  const keyMap = {
    'ArrowUp': 'up',
    'ArrowDown': 'down',
    'ArrowLeft': 'left',
    'ArrowRight': 'right'
  };

  const newDirection = keyMap[e.key];
  const oppositeDirections = {
    up: 'down',
    down: 'up',
    left: 'right',
    right: 'left'
  };

  if (newDirection && oppositeDirections[this.direction] !== newDirection) {
    this.direction = newDirection;
  }
}

样式设计

.game-container {
  display: flex;
  justify-content: center;
}

.grid {
  display: grid;
  grid-template-columns: repeat(20, 20px);
  gap: 1px;
  background: #eee;
}

.cell {
  width: 20px;
  height: 20px;
  background: white;
}

.snake {
  background: #4CAF50;
}

.food {
  background: #F44336;
  border-radius: 50%;
}

游戏状态管理

gameOver() {
  clearInterval(this.gameInterval);
  alert('Game Over!');
  this.resetGame();
},

resetGame() {
  this.snake = [{x: 10, y: 10}];
  this.direction = 'right';
  this.generateFood();
  this.initGame();
}

响应式网格计算

computed: {
  grid() {
    const grid = [];
    for (let y = 0; y < this.gridSize; y++) {
      for (let x = 0; x < this.gridSize; x++) {
        grid.push({
          x, y,
          isSnake: this.snake.some(segment => segment.x === x && segment.y === y),
          isFood: this.food.x === x && this.food.y === y
        });
      }
    }
    return grid;
  },

  gridStyle() {
    return {
      gridTemplateColumns: `repeat(${this.gridSize}, 20px)`
    };
  }
}

生命周期控制

mounted() {
  this.initGame();
},

beforeDestroy() {
  clearInterval(this.gameInterval);
  window.removeEventListener('keydown', this.handleKeyPress);
}

扩展功能建议

  1. 添加分数计算系统
  2. 实现游戏暂停功能
  3. 增加难度等级选择
  4. 添加移动端触摸控制
  5. 实现游戏存档功能

标签: 贪吃蛇vue
分享给朋友:

相关文章

vue实现监听

vue实现监听

监听数据变化 在Vue中,可以通过watch选项或$watch方法监听数据的变化。watch适用于组件选项内声明式监听,$watch适用于动态监听。 // 选项式API export default…

vue实现tap

vue实现tap

Vue 实现 Tap 事件 在移动端开发中,Tap 事件比 Click 事件更常用,因为 Click 事件有 300ms 延迟。以下是几种在 Vue 中实现 Tap 事件的方法。 使用第三方库 安装…

vue实现 页面

vue实现 页面

Vue 实现页面的核心方法 创建 Vue 项目 使用 Vue CLI 或 Vite 快速初始化项目。Vue CLI 是官方脚手架工具,适合传统项目;Vite 提供更快的现代构建体验。 npm cre…

vue系统实现

vue系统实现

Vue 系统实现的关键步骤 项目初始化与配置 使用 Vue CLI 或 Vite 创建项目,安装核心依赖(如 Vue 3、Vue Router、Pinia)。配置开发环境(如 ESLint、Prett…

vue原生实现

vue原生实现

Vue 原生实现方法 在 Vue 中实现原生功能通常指直接使用 Vue 的核心特性(如指令、响应式数据、组件等)而非依赖第三方库。以下是几种常见场景的原生实现方式: 数据绑定与响应式更新 Vue 的…

vue实现指引

vue实现指引

Vue 实现指引功能 Vue 中实现指引功能可以通过多种方式完成,常见的有使用第三方库或自定义实现。以下是几种常见方法: 使用第三方库(如 driver.js) 安装 driver.js: np…