Я создаю простую консольную игру в Go. Я хочу каким-то образом принимать небуферизованный ввод (например, вы вводите одну клавишу, и она немедленно возвращается). Я начал с этого кода:
func InitInput() {
exec.Command("stty", "-f", "/dev/tty", "cbreak", "min", "1").Run()
exec.Command("stty", "-f", "/dev/tty", "-echo").Run()
}
func StopInput() {
exec.Command("stty", "-f", "/dev/tty", "echo").Run()
}
func GetInput() string {
var b []byte = make([]byte, 1)
for {
os.Stdin.Read(b)
return string(b)
}
}
Это было потрясающе, но работает только на ОС *nix и требует 3 функции. Затем кто-то порекомендовал мне этот код:
/*
// Works also for 64 bits
#ifdef _WIN32
// Lib for console management in windows
#include "conio.h"
#else
// Libs terminal management in Unix, Linux...
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
// Implement reading a key pressed in terminal
char getch(){
char ch = 0;
struct termios old = {0};
fflush(stdout);
if( tcgetattr(0, &old) < 0 ) perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if( tcsetattr(0, TCSANOW, &old) < 0 ) perror("tcsetattr ICANON");
if( read(0, &ch,1) < 0 ) perror("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if(tcsetattr(0, TCSADRAIN, &old) < 0) perror("tcsetattr ~ICANON");
return ch;
}
#endif
*/
import "C"
И тогда вам нужна только 1 функция:
func GetInput() string {
return string(byte(C.getch()))
}
Это работает отлично, за исключением того, что из-за того, как работает cgo, он очень медленный, что не идеально для игры. Кроме того, исходный код для проверки новой строки, if extras.GetInput() == "\n" {}
, больше не работает. Есть ли способ заставить односимвольный небуферизованный менеджер ввода работать в Go без использования большой, толстой внешней библиотеки?
termbox-go
занимает экран терминала. Я не хочу этого. - person Kognise   schedule 16.02.2018termbox-go
. Прочтите это. - person Kognise   schedule 19.02.2018