Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <curses.h>
- #include <time.h>
- #include <thread>
- #include <string>
- #include <vector>
- #include <math.h>
- #include <iostream>
- using namespace std;
- int RELAY = 20000;
- int sleeping=0;
- pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
- bool ramka=true;
- pthread_t threads1[20];
- class Ball
- {
- public:
- int color;
- double x; // wspolrzedne
- double y;
- double velx; // predkosc w osi x i y
- double vely;
- int time;
- bool En; // jest w ruchu
- bool sleep;
- Ball()
- {
- En=false;
- sleep=false;
- x=40;
- y=20;
- velx=(rand()%5) - 2; // losowanie kierunku oraz predkosci w osi x
- vely=rand()%5; // losowanie predkosci w osi y
- if(velx==0 && vely==0) vely=-1; // jesli wylosuje 0 i 0, czyli bez ruchu to spadek swobodny
- time = RELAY;
- }
- void Wyp();
- };
- int l_box=5;
- int r_box=10;
- int u_box=40;
- int d_box=45;
- /*
- WYPISYWANIE
- */
- void Ball::Wyp()
- {
- attrset(COLOR_PAIR(color));
- mvprintw(round(y), round(x), "o");
- attrset(COLOR_PAIR(0));
- }
- vector <Ball> tab(20);
- // Obsluga thread'a do rysowania, refresh
- void *ref(void *args)
- {
- while(true)
- {
- int maxX, maxY;
- getmaxyx(stdscr, maxY, maxX);
- char c=getch();
- if(c=='q' || c=='e') break; // q-quit e-exit
- clear();
- for(Ball b : tab) // kazdy obiekt klasy Ball znajdujacy sie w tab
- {
- if(b.En==true)
- {
- b.Wyp(); // rysuj kazda kulke w ruchu
- }
- }
- if(ramka)
- {
- // malowanie kwadratu 5x5 (stale wartosci)
- for(int i=l_box; i<r_box-1; i++)
- {
- mvprintw(i, u_box, "x");
- mvprintw(i, d_box-1, "x");
- }
- for(int i=u_box; i<d_box; i++)
- {
- mvprintw(l_box-1, i, "x");
- mvprintw(r_box-1, i, "x");
- }
- for(int i=1;i<maxY;i++)
- {
- mvprintw(i, 0, "|");
- mvprintw(i, maxX-1, "|");
- }
- for(int i=1;i<maxX-1;i++)
- {
- mvprintw(0, i, "_");
- mvprintw(maxY-1, i, "_");
- }
- }
- refresh();
- usleep(RELAY);
- }
- pthread_exit(NULL);
- }
- // Obsluga ruchu kulek, zmien ich stan En-> true, by je rysowac w wyzszej metodzie
- void *p_work(void *args){
- // sygnal zakonczenia
- int k=(int)args;
- Ball& b = tab.at(k);
- int maxX, maxY;
- getmaxyx(stdscr,maxY, maxX);
- b.color=k%6;
- b.x=maxX/2; // wystartuj kulki ze srodka aktualnego ekranu
- b.y=20; // poczatkowa wysokosc
- int maxx = maxX;
- int maxy = maxY-1;
- // obsluga znikania kulek w kwadracie
- if(b.x>=l_box && b.x<=r_box)
- {
- if(b.y>=d_box && b.x<=u_box){
- b.En=false;
- b.sleep=true;
- /*pthread_mutex_lock(&mutex);
- sleeping++;
- pthread_cond_wait(&cond, &mutex);
- b.sleep=false;
- b.En=true;
- pthread_mutex_unlock(&mutex);
- */
- }
- }
- else b.En=true; // zmiana stanu
- while(true)
- {
- Ball& b = tab.at(k);
- if (b.sleep){
- pthread_mutex_lock(&mutex);
- sleeping++;
- pthread_cond_wait(&cond, &mutex);
- b.sleep=false;
- pthread_mutex_unlock(&mutex);
- }
- else {
- b.x+=b.velx; // przesuniecie kulki
- b.y-=b.vely;
- if(b.x>=maxx) // obsluga odbic
- {
- b.velx*=-1;
- b.velx/=2.0f;
- b.x+=b.velx;
- }
- if(b.x<=1)
- {
- b.velx*=-1;
- b.velx/=2.0f;
- b.x+=b.velx;
- }
- if(b.y>maxy)
- {
- b.vely*=-1;
- b.vely/=1.1f;
- b.y=maxy;
- }
- if(b.y<1)
- {
- b.vely*=-1;
- b.vely/=1.1f;
- b.y=1;
- }
- }
- usleep(RELAY); //300000 -> skrocic
- b.vely-=0.2; // obsluga grawitacji
- }
- pthread_exit(NULL);
- }
- // dodawanie kulek
- void *addBalls(void *args)
- {
- int i=0;
- if (sleeping==5)
- {
- sleeping=0;
- pthread_cond_broadcast(&cond);
- }
- std::vector<Ball>::iterator it=tab.begin();
- while(i<50)
- {
- int args=i;
- pthread_create(&threads1[i], NULL, p_work, (void *) args);
- i++;
- sleep(1);
- }
- pthread_exit(NULL);
- }
- int main(void) {
- srand(time(NULL));
- WINDOW * mainwin;
- if ( (mainwin = initscr()) == NULL )
- {
- fprintf(stderr, "Blad. Nie udalo sie zainicjalizowac ncurses .\n");
- exit(EXIT_FAILURE);
- }
- noecho();
- cbreak();
- nodelay(stdscr, TRUE);
- start_color();
- // w celu rozroznienia kulek zastosowalem kolory, lecz przez ograniczenia biblioteki
- // moglem uzyc tylko 6 wariantow (jest jeszcze kolor czarny, ale na czarnym tle go nie zobaczymy)
- // ewentualnie mozemy uzyc funkcji init_color, aby zmienic podstawowe kolory
- if ( has_colors()) {
- init_pair(0, COLOR_RED, COLOR_BLACK);
- init_pair(1, COLOR_GREEN, COLOR_BLACK);
- init_pair(2, COLOR_BLUE, COLOR_BLACK);
- init_pair(3, COLOR_YELLOW, COLOR_BLACK);
- init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
- init_pair(5, COLOR_CYAN, COLOR_BLACK);
- }
- // obsluga watkow
- pthread_t a;
- pthread_create(&a, NULL, ref, NULL );
- pthread_t b;
- pthread_create(&b, NULL, addBalls, NULL);
- pthread_join(a, NULL);
- // zamkniecie okna
- // popraw zamykanie watku
- delwin(mainwin);
- endwin();
- refresh();
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement