Munashedov

Windows Terminal Cube Bounce

Nov 29th, 2021
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.61 KB | None | 0 0
  1. // 2021-11-28
  2. //
  3. // Bounces a square around a windows terminal.
  4. // I had a problem with flicker when trying to use system("cls") to clear the screen (I guess it's too slow?)
  5. // But after some suggestions from some other people, and a bit of copying from stack overflow, it turns out that
  6. // I can easily get any frame rate I could want with my current method, which is to reset the cursor to the top left
  7. // and reprint the whole buffer. It's also possible to update on a per character basis by moving the cursor
  8. // around to only update characters which have changed between two frames, but I like the full reprint method.
  9.  
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdint.h>
  14. #include <conio.h>
  15.  
  16. #define NOMINMAX
  17. #define WIN32_LEAN_AND_MEAN
  18. #include <Windows.h>
  19.  
  20. #define COLS 60
  21. #define ROWS 40
  22.  
  23. #define FRAMERATE 24
  24.  
  25.  
  26. int ToIndex(int x, int y){ return y * COLS + x; }
  27.  
  28. char world[COLS*ROWS] = {0};
  29. char buffer[(COLS+1)*ROWS] = {0};
  30.  
  31. void BufferPrint(char *world);
  32. void WorldClear(char clearCharacter);
  33.  
  34. void setCursorPosition(int x, int y);
  35. void setCursorVisibility(int isShown);
  36.  
  37. void PaintRect(int x, int y, int w, int h, char c);
  38.  
  39. int posX = 20;
  40. int posY = 4;
  41. int width = 10;
  42. int height = 6;
  43. int velX = 1;
  44. int velY = 1;
  45.  
  46. int main(void){
  47.     setCursorVisibility(FALSE);
  48.     system("cls");
  49.     while(1){
  50.         Sleep(1000/FRAMERATE);
  51.         WorldClear('.');
  52.         PaintRect(posX, posY, width, height, 'O');
  53.         if(posX+width >= COLS-1 || posX <= 0){ velX *= -1; }
  54.         if(posY+height >= ROWS || posY <= 0){ velY *= -1; }
  55.         posX += velX;
  56.         posY += velY;
  57.         BufferPrint(world);
  58.     }
  59.     return 0;
  60. }
  61.  
  62. void PaintRect(int x, int y, int w, int h, char c){
  63.     for(int i = 0; i < h; ++i){
  64.         for(int j = 0; j < w; ++j){
  65.             world[ToIndex(x+j, y+i)] = c;
  66.         }
  67.     }
  68. }
  69.  
  70. void WorldClear(char clearCharacter){
  71.     for(int i = 0; i < COLS*ROWS; ++i){
  72.         world[i] = clearCharacter;
  73.     }
  74. }
  75.  
  76. void BufferPrint(char *world){
  77.     setCursorPosition(0,0);
  78.     for(int i = 0; i < (COLS+1)*ROWS; ++i){
  79.         buffer[i] = world[i];
  80.         if(i % (COLS) == (COLS-1)){
  81.             buffer[i] = '\n';
  82.         }
  83.     }
  84.     buffer[COLS*ROWS] = '\0';
  85.     fprintf(stdout, "%s", buffer);
  86.     fflush(stdout);
  87.     setCursorPosition(0,0);
  88. }
  89.  
  90. void setCursorPosition(int x, int y){
  91.     const HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
  92.     fflush(stdout);
  93.     COORD coord = { (SHORT)x, (SHORT)y };
  94.     SetConsoleCursorPosition(hOut, coord);
  95. }
  96.  
  97. void setCursorVisibility(int isShown){
  98.    HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
  99.    CONSOLE_CURSOR_INFO info;
  100.    info.dwSize = 100;
  101.    info.bVisible = isShown;
  102.    SetConsoleCursorInfo(consoleHandle, &info);
  103. }
Add Comment
Please, Sign In to add comment