1
0

pong_sp.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include <ncurses.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #define BALL_SYMBOL "O"
  5. #define BORDER "#"
  6. #define PADDLE "||"
  7. #define SLEEP_TIME 20000
  8. struct Ball {
  9. int px, py, dx, dy;
  10. };
  11. struct Paddle {
  12. int px, py, length;
  13. };
  14. int main(void) {
  15. // initialization
  16. int hits = 0, misses = 0, best = 0, streak = 0, quit = 0, frame = 1, max_y,
  17. max_x;
  18. struct Ball ball;
  19. struct Paddle paddle;
  20. system("clear");
  21. initscr();
  22. curs_set(0);
  23. cbreak();
  24. noecho();
  25. nodelay(stdscr, 1);
  26. start_color();
  27. init_pair(1, COLOR_CYAN, COLOR_BLACK);
  28. init_pair(2, COLOR_YELLOW, COLOR_BLACK);
  29. init_pair(3, COLOR_GREEN, COLOR_BLACK);
  30. getmaxyx(stdscr, max_y, max_x);
  31. ball.py = max_y / 2;
  32. ball.px = max_x / 2;
  33. ball.dy = rand() & 1 ? 1 : -1;
  34. ball.dx = rand() & 1 ? 1 : -1;
  35. paddle.length = 6;
  36. paddle.py = (max_y / 2) - (paddle.length / 2);
  37. paddle.px = max_x - 3;
  38. // game logic
  39. while (!quit) {
  40. // drawing
  41. getmaxyx(stdscr, max_y, max_x);
  42. mvprintw(
  43. 0, 0,
  44. "Hits: %d Misses: %d Streak: %d Best: %d Time: %d",
  45. hits, misses, streak, best, frame / 50); // draw stats
  46. attron(COLOR_PAIR(3));
  47. int i;
  48. for ( i = 0; i < max_x; i++) { // draw top borders
  49. mvprintw(1, i, BORDER);
  50. mvprintw(max_y - 1, i, BORDER);
  51. }
  52. for ( i = 1; i < max_y; i++) { // draw side border
  53. mvprintw(i, 0, BORDER);
  54. }
  55. attroff(COLOR_PAIR(3));
  56. attron(COLOR_PAIR(1));
  57. paddle.px = max_x - 3; // in case window was resized update paddle x-pos
  58. for ( i = 0; i < paddle.length; i++) {
  59. mvprintw(paddle.py + i, paddle.px, PADDLE); // draw paddle
  60. }
  61. attroff(COLOR_PAIR(1));
  62. attron(COLOR_PAIR(2));
  63. mvprintw(ball.py, ball.px, BALL_SYMBOL); // draw ball
  64. attroff(COLOR_PAIR(2));
  65. // collisions
  66. if ((ball.py + ball.dy) < 2 ||
  67. (ball.py + ball.dy) > max_y - 2) { // ball-top collision
  68. ball.dy *= -1;
  69. }
  70. if ((ball.px + ball.dx) < 1) { // ball-side collision
  71. ball.dx *= -1;
  72. }
  73. if ((ball.px + ball.dx == paddle.px) &&
  74. (ball.py + ball.dy >= paddle.py) &&
  75. (ball.py + ball.dy <=
  76. (paddle.py + paddle.length))) { // ball-paddle collision
  77. hits--;
  78. streak++;
  79. if (streak > best) best = streak;
  80. ball.dx *= -1;
  81. }
  82. if (ball.px > max_x) { // ball has passed the paddle
  83. misses++;
  84. streak = 0;
  85. ball.py = max_y / 2;
  86. ball.px = max_x / 2;
  87. ball.dy = rand() & 1 ? 1 : -1;
  88. ball.dx = rand() & 1 ? 1 : -1;
  89. }
  90. if (frame % 4 == 0) {
  91. ball.py += ball.dy;
  92. ball.px += ball.dx;
  93. }
  94. // input
  95. switch (getch()) {
  96. case 'j':
  97. if (paddle.py - 1 > 1) paddle.py -= 1;
  98. break;
  99. case 'k':
  100. if ((paddle.py + paddle.length) + 1 < max_y) paddle.py += 1;
  101. break;
  102. case 'Q':
  103. quit = 1;
  104. break;
  105. }
  106. frame++;
  107. usleep(SLEEP_TIME);
  108. }
  109. // exit
  110. endwin();
  111. system("clear");
  112. return 0;
  113. }