目录
Vue.js写一个命令行贪吃蛇游戏
首页 web前端 Vue.js 教你用Vue轻松做个贪吃蛇游戏(附演示代码)

教你用Vue轻松做个贪吃蛇游戏(附演示代码)

Nov 25, 2022 pm 04:59 PM
vue.js 贪吃蛇

本文要分享的是如何使用Vue.js实现一个命令行贪吃蛇游戏(temir-snake-game).对于贪吃蛇游戏想必大家都不陌生了,使用Vue.js实现一个Web版的贪吃蛇游戏似乎没什么难度,那如果是命令行版的呢?是不是你会对它的实现原理感兴趣呢?让我们开始吧!

Vue.js写一个命令行贪吃蛇游戏

安装

npm install temir-snake-game -g
登录后复制

开始游戏

在终端窗口运行temir-sg.

对于Windows系统,推荐使用hyper终端进行体验.

将Vue渲染到命令行界面

使用Vue.js实现命令行贪吃蛇游戏,首先意味着我们要将Vue.js渲染到命令行界面,才能开始具体的游戏实现.我们经常用Vue.js来编写Web应用,但是Vue的能力却不仅仅局限于此,它的舞台也不只有浏览器.Vue3拥有出色的跨平台能力,我们可以通过createRenderer API创建一个自定义渲染器,通过创建宿主环境中对应的Node和Element,并对元素进行增删改查操作.【推荐:vue.js视频教程

得益于Vue3出色的跨平台能力,我实现了Temir,一个用Vue组件来编写命令行界面应用的工具.开发者只需要使用Vue就可以编写命令行应用,不需要任何额外的学习成本.顺便值得一提的是,它还支持HMR~

8f0ef583a65ad9f5e7ce14d23789ca1.jpg

关于Temir就不在这里进行详细的介绍了,有兴趣的童鞋可以上Github查看介绍或者看使用Vue.js编写命令行界面这篇文章.

贪吃蛇游戏实现

有了Temir,我们就具备了使用Vue.js编写命令行游戏的条件,接下来我们来看看游戏的具体实现:

实现拆解

首先我们对游戏实现进行一下简单的拆解,从元素+逻辑的维度来看,可以简单分为几部分:

7c2884e8b9ff854e6d37efbb3a56d17.jpg

元素初始化

竞技台

蛇的爬行与食物的生成都需要依赖坐标,最简单的坐标其实只需要一个索引值.因此竞技台的组成也很简单,就是由很多个小盒子(这里以⬛表示)组成,每一个盒子对应一个坐标(索引),我们要做的是一个28*28的竞技台,因此它的索引集合就是(0~783).

const basic = 28
const backgroundIcon = '⬛'
const arena = ref<string[]>([])

function initArena() {
 arena.value = Array.from({ length: basic * basic }, () => backgroundIcon)
}
登录后复制

前面我们提到了坐标的概念,蛇身的组成就是一串有规律的坐标.

const snakeIcon = &#39;?&#39;
// 坐标(索引)30,29 长度为2的蛇身
const snakeBody = ref([30, 29])
登录后复制

食物

食物的生成其实也就是随机一个坐标(索引),只不过要注意的是,我们需要避开蛇身本身的坐标.

const foodIcon = &#39;?&#39;
// 食物坐标
const foodCoord = ref(77)

// 生成食物
function generateFood() {
  const food = Math.floor(Math.random() * basic * basic)
  // 与蛇身冲突,重新生成
  if (snakeBody.value.includes(food)) {
    generateFood()
    return
  }
  foodCoord.value = food
}
登录后复制

初始化后的元素长这样 :

046555b229c397062d21dbbaefacb93.jpg

蛇的爬行

蛇的爬行逻辑有两个基础元素,方向 + 步数.前面我们提到了竞技台的组成是一个28*28的行列式结构,那么关于方向和步数的映射,就比较清晰了:

const map = {
 left: -1,
 right: 1,
 top: -28,
 bottom: 28
}
登录后复制

有了两个基本元素,我们就可以得出我们每一次爬行的下一个坐标.我们只需要在每次爬行的时候往蛇头添加对应的坐标,并移除蛇尾所在的坐标就可以达到蛇爬行的效果.

function move() {
  const h = snakeBody.value[0]
  // 计算下一次爬行坐标,并添加至蛇头
  head.value = h + direction.value
  snakeBody.value.unshift(head.value)

  // 吃到食物,重新生成
  if (head.value === foodCoord.value) {
    generateFood()
  }
  // 只有在未吃到食物的时候,才需要移除蛇尾
  else { snakeBody.value.pop() }
}
登录后复制

越界逻辑

贪吃蛇的游戏结束规则判断就是爬行时蛇头越界(这里的界限指的是超出竞技台的范围)或者碰到蛇身.

function isOutOfRange(h: number) {
    // 1. 蛇头碰到蛇身
  return snakeBody.value.indexOf(h, 1) > 0
    // 2. 蛇头超出竞技台上方
    || h < 0
    // 3. 蛇头超出竞技台下方
    || h > basic * basic - 1
    // 4. 蛇头超出竞技台右方
    || (direction.value === 1 && h % basic === 0)
    // 5. 蛇头超出竞技台左方
    || (direction.value === -1 && h % basic === basic - 1)
}
登录后复制

