简体   繁体   English

c++程序,cmd中文字不断抖动

[英]c++ program, text constantly shaking in cmd

This program is supposed to have a map made out of dots and a player which you can move around.这个程序应该有一个由点组成的 map 和一个可以移动的播放器。

But when I opened this program one day, the text was flickering and moving up and down.但是有一天我打开这个程序时,文字闪烁,上下移动。

It uses Windows.h to redraw on the console without flickering and to hide the cursor它使用 Windows.h 在控制台上重绘而不闪烁并隐藏 cursor

Does it have to do something with the cmd properties, the code or the Windows.h header file?它是否与 cmd 属性、代码或 Windows.h header 文件有关?


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

char map[1000][1000];
int width = 100;
int height = 10;
char Tmt = '.';

void cls()
{
    COORD cursorPosition;
    cursorPosition.X = 0;
    cursorPosition.Y = 0;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), cursorPosition);
}

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

class Player {
public:

    int x;
    int y;
    char sym;

    void Draw()
    {
        map[x][y] = sym;
    }

    void Logic()
    {
        if (x < 1) { x++; }
        if (y < 1) { y++; }
        if (x > width) { x--; }
        if (y > height) { y--; }
    }

    void Input()
    {
        if (_kbhit())
        {
            switch (_getch())
            {
            case 'w':
                map[x][y] = Tmt;
                y--;
                break;
            case 'a':
                map[x][y] = Tmt;
                x--;
                break;
            case 's':
                map[x][y] = Tmt;
                y++;
                break;
            case 'd':
                map[x][y] = Tmt;
                x++;
                break;
            case 'p':
                system("cls");
                break;
            }
        }
    }

    void PrintPos()
    {
        printf("Pos:\n");
        if (x >= 10) { printf("    %d\n", x); }
        else { printf("    0%d\n", x); }
        if (y >= 10) { printf("    %d\n", y); }
        else { printf("    0%d\n", y); }
    }
};

Player player1;

void Setup()
{
    player1.x = 2;
    player1.y = 2;
    player1.sym = '@';
    player1.Draw();
    player1.Logic();

    for (int mapsui = 1; mapsui <= width; mapsui++)
    {
        for (int mapsuj = 1; mapsuj <= height; mapsuj++)
        {
            map[mapsui][mapsuj] = Tmt;
        }
    }
}

void DrawMap()
{
    player1.PrintPos();
    printf("\n\n\n");
    for (int drawi = 1; drawi <= width; drawi++)
    {
        for (int drawj = 1; drawj <= height; drawj++)
        {
            printf("%c", map[drawj][drawi]);
        }
        printf("\n");
    }
}

int main()
{
    Setup();

    while (1)
    {
        DrawMap();
        player1.Input();
        player1.Logic();
        player1.Draw();

        cls();
        hidcur();
    }

    return 0;
}

In the DrawMap method, when you have the two for loops, you are checking width in the outer loop and height in the inner loop, while it should be the other way round.在 DrawMap 方法中,当您有两个 for 循环时,您正在检查外循环的宽度和内循环的高度,而应该反过来。 Note that the outer loop controls the number of lines, and as you are limiting it to the width (100) you are displaying 100 lines most of which are empty, because Setup just initializes 10 lines.请注意,外部循环控制行数,当您将其限制为宽度 (100) 时,您将显示 100 行,其中大部分为空,因为安装程序仅初始化 10 行。 As the command window shows less lines (I think it's about 30 by default or something like that) the map goes up and that results in the flicker you see.由于命令 window 显示的行数较少(我认为默认情况下约为 30 或类似的东西),因此 map 上升,导致您看到闪烁。 It should be:它应该是:

for (int drawi = 1; drawi <= height; drawi++)
{
    for (int drawj = 1; drawj <= width; drawj++)
    {
        printf("%c", map[drawj][drawi]);
    }
    printf("\n");
}

Note than in Setup you also use the loops in this way (the outer loop checks width and the inner loop checks height) but in that case you are later using the indexes to the map the other way round (first i and then j) so that results in the correct initialization of the map (10 rows of 100 columns).请注意,在安装程序中,您也以这种方式使用循环(外循环检查宽度,内循环检查高度),但在这种情况下,您稍后将使用 map 的索引以相反的方式(首先是 i,然后是 j)所以这导致 map(10 行,100 列)的正确初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM