JavaScript >> Javascript 文檔 >  >> JavaScript

用 JavaScript 為終端編寫一個貪吃蛇遊戲

通常,當您想到 JavaScript 遊戲時,您可能會想像在瀏覽器中播放的東西,要么呈現到 DOM,要么呈現在 HTML5 畫布元素中。

對於最近的一個 Node.js 項目,我想將像素渲染到終端界面而不是瀏覽器。為此,我需要找到並學習如何使用像 curses 這樣的終端 UI 庫。 JavaScript 環境中最受歡迎的有福了。

我認為編寫經典的貪吃蛇遊戲會是一個有趣且容易習慣的項目,所以我寫了🐍Snek.js。

這是遊戲的簡要預覽圖:

可以查看源碼,也可以自己下載播放:

git clone https://github.com/taniarascia/snek
cd snek
npm i && npm run play

我用舊諾基亞積木製作了我記憶中的遊戲:

  • 有一個隨機生成的點
  • 有一條蛇可以上、下、左或右
  • 如果蛇吃了點,它就會長大,分數會上升 1
  • 如果蛇撞到牆或撞到自己,遊戲會重置

面向對象

我廣泛使用了 ES6 JavaScript class 關鍵詞,並將游戲分為兩類:

  • Game ,它將跟踪蛇、點和分數的狀態
  • UserInterface ,它將處理所有 i/o,這意味著鍵輸入、屏幕以及將任何內容渲染到屏幕

用戶界面

Blessed 使用“盒子”來表示元素,所以我有一個 gameBox 表示整個遊戲區域,scoreBox 表示將設置和更新分數的單行,以及 gameOverBox 顯示遊戲結束模式。

所有將被繪製到屏幕上的像素——在這種情況下,點和蛇的每一段——都通過 draw() 方法,這是一個 1px x 1px 盒子。

因為所有的按鍵輸入都會通過 UserInterface 檢測到 類,我必須綁定所有處理程序方法,以便可以通過 Game 使用它們 類。

UserInterface.js
bindHandlers(keyPressHandler, quitHandler, enterHandler) {
  this.screen.on('keypress', keyPressHandler)
  this.screen.key(['escape', 'q', 'C-c'], quitHandler)
  this.screen.key(['enter'], enterHandler)
}
Game.js
this.ui.bindHandlers(this.changeDirection.bind(this), this.quit.bind(this), this.start.bind(this))

遊戲

Game 跟踪蛇、點和分數。

蛇是一個 x/y 坐標數組,對應於屏幕上的像素。蛇根據按鍵輸入的方向移動(支持箭頭鍵和 WASD!)。要移動,刪除數組中的最後一項(尾部),並在開頭添加一個新項(頭部)。如果蛇吃掉一個點,最後一個項目不會被移除,蛇就會長大。

被吃掉後隨機產生一個新的點。點不會在現有的蛇段上生成。

如果蛇撞到終端屏幕的邊緣(牆壁)或撞到自己的尾巴,則遊戲結束,並顯示遊戲結束模式。

按下回車鍵將通過調用 start 開始一個新遊戲 方法,重置遊戲狀態並在不存在時啟動計時器。

start() {
  if (!this.timer) {
    this.reset()

    this.timer = setInterval(this.tick.bind(this), 50)
  }
}

50 毫秒,tick 被稱為,也就是遊戲循環。如果比賽結束,計時器將重新開始。否則,每個刻度都會清除屏幕、繪製一個點、移動蛇、繪製蛇並將所有內容渲染到 UI。

tick() {
  if (this.gameOver()) {
    this.showGameOverScreen()
    clearInterval(this.timer)
    this.timer = null

    return
  }

  this.clear()
  this.drawDot()
  this.moveSnake()
  this.drawSnake()
  this.ui.render()
}

結論

同樣,您可以在 GitHub 上的 🐍 Snek.js 查看源代碼。

在過去的幾天裡,我學到了很多寫作和重構。我在第一次迭代中遇到了很多錯誤,例如蛇能夠碰撞到除了最後一個尾部以外的所有部分,還有一個主要問題是祝福的盒子沒有被垃圾收集,遊戲變得越來越慢變得效率低下,運行起來更加密集。

vsergeev 為 Snake 編寫了一個非常乾淨、更高級和可擴展的 Typescript 實現,帶有一個迷你游戲引擎和 AI 怪物實體。研究這個幫助我在第一次迭代中發現並修復了一些錯誤。


Tutorial JavaScript 教程
  1. 我是如何建立我的投資組合的

  2. JavaScript 映射返回對像數組 |代碼

  3. 使用 Angular CLI 過濾 Protractor 端到端測試

  4. 高級 Node.js 項目結構教程

  5. fetch() 輸入意外結束

  6. React 中高階組件的簡要介紹

  7. 為什麼我開發了一個靜態網站構建器🤦🏻‍♂️

  1. Jquery - JavaScript 系列 - 第 30 部分

  2. 第 3 部分:使用 React-App-Rewired 設置模板

  3. 使用 JavaScript 對象動態填充 HTML

  4. 使用 Angus 更快地構建 Web 應用程序

  5. 構建塊(學習 ClojureScript)

  6. 重新創建 Apple 的深色模式圖標

  7. JavaScript 單元測試 101:Mocha 和 Chai ☕️

  1. 使用您的學生帳戶免費獲得這些服務。

  2. 非 CS 視角下的大 O 表示法

  3. 使用 AWS Lambda 和 RapidAPI 創建 API [教程]

  4. React:ContextAPI 作為狀態解決方案?