Advertisement
Guest User

Untitled

a guest
Mar 29th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.29 KB | None | 0 0
  1. /************************************************************
  2. Interakcja:
  3. Wysyłanie, odbiór komunikatów, interakcja z innymi
  4. uczestnikami WZR, sterowanie wirtualnymi obiektami
  5. *************************************************************/
  6.  
  7. #include <windows.h>
  8. #include <time.h>
  9. #include <stdio.h>
  10. #include "interakcja.h"
  11. #include "obiekty.h"
  12. #include "grafika.h"
  13.  
  14. #include "siec.h"
  15.  
  16. FILE *f = fopen("wwc_log.txt","w"); // plik do zapisu informacji testowych
  17.  
  18. ObiektRuchomy *pMojObiekt; // obiekt przypisany do tej aplikacji
  19.  
  20. Teren teren;
  21. int iLiczbaCudzychOb = 0;
  22. ObiektRuchomy *CudzeObiekty[1000]; // obiekty z innych aplikacji lub inne obiekty niz pCraft
  23. int IndeksyOb[1000]; // tablica indeksow innych obiektow ulatwiajaca wyszukiwanie
  24.  
  25. float fDt; // sredni czas pomiedzy dwoma kolejnymi cyklami symulacji i wyswietlania
  26. long czas_cyklu_WS,licznik_sym; // zmienne pomocnicze potrzebne do obliczania fDt
  27. float sr_czestosc; // srednia czestosc wysylania ramek w [ramkach/s]
  28. long czas_start = clock(); // czas od poczatku dzialania aplikacji
  29.  
  30. multicast_net *multi_reciv; // wsk do obiektu zajmujacego sie odbiorem komunikatow
  31. multicast_net *multi_send; // -||- wysylaniem komunikatow
  32.  
  33. HANDLE threadReciv; // uchwyt wątku odbioru komunikatów
  34. extern HWND okno;
  35. int SHIFTwcisniety = 0;
  36.  
  37.  
  38. // Parametry widoku:
  39. Wektor3 kierunek_kamery = Wektor3(10,-3,-11); // kierunek patrzenia
  40. Wektor3 pol_kamery = Wektor3(-5,3,10); // położenie kamery
  41. Wektor3 pion_kamery = Wektor3(0,1,0); // kierunek pionu kamery
  42. bool sledzenie = 0; // tryb śledzenia obiektu przez kamerę
  43. float oddalenie = 1.0; // oddalenie lub przybliżenie kamery
  44. float zoom = 1.0; // zmiana kąta widzenia
  45. float kat_kam_z = 0; // obrót kamery góra-dół
  46. bool sterowanie_myszkowe = 0; // sterowanie pojazdem za pomocą myszki
  47. int kursor_x, kursor_y; // polożenie kursora myszki w chwili włączenia sterowania
  48. char napis1[200], napis2[200]; // napisy wyświetlane w trybie graficznym
  49.  
  50. int opoznienia = 0;
  51. bool podnoszenie_przedm = 1; // czy mozna podnosic przedmioty
  52. bool rejestracja_uczestnikow = 1; // rejestracja trwa do momentu wzięcia przedmiotu przez któregokolwiek uczestnika,
  53. // w przeciwnym razie trzeba by przesyłać cały stan środowiska nowicjuszowi
  54. float czas_odnowy_przedm = 90; // czas w [s] po którym wzięte przedmioty odnawiają się
  55. bool czy_umiejetnosci = 1; // czy zróżnicowanie umiejętności (dla każdego pojazdu losowane są umiejętności
  56. // zbierania gotówki i paliwa)
  57.  
  58. extern float WyslaniePrzekazu(int ID_adresata, int typ_przekazu, float wartosc_przekazu);
  59.  
  60. enum typy_ramek {STAN_OBIEKTU, WZIECIE_PRZEDMIOTU, ODNOWIENIE_SIE_PRZEDMIOTU, KOLIZJA, PRZEKAZ,
  61. PROSBA_O_ZAMKNIECIE, NEGOCJACJE_HANDLOWE, TEKST, ZAPROSZENIE, ODPOWIEDZ, ZGODA, START_LICYTACJI, LICYTACJA, KONIEC_LICYTACJI, PROPOZYCJA};
  62.  
  63. enum typy_przekazu {GOTOWKA, PALIWO};
  64.  
  65. struct Ramka
  66. {
  67. int typ_ramki;
  68. long czas_wyslania;
  69. int iID_adresata; // nr ID adresata wiadomości (pozostali uczestnicy powinni wiadomość zignorować)
  70.  
  71. int nr_przedmiotu; // nr przedmiotu, który został wzięty lub odzyskany
  72. Wektor3 wdV_kolid; // wektor prędkości wyjściowej po kolizji (uczestnik o wskazanym adresie powinien
  73. // przyjąć tą prędkość)
  74.  
  75. int typ_przekazu; // gotówka, paliwo
  76. float wartosc_przekazu; // ilość gotówki lub paliwa
  77. int nr_druzyny;
  78.  
  79. StanObiektu stan;
  80. };
  81.  
  82.  
  83. //******************************************
  84. // Funkcja obsługi wątku odbioru komunikatów
  85. DWORD WINAPI WatekOdbioru(void *ptr)
  86. {
  87. multicast_net *pmt_net=(multicast_net*)ptr; // wskaźnik do obiektu klasy multicast_net
  88. int rozmiar; // liczba bajtów ramki otrzymanej z sieci
  89. Ramka ramka;
  90. StanObiektu stan;
  91.  
  92. while(1)
  93. {
  94. rozmiar = pmt_net->reciv((char*)&ramka,sizeof(Ramka)); // oczekiwanie na nadejście ramki
  95. switch (ramka.typ_ramki)
  96. {
  97. case STAN_OBIEKTU: // podstawowy typ ramki informującej o stanie obiektu
  98. {
  99. stan = ramka.stan;
  100. //fprintf(f,"odebrano stan iID = %d, ID dla mojego obiektu = %d\n",stan.iID,pMojObiekt->iID);
  101. int niewlasny = 1;
  102. if ((stan.iID != pMojObiekt->iID)) // jeśli to nie mój własny obiekt
  103. {
  104.  
  105. if ((rejestracja_uczestnikow)&&(IndeksyOb[stan.iID] == -1)) // nie ma jeszcze takiego obiektu w tablicy -> trzeba go stworzyć
  106. {
  107. CudzeObiekty[iLiczbaCudzychOb] = new ObiektRuchomy();
  108. IndeksyOb[stan.iID] = iLiczbaCudzychOb; // wpis do tablicy indeksowanej numerami ID
  109. // ułatwia wyszukiwanie, alternatywą może być tabl. rozproszona
  110. iLiczbaCudzychOb++;
  111. CudzeObiekty[IndeksyOb[stan.iID]]->ZmienStan(stan); // aktualizacja stanu obiektu obcego
  112. }
  113. else if (IndeksyOb[stan.iID] != -1)
  114. CudzeObiekty[IndeksyOb[stan.iID]]->ZmienStan(stan); // aktualizacja stanu obiektu obcego
  115. else
  116. {
  117. Ramka ramka;
  118. ramka.typ_ramki = PROSBA_O_ZAMKNIECIE; // żądanie zamkięcia aplikacji
  119. ramka.iID_adresata = stan.iID;
  120. int iRozmiar = multi_send->send((char*)&ramka,sizeof(Ramka));
  121. }
  122. }
  123. break;
  124. }
  125. case WZIECIE_PRZEDMIOTU: // ramka informująca, że ktoś wziął przedmiot o podanym numerze
  126. {
  127. if ((ramka.nr_przedmiotu < teren.liczba_przedmiotow)&&(stan.iID != pMojObiekt->iID))
  128. {
  129. teren.p[ramka.nr_przedmiotu].do_wziecia = 0;
  130. teren.p[ramka.nr_przedmiotu].czy_ja_wzialem = 0;
  131. rejestracja_uczestnikow = 0;
  132. sprintf(napis2,"Pojazd_id_%d_zabral_przedmiot_nr_%d",stan.iID,ramka.nr_przedmiotu);
  133. }
  134. break;
  135. }
  136. case ODNOWIENIE_SIE_PRZEDMIOTU: // ramka informujaca, że przedmiot wcześniej wzięty pojawił się znowu w tym samym miejscu
  137. {
  138. if (ramka.nr_przedmiotu < teren.liczba_przedmiotow)
  139. teren.p[ramka.nr_przedmiotu].do_wziecia = 1;
  140. break;
  141. }
  142. case KOLIZJA: // ramka informująca o tym, że obiekt uległ kolizji
  143. {
  144. if (ramka.iID_adresata == pMojObiekt->iID) // ID pojazdu, który uczestniczył w kolizji zgadza się z moim ID
  145. {
  146. pMojObiekt->wdV_kolid = ramka.wdV_kolid; // przepisuje poprawkę własnej prędkości
  147. pMojObiekt->iID_kolid = pMojObiekt->iID; // ustawiam nr. kolidujacego jako własny na znak, że powinienem poprawić prędkość
  148. }
  149. break;
  150. }
  151. case PRZEKAZ: // ramka informująca o przelewie pieniężnym lub przekazaniu towaru
  152. {
  153. if (ramka.iID_adresata == pMojObiekt->iID) // ID pojazdu, ktory otrzymal przelew zgadza się z moim ID
  154. {
  155. if (ramka.typ_przekazu == GOTOWKA)
  156. pMojObiekt->pieniadze += ramka.wartosc_przekazu;
  157. else if (ramka.typ_przekazu == PALIWO)
  158. pMojObiekt->ilosc_paliwa += ramka.wartosc_przekazu;
  159.  
  160. // należałoby jeszcze przelew potwierdzić (w UDP ramki mogą być gubione!)
  161. }
  162. break;
  163. }
  164. case PROSBA_O_ZAMKNIECIE: // ramka informująca, że powinieneś się zamknąć
  165. {
  166. if (ramka.iID_adresata == pMojObiekt->iID)
  167. {
  168. SendMessage(okno,WM_DESTROY,0,100);
  169. }
  170. break;
  171. }
  172. case NEGOCJACJE_HANDLOWE:
  173. {
  174. // ------------------------------------------------------------------------
  175. // --------------- MIEJSCE #1 NA NEGOCJACJE HANDLOWE ---------------------
  176. // (szczegóły na stronie w instrukcji do zadania)
  177.  
  178.  
  179.  
  180.  
  181. // ------------------------------------------------------------------------
  182.  
  183. break;
  184. }
  185. case ZAPROSZENIE:
  186.  
  187. if (ramka.stan.iID != pMojObiekt->iID)
  188. {
  189. sprintf(buff, "Uzytkownik %d chce zaczac wspolpracowac!!", ramka.stan.iID);
  190. if (MessageBox(okno, buff, "Zaproszenie", MB_OKCANCEL) == IDOK)
  191. {
  192. odpowiadam = true;
  193. idZapraszajacego = stan.iID;
  194. }
  195. }
  196.  
  197. break;
  198. case ODPOWIEDZ:
  199. if (ramka.idZapraszajacego == pMojObiekt->iID && idDruzyny == -1)
  200. {
  201. sprintf(buff, "Uzytkownik %d odpowiedzial na zaproszenie!!", ramka.stan.iID);
  202. if (MessageBox(okno, buff, "Odpowiedz", MB_OKCANCEL) == IDOK)
  203. {
  204. idKolaboratora = ramka.stan.iID;
  205. zgadzam = true;
  206. sprintf(buff, "%d%d", pMojObiekt->iID, idKolaboratora);
  207. idDruzyny = atoi(buff);
  208. pMojObiekt->idDruzyny = idDruzyny;
  209. CudzeObiekty[IndeksyOb[idKolaboratora]]->idDruzyny = idDruzyny;
  210. }
  211. }
  212. break;
  213.  
  214. case ZGODA:
  215. if (ramka.stan.iID == idZapraszajacego)
  216. {
  217. idKolaboratora = idZapraszajacego;
  218. idDruzyny = ramka.nr_druzyny;
  219. pMojObiekt->idDruzyny = idDruzyny;
  220. CudzeObiekty[IndeksyOb[idKolaboratora]]->idDruzyny = idDruzyny;
  221. }
  222. listaIdDruzyn[iloscDruzyn] = ramka.nr_druzyny;
  223. case LICYTACJA:
  224. printf("ROZMIAR: %d\n", rozmiar);
  225. if (!licytacja)
  226. {
  227. licytacja = ramka.licytacja;
  228. idLicytenta = ramka.idLic;
  229. }
  230.  
  231. if (ramka.secLeft)
  232. {
  233. czasDoZakonczenia = ramka.secLeft;
  234. }
  235. oferta1 = ramka.o1;
  236. oferta2 = ramka.o2;
  237. idGraczaNajlepszego = ramka.idNajlep;
  238. break;
  239. case KONIEC_LICYTACJI:
  240. licytacja = false;
  241. break;
  242. case PROPOZYCJA:
  243. if (ramka.idLic == pMojObiekt->iID)
  244. {
  245. if (ramka.o2 < oferta2)
  246. {
  247. oferta2 = ramka.o2;
  248. oferta1 = 100 - oferta2;
  249. idGraczaNajlepszego = ramka.stan.iID;
  250. czasDoZakonczeniaWlasciciel += 3;
  251. }
  252. }
  253.  
  254. } // switch po typach ramek
  255. } // while(1)
  256. return 1;
  257. }
  258.  
  259. // *****************************************************************
  260. // **** Wszystko co trzeba zrobić podczas uruchamiania aplikacji
  261. // **** poza grafiką
  262. void PoczatekInterakcji()
  263. {
  264. DWORD dwThreadId;
  265.  
  266. pMojObiekt = new ObiektRuchomy(); // tworzenie wlasnego obiektu
  267.  
  268. for (long i=0;i<1000;i++) // inicjacja indeksow obcych obiektow
  269. IndeksyOb[i] = -1;
  270.  
  271. czas_cyklu_WS = clock(); // pomiar aktualnego czasu
  272.  
  273. // obiekty sieciowe typu multicast (z podaniem adresu WZR oraz numeru portu)
  274. multi_reciv = new multicast_net("224.10.11.11",10001); // obiekt do odbioru ramek sieciowych
  275. multi_send = new multicast_net("224.10.11.11",10001); // obiekt do wysyłania ramek
  276.  
  277. if (opoznienia)
  278. {
  279. float srednie_opoznienie = 3*(float)rand()/RAND_MAX, wariancja_opoznienia = 2;
  280. multi_send->PrepareDelay(srednie_opoznienie,wariancja_opoznienia);
  281. }
  282.  
  283. // uruchomienie watku obslugujacego odbior komunikatow
  284. threadReciv = CreateThread(
  285. NULL, // no security attributes
  286. 0, // use default stack size
  287. WatekOdbioru, // thread function
  288. (void *)multi_reciv, // argument to thread function
  289. 0, // use default creation flags
  290. &dwThreadId); // returns the thread identifier
  291.  
  292. }
  293.  
  294.  
  295. // *****************************************************************
  296. // **** Wszystko co trzeba zrobić w każdym cyklu działania
  297. // **** aplikacji poza grafiką
  298. void Cykl_WS()
  299. {
  300. licznik_sym++;
  301.  
  302. // obliczenie średniego czasu pomiędzy dwoma kolejnnymi symulacjami po to, by zachować fizycznych
  303. if (licznik_sym % 50 == 0) // jeśli licznik cykli przekroczył pewną wartość, to
  304. { // należy na nowo obliczyć średni czas cyklu fDt
  305. char text[200];
  306. long czas_pop = czas_cyklu_WS;
  307. czas_cyklu_WS = clock();
  308. float fFps = (50*CLOCKS_PER_SEC)/(float)(czas_cyklu_WS-czas_pop);
  309. if (fFps!=0) fDt=1.0/fFps; else fDt=1;
  310.  
  311. sprintf(napis1," %0.0f_fps, paliwo = %0.2f, gotowka = %d,",fFps,pMojObiekt->ilosc_paliwa,pMojObiekt->pieniadze);
  312. if (licznik_sym % 500 == 0) sprintf(napis2,"");
  313. }
  314.  
  315. pMojObiekt->Symulacja(fDt); // symulacja własnego obiektu
  316.  
  317.  
  318. if ((pMojObiekt->iID_kolid > -1)&& // wykryto kolizję - wysyłam specjalną ramkę, by poinformować o tym drugiego uczestnika
  319. (pMojObiekt->iID_kolid != pMojObiekt->iID)) // oczywiście wtedy, gdy nie chodzi o mój pojazd
  320. {
  321. Ramka ramka;
  322. ramka.typ_ramki = KOLIZJA;
  323. ramka.iID_adresata = pMojObiekt->iID_kolid;
  324. ramka.wdV_kolid = pMojObiekt->wdV_kolid;
  325. int iRozmiar = multi_send->send((char*)&ramka,sizeof(Ramka));
  326.  
  327. char text[128];
  328. sprintf(napis2,"Kolizja_z_obiektem_o_ID = %d",pMojObiekt->iID_kolid);
  329. //SetWindowText(okno,text);
  330.  
  331. pMojObiekt->iID_kolid = -1;
  332. }
  333.  
  334. // wyslanie komunikatu o stanie obiektu przypisanego do aplikacji (pMojObiekt):
  335. if (licznik_sym % 1 == 0)
  336. {
  337. Ramka ramka;
  338. ramka.typ_ramki = STAN_OBIEKTU;
  339. ramka.stan = pMojObiekt->Stan(); // stan własnego obiektu
  340. int iRozmiar = multi_send->send((char*)&ramka,sizeof(Ramka));
  341. }
  342.  
  343. long czas_akt = clock();
  344.  
  345. // sprawdzam, czy nie najechałem na monetę lub beczkę z paliwem. Jeśli tak, to zdobywam pieniądze lub paliwo oraz wysyłam innym uczestnikom
  346. // informację o zabraniu beczki: (wcześniej trzeba wcisnąć P)
  347. for (long i=0;i<teren.liczba_przedmiotow;i++)
  348. {
  349. if ((teren.p[i].do_wziecia == 1)&&(podnoszenie_przedm)&&
  350. ((teren.p[i].wPol - pMojObiekt->wPol + Wektor3(0,pMojObiekt->wPol.y - teren.p[i].wPol.y,0)).dlugosc() < pMojObiekt->promien))
  351. {
  352.  
  353. long wartosc = teren.p[i].wartosc;
  354.  
  355. if (teren.p[i].typ == MONETA)
  356. {
  357. if (czy_umiejetnosci)
  358. wartosc = (long)(float)wartosc*pMojObiekt->umiejetn_zb_monet;
  359. pMojObiekt->pieniadze += wartosc;
  360. sprintf(napis2,"Wziecie_gotowki_o_wartosci_ %d",wartosc);
  361. }
  362. else
  363. {
  364. if (czy_umiejetnosci)
  365. wartosc = (float)wartosc*pMojObiekt->umiejetn_zb_paliwa;
  366. pMojObiekt->ilosc_paliwa += wartosc;
  367. sprintf(napis2,"Wziecie_paliwa_w_ilosci_ %d",wartosc);
  368. }
  369.  
  370. teren.p[i].do_wziecia = 0;
  371. teren.p[i].czy_ja_wzialem = 1;
  372. teren.p[i].czas_wziecia = clock();
  373. rejestracja_uczestnikow = 0; // koniec rejestracji nowych uczestników
  374.  
  375. Ramka ramka;
  376. ramka.typ_ramki = WZIECIE_PRZEDMIOTU;
  377. ramka.nr_przedmiotu = i;
  378. ramka.stan = pMojObiekt->Stan();
  379. int iRozmiar = multi_send->send((char*)&ramka,sizeof(Ramka));
  380. }
  381. else if ((teren.p[i].do_wziecia == 0)&&(teren.p[i].czy_ja_wzialem)&&(teren.p[i].czy_odnawialny)&&
  382. (czas_akt - teren.p[i].czas_wziecia >= czas_odnowy_przedm*CLOCKS_PER_SEC))
  383. { // jeśli minął pewnien okres czasu przedmiot może zostać przywrócony
  384. teren.p[i].do_wziecia = 1;
  385. Ramka ramka;
  386. ramka.typ_ramki = ODNOWIENIE_SIE_PRZEDMIOTU;
  387. ramka.nr_przedmiotu = i;
  388. int iRozmiar = multi_send->send((char*)&ramka,sizeof(Ramka));
  389. }
  390. } // for po przedmiotach
  391.  
  392. }
  393.  
  394. // *****************************************************************
  395. // **** Wszystko co trzeba zrobić podczas zamykania aplikacji
  396. // **** poza grafiką
  397. void ZakonczenieInterakcji()
  398. {
  399. fprintf(f,"Koniec interakcji\n");
  400. fclose(f);
  401. }
  402.  
  403. // Funkcja wysylajaca ramke z przekazem, zwraca zrealizowaną wartość przekazu
  404. float WyslaniePrzekazu(int ID_adresata, int typ_przekazu, float wartosc_przekazu)
  405. {
  406. Ramka ramka;
  407. ramka.typ_ramki = PRZEKAZ;
  408. ramka.iID_adresata = ID_adresata;
  409. ramka.typ_przekazu = typ_przekazu;
  410. ramka.wartosc_przekazu = wartosc_przekazu;
  411.  
  412. // tutaj należałoby uzyskać potwierdzenie przekazu zanim sumy zostaną odjęte
  413. if (typ_przekazu == GOTOWKA)
  414. {
  415. if (pMojObiekt->pieniadze < wartosc_przekazu)
  416. ramka.wartosc_przekazu = pMojObiekt->pieniadze;
  417. pMojObiekt->pieniadze -= ramka.wartosc_przekazu;
  418. sprintf(napis2,"Przelew_sumy_ %f _na_rzecz_ID_ %d",wartosc_przekazu,ID_adresata);
  419. }
  420. else if (typ_przekazu == PALIWO)
  421. {
  422. // odszukanie adresata, sprawdzenie czy jest odpowiednio blisko:
  423. int indeks_adresata = -1;
  424. for (int i=0;i<iLiczbaCudzychOb;i++)
  425. if (CudzeObiekty[i]->iID == ID_adresata) {indeks_adresata = i; break;}
  426. if ((CudzeObiekty[indeks_adresata]->wPol - pMojObiekt->wPol).dlugosc() >
  427. CudzeObiekty[indeks_adresata]->dlugosc + pMojObiekt->dlugosc)
  428. ramka.wartosc_przekazu = 0;
  429. else
  430. {
  431. if (pMojObiekt->ilosc_paliwa < wartosc_przekazu)
  432. ramka.wartosc_przekazu = pMojObiekt->ilosc_paliwa;
  433. pMojObiekt->ilosc_paliwa -= ramka.wartosc_przekazu;
  434. sprintf(napis2,"Przekazanie_paliwa_w_ilości_ %f _na_rzecz_ID_ %d",wartosc_przekazu,ID_adresata);
  435. }
  436. }
  437.  
  438. if (ramka.wartosc_przekazu > 0)
  439. int iRozmiar = multi_send->send((char*)&ramka,sizeof(Ramka));
  440.  
  441. return ramka.wartosc_przekazu;
  442. }
  443.  
  444.  
  445. // ************************************************************************
  446. // **** Obsługa klawiszy służących do sterowania obiektami lub
  447. // **** widokami
  448. void KlawiszologiaSterowania(UINT kod_meldunku, WPARAM wParam, LPARAM lParam)
  449. {
  450.  
  451. switch (kod_meldunku)
  452. {
  453.  
  454. case WM_LBUTTONDOWN: //reakcja na lewy przycisk myszki
  455. {
  456. int x = LOWORD(lParam);
  457. int y = HIWORD(lParam);
  458. if (sterowanie_myszkowe)
  459. pMojObiekt->F = 4100.0; // siła pchająca do przodu
  460. break;
  461. }
  462. case WM_RBUTTONDOWN: //reakcja na prawy przycisk myszki - zaznaczanie obiektów
  463. {
  464. int x = LOWORD(lParam);
  465. int y = HIWORD(lParam);
  466. if (sterowanie_myszkowe)
  467. pMojObiekt->F = -2100.0; // siła pchająca do tylu
  468. else // zaznaczanie obiektów
  469. {
  470. RECT r;
  471. //GetWindowRect(okno,&r);
  472. GetClientRect(okno,&r);
  473. Wektor3 w = WspolrzedneKursora3D(x,r.bottom - r.top - y);
  474. //float promien = (w - punkt_klik).dlugosc();
  475. float odl_min = 1e10;
  476. long ind_min = -1;
  477. bool czy_ob_ruch;
  478. for (long i=0;i<iLiczbaCudzychOb;i++)
  479. {
  480. float xx,yy,zz;
  481. WspolrzedneEkranu(&xx,&yy,&zz, CudzeObiekty[i]->wPol);
  482. yy = r.bottom - r.top - yy;
  483. float odl_kw = (xx-x)*(xx-x) + (yy-y)*(yy-y);
  484. if (odl_min > odl_kw)
  485. {
  486. odl_min = odl_kw;
  487. ind_min = i;
  488. czy_ob_ruch = 1;
  489. }
  490. }
  491.  
  492. for (long i=0;i<teren.liczba_przedmiotow;i++)
  493. {
  494. float xx,yy,zz;
  495. WspolrzedneEkranu(&xx,&yy,&zz, teren.p[i].wPol);
  496. yy = r.bottom - r.top - yy;
  497. float odl_kw = (xx-x)*(xx-x) + (yy-y)*(yy-y);
  498. if (odl_min > odl_kw)
  499. {
  500. odl_min = odl_kw;
  501. ind_min = i;
  502. czy_ob_ruch = 0;
  503. }
  504. }
  505. if (ind_min > -1)
  506. {
  507. //fprintf(f,"zaznaczono przedmiot %d pol = (%f, %f, %f)\n",ind_min,teren.p[ind_min].wPol.x,teren.p[ind_min].wPol.y,teren.p[ind_min].wPol.z);
  508. //teren.p[ind_min].czy_zazn = 1 - teren.p[ind_min].czy_zazn;
  509. if (czy_ob_ruch)
  510. CudzeObiekty[ind_min]->czy_zazn = 1 - CudzeObiekty[ind_min]->czy_zazn;
  511. else
  512. teren.p[ind_min].czy_zazn = 1 - teren.p[ind_min].czy_zazn;
  513. //char lan[256];
  514. //sprintf(lan, "kliknięto w przedmiot %d pol = (%f, %f, %f)\n",ind_min,teren.p[ind_min].wPol.x,teren.p[ind_min].wPol.y,teren.p[ind_min].wPol.z);
  515. //SetWindowText(okno,lan);
  516. }
  517. Wektor3 punkt_klik = WspolrzedneKursora3D(x,r.bottom - r.top - y);
  518.  
  519. }
  520. break;
  521. }
  522. case WM_MBUTTONDOWN: //reakcja na środkowy przycisk myszki : uaktywnienie/dezaktywacja sterwania myszkowego
  523. {
  524. sterowanie_myszkowe = 1 - sterowanie_myszkowe;
  525. kursor_x = LOWORD(lParam);
  526. kursor_y = HIWORD(lParam);
  527. break;
  528. }
  529. case WM_LBUTTONUP: //reakcja na puszczenie lewego przycisku myszki
  530. {
  531. if (sterowanie_myszkowe)
  532. pMojObiekt->F = 0.0; // siła pchająca do przodu
  533. break;
  534. }
  535. case WM_RBUTTONUP: //reakcja na puszczenie lewy przycisk myszki
  536. {
  537. if (sterowanie_myszkowe)
  538. pMojObiekt->F = 0.0; // siła pchająca do przodu
  539. break;
  540. }
  541. case WM_MOUSEMOVE:
  542. {
  543. int x = LOWORD(lParam);
  544. int y = HIWORD(lParam);
  545. if (sterowanie_myszkowe)
  546. {
  547. float kat_skretu = (float)(kursor_x - x)/20;
  548. if (kat_skretu > 45) kat_skretu = 45;
  549. if (kat_skretu < -45) kat_skretu = -45;
  550. pMojObiekt->alfa = PI*kat_skretu/180;
  551. }
  552. break;
  553. }
  554. case WM_KEYDOWN:
  555. {
  556.  
  557. switch (LOWORD(wParam))
  558. {
  559. case VK_SHIFT:
  560. {
  561. SHIFTwcisniety = 1;
  562. break;
  563. }
  564. case VK_SPACE:
  565. {
  566. pMojObiekt->ham = 1.0; // stopień hamowania (reszta zależy od siły docisku i wsp. tarcia)
  567. break; // 1.0 to maksymalny stopień (np. zablokowanie kół)
  568. }
  569. case VK_UP:
  570. {
  571.  
  572. pMojObiekt->F = 4100.0; // siła pchająca do przodu
  573. break;
  574. }
  575. case VK_DOWN:
  576. {
  577. pMojObiekt->F = -2100.0; // sila pchajaca do tylu
  578. break;
  579. }
  580. case VK_LEFT:
  581. {
  582. if (SHIFTwcisniety) pMojObiekt->alfa = PI*35/180;
  583. else pMojObiekt->alfa = PI*15/180;
  584.  
  585. break;
  586. }
  587. case VK_RIGHT:
  588. {
  589. if (SHIFTwcisniety) pMojObiekt->alfa = -PI*35/180;
  590. else pMojObiekt->alfa = -PI*15/180;
  591. break;
  592. }
  593. case 'W': // przybliżenie widoku
  594. {
  595. //pol_kamery = pol_kamery - kierunek_kamery*0.3;
  596. if (oddalenie > 0.5) oddalenie /= 1.2;
  597. else oddalenie = 0;
  598. break;
  599. }
  600. case 'S': // oddalenie widoku
  601. {
  602. //pol_kamery = pol_kamery + kierunek_kamery*0.3;
  603. if (oddalenie > 0) oddalenie *= 1.2;
  604. else oddalenie = 0.5;
  605. break;
  606. }
  607. case 'Q': // widok z góry
  608. {
  609. pol_kamery = Wektor3(0,100,0);
  610. kierunek_kamery = Wektor3(0,-1,0.01);
  611. pion_kamery = Wektor3(0,0,-1);
  612. break;
  613. }
  614. case 'E': // obrót kamery ku górze (względem lokalnej osi z)
  615. {
  616. kat_kam_z += PI*5/180;
  617. break;
  618. }
  619. case 'D': // obrót kamery ku dołowi (względem lokalnej osi z)
  620. {
  621. kat_kam_z -= PI*5/180;
  622. break;
  623. }
  624. case 'A': // włączanie, wyłączanie trybu śledzenia obiektu
  625. {
  626. sledzenie = 1 - sledzenie;
  627. break;
  628. }
  629. case 'Z': // zoom - zmniejszenie kąta widzenia
  630. {
  631. zoom /= 1.1;
  632. RECT rc;
  633. GetClientRect (okno, &rc);
  634. ZmianaRozmiaruOkna(rc.right - rc.left,rc.bottom-rc.top);
  635. break;
  636. }
  637. case 'X': // zoom - zwiększenie kąta widzenia
  638. {
  639. zoom *= 1.1;
  640. RECT rc;
  641. GetClientRect (okno, &rc);
  642. ZmianaRozmiaruOkna(rc.right - rc.left,rc.bottom-rc.top);
  643. break;
  644. }
  645. case 'P': // podnoszenie przedmiotów
  646. {
  647. //Wektor3 w_przod = pMojObiekt->qOrient.obroc_wektor(Wektor3(1,0,0));
  648. //+ Wector3(0,pMojObiekt->wPol.y - teren.p[i].wPol.y,0)
  649. podnoszenie_przedm = 1 - podnoszenie_przedm;
  650. break;
  651. }
  652. case 'F': // przekazanie 10 kg paliwa pojazdowi, który znajduje się najbliżej
  653. {
  654. float min_odleglosc = 1e10;
  655. int indeks_min = -1;
  656. for (int i=0;i<iLiczbaCudzychOb;i++)
  657. {
  658. if (min_odleglosc > (CudzeObiekty[i]->wPol - pMojObiekt->wPol).dlugosc() )
  659. {
  660. min_odleglosc = (CudzeObiekty[i]->wPol - pMojObiekt->wPol).dlugosc();
  661. indeks_min = i;
  662. }
  663. }
  664.  
  665. float ilosc_p = 0;
  666. if (indeks_min > -1)
  667. ilosc_p = WyslaniePrzekazu(CudzeObiekty[indeks_min]->iID, PALIWO, 10);
  668.  
  669. if (ilosc_p == 0)
  670. MessageBox(okno,"Paliwa nie dało się przekazać, bo być może najbliższy obiekt ruchomy znajduje się zbyt daleko.",
  671. "Nie dało się przekazać paliwa!",MB_OK);
  672. break;
  673. }
  674. case 'G': // przekazanie 100 jednostek gotowki pojazdowi, który znajduje się najbliżej
  675. {
  676. float min_odleglosc = 1e10;
  677. int indeks_min = -1;
  678. for (int i=0;i<iLiczbaCudzychOb;i++)
  679. {
  680. if (min_odleglosc > (CudzeObiekty[i]->wPol - pMojObiekt->wPol).dlugosc() )
  681. {
  682. min_odleglosc = (CudzeObiekty[i]->wPol - pMojObiekt->wPol).dlugosc();
  683. indeks_min = i;
  684. }
  685. }
  686.  
  687. float ilosc_p = 0;
  688. if (indeks_min > -1)
  689. ilosc_p = WyslaniePrzekazu(CudzeObiekty[indeks_min]->iID, GOTOWKA, 100);
  690.  
  691. if (ilosc_p == 0)
  692. MessageBox(okno,"Gotówki nie dało się przekazać, bo być może najbliższy obiekt ruchomy znajduje się zbyt daleko.",
  693. "Nie dało się przekazać gotówki!",MB_OK);
  694. break;
  695. }
  696. } // switch po klawiszach
  697.  
  698. break;
  699. }
  700. case WM_KEYUP:
  701. {
  702. switch (LOWORD(wParam))
  703. {
  704. case VK_SHIFT:
  705. {
  706. SHIFTwcisniety = 0;
  707. break;
  708. }
  709. case VK_SPACE:
  710. {
  711. pMojObiekt->ham = 0.0;
  712. break;
  713. }
  714. case VK_UP:
  715. {
  716. pMojObiekt->F = 0.0;
  717.  
  718. break;
  719. }
  720. case VK_DOWN:
  721. {
  722. pMojObiekt->F = 0.0;
  723. break;
  724. }
  725. case VK_LEFT:
  726. {
  727. pMojObiekt->Fb = 0.00;
  728. pMojObiekt->alfa = 0;
  729. break;
  730. }
  731. case VK_RIGHT:
  732. {
  733. pMojObiekt->Fb = 0.00;
  734. pMojObiekt->alfa = 0;
  735. break;
  736. }
  737.  
  738. }
  739.  
  740. break;
  741. }
  742.  
  743. } // switch po komunikatach
  744. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement