c++windowsconsole-applicationconio

How can I move my picture on the screen using a keypress?


I'm currently writing a program that will display a house on a screen based on the size of the house, It will also detect 'A' 'S' 'W' 'D' key presses and breaks on the key press of esc. Now that I have gotten all of these functions working, as well as borrowing clear screen function. I would like to move this image that i have on the screen up and down. I know that I am very close, however I'm not sure how I should go about moving the picture. I would like the program to move to the right if the user presses "d", I'm assuming this would be like adding 1 to the x coordinate, and moving left by pressing "a" subtract one from x, and likewise for up and down, would be pressing "w" or "s" and adding or subtracting from the y value.

#include <windows.h>
#include <iostream>
#include <cstdlib>
#include <conio.h>

using namespace std;

void ClearScreen();

void draw(int j)
{
    cout <<"  /";
    for(int c=0; c<j; c++)
    {
        cout <<"  ";
    }
    {
        cout << "\\ \n";
    }
    cout << " /";
    for(int c=0; c<j; c++)
    {
        cout << "  ";
    }
    cout <<"  \\ \n";
    cout << "/";
    for(int c=0; c<j; c++)
    {
        cout <<"  ";
    }
    cout <<"    \\ \n";
    cout <<"|";
    for(int c=0; c<j; c++)
    {
        cout << "----";
    }
    cout <<"| \n";
    cout <<"|";
    for(int c=0; c<j; c++)
    {
        cout << "    ";
    }
    cout <<"| \n";
    cout <<"|";
    for(int c=0; c<j; c++)
    {
        cout << "    ";
    }
    cout <<"| \n";
    cout <<"|";
    for(int c=0; c<j; c++)
    {
        cout << "----";
    }
    cout <<"| \n";
}

/////////////////////////////////
////////////////////////////////

void Move(int key,int housesize)
{
    if (key ==97)
    {
        cout << "you pressed 'a' \n";
        draw(housesize);
    }
    else if (key==115)
    {
        cout<< "you pressed 's' \n \t";
        draw(housesize);
    }
    else if (key==100)
    {
        cout<< "you pressed 'd' \n";
        draw(housesize);
    }
    else if (key==119)
    {
        cout<< "you pressed 'w' \n";
        draw(housesize);
    }
}
////// MAIN //////////////
int main(int argc, char *argv[])
{
    int i,number;
    char letter;

    cout << "How large would you like me to draw a house from 1 to 5? \n";
    cin >> i;
    draw(i);
    cout << "Press a key to move the picture and esc to close \n";
    while(1)
    {
        letter=getch();
        number=letter;
        if(number==27)
        {
            break;
        }
        else if (number !=27)
        {
            Move(number, i);
        }
        ClearScreen();
        Move(number, i);
    }

    system ("PAUSE");
    return 0;
}
////// CLEARSCREEN ////////////////////////////////////
void ClearScreen()
{
    HANDLE                     hStdOut;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    DWORD                      count;
    DWORD                      cellCount;
    COORD                      homeCoords = { 0, 0 };

    hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
    if (hStdOut == INVALID_HANDLE_VALUE) return;
    /* Get the number of cells in the current buffer */
    if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return;
    cellCount = csbi.dwSize.X *csbi.dwSize.Y;
    /* Fill the entire buffer with spaces */
    if (!FillConsoleOutputCharacter(
        hStdOut,(TCHAR) ' ',cellCount,homeCoords,&count)) return;
    /* Fill the entire buffer with the current colors and attributes */
    if (!FillConsoleOutputAttribute(
        hStdOut,csbi.wAttributes,cellCount,homeCoords,&count)) return;

    /* Move the cursor home */
    SetConsoleCursorPosition( hStdOut, homeCoords );
}   

Solution

  • What is missing here, is the position at which you draw the house. Let's change the drawing function accordingly:

    void draw(int h, int v, int j)
    {
        cout << string(v, '\n');  //vertical offset
        string hs(h,' '); // prepare horizontal offset
    
        cout <<hs<< "  /";       // add horizontal offset at each start of line
        for (int c = 0; c<j; c++) {
            cout << "  ";
        }
        ...
    }
    

    Now moving just requires to change the horizontal and vertical offset. So let's revise the function. We will pass these two by reference so to change their value in the calling function:

    void Move(int key, int& h, int& v, int housesize)  
    {
        if (key == 'a') {     // would worth considering tolower(key) 
            if (h>1) 
                h--;
        }
        else if (key == 's') {
            h++;             // is there a maximum (e.g. screensize - housewidth) ?
        }
        else if (key == 'd') {
            v++;
        }
        else if (key == 'w') {
            if (v>1) 
                v--;
        }
    }
    

    Then finally, in main() you need to keep the horizontal and vertical offset, and use them in the redesigned functions:

    int h = 0, v = 0;  // horizontal and vertical offset
    ...
    while (1) {
        letter = getch();
        ...
        else if (number != 27) {
            Move(number, h, v, i);  // <=== just change position.  Will redraw later
        }
        ClearScreen();              
        draw(h, v, i);              // draw at new position what ever happened
    }