1

Doing first project and it's tetris; Now I'm doing the animation part, but I have a problem with clearing the screen, I've tried :

void clrscr() 
{ 
  system("cls"); 
}

It worked but it kept flashing the screen, is there a way using gotoxy function instead of clrscr on same purpose?

I'm using windows console system 32, on visual studio 2008.

Christophe
  • 68,716
  • 7
  • 72
  • 138

1 Answers1

3

system("cls") executes a shell command to clear the screen. This is tremendously innefficient and definitievly not for game programming.

Unfortunately screen I/O is system dependent. As you refer to "cls" and not to "clear", I guess you're working with windows console:

  • If you have a function gotoxy(), it's possible to position on one line after the other and print a lot of spaces. It's not ultra performant, but it's an approach. This SO question provides gotoxy() alternatves, as it's a non-standard function.

  • This microsoft support recommendation provides a more performant alternative to clear the screen on Windows, using the winapi console functions such as GetConsoleScreenBufferInfo(), FillConsoleOutputCharacter() and SetConsoleCursorPosition().

Edit:

I understand that you use character based output, as you write a console app and not a full featured win32 graphic app.

You can then adapt the code provided above, by clearing only a part of the console:

void console_clear_region (int x, int y, int dx, int dy, char clearwith = ' ')
{
    HANDLE hc = GetStdHandle(STD_OUTPUT_HANDLE);  // get console handle 
    CONSOLE_SCREEN_BUFFER_INFO csbi;        // screen buffer information
    DWORD chars_written;                    // count successful output

    GetConsoleScreenBufferInfo(hc, &csbi);      // Get screen info & size 
    GetConsoleScreenBufferInfo(hc, &csbi);      // Get current text display attributes
    if (x + dx > csbi.dwSize.X)                 // verify maximum width and height
        dx = csbi.dwSize.X - x;                 // and adjust if necessary
    if (y + dy > csbi.dwSize.Y)
        dy = csbi.dwSize.Y - y;

    for (int j = 0; j < dy; j++) {              // loop for the lines 
        COORD cursor = { x, y+j };              // start filling 
        // Fill the line part with a char (blank by default)
        FillConsoleOutputCharacter(hc, TCHAR(clearwith),
            dx, cursor, &chars_written);
        // Change text attributes accordingly 
        FillConsoleOutputAttribute(hc, csbi.wAttributes,
            dx, cursor, &chars_written);
    }
    COORD cursor = { x, y };
    SetConsoleCursorPosition(hc, cursor);  // set new cursor position
}

Edit 2:

And in addition, here two cusor positionning function that you can mix with standard cout output:

void console_gotoxy(int x, int y)
{
    HANDLE hc = GetStdHandle(STD_OUTPUT_HANDLE);  // get console handle 
    COORD cursor = { x, y };
    SetConsoleCursorPosition(hc, cursor);  // set new cursor position
}

void console_getxy(int& x, int& y)
{
    HANDLE hc = GetStdHandle(STD_OUTPUT_HANDLE);  // get console handle 
    CONSOLE_SCREEN_BUFFER_INFO csbi;        // screen buffer information
    GetConsoleScreenBufferInfo(hc, &csbi);      // Get screen info & size 
    x = csbi.dwCursorPosition.X;
    y = csbi.dwCursorPosition.Y;
}  
Community
  • 1
  • 1
Christophe
  • 68,716
  • 7
  • 72
  • 138
  • Well, i don't want to clear the whole screen, i just want to clear the shape before being printed once more, so that it i won't draw the shape in the whole screen, but only moving it. @Christophe – UserNotFound Apr 20 '15 at 14:28
  • @Christine I've made an edit to show how a partieal clearing is possible. – Christophe Apr 20 '15 at 18:24
  • @Christine and rereading your question, I've also added two functions to get and set the cursor position. Now you should be fully equiped for your console game ;-) – Christophe Apr 20 '15 at 18:49