我做了一个非常简单的labirinth游戏,但是有一个奇怪的错误,我无法弄清楚为什么会发生。
当我试图进入障碍物时,我的输出的第一行发生了变化。此外,根据我尝试移动的位置,它可以向右移动1个或多个1个字符。考虑到我的showFrame()
函数在输出之前每次都清除屏幕,这对我来说非常奇怪。
当您尝试进入障碍物时,第90行正在运行。如果新位置无效,它将首先恢复位置,然后调用showFrame()
,showFrame()
在输出之前清除控制台。那么是什么导致第一行转移?为什么它会根据按下哪个键而改变?
代码如下。如果我理解正确,你需要在linux上编译和运行,而不是windows,因为ncurses事物和getchar函数?但我不确定。 (不是真正的C程序员)
编译时添加-lncurses
参数。如果您没有安装ncurses库,可以在此处下载:
http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.7.tar.gz
#include <stdio.h>
#include <ncurses.h>
#include <stdlib.h>
int positionX = 1,
positionY = 19,
oldPositionX,
oldPositionY,
sizeX,
sizeY;
char matrix[20][20] =
{'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '|',
'|', ' ', '|', ' ', ' ', ' ', '|', '-', '-', ' ', ' ', ' ', '-', '-', '|', ' ', ' ', ' ', ' ', '|',
'|', ' ', '-', '-', '-', '-', '-', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
'-', '-', '-', '|', ' ', '|', ' ', ' ', '|', ' ', '|', ' ', ' ', ' ', '-', '-', ' ', '|', ' ', '|',
' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '-', '-', '|', ' ', ' ', '|', ' ', '|', ' ', '|',
' ', '|', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', '|', '|', ' ', '|', ' ', '|',
' ', '|', ' ', ' ', ' ', '-', '-', '|', '|', ' ', ' ', ' ', '|', ' ', '|', ' ', ' ', '|', ' ', '|',
' ', '-', '-', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '|', ' ', '-', '-', '-', '|',
' ', ' ', ' ', '|', ' ', '|', ' ', '|', ' ', '|', '-', '-', '-', ' ', '|', ' ', '|', ' ', ' ', '|',
'-', '-', '-', '|', ' ', '|', ' ', '|', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', '-', '|', ' ', '|',
'|', ' ', ' ', ' ', ' ', '|', ' ', ' ', ' ', '|', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', '-', '|', ' ', ' ', '|', ' ', '|',
'|', ' ', '|', '-', '-', '-', '-', '-', '-', '-', ' ', ' ', ' ', ' ', '|', ' ', '-', '-', ' ', '|',
'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', ' ', ' ', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', '-', '-', '-', ' ', ' ', ' ', ' ', ' ', ' ', '|',
'|', '-', '-', '-', '-', '-', ' ', '|', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', '-', '-', '-', '|',
'|', ' ', ' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', '-', '|', ' ', ' ', ' ', ' ', ' ', '|',
'|', ' ', '|', '-', '-', '-', '-', '-', ' ', ' ', '|', ' ', ' ', ' ', ' ', '-', '-', '-', '-', '|',
'|', ' ', '|', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '|', '-', '-', '|', ' ', '|', ' ', ' ', ' ', ' '};
void main() {
char key;
int stty;
// Get the size of the matrix
sizeX = sizeof(matrix) / sizeof(matrix[0]);
sizeY = sizeof(matrix[0]);
while(1) {
// Output level
showFrame();
// Wait for user input to move player position
stty = system("stty raw");
key = getchar();
system("stty cooked");
// Store previou position and move player position accordingly
oldPositionX = positionX;
oldPositionY = positionY;
switch(key) {
case 'w': positionY--;
break;
case 'a': positionX--;
break;
case 's': positionY++;
break;
case 'd': positionX++;
break;
default: printf("\bThat's an invalid key, stupid!\nYou're supposed to play with WASD keys.\n");
exit(0);
}
// Check to see if new position is okay
if(positionY >= sizeY || positionY < 0 || positionX >= sizeX || positionX < 0) {
revertPosition();
}
// Check to see if level cleared!
if(positionX == 1 && positionY == 0) {
showFrame();
printf("You cleared the level, Sherlock.\nYou must be really proud of yourself\n");
return;
}
}
}
int showFrame() {
int i, j;
// Output the matrix
system("clear");
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
// Check if player's position is at the current block
if(i == positionY && j == positionX) {
// If the players position is in an invalid block, revert his position
if(matrix[i][j] != ' ') {
revertPosition();
showFrame();
printf("You can't go there, stupid!\n");
return 1;
} else {
printf("* ");
}
} else {
printf("%c ", matrix[i][j]);
}
}
printf("\n");
}
return 0;
}
void revertPosition() {
positionX = oldPositionX;
positionY = oldPositionY;
}
答案 0 :(得分:1)
似乎有一个明确的问题。
要确定问题,您应该开始查找转移第一行的字符来自哪些内容。添加:
system("clear");
printf('\n');
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
带来一点点光明。似乎如果我想上去,那里的人物与上线,我的位置相同。
现在,您需要找到system("clear");
未删除这些字符的原因。经过一些反复试验后,我设法发现如果您打印了一个&#39; \ n&#39;在清理之前,它按照预期工作。
由于我之前从未使用过ncurses,我无法解释你为什么会这样。我的结果是清除命令逐行清除终端。一行以换行符结束。所以,你需要做的就是在那些尾随字符之后添加换行符(我建议你在showFrame函数的开头打印它,以避免类似情况):
int showFrame() {
int i, j;
// Output the matrix
printf('\n');
system("clear");
for(i=0; i<sizeX; i++) {
for(j=0; j<sizeY; j++) {
// Check if player's position is at the current block
if(i == positionY && j == positionX) {
// If the players position is in an invalid block, revert his position
if(matrix[i][j] != ' ') {
revertPosition();
showFrame();
printf("You can't go there, stupid!\n");
return 1;
} else {
printf("* ");
}
} else {
printf("%c ", matrix[i][j]);
}
}
printf("\n");
}
return 0;
}
我希望这对你有用。另外,让我对您的代码做一些评论:
使用全局变量是strongly discouraged。 关于主要的返回值,我建议您阅读this。 此外,您的ethier在main之前声明您的功能:
int showFrame();
void revertPosition();
要么在main之前移动它们的整个定义。实际上,你的代码没有在我的机器上编译(gcc 4.8.1)。