教你用Vue基础语法来写一个五子棋小游戏

教你用Vue基础语法来写一个五子棋小游戏

1. 前言

本篇攻略将通过使用 Vue 基础语法实现一个简单的五子棋小游戏。这个项目不是一个完整可玩的游戏,它只是演示了使用Vue框架来实现五子棋的各种功能和思路。在这个过程中,你将了解到如何使用Vue开发一个复杂的项目。如果你是初学者,建议先学习 Vue 的基础语法再来实践本文内容。

2. 开始实现五子棋小游戏

首先,我们需要构建一个Vue程序。使用Vue-cli建立一个项目,或者在CodePen等在线编译器中开始编写代码。这里我们以 Vue-cli 为例:

# 安装脚手架
npm install -g vue-cli

# 创建一个基于 webpack 模板的新项目
vue init webpack my-project

# 安装依赖
cd my-project
npm install

src 目录下添加两个 vue 组件文件:

  • Board.vue 渲染游戏棋盘和监听用户的交互事件。
  • Game.vue 完成游戏当前状态的渲染,并提供落子的方法。
<!-- Board.vue -->

<template>
  <div class="board">
    <div class="cell"
      v-for="i in 15"
      :key="i">
      <div
        class="row"
        v-for="j in 15"
        :key="'r'+i+j"
        :class="{ 'cell-black': list.some(item => item.x === i && item.y === j && item.type === 1), 'cell-white': list.some(item => item.x === i && item.y === j && item.type === 2) }"
        @click="handleClick(i, j)"></div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Board',
  props: {
    list: {
      type: Array,
      default: () => []
    }
  },
  methods: {
    handleClick(row, col) {
      this.$emit('click', row, col);
    }
  }
}
</script>

<style>
.board {
  width: 630px;
  height: 630px;
  display: flex;
  flex-wrap: wrap;
  border: 2px solid #777;
}

.cell {
  width: 42px;
  height: 42px;
  box-sizing: border-box;
  border: 1px solid #777;
  cursor: pointer;
  position: relative;
  &.cell-black::before {
    content: '';
    position: absolute;
    width: 20px;
    height: 20px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background-color: black;
  }
  &.cell-white::before {
    content: '';
    position: absolute;
    width: 20px;
    height: 20px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background-color: white;
  }
}
.row {
  width: 40px;
  height: 40px;
  box-sizing: border-box;
}
</style>
<!-- Game.vue -->

<template>
  <div class="game">
    <board
      :list="list"
      @click="handleClick"/>
    <div class="info">
      <div>{{message}}</div>
      <button @click="handleReset">重新开始</button>
    </div>
  </div>
</template>

<script>
import Board from '@/components/Board';

export default {
  name: 'Game',
  components: { Board },
  data() {
    return {
      list: [],
      message: '',
      current: 1
    }
  },
  methods: {
    handleClick(row, col) {
      //判断是否存在这个点
      if (this.list.some(item => item.x === row && item.y === col )) {
        return;
      }
      // 更新落子状态类
      this.list.push({
        x: row,
        y: col,
        type: this.current
      })
      // 翻转落子状态
      this.current = this.current === 1 ? 2 : 1;
      // 判断胜利条件: 行、列、对角线
      if (this.checkWin(row, col)) {
        this.message = this.current === 1 ? '黑方胜利' : '白方胜利';
      }
    },

    // 判断胜利条件
    checkWin(row, col) {
      const x = row;
      const y = col;
      const list = this.list;
      const count = this.current; // 红子和黄子

      let rowCounter = 0;
      let colCounter = 0;
      let diagonalCounter = 0;
      let oDiagonalCounter = 0;

      // 判断行
      for (let i = x - 4; i <= x; i++) {
        if (list.some(item => item.x === i && item.y === y && item.type === count)) {
          rowCounter++;
        }
      }

      // 判断列
      for (let j = y - 4; j <= y; j++) {
        if (list.some(item => item.x === x && item.y === j && item.type === count)) {
          colCounter++;
        }
      }

      // 判断左上角到右下角斜线 /
      for (let k = 4; k >= -4; k--) {
        if (list.some(item => item.x === x + k && item.y === y + k && item.type === count)) {
          diagonalCounter++;
        }
      }

      // 判断右上角到左下角斜线 \
      for (let l = 4; l >= -4; l--) {
        if (list.some(item => item.x === x - l && item.y === y + l && item.type === count)) {
          oDiagonalCounter++;
        }
      }

      return rowCounter === 5 || colCounter === 5 || diagonalCounter === 5 || oDiagonalCounter === 5;
    },

    handleReset() {
      this.current = 1;
      this.list = [];
      this.message = '';
    }
  }
}
</script>

