SetConsoleCursorPosition在C中无法正常工作:字符在随机位置打印

SetConsoleCursorPosition在C中无法正常工作:字符在随机位置打印,c,windows,winapi,console,C,Windows,Winapi,Console,我正在尝试制作一个简单的控制台游戏引擎,能够在指定位置显示字符数组。目前,一切正常,但控制台不想配合: 我使用SetConsoleCursorPosition函数(从Windows.h)在控制台中设置正确的位置,并使用putchar()逐个打印字符(我还测试了putc()、fputc()和\u putch(),但没有帮助) 为了测试,我设置了一个简单的程序。在图形引擎.h中: void setCoordinates(int x, int y) { COORD cursorPos;

我正在尝试制作一个简单的控制台游戏引擎,能够在指定位置显示字符数组。目前,一切正常,但控制台不想配合:

我使用SetConsoleCursorPosition函数(从
Windows.h
)在控制台中设置正确的位置,并使用
putchar()
逐个打印字符(我还测试了
putc()
fputc()
\u putch()
,但没有帮助)

为了测试,我设置了一个简单的程序。在
图形引擎.h
中:

void setCoordinates(int x, int y) {
    COORD cursorPos;
    cursorPos.X = x;
    cursorPos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cursorPos);
}

void printObject(const unsigned char* object, int x, int y, int* xOld, int* yOld) {

    int i = 0;
    int j = 0;
    *xOld = x;
    *yOld = y;
    while (object[i] != '\t') {
        putchar(object[i]);
        fflush(stdout);
        if (object[i] == '\n') { //if approached newline, travel one line down
            y++;
            setCoordinates(x, y);
        }
        i++;
    }
}
main.c
中:

    int x = 0;
    int y = 10;
    int xOld = 0;
    int yOld = 0;
    setCoordinates(x, y);
    printObject(ship, x, y, &xOld, &yOld, true);
传递给
printObject()
函数的数组:

const unsigned char ship[] = 
{
32,32,64,'\n',
32,47,'#',92,'\n',
174,'#','#','#',175,'\n','\t'
};
例如,给定x=20和y=20,代码似乎可以正确打印船舶:

但通常(随机,有时每次,有时每10次发射)打印阵列完全不正常:


这是一个大问题,因为我想制作一个允许玩家在2D平面(x轴和y轴)上移动的游戏,并且在多次刷新屏幕的同时,一些角色出现了一些问题。

您的线程缺少可以重现问题的代码。我修改了您的代码并添加了部分代码,现在应该可以满足您的需要了

#include <iostream>
#include <Windows.h>

const unsigned char ship[] =
{
32,32,64,'\n',
32,47,'#',92,'\n',
174,'#','#','#',175,'\n','\t'
};

const unsigned char ship_remove[] =
{
32,32,32,'\n',
32,32,32,32,'\n',
32,32,32,32,32,'\n','\t'
};

void hidecursor()
{
    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO info;
    info.dwSize = 100;
    info.bVisible = FALSE;
    SetConsoleCursorInfo(consoleHandle, &info);
}

void setCoordinates(int x, int y) {
    COORD cursorPos;
    cursorPos.X = x;
    cursorPos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cursorPos);
}

void printObject(const unsigned char* object, int x, int y, int *xOld, int *yOld) {

    int i = 0;
    *xOld = x;
    *yOld = y;
    while (object[i] != '\t') {
        char r = object[i];
        putchar(object[i]);
        fflush(stdout);
        if (object[i] == '\n') { //if approached newline, travel one line down
            y++;
            setCoordinates(x, y);
        }
        i++;
    }
}

void clear(const unsigned char* object, int x, int y)
{
    setCoordinates(x, y);
    int i = 0;
    while (object[i] != '\t') {
        char r = object[i];
        putchar(object[i]);
        fflush(stdout);
        if (object[i] == '\n') { //if approached newline, travel one line down
            y++;
            setCoordinates(x, y);
        }
        i++;
    }
}

