Here I wrote:

#include <iostream> #include <conio.h> #include <cstdlib> #include <Windows.h> using namespace std; char a[100][100]; //Початкові координати int sx = 15, sy = 10; //Напрям int direct; void view(); void border(); //Напрямок int direction(int direct) { if (direct == 0) return sy--; if (direct == 1) return sx++; if (direct == 2) return sy++; if (direct == 3) return sx--; } int main(){ while (getch() != 27) { border(); Sleep(500); switch (getch()) { case 72: direct = 0; break; //вгору case 77: direct = 1; break; //вправо case 80: direct = 2; break; //вниз case 75: direct = 3; break; //вліво } direction(direct); for (int i = 0; i < 20; i++) for (int j = 0; j < 60; j++) { a[sy][sx] = '0'; if (sy >= 19 || sy <= 0 || sx >= 59 || sx <= 0) goto gameover; } system("cls"); view(); } gameover: cout << "Game over..." << endl; system("pause"); return 0; } //Границі поля void border() { for (int i = 0; i < 20; i++) for (int j = 0; j < 60; j++) { a[i][j] = ' '; a[0][j] = '#'; a[i][0] = '#'; a[19][j] = '#'; a[i][59] = '#'; } } //Малює поле void view() { for (int i = 0; i < 20; i++) { for (int j = 0; j < 60; j++) { cout << a[i][j]; } cout << endl; } } 

Question: I don’t understand the moment with time, therefore I don’t have the right idea here. Please help me make sure that when passing every second the element "0" is moved in the right direction.

  • You can run in a separate thread ... - user31238

2 answers 2

It does not work out. You expect to enter - stopping the cycle, and in time Sleep (500); and input will not work.

Exit: you need a timer, which will be checked in a cycle, and when a second passes it will shift the "0" in the specified direction. And if the key was pressed (changed direction), the timer will be reset. And also waiting for an input that does not stop the loop (intercepting an event, another thread ....).

  • Yes, I know that, but with the help of what should I do it? - goodalien
  • @ goodalien1125 as far as I know there is no normal timer in the pluses, only the timer for which you need to write code more than you spent on a snake is googling ... msdn.microsoft.com/ru-ru/library/windows/desktop/… - Valera Kvip
  • this is not the whole snake)) Thanks and on that .. - goodalien
  • 3
    When entering, it is enough to use not waiting for kbhit() from the same conio.h . We just don’t wait for pressing, but check if it is there, and read only when there is something there ... - Harry
  • @Harry, please tell me how to embody correctly? - goodalien

I give here a simple answer that solves the problem without unnecessary complications. That is, without timers, multi-threading and asynchrony.

In general, we have a game cycle (while) that ticks as fast as the processor can. It should be noted that on different processors the speed will be different, but for good I would like to have the same speed on any processor. How can snake movement be organized? Obviously, there are two solutions - either to move the snake a very small distance on each tick (which is slightly inappropriate in the terminology of using text mode), or not on every tick. Actually, below will be an example of how to do this not on every tick.

The idea is that at each iteration of the game cycle, calculate the time that has passed since the last update of the placement of the snake on the playing field. That is, if we want to move the snake one position exactly every second, then we need to skip so many iterations of the game cycle that correspond to this time interval.

You should save the current time before the main loop, and measure the delta at each iteration - the difference between the current time and the time previously saved. If the delta is greater than or equal to the required interval (1 second), perform the necessary actions.

 auto lastUpdate = std::chrono::steady_clock::now(); char ch = 0; while (ch != 27) { auto now(std::chrono::steady_clock::now()); auto dt = now - lastUpdate; if (dt >= std::chrono::seconds(1)) { lastUpdate = now; // здесь производим необходимые действия - тоесть сдвигаем змейку на 1 позициию } if (kbhit()) { // обработка ввода ch = getch(); } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } 
  • Why not use sleep ()? - goodalien
  • @ goodalien1125, you can use, I suppose, your usual Sleep() . Already working your example should simply be supplemented with 4-5 lines of code - calculating the delta (elapsed time) in any convenient way. I just gave an example using the standard C ++ 11. - sba
  • What can you say about the very tight control of the snake? I mean, the keys once again realize that I press them .. - goodalien
  • Take the code from the example for the skeleton of the main loop - control should be smooth. Your 500 ms is noticeable by eye, 10 ms is invisible and adds smoothness. - sba
  • well no! Vishka is that even if I put sleep (30-150), the snake moves very quickly and does not have time to grab my tyk on the key .. - goodalien