0
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#include <algorithm>
#include <vector>

using namespace std;


void gotoxy( int column, int line )  /// http://www.cplusplus.com/forum/general/33846/
{
    COORD coord;
    coord.X = column;
    coord.Y = line;
    SetConsoleCursorPosition(
        GetStdHandle( STD_OUTPUT_HANDLE ),
        coord
    );
}

int wherex()
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    COORD  result;
    if (!GetConsoleScreenBufferInfo(
                GetStdHandle( STD_OUTPUT_HANDLE ),
                &csbi
            ))
        return -1;
    return result.X;
}

int wherey()
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    COORD  result;
    if (!GetConsoleScreenBufferInfo(
                GetStdHandle( STD_OUTPUT_HANDLE ),
                &csbi
            ))
        return -1;
    return result.Y;
}

class lik
{
public:

    lik()
    {
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
            {
                polje[i][j] = 0;
            }
        }
    }

    int get(int a=0, int b=0)
    {
        int c;

        c = polje[a][b];

        return c;
    }

    void setp(int a=0,int b=0, int c=0)
    {
        polje[a][b] = c;
    }

    void narisi(int x, int y)
    {
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
            {
                gotoxy(x+j,y+i);
                if(polje[i][j] == 0)
                    cout << " ";
                else
                    cout << polje[i][j];
            }
            cout << endl;
        }
    }

    void brisi(int x, int y)
    {
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
            {
                gotoxy(x+j,y+i);
                cout << " ";
            }
            cout << endl;
        }
    }

    void obrat() /// https://stackoverflow.com/questions/16684856/rotating-a-2d-pixel-array-by-90-degrees
    {
        int polje2[4][4];

        int polje3[4][4];

        kopiraj(polje2);
        kopiraj(polje3);

        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
            {
                /// swap(polje2[i][j] , polje3[j][i]);
                polje2[i][j] = polje3[4-1-j][i];
            }
        }

        for(int k=0; k<4; k++)
        {
            for(int m=0; m<4; m++)
            {
                polje[k][m] = polje2[k][m];
            }
        }

    }

    void kopiraj(int polje2[][4]) /// https://stackoverflow.com/questions/8767166/passing-a-2d-array-to-a-c-function
    {
        polje2[4][4];

        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
            {
                polje2[i][j] = polje[i][j];
            }
        }
    }


private:
    int polje[4][4];
};

void preveri(int &x, int &y, char &check)
{
    if(check == 80)
    {
        y = 25;
        check = 20;
    }

    if(check == 75)
    {
        x--;
        check = 20;
    }

    if(check == 77)
    {
        x++;
        check = 20;
    }
}

int main()
{

    lik oblika[7]; ///https://tutorialink.com/cpp/array-of-objects-in-cpp.cpp
    int x=0, y=0, delay=200, exit=0, trenutni=0;
    char check;
    srand(time(0));

    oblika[0].setp(0,0,1);  /// 4 long
    oblika[0].setp(1,0,1);
    oblika[0].setp(2,0,1);
    oblika[0].setp(3,0,1);

    oblika[1].setp(1,1,1); /// square
    oblika[1].setp(1,2,1);
    oblika[1].setp(2,2,1);
    oblika[1].setp(2,1,1);

    oblika[2].setp(1,1,1); /// T
    oblika[2].setp(1,2,1);
    oblika[2].setp(1,3,1);
    oblika[2].setp(2,2,1);

    oblika[3].setp(0,1,1); /// S
    oblika[3].setp(1,1,1);
    oblika[3].setp(1,2,1);
    oblika[3].setp(2,2,1);

    oblika[4].setp(0,2,1); /// Z
    oblika[4].setp(1,2,1);
    oblika[4].setp(1,1,1);
    oblika[4].setp(2,1,1);

    oblika[5].setp(0,1,1); /// L
    oblika[5].setp(1,1,1);
    oblika[5].setp(2,1,1);
    oblika[5].setp(2,2,1);

    oblika[6].setp(0,2,1); /// Reversed L
    oblika[6].setp(1,2,1);
    oblika[6].setp(2,2,1);
    oblika[6].setp(2,1,1);

    do
    {
        do /// 80 = down  |  75 = left  |  77 = right  | 72 = up
        {

            if(kbhit())
            {
                check = getch(); /// http://pz-c-cout.blogspot.com/2009/07/how-to-reset-kbhit-in-c.html

                preveri(x,y,check);

                if(check == 72)
                {
                    oblika[trenutni].obrat();
                    check = 20;
                }
            }

            oblika[trenutni].narisi(x,y);
            Sleep(delay);
            oblika[trenutni].brisi(x,y);
            y++;



            if(y >= 25)
            {
                oblika[trenutni].brisi(x,y);
                gotoxy(x,25);
                oblika[trenutni].narisi(x,y);

                break;
            }
        }
        while(true);
        trenutni = rand()%7+1;
        system("cls");
        y=0;

        ///if(exit == 1) break;
    }
    while(true);
    return 0;
}

This is my current code for trying to recreate tetris, and I want to fix this issue before I continue with the program. If you compile the provided code, you can see that the demo works, but the input is delayed (Input is up arrow for turning, left and right for moving, and down for making the current falling object instantly fall to the bottom). I'm pretty sure that this is happening because of the Sleep function that I'm using in line 234.

I want the program to behave so that the objects fall down at a certain speed, but if you turn them or move them, they can turn / move freely, not having to wait for the program to make them fall first. so let's say that the fall delay would be 1 second, the object could move left / right or rotate as many times as you could press those buttons with no delay before the 1 second would be up and it would move down 1 block.

If you have a solution involving c++11 or c++14 compiling, I have no problem with that. Thanks!

no_rasora
  • 23
  • 3
  • This is what threads are for. You have one thread that handle user movement, and then another thread that once every x seconds, it moves all objects down one level. – NathanOliver Mar 06 '20 at 22:08
  • @NathanOliver I would consider multithreading to be totally overkill here, a simple time slice loop would work just fine – Quentin Mar 06 '20 at 22:09
  • [`std::this_thread::sleep_for`](https://en.cppreference.com/w/cpp/thread/sleep_for) or [`std::this_thread::sleep_until`](https://en.cppreference.com/w/cpp/thread/sleep_until) are where I would start. If the resolution is not good enough you may have to fall back on target-specific API calls. – user4581301 Mar 06 '20 at 22:30
  • 1
    You could create a keyframe animation class that, given a start time, end time, start pos, end pos can calculate the position at any point in time. You should be able to incorporate this into your current game loop without threads. – 001 Mar 06 '20 at 22:32
  • Question, if the problem is an issue of smoothness, why not decrease `delay`? 200 is roughly 5 ticks a second (assuming `Sleep` observes the standard Windows 1/64 tick) and pretty brutal. – user4581301 Mar 06 '20 at 22:44

0 Answers0