Я начал разрабатывать простое MUD (текстовое многопользовательское подземелье), где клиент использует только терминал для подключения и игры.
Однако я подошел к нему по-другому, я хочу, чтобы игрок мог перемещаться по комнатам (x, y) и видеть карту комнаты, как на скриншоте ниже.
Весь экран, как видно, отправляется сервером клиенту с такими обновлениями, как:
кто-то переехал, что-то изменилось в текущем местоположении, кто-то что-то уронил и т.д …
Внизу экрана есть место, где клиенты могут помещать такие команды:
посмотрите, восток, запад, забрать, упасть, инвентарь, …
проблема
Однако проблема с дизайном заключается в том, что когда пользователь находится в процессе ввода команды, а сервер тем временем обновил свой экран (кто-то переместился или сгенерировано какое-то событие), он потеряет набранную команду, потому что весь экран получил обновилась.
Как отправить экран на плеер?
Я строю представление на стороне сервера, и при отправке клиенту я использую символы ANSI для:
Вопрос
Возможно ли, что клиенты не теряют свой вклад, когда я отправляю им представление?
Другими словами, возможно ли (может быть, требуется какой-то код ANSI?), Что, когда я что-то набираю в терминале, а между тем, если я что-то получаю, мой ввод не прерывается вновь полученным сообщением?
Чтобы визуализировать проблему:
Хорошо:
from server: aaa
from server: bbb
> input
Текущий:
from server: aaa
> in
from server: bbb
put
Вероятно, лучше создать представление на стороне клиента — тогда серверу нужно только отправить «необработанную информацию», а клиент может отобразить ее. В этом случае вы сказали, что сервер отправляет новое представление о событиях, например, о том, что кто-то движется, поэтому просто отправьте клиенту сообщение «Боб переехал», а не совершенно новый отображаемый экран, и позвольте клиенту обработать обновление ,
Это имеет несколько преимуществ — чтобы решить вашу проблему, вы можете просто буферизовать любой ввод с сервера, пока пользователь не закончит ввод, или перерисовать любые биты экрана, которые клиентский пользователь не изменяет активно.
Это также позволяет больше настраивать на стороне клиента — если сервер отправляет представление, как клиент отображает его на терминале, разрешение которого отличается от представления сервера? С рендерингом на стороне клиента вы можете справиться с такого рода проблемами для каждого клиента. Вы также можете открыть дверь к большему количеству настроек, позволяя пользователям клиентов настраивать свои личные представления.
Если вы не хотите, чтобы сервер создавал представления, то на клиенте вы можете читать односимвольные вводы одновременно (в Windows _getch
на Linux ncurses
обеспечивает эту функциональность), затем, если происходит обновление сервера, просто визуализируйте новое представление, а затем повторно выполните рендеринг того, что пользователь ввел заранее.
Коды ANSI … грязные. Использование библиотеки как curses
может сделать консольный интерфейс намного приятнее и удобнее в обслуживании. На Linux есть ncurses
и на окнах есть вариант с открытым исходным кодом под названием pdcurses
(очевидно, имеет тот же API, только что выставленный в независимой библиотеке. Вам нужно будет изменить настройки компоновщика при компиляции в Windows, но, надеюсь, не какой-либо код). Спасибо Bartek за упоминание этого.
Других решений пока нет …