kbhit()- it's use and alternatives, and input buffer lag

Hello fellow coders,
I've been working within the console on the logic of plotting positions, altering positional variables, clearing the screen or area and drawing the new position, etc. Upon discovering kbhit(), I can now allow movements to continue without waiting on input from the user, while still responding to specified commands. However, it seems sort of laggy and sometimes involves the console window responding to a command several "frames" after the fact.

The following code draws a box, prints some labels for basic controls, and has the text string bounce around within the box. The lagging seems to increase after changing color multiple times in succession. The arrow keys have also been designated to alter the speed of movement, but this seems less problematic somehow. I was hoping somebody could point me to a preferable method over what I have developed, because the same behavior is experienced with this particular method regardless of what is being displayed. I suspect that multiple quick keyboard entries overloads the input buffer somehow when using it in this manner, but I can think of many things that don't behave this way, and I am wondering how it is accomplished.
basic.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#ifndef BASIC_H_INCLUDED
#define BASIC_H_INCLUDED
#endif // BASIC_H_INCLUDED

#include<iostream>//required for cout
#include<windows.h>//required for rand
#include<time.h>//required for time
#include<conio.h>
#include<string>
#include <iomanip>
using namespace std;

void Color(int color)
{
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hCon,color);
}

void cursorJump(short x,short y, bool clearLine)
{
    //move to desired position
    COORD cursor={x,y};
    HANDLE console=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(console,cursor);
    //clear remaining line when desired
    if (clearLine==true)
    {
        for (int i=x;i<80;i++)
        cout<<" ";
        //return to desired position
        cursorJump(x,y,false);
    }
}

void border(int x,int y,int width,int height)
{   //function to create border, with x and y
    //as coordinates of the top/left corner
    //text inside border remains unaltered

    //increment values to make them inclusive
    width++,height++;
    char v_side=186,h_side=205;
    char tl_corner=201,tr_corner=187;
    char br_corner=188,bl_corner=200;

    //top left corner
    cursorJump(x,y,false);cout<<tl_corner;
    //bottom left corner
    cursorJump(x,y+height,false);cout<<bl_corner;
    //top right corner
    cursorJump(x+width,y,false);cout<<tr_corner;
    //bottom right corner
    cursorJump(x+width,y+height,false);cout<<br_corner;

    //top/bottom sides
    for (int i=x+1;i<width+x;i++)
    {
        cursorJump(i,y+height,false);
        cout<<h_side;
        cursorJump(i,y,false);
        cout<<h_side;
    }
    //left/right sides
    for (int i=y+1;i<height+y;i++)
    {
        cursorJump(x,i,false);
        cout<<v_side;
        cursorJump(x+width,i,false);
        cout<<v_side;
    }
}

void showCursor(bool showFlag)
{   //enable/disable cursor visibility
    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO cursorInfo;
    GetConsoleCursorInfo(out, &cursorInfo);
    cursorInfo.bVisible = showFlag; // set the cursor visibility
    SetConsoleCursorInfo(out, &cursorInfo);
}

void clearSpace(int x,int y,int width,int height)
{   //function to clear an area, it works like
    //border with x,y representing the top/left
    //corner while clearing the desired area
    //ALL TEXT WITHIN THIS AREA WILL BE CLEARED
    cursorJump(x,y,false);
    for (int i2=0;i2<height;i2++)
    {   cursorJump(x,y+i2,false);
        for (int i=x;i<width+x;i++)
        cout<<" ";
    }
}

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "basic.h"

int main()
{
    int x=3,y=3,state_y=0,state_x=0,speed=200,go=1,color=10;
    showCursor(false);

    border(2,2,74,18);
    border(9,21,60,2);
    border(2,21,74,2);
    cursorJump(11,22,false);
    cout<<"+ Go Faster";
    cursorJump(11,23,false);
    cout<<"- Go Slower";
    cursorJump(56,22,false);
    cout<<"\30  Color Up";
    cursorJump(56,23,false);
    cout<<"\31  Color Down";
    cursorJump(30,22,false);
    cout<<"Push ENTER to quit";
    cursorJump(3,22,false);
    cout<<"Speed";
    cursorJump(72,22,false);
    cout<<"Color";
    //fix border intersections using loop with conditional incrementing
    for (int i=9;i<71;i=((i==9) ? 23 : (i==23) ? 54 : (i==54) ? 70 : 71))
    {
        cursorJump(i,21,false);
        cout<<(char)203;
        cursorJump(i,24,false);
        cout<<(char)202;
    }
    for (int i=23;i<55;i+=31)
    {
    cursorJump(i,22,false);
    cout<<(char)186;
    cursorJump(i,23,false);
    cout<<(char)186;
    }
    cursorJump(2,21,false);
    cout<<(char)204;
    cursorJump(77,21,false);
    cout<<(char)185;

    //control loop
    while (go)
    {
        clearSpace(3,3,74,18);//clear everything inside border
        cursorJump(x,y,false);//go to x,y position
        Color(color);//apply color value
        cout<<"C++ is Awesome!";
        cursorJump(73,23,false);
        cout<<color<<" ";
        Color(7);//revert to default color
        cursorJump(4,23,false);
        cout<<speed<<" ";
        //determine whether it is rising or falling
        if (state_x==00)
            x++;
        else
            x--;
        //determine whether is going left or right
        if (state_y==0)
            y++;
        else
            y--;
        //change values as needed to keep within borders
        if (y>19)
            state_y=1;
        else if (state_y==1 && y<4)
            state_y=0;
        if (x>61)
            state_x=1;
        else if (state_x==1 && x<4)
            state_x=0;


        //if input is entered check
        //it, otherwise keep going
        if (kbhit())
        {
            char c=getch();
            //use enter to quit
            if (c==13)
                go=0;
            //use +/- to control speed
            if (c==43 && speed>0)
                speed-=50;
            if (c==45 && speed<350)
                speed+=50;
            //use up/down to toggle color
            if (c==72 && color<15)
                color++;
            if (c==80 && color>1)
                color--;
        }
        Sleep(speed);//pause for speed's value
    }//repeat loop unless enter key was pressed
    cursorJump(0,0,false);//go back to top
    return 0;
}
Last edited on
Topic archived. No new replies allowed.