<style>
.game {
  width: 630px;
  margin: 30px auto;
  padding: 20px;
  background-color: #eee;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.info {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>

App.vue 文件中引入 Game 即可。

<!-- App.vue -->

<template>
  <div id="app">
    <Game />
  </div>
</template>

<script>
import Game from './components/Game';

export default {
  name: 'App',
  components: {
    Game
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
}
</style>

至此,我们完成了五子棋小游戏的大体呈现。接下来就可以试着打开预览网页了。

3. 运行Vue项目

my-project 目录下运行如下命令启动Web服务器:

npm run dev

在浏览器中打开 http://localhost:8080 即可看到五子棋游戏界面。

4. 示例说明

4.1. 在棋盘任意位置落子

你可以通过通过点击游戏棋盘上的任意一个格子,来进行落子。如果该格子已经有落子则无法落子。

<!-- Board.vue -->

<template>
  <div class="board">
    <div class="cell"
      v-for="i in 15"
      :key="i">
      <div
        class="row"
        v-for="j in 15"
        :key="'r'+i+j"
        :class="{ 'cell-black': list.some(item => item.x === i && item.y === j && item.type === 1), 'cell-white': list.some(item => item.x === i && item.y === j && item.type === 2) }"
        @click="handleClick(i, j)"></div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Board',
  props: {
    list: {
      type: Array,
      default: () => []
    }
  },
  methods: {
    handleClick(row, col) {
      this.$emit('click', row, col);
    }
  }
}
</script>

4.2. 判断胜利条件

游戏需要有胜利条件判断和显示,这里简单地判断胜利条件是该列或该行或该斜线连续的五个棋子颜色与当前落子颜色一致。

<!-- Game.vue -->

<template>
  <div class="game">
    <board
      :list="list"
      @click="handleClick"/>
    <div class="info">
      <div>{{message}}</div>
      <button @click="handleReset">重新开始</button>
    </div>
  </div>
</template>

<script>
import Board from '@/components/Board';

export default {
  name: 'Game',
  components: { Board },
  data() {
    return {
      list: [],
      message: '',
      current: 1
    }
  },
  methods: {
    handleClick(row, col) {
      //判断是否存在这个点
      if (this.list.some(item => item.x === row && item.y === col )) {
        return;
      }
      // 更新落子状态类
      this.list.push({
        x: row,
        y: col,
        type: this.current
      })
      // 翻转落子状态
      this.current = this.current === 1 ? 2 : 1;
      // 判断胜利条件: 行、列、对角线
      if (this.checkWin(row, col)) {
        this.message = this.current === 1 ? '黑方胜利' : '白方胜利';
      }
    },

    // 判断胜利条件
    checkWin(row, col) {
      const x = row;
      const y = col;
      const list = this.list;
      const count = this.current; // 红子和黄子

      let rowCounter = 0;
      let colCounter = 0;
      let diagonalCounter = 0;
      let oDiagonalCounter = 0;

      // 判断行
      for (let i = x - 4; i <= x; i++) {
        if (list.some(item => item.x === i && item.y === y && item.type === count)) {
          rowCounter++;
        }
      }

      // 判断列
      for (let j = y - 4; j <= y; j++) {
        if (list.some(item => item.x === x && item.y === j && item.type === count)) {
          colCounter++;
        }
      }

      // 判断左上角到右下角斜线 /
      for (let k = 4; k >= -4; k--) {
        if (list.some(item => item.x === x + k && item.y === y + k && item.type === count)) {
          diagonalCounter++;
        }
      }

      // 判断右上角到左下角斜线 \
      for (let l = 4; l >= -4; l--) {
        if (list.some(item => item.x === x - l && item.y === y + l && item.type === count)) {
          oDiagonalCounter++;
        }
      }

      return rowCounter === 5 || colCounter === 5 || diagonalCounter === 5 || oDiagonalCounter === 5;
    },

    handleReset() {
      this.current = 1;
      this.list = [];
      this.message = '';
    }
  }
}
</script>

以上就是示例内容的讲解,理论上你可以通过将以上代码拷贝至对应文件再运行应该就可以看到效果了。当然最好自己手动敲一遍来加深理解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:教你用Vue基础语法来写一个五子棋小游戏 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • 基于vue-resource jsonp跨域问题的解决方法

    基于vue-resource进行跨域请求时会存在一些问题,其中最常见的就是会因为浏览器同源策略的限制而导致请求失败。为了解决这个问题,可以使用JSONP技术进行跨域请求。 JSONP是什么? JSONP(JSON with padding)是一种前端跨域解决方案。 JSONP的原理是利用 script 标签没有跨域限制这个特性。例如在本地jsp向http:/…

    Vue 2023年5月28日
    00
  • 用npm安装vue和vue-cli,并使用webpack创建项目的方法

    下面是用npm安装vue和vue-cli、并使用webpack创建项目的详细攻略: 1. 安装 Node.js 首先需要安装 Node.js,如果您已经安装过了,请跳过此步骤。 Node.js 的安装方法根据不同的操作系统略有区别,这里以 Mac 为例: 在官网下载 Node.js 的安装包:https://nodejs.org/zh-cn/download…

    Vue 2023年5月28日
    00
  • vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)

    为了实现文件上传,我们需要使用Vue.js和Vant UI框架的一些组件和方法。具体步骤如下: 步骤一:安装所需依赖 首先,在项目目录下安装相应的依赖库。 npm install vant -S # 安装 vant ui 库 npm install vue-awesome-uploader -S # 安装 vue-awesome-uploader 库 步骤二…

    Vue 2023年5月28日
    00
  • vue3+vite2中使用svg的方法详解(亲测可用)

    下面是详细讲解“vue3+vite2中使用svg的方法详解(亲测可用)”的完整攻略。 一、前言 在前端开发中,常常需要使用图片来进行页面的美化,而其中一类图片是矢量图形,例如SVG。在使用Vue3 + Vite2进行开发时,使用SVG可以更加方便灵活地进行页面布局和图形展示。本文将详细讲解在Vue3 + Vite2中使用SVG的方法。 二、在Vue3中进行S…

    Vue 2023年5月29日
    00
  • 一文学会什么是vue.nextTick()

    一文学会什么是vue.nextTick() 什么是vue.nextTick() vue.nextTick()是Vue.js的一个方法,它的作用是在修改数据之后等待DOM更新完毕后执行回调函数。在有些情况下,当我们修改了某个数据后需要对DOM进行操作(比如获取某个元素的高度),此时DOM可能还没有更新完毕,这就需要加入一个异步任务,等待DOM更新完毕后再执行相…

    Vue 2023年5月29日
    00
  • VueCli3构建TS项目的方法步骤

    下面是关于使用VueCli3构建TS项目的攻略: 1. 安装 VueCli3 如果你尚未安装VueCli3,需要使用以下命令进行安装: npm install -g @vue/cli 2. 创建项目 创建项目时,需要选择”Manually select features”,并勾选TypeScript、Linter / Formatter等功能。命令如下: v…

    Vue 2023年5月27日
    00
  • Vue数组的劫持逐步分析讲解

    Vue数组的劫持是Vue.js框架的核心功能之一,它通过监测数组的变化,实现了数据更新与视图更新的自动同步。下面我们将从以下几个方面逐步分析Vue数组的劫持原理。 劫持原理 当使用Vue.js框架时,我们通常会使用Vue的实例对数据进行绑定。例如: var vm = new Vue({ el: ‘#app’, data: { list: [1, 2, 3] …

    Vue 2023年5月28日
    00
  • vue实现日历组件

    下面我将为您详细介绍如何使用Vue实现日历组件。 步骤一:创建 Vue 项目 首先,我们需要先创建一个 Vue 项目。您可以使用 Vue CLI 工具来快速创建一个基础的 Vue 项目,命令如下: vue create my-calendar 步骤二:安装依赖 在创建完项目之后,我们需要安装一些需要用到的依赖。具体可参考下方代码块: npm install …

    Vue 2023年5月29日
    00
合作推广
合作推广
分享本页
返回顶部