MUD 服务器和基于文本的客户端
MUD Server and text based client
我已经开始开发一个简单的 MUD(基于文本的多人地牢),客户端只使用终端连接和玩游戏。
但是我采用了不同的方式,我希望玩家能够在房间 (x,y) 中移动并查看房间的地图,如下面的屏幕截图所示
看到的整个屏幕正在由服务器发送到客户端,更新如下:
有人移动,当前位置发生变化,有人掉落东西,等等...
在屏幕底部,有一个地方可以让客户输入如下命令:
看,东,西,拾取,掉落,库存,...
问题
然而,设计的问题是,当用户正在输入命令时,同时服务器更新了它的屏幕(有人移动,或生成了某些事件),他将失去他正在输入的命令因为整个屏幕都刷新了。
如何将画面发送给播放器?
我在服务器端构建视图,当发送到客户端时,我使用 ANSI 字符来:
- 清除屏幕 (\u001b[H\u001b[2J)
- 将光标定位在 window (\033[....) 的特定区域以绘制视图的特定区域
问题
有没有可能,当我向他们发送视图时,客户不会丢失他们的输入?
换句话说,是否有可能(可能需要一些 ANSI 代码?)当我在终端中输入内容时,同时如果我收到内容,我的输入不会被新收到的消息破坏?
可视化问题:
好:
from server: aaa
from server: bbb
> input
当前:
from server: aaa
> in
from server: bbb
put
备选方案
在客户端构建视图可能是一个更好的主意 - 然后服务器只需要发送 "raw information" 客户端就可以显示它。在这种情况下,您已经说过服务器会发送一个关于事件的新视图,例如有人移动 - 所以只需向客户端发送一条消息说 "Bob has moved",而不是一个全新的渲染屏幕,并让客户端处理更新.
这有多个优点 - 要解决您的问题,您可以只缓冲任何服务器输入,直到用户完成输入,或者重绘客户端用户未主动更改的任何屏幕位。
它还允许在客户端进行更多自定义 - 如果服务器发送视图,客户端如何在与服务器视图分辨率不同的终端上显示它?使用客户端呈现,您可以在每个客户端的基础上处理此类问题。您还可以通过让客户端用户自定义他们的个人视图来打开更多自定义的大门。
解决现有策略
如果您固定让服务器构建视图,那么在客户端上您可以一次读取单个字符输入(windows _getch
,linux ncurses
提供此功能),然后如果发生服务器更新,只需呈现新视图,然后重新呈现用户预先输入的内容。
另一个建议
ANSI 代码……很乱。使用像 curses
这样的库可以使基于控制台的 GUI 更好、更易于维护。在 linux 上有 ncurses
,在 windows 上有一个名为 pdcurses
的开源变体(显然有相同的 API,只是暴露在一个独立的库中。在 Windows 上编译时,您需要更改链接器设置,但希望不是任何代码)。感谢 Bartek 提到这一点。
我已经开始开发一个简单的 MUD(基于文本的多人地牢),客户端只使用终端连接和玩游戏。
但是我采用了不同的方式,我希望玩家能够在房间 (x,y) 中移动并查看房间的地图,如下面的屏幕截图所示
看到的整个屏幕正在由服务器发送到客户端,更新如下:
有人移动,当前位置发生变化,有人掉落东西,等等...
在屏幕底部,有一个地方可以让客户输入如下命令:
看,东,西,拾取,掉落,库存,...
问题
然而,设计的问题是,当用户正在输入命令时,同时服务器更新了它的屏幕(有人移动,或生成了某些事件),他将失去他正在输入的命令因为整个屏幕都刷新了。
如何将画面发送给播放器?
我在服务器端构建视图,当发送到客户端时,我使用 ANSI 字符来:
- 清除屏幕 (\u001b[H\u001b[2J)
- 将光标定位在 window (\033[....) 的特定区域以绘制视图的特定区域
问题
有没有可能,当我向他们发送视图时,客户不会丢失他们的输入?
换句话说,是否有可能(可能需要一些 ANSI 代码?)当我在终端中输入内容时,同时如果我收到内容,我的输入不会被新收到的消息破坏?
可视化问题:
好:
from server: aaa
from server: bbb
> input
当前:
from server: aaa
> in
from server: bbb
put
备选方案
在客户端构建视图可能是一个更好的主意 - 然后服务器只需要发送 "raw information" 客户端就可以显示它。在这种情况下,您已经说过服务器会发送一个关于事件的新视图,例如有人移动 - 所以只需向客户端发送一条消息说 "Bob has moved",而不是一个全新的渲染屏幕,并让客户端处理更新.
这有多个优点 - 要解决您的问题,您可以只缓冲任何服务器输入,直到用户完成输入,或者重绘客户端用户未主动更改的任何屏幕位。
它还允许在客户端进行更多自定义 - 如果服务器发送视图,客户端如何在与服务器视图分辨率不同的终端上显示它?使用客户端呈现,您可以在每个客户端的基础上处理此类问题。您还可以通过让客户端用户自定义他们的个人视图来打开更多自定义的大门。
解决现有策略
如果您固定让服务器构建视图,那么在客户端上您可以一次读取单个字符输入(windows _getch
,linux ncurses
提供此功能),然后如果发生服务器更新,只需呈现新视图,然后重新呈现用户预先输入的内容。
另一个建议
ANSI 代码……很乱。使用像 curses
这样的库可以使基于控制台的 GUI 更好、更易于维护。在 linux 上有 ncurses
,在 windows 上有一个名为 pdcurses
的开源变体(显然有相同的 API,只是暴露在一个独立的库中。在 Windows 上编译时,您需要更改链接器设置,但希望不是任何代码)。感谢 Bartek 提到这一点。