Advertisement
Guest User

so2_p1_proj

a guest
Mar 19th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.35 KB | None | 0 0
  1. #include <cstdlib>
  2. #include <string>
  3. #include <cmath>
  4. #include <ncurses.h>
  5. #include <iostream>
  6. #include <thread>
  7. #include <mutex>
  8. #include <chrono>
  9. #include <ctime>
  10.  
  11.  
  12. typedef std::chrono::time_point<std::chrono::high_resolution_clock> timestamp;
  13. //std::chrono::high_resolution_clock clock;
  14.  
  15. WINDOW * window;          //obiekt okan ncurses
  16. int screenH, screenW;     //wielkosc okna ncurses
  17. double gravity = 9.8 / 5.0;     //przyspieszenie grawitacyjne [m/s2]
  18. double energy_loss = 0.5; //wspolczynnik zachowanej energii po kolicji
  19. std::mutex window_mutex;  //mutex chroniacy operacje na oknie
  20.  
  21. //Pomocnicza klasa - wrapper chrono::high_resolution_clock
  22. class Timer{
  23. public:
  24.   static timestamp now(){
  25.     return std::chrono::high_resolution_clock::now();
  26.   }
  27.  
  28.   static double periodToSec(timestamp begin, timestamp end){
  29.     //std::chrono::duration<double, std::chrono::seconds> seconds = end - begin;
  30.     return std::chrono::duration_cast<std::chrono::seconds>(end - begin).count();
  31.   }
  32. };
  33.  
  34. void spawnBall(double vy, double vx)
  35. {
  36.   vy /= 5.0; vx /= 5.0;
  37.  
  38.   std::string ball = "O";
  39.   std::string eraser = " ";
  40.  
  41.   double py = screenH / 2.0;
  42.   double px = screenW / 2.0;
  43.   double oldPy, oldPx;
  44.  
  45.   window_mutex.lock();
  46.   mvwprintw(window, py, px, ball.c_str());
  47.   window_mutex.unlock();
  48.  
  49.   timestamp p_begin = Timer::now();
  50.   timestamp p_end;
  51.   double timePassed = 0.0;
  52.  
  53.   while(1)
  54.     {
  55.       std::this_thread::sleep_for(std::chrono::milliseconds(500));
  56.       //Pozyskaj czas od ostatnich obliczen
  57.       p_end = Timer::now();
  58.       timePassed = Timer::periodToSec(p_begin, p_end);
  59.       //mvwprintw(window, 1, 0, std::to_string(
  60.       //  std::ctime((std::chrono::high_resolution_clock::to_time_t(p_begin)))
  61.       //).c_str())
  62.       //mvwprintw(window, 2, 0, std::to_string(p_end).c_str());
  63.       p_begin = p_end;
  64.  
  65.       //Zachowaj poprzednia pozycje pilki
  66.       oldPy = py; oldPx = px;
  67.       //Przemiesc pilke zgodnie z wektorem predkosci
  68.       py -= vy * timePassed;
  69.  
  70.       ///-------------------ODBICIA----------------------------
  71.  
  72.       //Jezeli kolizja z sufitem
  73.       if(py < 1.0){
  74.         //Skoryguj odbicie
  75.         py = 1-py;
  76.         //Zmien kierunek pionowej skladowej wektra predkosi
  77.         vy = -vy;
  78.       }
  79.       else if(py > screenH-1.0){
  80.         //Skoryguj odbicie + wprowadz utrate energii
  81.         py = (screenH-1.0) - ((py-(screenH-1.0)) * energy_loss);
  82.         //Zmien kierunek pionowej skladowej wektra predkosi
  83.         //+ wprowadz utrate energii
  84.         vy = -vy * energy_loss;
  85.       }
  86.  
  87.       vy -= gravity * timePassed;
  88.  
  89.       if(vy > 10) vy = 10;
  90.       if(vy < -10) vy = -10;
  91.  
  92.  
  93.       mvwprintw(window, 0, 0, std::to_string(vy).c_str());
  94.       //mvwprintw(window, 1, 0, std::to_string(py).c_str());
  95.  
  96.  
  97.       px += vx * timePassed;
  98.       if(px >= screenW-1 || px <= 0){vx = -vx; px += 2*vx;}
  99.  
  100.       //Narysuj pilke w nowym miejsu
  101.       window_mutex.lock();
  102.       mvwprintw(window, oldPy, oldPx, eraser.c_str());
  103.       mvwprintw(window, py, px, ball.c_str());
  104.       window_mutex.unlock();
  105.     }
  106. }
  107.  
  108. void ballDispenser(int spawnTimeGap)
  109. {
  110.   int counter = 0;
  111.   while(1)
  112.     {
  113.       // mvwprintw(window, screenH/2, screenW/2, std::to_string(counter).c_str());
  114.       //std::cout << "ball spawned!" <<std::endl;
  115.       std::this_thread::sleep_for(std::chrono::milliseconds(spawnTimeGap));
  116.       ++counter;
  117.     }
  118. }
  119.  
  120. void setFPS(int fps)
  121. {
  122.   int period = 100.0 / fps;
  123.  
  124.   while(1)
  125.     {
  126.       window_mutex.lock();
  127.       wrefresh(window);
  128.       window_mutex.unlock();
  129.       std::this_thread::sleep_for(std::chrono::milliseconds(period));
  130.     }
  131. }
  132.  
  133. int main(int argc, char ** argv)
  134. {
  135.   int timeGap = 1200;
  136.   screenH = 15;
  137.   screenW = 40;
  138.  
  139.   if(argc > 1)
  140.     timeGap = std::atoi(argv[1]);
  141.   if(argc > 3)
  142.     {
  143.       screenH = atoi(argv[2]);
  144.       screenW = atoi(argv[3]);
  145.     }
  146.  
  147.   initscr();
  148.   window = newwin(screenH, screenW, 0, 0);
  149.   curs_set(0);
  150.   refresh();
  151.   box(window, 0, 0);
  152.   wrefresh(window);
  153.  
  154.   std::thread refresh_thread(setFPS, 15);
  155.   refresh_thread.detach();
  156.  
  157.   //std::thread dispenser(ballDispenser, timeGap);
  158.   //dispenser.detach();
  159.  
  160.   std::thread releaseBall(spawnBall, 25, 10);
  161.   releaseBall.detach();
  162.  
  163.   //std::cout << std::chrono::high_resolution_clock::period::den <<std::endl;
  164.  
  165.   //std::cout<<"main: On it!"<<std::endl;
  166.  
  167.   std::getchar();
  168.   endwin();
  169.   return 0;
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement