SetConsoleCursorPosition 在 C 中无法正常工作:字符在随机位置打印
SetConsoleCursorPosition not working correctly in C: characters get printed at random locations
我正在尝试制作一个简单的控制台游戏引擎,能够在指定位置显示字符数组。目前,一切正常,但控制台不想配合:
我使用 SetConsoleCursorPosition 函数(来自 Windows.h
)以在控制台中设置正确的位置,并使用 putchar()
以逐个打印字符(我还测试了 putc()
, fputc()
和 _putch()
, 但没有帮助)
为了测试,我设置了简单的程序。在 GraphicsEngine.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;
}
运算:'A'←'D'→'W'↑'S'↓
调试:
我正在尝试制作一个简单的控制台游戏引擎,能够在指定位置显示字符数组。目前,一切正常,但控制台不想配合:
我使用 SetConsoleCursorPosition 函数(来自 Windows.h
)以在控制台中设置正确的位置,并使用 putchar()
以逐个打印字符(我还测试了 putc()
, fputc()
和 _putch()
, 但没有帮助)
为了测试,我设置了简单的程序。在 GraphicsEngine.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;
}
运算:'A'←'D'→'W'↑'S'↓
调试: