dwj*_*ton 3 terminal user-interface node.js
我想使用 Node.js 将经典游戏“贪吃蛇”制作为 CLI 游戏。
为此,我想逃避“将文本打印到屏幕”终端,并完全控制终端(在视觉上可能的有限范围内)。
很高兴(实际上,更可取)让终端充当等宽字符的矩阵。
终端仍应接收键盘事件。
基本上,想想 Jest 在监视模式下如何工作,或者当你执行npm init.
我想找到这个问题的答案很容易 - 但我不知道谷歌这个词是什么。
更新我知道我会用process.stdout这个。一个好的答案可以展示一个简单的例子:
更新 2 - 我创建了一个实用程序库,可以帮助执行此操作:node-cli-character-matrix。
对于 Unix 终端(Linux、MacOS、Windows 上的 WSL),它们只是使用发送到标准输出的普通字节序列来控制一切。这些称为转义序列。
此协议是 VT 系列协议,它是从 Teletype 协议(您在电影中看到的打字机)发展而来的。VT 代表视频终端(因为当时的常规终端是点阵打印机或电传打字机),是 DEC 销售的一系列产品。
最畅销的型号是 VT100。因此,目前软件终端模拟的最流行的协议是基于VT100协议的。
如果您搜索“VT100 转义码”,您将找到有关如何控制终端的文档。
一旦软件开始模拟这些硬件终端,人们就希望标准化支持哪些功能(产生了各种终端,例如:VT52、VT100、VT102 等),因此 ANSI 为文本终端制定了一个标准 X3.64(后来也由ECMA 为 ECMA-48)。因此,您也可以选择搜索“ANSI 转义代码”来获取您想要的内容。
维基百科实际上有一个相当不错的页面: https: //en.wikipedia.org/wiki/ANSI_escape_code。然而,我个人更喜欢使用如下更简单的东西,并避免维基百科上的所有历史内容:https ://espterm.github.io/docs/VT100%20escape%20codes.html
(注意:一些文档将 ESC 字符表示为^[即使它只是一个字节0x1B:)
请注意,Linux 进一步扩展了 ANSI 控制代码以包含更多功能,例如鼠标支持和 RGB 颜色:https://man7.org/linux/man-pages/man4/console_codes.4.html
转义码的工作方式很简单。打印一个不可打印的字符来告诉终端要做什么。例如,要清除您发送的屏幕:
ESC [ 2 J
Run Code Online (Sandbox Code Playgroud)
或者用普通的 JavaScript:
console.log("\x1b[2J");
Run Code Online (Sandbox Code Playgroud)
当然,在打印字符串后console.log()也会发送换行符("\n"或0x0A),但上面的行应该可以工作。显然,为了避免节点上的换行符,您可以使用:
process.stdout.write("\x1b[2J"); // clear screen
Run Code Online (Sandbox Code Playgroud)
在终端中随机打印一些内容,例如在 row=5 column=20 处打印笑脸,就是:
ESC [ 5 ; 2 0 H
Run Code Online (Sandbox Code Playgroud)
当然,假设您的终端支持 utf8(对于笑脸,如果您只打印常规 ASCII 字符,则无需 utf8 支持即可工作)。或者在节点中:
process.stdout.write("\x1b[5;20H");
Run Code Online (Sandbox Code Playgroud)
您可以轻松地使其可重用:
function goto (x, y) {
process.stdout.write(`\x1b[${y};${x}H`);
}
function print (txt) {
process.stdout.write(txt);
}
goto(20,5);
print('');
Run Code Online (Sandbox Code Playgroud)
当然,有很多库可以帮助您控制终端。其中一些也适用于 Windows 控制台(我上面的示例通常不适用于 Windows 控制台,但我听说您可以在 Windows 10 的终端中启用 ANSI 支持,我不使用 Windows)。一些比较流行的有:
从终端获取原始输入并不那么简单。通常情况下,您的stdin命令将由终端默认进行行缓冲。这意味着在按下 Enter 键之前您不会看到任何键盘事件。如果您想从键盘上按下原始按键,则需要关闭行缓冲。不幸的是,节点没有内置任何东西来帮助你做到这一点。幸运的是,unix 确实有标准工具来支持原始输入。
以下命令启用和禁用原始模式,并且已知可在 Linux 和 BSD(例如 MacOS)上运行:
# turn on raw mode, turn off echo
stty raw -echo
# turn off raw mode, turn on echo
stty -raw echo
Run Code Online (Sandbox Code Playgroud)
以下是 node.js 中的一个简单程序,它接受原始键盘输入(如果您想知道 ctrl-x 或箭头键或 F3 键的代码是什么,则很有用):
#! /usr/bin/env node
const exec = require('child_process').execSync;
exec('stty raw -echo', {
stdio: 'inherit' // this is important!
});
process.stdin.on('data', input => {
console.log(`${input.toString('hex')}\r`);
// note: We add \r because in raw mode the terminal won't
// do it automatically for us.
// Example of how to handle key presses:
// Since we are in raw mode the terminal won't send the
// kill signal to our process when we press ctrl-c so
// we need to handle ctrl-c manually:
if (input == '\x03') { // ctrl-c
process.exit();
}
});
process.on('exit', () => {
// remember to restore normal terminal behavior:
exec('stty -raw echo',{
stdio: 'inherit' // this is important!
});
});
Run Code Online (Sandbox Code Playgroud)
您可以在回调中添加所有 UI 控制器逻辑stdin.on('data')。
当然,对于 Windows,您将需要另一个答案(或问题)。
| 归档时间: |
|
| 查看次数: |
999 次 |
| 最近记录: |