在我的程序中,显示5x20的点域。具有符号“#”的玩家也在场上。您可以使用w,a,s和d移动播放器。如果我使用缓冲输入,一切都很好。但是用户不想每次都按回车。所以我使用了命令
system("/bin/stty raw")
现在的问题是输出行为非常奇怪。该字段的行现在无法正确显示。我浪费了很多时间试图自己找出错误。而且Google似乎对此行为没有适当的解释。
你能告诉我为什么程序表现得这么奇怪,以及如何解决吗?
#include <stdio.h>
#define FIELD_VERTIKAL 5
#define FIELD_HORIZONTAL 20
#define PLAYER_SYMBOL '#'
void print_field(char field[FIELD_VERTIKAL][FIELD_HORIZONTAL])
{
// reset display
for (int i = 0; i < 20; i++)
putchar('\n');
// display field
for (int i = 0; i < FIELD_VERTIKAL; i++)
{
for (int j = 0; j < FIELD_HORIZONTAL; j++)
putchar(field[i][j]);
putchar('\n');
}
}
void draw_field(char field[FIELD_VERTIKAL][FIELD_HORIZONTAL],
int pos_vertikal, int pos_horizontal)
{
for (int i = 0; i < FIELD_VERTIKAL; i++)
for (int j = 0; j < FIELD_HORIZONTAL; j++)
field[i][j] = '.';
field[pos_vertikal][pos_horizontal] = '#';
}
int main()
{
// create field and initialize it
char field[FIELD_VERTIKAL][FIELD_HORIZONTAL];
// position of player
int pos_vertikal = 0;
int pos_horizontal = 0;
// initialize field
draw_field(field, pos_vertikal, pos_horizontal);
system("/bin/stty raw");
print_field(field);
char input;
while ((input = getchar()) != EOF)
{
// move player
if (input == 'w')
{
pos_vertikal--;
}
else if (input == 'a')
{
pos_horizontal--;
}
else if (input == 's')
{
pos_vertikal++;
}
else if (input == 'd')
{
pos_horizontal++;
}
// place player and display field
draw_field(field, pos_vertikal, pos_horizontal);
print_field(field);
}
}
答案 0 :(得分:4)
Terminals是非常复杂的设备(今天的terminal emulators试图模仿它们,类似于VT100;当然,这些仿真器是operating-system特有的)。阅读TTY demystified页和termios(3)。另请注意ANSI escape codes。
stty raw
并没有实现您的梦想(与line discipline有关)。另请参见stty(1)和pty(7)。
如果要编写面向终端文本的应用程序,请使用诸如ncurses之类的库。因此,扔掉代码,花几天时间阅读文档,然后从头开始编写代码。
也许您可以考虑将游戏制作成一些图形应用程序,例如通过使用诸如GTK或libSDL之类的工具包。
PS。您没有提到它,但是我想您正在使用某些Linux系统。