首頁 >web前端 >Vue.js >教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)

教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)

藏色散人
藏色散人轉載
2022-11-25 16:59:132792瀏覽

本文要分享的是如何使用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~

教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)

關於Temir就不在這裡進行詳細的介紹了,有興趣的童鞋可以上Github查看介紹或者看使用Vue.js編寫命令行界面這篇文章.

##貪吃蛇遊戲實現

有了Temir,我們就具備了使用Vue.js編寫命令列遊戲的條件,接下來我們來看看遊戲的具體實現:

實現拆解

首先我們對遊戲實作進行簡單的拆解,從元素邏輯的維度來看,可以簡單分為幾部分:

教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)

#元素初始化

競技台

蛇的爬行與食物的生成都需要依賴座標,最簡單的座標其實只需要一個索引值.因此競技台的組成也很簡單,就是由很多個小盒子(這裡以⬛表示)組成,每一個盒子對應一個坐標(索引),我們要做的是一個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
}

初始化後的元素長這樣:

教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)

蛇的爬行

蛇的爬行邏輯有兩個基礎元素,方向步數.前面我們提到了競技台的組成是一個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>

到這裡,貪吃蛇的實現就結束了,對具體實現感興趣的可以戳原始碼查看.

示範

教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)

教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)

######################

以上是教你用Vue輕鬆做個貪吃蛇遊戲(附示範代碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除