int main()
{  
    hidecursor();
    int x = 20;
    int y = 20;
    int xOld = 0;
    int yOld = 0;
    setCoordinates(x, y);
    printObject(ship, x, y, &xOld, &yOld);
    while (1)
    {
        if (GetAsyncKeyState(0x41) & 0x0001)
        {           
            clear(ship_remove, xOld, yOld);
            x = xOld;
            y = yOld;
            setCoordinates(x - 1, y);
            printObject(ship, x - 1, y, &xOld, &yOld);
        }
        if (GetAsyncKeyState(0x44) & 0x0001)
        {
            clear(ship_remove, xOld, yOld);
            x = xOld;
            y = yOld;
            setCoordinates(x + 1, y);
            printObject(ship, x + 1, y, &xOld, &yOld);
        }
        if (GetAsyncKeyState(0x57) & 0x0001)
        {
            clear(ship_remove, xOld, yOld);
            x = xOld;
            y = yOld;
            setCoordinates(x, y - 1);
            printObject(ship, x, y - 1, &xOld, &yOld);
        }
        if (GetAsyncKeyState(0x53) & 0x0001)
        {
            clear(ship_remove, xOld, yOld);
            x = xOld;
            y = yOld;
            setCoordinates(x, y + 1 );
            printObject(ship, x, y + 1, &xOld, &yOld);
        }
    }
    return 0;
}
#包括
#包括
常量无符号字符ship[]=
{
32,32,64,“\n”,
32,47,“#”,92,“\n”,
174、“#”、“#”、“#”、“175”、“n”、“t”
};
常量无符号字符ship_remove[]=
{
32,32,32,“\n”,
32,32,32,32,“\n”,
32,32,32,32,32,'\n','\t'
};
无效隐藏器()
{
句柄控制台HANDLE=GetStdHandle(标准输出句柄);
控制台\光标\信息;
info.dwSize=100;
info.bVisible=FALSE;
SetConsoleCursorInfo(控制台句柄和信息);
}
无效集合坐标(整数x,整数y){
库索波斯;
cursorPos.X=X;
cursorPos.Y=Y;
设置控制台或位置(GetStdHandle(标准输出或句柄),光标);
}
void printObject(常量无符号字符*对象,int x,int y,int*xOld,int*yOld){
int i=0;
*xOld=x;
*yOld=y;
while(对象[i]!='\t'){
charr=对象[i];
putchar(对象[i]);
fflush(stdout);
如果(对象[i]='\n'){//如果接近换行符,向下移动一行
y++;
设定坐标(x,y);
}
i++;
}
}
无效清除(常量无符号字符*对象,整数x,整数y)
{
设定坐标(x,y);
int i=0;
while(对象[i]!='\t'){
charr=对象[i];
putchar(对象[i]);
fflush(stdout);
如果(对象[i]='\n'){//如果接近换行符,向下移动一行
y++;
设定坐标(x,y);
}
i++;
}
}
int main()
{  
hidecursor();
int x=20;
int y=20;
int-xOld=0;
int-yOld=0;
设定坐标(x,y);
打印对象(ship、x、y、xOld和yOld);
而(1)
{
if(GetAsyncKeyState(0x41)&0x0001)
{           
清除(装运/移除、xOld、yOld);
x=xOld;
y=卵黄;
设定坐标(x-1,y);
打印对象(ship、x-1、y、xOld和yOld);
}
if(GetAsyncKeyState(0x44)&0x0001)
{
清除(装运/移除、xOld、yOld);
x=xOld;
y=卵黄;
设定坐标(x+1,y);
打印对象(ship、x+1、y、xOld和yOld);
}
if(GetAsyncKeyState(0x57)&0x0001)
{
清除(装运/移除、xOld、yOld);
x=xOld;
y=卵黄;
设定坐标(x,y-1);
打印对象(ship、x、y-1、xOld和yOld);
}
if(GetAsyncKeyState(0x53)&0x0001)
{
清除(装运/移除、xOld、yOld);
x=xOld;
y=卵黄;
设定坐标(x,y+1);
打印对象(ship、x、y+1、&xOld和&yOld);
}
}
返回0;
}
操作:“A”← 'D'→ 'W'↑ '是的↓

调试:


将代码片段复制到问题中是我的错误,我有
设置坐标(x,y)
在真实代码中,您应该提供一个。也就是说,一个小而完整的代码示例,任何人都可以运行它来重现问题。例如,代码的其他部分是否存在线程?不清楚为什么您在确认问题不可回答后决定发布答案。