方向控制

贪吃蛇游戏核心的操作逻辑在于操纵蛇的方向进行食物的捕捉.所以我们需要做的就是捕捉用户方向键的输入进行方向的切换.Temir提供了useInput函数监听用户的输入.

import { useInput } from &#39;@temir/core&#39;
useInput(onKeyBoard, { isActive: true })

function onKeyBoard(_, keys) {
  const { upArrow, downArrow, leftArrow, rightArrow } = keys
  const d = {
    [+leftArrow]: -1,
    [+rightArrow]: 1,
    [+upArrow]: -basic,
    [+downArrow]: basic,
  }[1] ?? direction.value
  direction.value = (snakeBody.value[1] - snakeBody.value[0] === d) ? direction.value : d
}
登录后复制

UI绘制

关于UI的绘制与呈现Temir提供了一些Vue组件,我们只需要像构建Flexbox布局那样构建终端UI:

<script setup>
import { computed } from &#39;vue&#39;
import { TBox, TText } from &#39;@temir/core&#39;
import { useGame } from &#39;./composables&#39;
import Header from &#39;./components/Header.vue&#39;
import Home from &#39;./components/Home.vue&#39;
import Game from &#39;./components/Game.vue&#39;
import GameOver from &#39;./components/GameOver.vue&#39;
import Exit from &#39;./components/Exit.vue&#39;
const { playStatus } = useGame()
const activeComponent = computed(() => {
  return {
    unplayed: Home,
    playing: Game,
    over: GameOver,
    exit: Exit,
  }[playStatus.value]
})
</script>

<template>
  <TBox
    :width="100"
    justify-content="center"
    align-items="center"
    flex-direction="column"
    border-style="double"
  >
    <Header />
    <component :is="activeComponent" />
  </TBox>
</template>
登录后复制

到这里,贪吃蛇的实现就结束了,对具体实现感兴趣的可以戳源码查看.

演示

ddd6f3bc4124d4bc6527c288790fa52.jpg

0fac59407a689bcf9dcf1bb8716b4b1.jpg

以上是教你用Vue轻松做个贪吃蛇游戏(附演示代码)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

深入探讨vite是怎么解析.env文件的 深入探讨vite是怎么解析.env文件的 Jan 24, 2023 am 05:30 AM

使用vue框架开发前端项目时,我们部署的时候都会部署多套环境,往往开发、测试以及线上环境调用的接口域名都是不一样的。如何能做到区分呢?那就是使用环境变量和模式。

图文详解如何在Vue项目中集成Ace代码编辑器 图文详解如何在Vue项目中集成Ace代码编辑器 Apr 24, 2023 am 10:52 AM

Ace 是一个用 JavaScript 编写的可嵌入代码编辑器。它与 Sublime、Vim 和 TextMate 等原生编辑器的功能和性能相匹配。它可以很容易地嵌入到任何网页和 JavaScript 应用程序中。Ace 被维护为Cloud9 IDE的主要编辑器 ,并且是 Mozilla Skywriter (Bespin) 项目的继承者。

vue中组件化和模块化有什么区别 vue中组件化和模块化有什么区别 Dec 15, 2022 pm 12:54 PM

组件化和模块化的区别:模块化是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个每个功能模块的职能一致。组件化是从UI界面的角度进行规划;前端的组件化,方便UI组件的重用。

探讨如何在Vue3中编写单元测试 探讨如何在Vue3中编写单元测试 Apr 25, 2023 pm 07:41 PM

当今前端开发中,Vue.js 已经成为了一个非常流行的框架。随着 Vue.js 的不断发展,单元测试变得越来越重要。今天,我们将探讨如何在 Vue.js 3 中编写单元测试,并提供一些最佳实践和常见的问题及解决方案。

深入聊聊vue3中的reactive() 深入聊聊vue3中的reactive() Jan 06, 2023 pm 09:21 PM

前言:在vue3的开发中,reactive是提供实现响应式数据的方法。日常开发这个是使用频率很高的api。这篇文章笔者就来探索其内部运行机制。

Vue中JSX语法和模板语法的简单对比(优劣势分析) Vue中JSX语法和模板语法的简单对比(优劣势分析) Mar 23, 2023 pm 07:53 PM

在Vue.js中,开发人员可以使用两种不同的语法来创建用户界面:JSX语法和模板语法。这两种语法各有优劣,下面就来探讨一下它们的区别和优劣势。

浅析Vue3动态组件怎么进行异常处理 浅析Vue3动态组件怎么进行异常处理 Dec 02, 2022 pm 09:11 PM

Vue3动态组件怎么进行异常处理?下面本篇文章带大家聊聊Vue3 动态组件异常处理的方法,希望对大家有所帮助!

浅析vue怎么实现文件切片上传 浅析vue怎么实现文件切片上传 Mar 24, 2023 pm 07:40 PM

在实际开发项目过程中有时候需要上传比较大的文件,然后呢,上传的时候相对来说就会慢一些,so,后台可能会要求前端进行文件切片上传,很简单哈,就是把比如说1个G的文件流切割成若干个小的文件流,然后分别请求接口传递这个小的文件流。

See all articles