使用 ink + react 制作一個命令行在線五子棋游戲客戶端

背景

InkReact 在命令行中渲染系統(tǒng)的一個實(shí)現(xiàn), 在 GitHub 上已經(jīng)有 1w+ Star. 看著蠻好玩, 因此嘗試著寫了一個五子棋游戲, 經(jīng)過若干天的劃水, 終于初見成效了!

先來看個演示動畫(Gif 太大這里放不下, 請移步 GitHub 觀看):

需要聲明的是: 這個客戶端我已經(jīng)開源在了 GitHub 上, 地址是 https://github.com/acrazing/gomoku-terminal, 但是這是一個在線游戲的客戶端, 因?yàn)樯虡I(yè)原因, 服務(wù)端代碼沒有開源, 所以這篇文章主要描述 Ink + React 構(gòu)建客戶端的過程, 后續(xù)如果有機(jī)會的話會考慮寫一篇文章來聊聊服務(wù)端的架構(gòu)與思路.

如何使用

首先需要你在本地安裝 node + npm, 然后使用 npm 全局安裝本項(xiàng)目的 npm 包:

npm i -g gomoku-terminal

這個時候全存在一個命令行入口 gomoku, 其使用方法是:

$ gomoku --help
gomoku [options]

Options:
  --version  Show version number                                       [boolean]
  --api      the api host        [string] [default: "http://23.106.139.99:5001"]
  --store    the config & session store file
                                   [string] [default: "~/.gomoku-terminal.json"]
  --help     Show help                                                 [boolean]

如果只啟動一個實(shí)例, 則不需要傳遞任何參數(shù)在命令行中直接調(diào)用即可, 但是如果要啟動多個實(shí)例, 則需要傳入 --store 參數(shù), 指向不同的文件名, 來儲存會話信息.

第一次啟動或者 token 過期時, 會首先進(jìn)入登錄界面:

image.png

這個時候你需要使用方向鍵來控制焦點(diǎn), 然后輸入用戶名和密碼再將焦點(diǎn)移動到 Go 上按回車鍵登錄, 或者不輸入用戶名和密碼直接按 Anonymous 進(jìn)行匿名登錄, 目前注冊接口似乎有問題, 只支持匿名登錄.

登錄成功后, 會跳轉(zhuǎn)到房間列表頁面:

image.png

這個頁面會展示5個房間, 你可以使用上下鍵來選擇一個房間進(jìn)入(如果有的話), 或者點(diǎn)擊 New 來創(chuàng)建一個房間并進(jìn)入. 按 R 可以手動刷新房間列表.

進(jìn)入房間后, 會自動跳轉(zhuǎn)到房間頁面:

image.png

這個時候你首先需要按 Ready 鍵(或者按鍵盤 R)來準(zhǔn)備, 長時間未準(zhǔn)備會被踢出, 雙方均準(zhǔn)備后游戲自動開始. 這個時候如果該你落子的話可以通過方向鍵來選擇要落子的位置, 然后按回車落子, 長時間未落子會自動判負(fù):

image.png

技術(shù)實(shí)現(xiàn)

主要有兩個難點(diǎn):

一個是鍵盤控制, 這個 ink 并沒有提供一個有效的方案來進(jìn)行操作, 只提供了一個 StdinContext 來暴露了標(biāo)準(zhǔn)輸入, 而通過按鍵來控制焦點(diǎn)則需要自行實(shí)現(xiàn), 本項(xiàng)目中的實(shí)現(xiàn)是通過一個 Focusable 組件來實(shí)現(xiàn)的, 具體可以查看該文件: Focusable.ts.

另一個是性能問題, Ink 的組件每一次刷新(render)都會觸發(fā)一次全量渲染, 這個和 react-dom 不一樣, react-dom 做了大量的優(yōu)化(主要是 diff 算法與 patch update). 在繪制棋盤界面的過程中, 至少需要有255(15 * 15)個元素, 因此必須要嚴(yán)格控制每個 Piece 的刷新過程, 絕對不能出現(xiàn)一個狀態(tài)變更導(dǎo)致所有 Piece 都渲染的情況, 因此只能通過元素局部狀態(tài)來控制, 而不能通過 props.

此外, 本項(xiàng)目中使用 mobx 來管理狀態(tài), mobx-sync 來持久化狀態(tài)到文件系統(tǒng), 還實(shí)現(xiàn)了一個快捷鍵系統(tǒng), 具體可以查看該文件: KeyboardReceiver.

TODO

  • 優(yōu)化性能: 目前的渲染性能實(shí)在太糟糕, 只能說是勉強(qiáng)能用的狀態(tài), 這個需要 ink 自身做大量的優(yōu)化
  • 優(yōu)化體驗(yàn): 目前只完成了基礎(chǔ)的交互功能, 但是外觀相當(dāng)丑

源代碼地址: https://github.com/acrazing/gomoku-terminal
npm 包地址: https://www.npmjs.com/package/gomoku-terminal

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末初狰,一起剝皮案震驚了整個濱河市爵憎,隨后出現(xiàn)的幾起案子审磁,更是在濱河造成了極大的恐慌,老刑警劉巖荧飞,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異措伐,居然都是意外死亡凝危,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門阔涉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缆娃,“玉大人捷绒,你說我怎么就攤上這事×淞担” “怎么了疙驾?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵凶伙,是天一觀的道長郭毕。 經(jīng)常有香客問我,道長函荣,這世上最難降的妖魔是什么显押? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮傻挂,結(jié)果婚禮上乘碑,老公的妹妹穿的比我還像新娘。我一直安慰自己金拒,他們只是感情好兽肤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著绪抛,像睡著了一般资铡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上幢码,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天笤休,我揣著相機(jī)與錄音,去河邊找鬼症副。 笑死店雅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贞铣。 我是一名探鬼主播闹啦,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辕坝!你這毒婦竟也來了亥揖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤圣勒,失蹤者是張志新(化名)和其女友劉穎费变,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體圣贸,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挚歧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吁峻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滑负。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡在张,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出矮慕,到底是詐尸還是另有隱情帮匾,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布痴鳄,位于F島的核電站瘟斜,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏痪寻。R本人自食惡果不足惜螺句,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望橡类。 院中可真熱鬧蛇尚,春花似錦、人聲如沸顾画。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽研侣。三九已至谱邪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間义辕,已是汗流浹背虾标。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灌砖,地道東北人璧函。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像基显,于是被迫代替她去往敵國和親蘸吓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

推薦閱讀更多精彩內(nèi)容