Advertisement
qtinio

cyber3

Apr 3rd, 2019
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.41 KB | None | 0 0
  1. /****************************************************
  2. Wirtualne zespoly robocze - przykladowy projekt w C++
  3. Do zadań dotyczących współpracy, ekstrapolacji i
  4. autonomicznych obiektów
  5. https://pastebin.com/LzWtyay5
  6. ****************************************************/
  7.  
  8. #include <windows.h>
  9. #include <math.h>
  10. #include <time.h>
  11. #include <string>
  12. #include <gl\gl.h>
  13. #include <gl\glu.h>
  14. #include <iterator>
  15. #include <map>
  16. using namespace std;
  17.  
  18. #include "objects.h"
  19. #include "graphics.h"
  20. #include "net.h"
  21.  
  22.  
  23. bool if_different_skills = true; // czy zró¿nicowanie umiejêtnoœci (dla ka¿dego pojazdu losowane s¹ umiejêtnoœci
  24. // zbierania gotówki i paliwa)
  25.  
  26. FILE *f = fopen("vct_log.txt", "w"); // plik do zapisu informacji testowych
  27.  
  28. MovableObject *my_vehicle; // Object przypisany do tej aplikacji
  29.  
  30. Terrain terrain;
  31. map<int, MovableObject*> network_vehicles;
  32. int tim = -1;
  33.  
  34. float fDt; // sredni czas pomiedzy dwoma kolejnymi cyklami symulacji i wyswietlania
  35. long VW_cycle_time, counter_of_simulations; // zmienne pomocnicze potrzebne do obliczania fDt
  36. long start_time = clock(); // czas od poczatku dzialania aplikacji
  37. long group_existing_time = clock(); // czas od pocz¹tku istnienia grupy roboczej (czas od uruchom. pierwszej aplikacji)
  38.  
  39. multicast_net *multi_reciv; // wsk do obiektu zajmujacego sie odbiorem komunikatow
  40. multicast_net *multi_send; // -||- wysylaniem komunikatow
  41.  
  42. HANDLE threadReciv; // uchwyt w¹tku odbioru komunikatów
  43. extern HWND main_window;
  44. CRITICAL_SECTION m_cs; // do synchronizacji wątków
  45.  
  46. bool SHIFT_pressed = 0;
  47. bool CTRL_pressed = 0;
  48. bool ALT_pressed = 0;
  49. bool L_pressed = 0;
  50. //bool rejestracja_uczestnikow = true; // rejestracja trwa do momentu wziêcia przedmiotu przez któregokolwiek uczestnika,
  51. // w przeciwnym razie trzeba by przesy³aæ ca³y state œrodowiska nowicjuszowi
  52.  
  53. // Parametry widoku:
  54. extern ViewParameters par_view;
  55.  
  56. bool mouse_control = 0; // sterowanie pojazdem za pomoc¹ myszki
  57. int cursor_x, cursor_y; // polo¿enie kursora myszki w chwili w³¹czenia sterowania
  58.  
  59. extern float TransferSending(int ID_receiver, int transfer_type, float transfer_value);
  60. // *********************************************
  61. int zaznaczony_id = -1;
  62. // ***********************************************
  63. enum frame_types {
  64. OBJECT_STATE, ITEM_TAKING, ITEM_RENEWAL, COLLISION, TRANSFER, ZAPRASZALAK, PRZYJAZNIALAK
  65. };
  66.  
  67. enum transfer_types { MONEY, FUEL};
  68.  
  69. struct Frame
  70. {
  71. int iID;
  72. int frame_type;
  73. ObjectState state;
  74.  
  75. int iID_receiver; // nr ID adresata wiadomoœci (pozostali uczestnicy powinni wiadomoœæ zignorowaæ)
  76.  
  77. int item_number; // nr przedmiotu, który zosta³ wziêty lub odzyskany
  78. Vector3 vdV_collision; // wektor prêdkoœci wyjœciowej po kolizji (uczestnik o wskazanym adresie powinien
  79. // przyj¹æ t¹ prêdkoœæ)
  80.  
  81. int transfer_type; // gotówka, paliwo
  82. float transfer_value; // iloœæ gotówki lub paliwa
  83. int team_number;
  84.  
  85. long existing_time; // czas jaki uplyn¹³ od uruchomienia programu
  86. };
  87.  
  88.  
  89. //******************************************
  90. // Funkcja obs³ugi w¹tku odbioru komunikatów
  91. DWORD WINAPI ReceiveThreadFunction(void *ptr)
  92. {
  93. multicast_net *pmt_net = (multicast_net*)ptr; // wskaŸnik do obiektu klasy multicast_net
  94. int size; // liczba bajtów ramki otrzymanej z sieci
  95. Frame frame;
  96. ObjectState state;
  97.  
  98. while (1)
  99. {
  100. size = pmt_net->reciv((char*)&frame, sizeof(Frame)); // oczekiwanie na nadejœcie ramki
  101. // Lock the Critical section
  102. EnterCriticalSection(&m_cs); // wejście na ścieżkę krytyczną - by inne wątki (np. główny) nie współdzielił
  103.  
  104. switch (frame.frame_type)
  105. {
  106. case OBJECT_STATE: // podstawowy typ ramki informuj¹cej o stanie obiektu
  107. {
  108. state = frame.state;
  109. //fprintf(f,"odebrano state iID = %d, ID dla mojego obiektu = %d\n",state.iID,my_vehicle->iID);
  110. if ((frame.iID != my_vehicle->iID)) // jeœli to nie mój w³asny Object
  111. {
  112.  
  113. if ((network_vehicles.size() == 0) || (network_vehicles[frame.iID] == NULL)) // nie ma jeszcze takiego obiektu w tablicy -> trzeba go stworzyæ
  114. {
  115. MovableObject *ob = new MovableObject(&terrain);
  116. ob->iID = frame.iID;
  117. network_vehicles[frame.iID] = ob;
  118. if (frame.existing_time > group_existing_time) group_existing_time = frame.existing_time;
  119. ob->ChangeState(state); // aktualizacja stanu obiektu obcego
  120. terrain.InsertObjectIntoSectors(ob);
  121. // wys³anie nowemu uczestnikowi informacji o wszystkich wziêtych przedmiotach:
  122. for (long i = 0; i < terrain.number_of_items; i++)
  123. if ((terrain.p[i].to_take == 0) && (terrain.p[i].if_taken_by_me))
  124. {
  125. Frame frame;
  126. frame.frame_type = ITEM_TAKING;
  127. frame.item_number = i;
  128. frame.state = my_vehicle->State();
  129. frame.iID = my_vehicle->iID;
  130. int iSIZE = multi_send->send((char*)&frame, sizeof(Frame));
  131. }
  132.  
  133. }
  134. else if ((network_vehicles.size() > 0) && (network_vehicles[frame.iID] != NULL))
  135. {
  136. terrain.DeleteObjectsFromSectors(network_vehicles[frame.iID]);
  137. network_vehicles[frame.iID]->ChangeState(state); // aktualizacja stanu obiektu obcego
  138. terrain.InsertObjectIntoSectors(network_vehicles[frame.iID]);
  139. }
  140.  
  141. }
  142. break;
  143. }
  144. case ITEM_TAKING: // frame informuj¹ca, ¿e ktoœ wzi¹³ przedmiot o podanym numerze
  145. {
  146. state = frame.state;
  147. if ((frame.item_number < terrain.number_of_items) && (frame.iID != my_vehicle->iID))
  148. {
  149. terrain.p[frame.item_number].to_take = 0;
  150. terrain.p[frame.item_number].if_taken_by_me = 0;
  151. }
  152. break;
  153. }
  154. case ITEM_RENEWAL: // frame informujaca, ¿e przedmiot wczeœniej wziêty pojawi³ siê znowu w tym samym miejscu
  155. {
  156. if (frame.item_number < terrain.number_of_items)
  157. terrain.p[frame.item_number].to_take = 1;
  158. break;
  159. }
  160. case COLLISION: // frame informuj¹ca o tym, ¿e Object uleg³ kolizji
  161. {
  162. if (frame.iID_receiver == my_vehicle->iID) // ID pojazdu, który uczestniczy³ w kolizji zgadza siê z moim ID
  163. {
  164. my_vehicle->vdV_collision = frame.vdV_collision; // przepisuje poprawkê w³asnej prêdkoœci
  165. my_vehicle->iID_collider = my_vehicle->iID; // ustawiam nr. kolidujacego jako w³asny na znak, ¿e powinienem poprawiæ prêdkoœæ
  166. }
  167. break;
  168. }
  169. case TRANSFER: // frame informuj¹ca o przelewie pieniê¿nym lub przekazaniu towaru
  170. {
  171. if (frame.iID_receiver == my_vehicle->iID) // ID pojazdu, ktory otrzymal przelew zgadza siê z moim ID
  172. {
  173. if (frame.transfer_type == MONEY)
  174. my_vehicle->state.money += frame.transfer_value;
  175. else if (frame.transfer_type == FUEL)
  176. my_vehicle->state.amount_of_fuel += frame.transfer_value;
  177.  
  178. // nale¿a³oby jeszcze przelew potwierdziæ (w UDP ramki mog¹ byæ gubione!)
  179. }
  180. break;
  181. }
  182.  
  183. case ZAPRASZALAK:
  184. {
  185. if (frame.iID_receiver == my_vehicle->iID) {
  186.  
  187. LPCSTR a;
  188. std::string s = std::to_string(frame.iID);
  189. a = (LPCSTR)s.c_str();
  190. LPCSTR b;
  191. std::string ss = "Zaproszenie";
  192. b = (LPCSTR)ss.c_str();
  193.  
  194. if (MessageBox(nullptr, a, b, MB_YESNO) == IDYES) // or IDNO, depending
  195. {
  196. tim = frame.iID;
  197. Frame frame;
  198. frame.frame_type = PRZYJAZNIALAK;
  199. frame.iID_receiver = tim;
  200. frame.transfer_type = 0;
  201. frame.transfer_value = 0;
  202. frame.iID = my_vehicle->iID;
  203. multi_send->send((char*)&frame, sizeof(Frame));
  204. }
  205.  
  206. }
  207. break;
  208. }
  209. case PRZYJAZNIALAK: {
  210. if (frame.iID_receiver == my_vehicle->iID) {
  211. tim = frame.iID;
  212. }
  213. }
  214. } // switch po typach ramek
  215. // Opuszczenie ścieżki krytycznej / Release the Critical section
  216. LeaveCriticalSection(&m_cs); // wyjście ze ścieżki krytycznej
  217. } // while(1)
  218. return 1;
  219. }
  220.  
  221. // *****************************************************************
  222. // **** Wszystko co trzeba zrobiæ podczas uruchamiania aplikacji
  223. // **** poza grafik¹
  224. void InteractionInitialisation()
  225. {
  226. DWORD dwThreadId;
  227.  
  228. my_vehicle = new MovableObject(&terrain); // tworzenie wlasnego obiektu
  229. if (if_different_skills == false)
  230. my_vehicle->planting_skills = my_vehicle->money_collection_skills = my_vehicle->fuel_collection_skills = 1.0;
  231.  
  232. VW_cycle_time = clock(); // pomiar aktualnego czasu
  233.  
  234. // obiekty sieciowe typu multicast (z podaniem adresu WZR oraz numeru portu)
  235. multi_reciv = new multicast_net("224.10.120.70", 10997); // Object do odbioru ramek sieciowych
  236. multi_send = new multicast_net("224.10.120.70", 10997); // Object do wysy³ania ramek
  237.  
  238. // uruchomienie watku obslugujacego odbior komunikatow
  239. threadReciv = CreateThread(
  240. NULL, // no security attributes
  241. 0, // use default stack size
  242. ReceiveThreadFunction, // thread function
  243. (void *)multi_reciv, // argument to thread function
  244. 0, // use default creation flags
  245. &dwThreadId); // returns the thread identifier
  246.  
  247. }
  248.  
  249.  
  250. // *****************************************************************
  251. // **** Wszystko co trzeba zrobiæ w ka¿dym cyklu dzia³ania
  252. // **** aplikacji poza grafik¹
  253. void VirtualWorldCycle()
  254. {
  255. counter_of_simulations++;
  256.  
  257. // obliczenie œredniego czasu pomiêdzy dwoma kolejnnymi symulacjami po to, by zachowaæ fizycznych
  258. if (counter_of_simulations % 50 == 0) // jeœli licznik cykli przekroczy³ pewn¹ wartoœæ, to
  259. { // nale¿y na nowo obliczyæ œredni czas cyklu fDt
  260. char text[200];
  261. long prev_time = VW_cycle_time;
  262. VW_cycle_time = clock();
  263. float fFps = (50 * CLOCKS_PER_SEC) / (float)(VW_cycle_time - prev_time);
  264. if (fFps != 0) fDt = 1.0 / fFps; else fDt = 1;
  265.  
  266. sprintf(par_view.inscription1, " %0.0f_fps, fuel = %0.2f, money = %d,", fFps, my_vehicle->state.amount_of_fuel, my_vehicle->state.money);
  267. if (counter_of_simulations % 500 == 0) sprintf(par_view.inscription2, "");
  268. }
  269.  
  270. terrain.DeleteObjectsFromSectors(my_vehicle);
  271. my_vehicle->Simulation(fDt); // symulacja w³asnego obiektu
  272. terrain.InsertObjectIntoSectors(my_vehicle);
  273.  
  274.  
  275. if ((my_vehicle->iID_collider > -1) && // wykryto kolizjê - wysy³am specjaln¹ ramkê, by poinformowaæ o tym drugiego uczestnika
  276. (my_vehicle->iID_collider != my_vehicle->iID)) // oczywiœcie wtedy, gdy nie chodzi o mój pojazd
  277. {
  278. Frame frame;
  279. frame.frame_type = COLLISION;
  280. frame.iID_receiver = my_vehicle->iID_collider;
  281. frame.vdV_collision = my_vehicle->vdV_collision;
  282. frame.iID = my_vehicle->iID;
  283. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  284.  
  285. char text[128];
  286. sprintf(par_view.inscription2, "Kolizja_z_obiektem_o_ID = %d", my_vehicle->iID_collider);
  287. //SetWindowText(main_window,text);
  288.  
  289. my_vehicle->iID_collider = -1;
  290. }
  291.  
  292. // wyslanie komunikatu o stanie obiektu przypisanego do aplikacji (my_vehicle):
  293.  
  294. Frame frame;
  295. frame.frame_type = OBJECT_STATE;
  296. frame.state = my_vehicle->State(); // state w³asnego obiektu
  297. frame.iID = my_vehicle->iID;
  298. frame.existing_time = clock() - start_time;
  299. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  300.  
  301.  
  302.  
  303. // wziêcie przedmiotu -> wysy³anie ramki
  304. if (my_vehicle->number_of_taking_item > -1)
  305. {
  306. Frame frame;
  307. frame.frame_type = ITEM_TAKING;
  308. frame.item_number = my_vehicle->number_of_taking_item;
  309. frame.state = my_vehicle->State();
  310. frame.iID = my_vehicle->iID;
  311. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  312.  
  313. sprintf(par_view.inscription2, "Wziecie_przedmiotu_o_wartosci_ %f", my_vehicle->taking_value);
  314.  
  315. my_vehicle->number_of_taking_item = -1;
  316. my_vehicle->taking_value = 0;
  317. }
  318.  
  319. // odnawianie siê przedmiotu -> wysy³anie ramki
  320. if (my_vehicle->number_of_renewed_item > -1)
  321. { // jeœli min¹³ pewnien okres czasu przedmiot mo¿e zostaæ przywrócony
  322. Frame frame;
  323. frame.frame_type = ITEM_RENEWAL;
  324. frame.item_number = my_vehicle->number_of_renewed_item;
  325. frame.iID = my_vehicle->iID;
  326. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  327.  
  328.  
  329. my_vehicle->number_of_renewed_item = -1;
  330. }
  331.  
  332. }
  333.  
  334. // *****************************************************************
  335. // **** Wszystko co trzeba zrobiæ podczas zamykania aplikacji
  336. // **** poza grafik¹
  337. void EndOfInteraction()
  338. {
  339. fprintf(f, "Koniec interakcji\n");
  340. fclose(f);
  341. }
  342.  
  343. // Funkcja wysylajaca ramke z przekazem, zwraca zrealizowan¹ wartoœæ przekazu
  344. float TransferSending(int ID_receiver, int transfer_type, float transfer_value)
  345. {
  346. Frame frame;
  347. frame.frame_type = TRANSFER;
  348. frame.iID_receiver = ID_receiver;
  349. frame.transfer_type = transfer_type;
  350. frame.transfer_value = transfer_value;
  351. frame.iID = my_vehicle->iID;
  352.  
  353. // tutaj nale¿a³oby uzyskaæ potwierdzenie przekazu zanim sumy zostan¹ odjête
  354. if (transfer_type == MONEY)
  355. {
  356. if (my_vehicle->state.money < transfer_value)
  357. frame.transfer_value = my_vehicle->state.money;
  358. my_vehicle->state.money -= frame.transfer_value;
  359. sprintf(par_view.inscription2, "Przelew_sumy_ %f _na_rzecz_ID_ %d", transfer_value, ID_receiver);
  360. }
  361. else if (transfer_type == FUEL)
  362. {
  363. if (my_vehicle->state.amount_of_fuel < transfer_value)
  364. frame.transfer_value = my_vehicle->state.amount_of_fuel;
  365. my_vehicle->state.amount_of_fuel -= frame.transfer_value;
  366. sprintf(par_view.inscription2, "Przekazanie_paliwa_w_ilosci_ %f _na_rzecz_ID_ %d", transfer_value, ID_receiver);
  367. }
  368.  
  369. if (frame.transfer_value > 0)
  370. int iRozmiar = multi_send->send((char*)&frame, sizeof(Frame));
  371.  
  372. return frame.transfer_value;
  373. }
  374.  
  375.  
  376.  
  377.  
  378.  
  379. //deklaracja funkcji obslugi okna
  380. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  381.  
  382.  
  383. HWND main_window; // uchwyt do okna aplikacji
  384. HDC g_context = NULL; // uchwyt kontekstu graficznego
  385.  
  386. bool terrain_edition_mode = 0;
  387.  
  388. //funkcja Main - dla Windows
  389. int WINAPI WinMain(HINSTANCE hInstance,
  390. HINSTANCE hPrevInstance,
  391. LPSTR lpCmdLine,
  392. int nCmdShow)
  393. {
  394. //Initilize the critical section:
  395. InitializeCriticalSection(&m_cs);
  396.  
  397. MSG system_message; //innymi slowy "komunikat"
  398. WNDCLASS window_class; //klasa głównego okna aplikacji
  399.  
  400. static char class_name[] = "Basic";
  401.  
  402. //Definiujemy klase głównego okna aplikacji
  403. //Okreslamy tu wlasciwosci okna, szczegoly wygladu oraz
  404. //adres funkcji przetwarzajacej komunikaty
  405. window_class.style = CS_HREDRAW | CS_VREDRAW;
  406. window_class.lpfnWndProc = WndProc; //adres funkcji realizującej przetwarzanie meldunków
  407. window_class.cbClsExtra = 0;
  408. window_class.cbWndExtra = 0;
  409. window_class.hInstance = hInstance; //identyfikator procesu przekazany przez MS Windows podczas uruchamiania programu
  410. window_class.hIcon = 0;
  411. window_class.hCursor = LoadCursor(0, IDC_ARROW);
  412. window_class.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
  413. window_class.lpszMenuName = "Menu";
  414. window_class.lpszClassName = class_name;
  415.  
  416. //teraz rejestrujemy klasę okna głównego
  417. RegisterClass(&window_class);
  418.  
  419. /*tworzymy main_window główne
  420. main_window będzie miało zmienne rozmiary, listwę z tytułem, menu systemowym
  421. i przyciskami do zwijania do ikony i rozwijania na cały ekran, po utworzeniu
  422. będzie widoczne na ekranie */
  423. main_window = CreateWindow(class_name, "WZR 2018/19, temat 3, wersja i ", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
  424. 100, 100, 1200, 800, NULL, NULL, hInstance, NULL);
  425.  
  426.  
  427. ShowWindow(main_window, nCmdShow);
  428.  
  429. //odswiezamy zawartosc okna
  430. UpdateWindow(main_window);
  431.  
  432.  
  433.  
  434. // GŁÓWNA PĘTLA PROGRAMU
  435.  
  436. // pobranie komunikatu z kolejki jeśli funkcja PeekMessage zwraca wartość inną niż FALSE,
  437. // w przeciwnym wypadku symulacja wirtualnego świata wraz z wizualizacją
  438. ZeroMemory(&system_message, sizeof(system_message));
  439. while (system_message.message != WM_QUIT)
  440. {
  441. if (PeekMessage(&system_message, NULL, 0U, 0U, PM_REMOVE))
  442. {
  443. TranslateMessage(&system_message);
  444. DispatchMessage(&system_message);
  445. }
  446. else
  447. {
  448. VirtualWorldCycle(); // Cykl wirtualnego świata
  449. InvalidateRect(main_window, NULL, FALSE);
  450. }
  451. }
  452.  
  453. return (int)system_message.wParam;
  454. }
  455.  
  456. // ************************************************************************
  457. // **** Obs³uga klawiszy s³u¿¹cych do sterowania obiektami lub
  458. // **** widokami
  459. void MessagesHandling(UINT message_type, WPARAM wParam, LPARAM lParam)
  460. {
  461.  
  462. int LCONTROL = GetKeyState(VK_LCONTROL);
  463. int RCONTROL = GetKeyState(VK_RCONTROL);
  464. int LALT = GetKeyState(VK_LMENU);
  465. int RALT = GetKeyState(VK_RMENU);
  466.  
  467.  
  468. switch (message_type)
  469. {
  470.  
  471. case WM_LBUTTONDOWN: //reakcja na lewy przycisk myszki
  472. {
  473. int x = LOWORD(lParam);
  474. int y = HIWORD(lParam);
  475. if (mouse_control)
  476. my_vehicle->F = my_vehicle->F_max; // si³a pchaj¹ca do przodu
  477.  
  478. break;
  479. }
  480. case WM_RBUTTONDOWN: //reakcja na prawy przycisk myszki
  481. {
  482. int x = LOWORD(lParam);
  483. int y = HIWORD(lParam);
  484. int LSHIFT = GetKeyState(VK_LSHIFT); // sprawdzenie czy lewy Shift wciśnięty, jeśli tak, to LSHIFT == 1
  485. int RSHIFT = GetKeyState(VK_RSHIFT);
  486.  
  487. if (mouse_control)
  488. my_vehicle->F = -my_vehicle->F_max / 2; // si³a pchaj¹ca do tylu
  489. else if (wParam & MK_SHIFT) // odznaczanie wszystkich obiektów
  490. {
  491. for (long i = 0; i < terrain.number_of_selected_items; i++)
  492. terrain.p[terrain.selected_items[i]].if_selected = 0;
  493. terrain.number_of_selected_items = 0;
  494. }
  495. else // zaznaczenie obiektów
  496. {
  497. RECT r;
  498. //GetWindowRect(main_window,&r);
  499. GetClientRect(main_window, &r);
  500. //Vector3 w = Cursor3dCoordinates(x, r.bottom - r.top - y);
  501. Vector3 w = terrain.Cursor3D_CoordinatesWithoutParallax(x, r.bottom - r.top - y);
  502.  
  503.  
  504. //float radius = (w - point_click).length();
  505. float min_dist = 1e10;
  506. long index_min = -1;
  507. bool if_movable_obj;
  508. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  509. {
  510. if (it->second)
  511. {
  512. MovableObject *ob = it->second;
  513. float xx, yy, zz;
  514. ScreenCoordinates(&xx, &yy, &zz, ob->state.vPos);
  515. yy = r.bottom - r.top - yy;
  516. float odl_kw = (xx - x)*(xx - x) + (yy - y)*(yy - y);
  517. if (min_dist > odl_kw)
  518. {
  519. min_dist = odl_kw;
  520. index_min = ob->iID;
  521. if_movable_obj = 1;
  522. }
  523. }
  524. }
  525.  
  526.  
  527. // trzeba to przerobić na wersję sektorową, gdyż przedmiotów może być dużo!
  528. // niestety nie jest to proste.
  529.  
  530. //Item **wsk_prz = NULL;
  531. //long liczba_prz_w_prom = terrain.ItemsInRadius(&wsk_prz, w,100);
  532.  
  533. for (long i = 0; i < terrain.number_of_items; i++)
  534. {
  535. float xx, yy, zz;
  536. Vector3 placement;
  537. if ((terrain.p[i].type == ITEM_EDGE) || (terrain.p[i].type == ITEM_WALL))
  538. {
  539. placement = (terrain.p[terrain.p[i].param_i[0]].vPos + terrain.p[terrain.p[i].param_i[1]].vPos) / 2;
  540. }
  541. else
  542. placement = terrain.p[i].vPos;
  543. ScreenCoordinates(&xx, &yy, &zz, placement);
  544. yy = r.bottom - r.top - yy;
  545. float odl_kw = (xx - x)*(xx - x) + (yy - y)*(yy - y);
  546. if (min_dist > odl_kw)
  547. {
  548. min_dist = odl_kw;
  549. index_min = i;
  550. if_movable_obj = 0;
  551. }
  552. }
  553.  
  554. if (index_min > -1)
  555. {
  556. //fprintf(f,"zaznaczono przedmiot %d pol = (%f, %f, %f)\n",ind_min,terrain.p[ind_min].vPos.x,terrain.p[ind_min].vPos.y,terrain.p[ind_min].vPos.z);
  557. //terrain.p[ind_min].if_selected = 1 - terrain.p[ind_min].if_selected;
  558. if (if_movable_obj)
  559. {
  560. network_vehicles[index_min]->if_selected = 1 - network_vehicles[index_min]->if_selected;
  561.  
  562. if (network_vehicles[index_min]->if_selected) {
  563. sprintf(par_view.inscription2, "zaznaczono_ obiekt_ID_%d", network_vehicles[index_min]->iID);
  564. zaznaczony_id = network_vehicles[index_min]->iID;
  565. }
  566. }
  567. else
  568. {
  569. terrain.SelectUnselectItemOrGroup(index_min);
  570. }
  571. //char lan[256];
  572. //sprintf(lan, "klikniêto w przedmiot %d pol = (%f, %f, %f)\n",ind_min,terrain.p[ind_min].vPos.x,terrain.p[ind_min].vPos.y,terrain.p[ind_min].vPos.z);
  573. //SetWindowText(main_window,lan);
  574. }
  575. Vector3 point_click = Cursor3dCoordinates(x, r.bottom - r.top - y);
  576.  
  577. }
  578.  
  579. break;
  580. }
  581. case WM_MBUTTONDOWN: //reakcja na œrodkowy przycisk myszki : uaktywnienie/dezaktywacja sterwania myszkowego
  582. {
  583. mouse_control = 1 - mouse_control;
  584. cursor_x = LOWORD(lParam);
  585. cursor_y = HIWORD(lParam);
  586. break;
  587. }
  588. case WM_LBUTTONUP: //reakcja na puszczenie lewego przycisku myszki
  589. {
  590. if (mouse_control)
  591. my_vehicle->F = 0.0; // si³a pchaj¹ca do przodu
  592. break;
  593. }
  594. case WM_RBUTTONUP: //reakcja na puszczenie lewy przycisk myszki
  595. {
  596. if (mouse_control)
  597. my_vehicle->F = 0.0; // si³a pchaj¹ca do przodu
  598. break;
  599. }
  600. case WM_MOUSEMOVE:
  601. {
  602. int x = LOWORD(lParam);
  603. int y = HIWORD(lParam);
  604. if (mouse_control)
  605. {
  606. float wheel_turn_angle = (float)(cursor_x - x) / 20;
  607. if (wheel_turn_angle > 45) wheel_turn_angle = 45;
  608. if (wheel_turn_angle < -45) wheel_turn_angle = -45;
  609. my_vehicle->state.wheel_turn_angle = PI*wheel_turn_angle / 180;
  610. }
  611. break;
  612. }
  613. case WM_MOUSEWHEEL: // ruch kó³kiem myszy -> przybli¿anie, oddalanie widoku
  614. {
  615. int zDelta = GET_WHEEL_DELTA_WPARAM(wParam); // dodatni do przodu, ujemny do ty³u
  616. //fprintf(f,"zDelta = %d\n",zDelta); // zwykle +-120, jak siê bardzo szybko zakrêci to czasmi wyjdzie +-240
  617. if (zDelta > 0){
  618. if (par_view.distance > 0.5) par_view.distance /= 1.2;
  619. else par_view.distance = 0;
  620. }
  621. else {
  622. if (par_view.distance > 0) par_view.distance *= 1.2;
  623. else par_view.distance = 0.5;
  624. }
  625.  
  626. break;
  627. }
  628. case WM_KEYDOWN:
  629. {
  630.  
  631. switch (LOWORD(wParam))
  632. {
  633. case VK_SHIFT:
  634. {
  635. SHIFT_pressed = 1;
  636. break;
  637. }
  638. case VK_CONTROL:
  639. {
  640. CTRL_pressed = 1;
  641. break;
  642. }
  643. case VK_MENU:
  644. {
  645. ALT_pressed = 1;
  646. break;
  647. }
  648.  
  649. case VK_SPACE:
  650. {
  651. my_vehicle->breaking_degree = 1.0; // stopieñ hamowania (reszta zale¿y od si³y docisku i wsp. tarcia)
  652. break; // 1.0 to maksymalny stopieñ (np. zablokowanie kó³)
  653. }
  654. case VK_UP:
  655. {
  656. if (CTRL_pressed && par_view.top_view)
  657. par_view.shift_to_bottom += par_view.distance / 2; // przesunięcie widoku z kamery w górę
  658. else
  659. my_vehicle->F = my_vehicle->F_max; // si³a pchaj¹ca do przodu
  660. break;
  661. }
  662. case VK_DOWN:
  663. {
  664. if (CTRL_pressed && par_view.top_view)
  665. par_view.shift_to_bottom -= par_view.distance / 2; // przesunięcie widoku z kamery w dół
  666. else
  667. my_vehicle->F = -my_vehicle->F_max / 2; // sila pchajaca do tylu
  668. break;
  669. }
  670. case VK_LEFT:
  671. {
  672. if (CTRL_pressed && par_view.top_view)
  673. par_view.shift_to_right += par_view.distance / 2;
  674. else
  675. {
  676. if (my_vehicle->steer_wheel_speed < 0) {
  677. my_vehicle->steer_wheel_speed = 0;
  678. my_vehicle->if_keep_steer_wheel = true;
  679. }
  680. else {
  681. if (SHIFT_pressed) my_vehicle->steer_wheel_speed = 0.5;
  682. else my_vehicle->steer_wheel_speed = 0.5 / 4;
  683. }
  684. }
  685.  
  686. break;
  687. }
  688. case VK_RIGHT:
  689. {
  690. if (CTRL_pressed && par_view.top_view)
  691. par_view.shift_to_right -= par_view.distance / 2;
  692. else
  693. {
  694. if (my_vehicle->steer_wheel_speed > 0) {
  695. my_vehicle->steer_wheel_speed = 0;
  696. my_vehicle->if_keep_steer_wheel = true;
  697. }
  698. else {
  699. if (SHIFT_pressed) my_vehicle->steer_wheel_speed = -0.5;
  700. else my_vehicle->steer_wheel_speed = -0.5 / 4;
  701. }
  702. }
  703. break;
  704. }
  705. case VK_HOME:
  706. {
  707. if (CTRL_pressed && par_view.top_view)
  708. par_view.shift_to_right = par_view.shift_to_bottom = 0;
  709.  
  710. break;
  711. }
  712. case 'W': // przybli¿enie widoku
  713. {
  714. //initial_camera_position = initial_camera_position - initial_camera_direction*0.3;
  715. if (par_view.distance > 0.5)par_view.distance /= 1.2;
  716. else par_view.distance = 0;
  717. break;
  718. }
  719. case 'S': // distance widoku
  720. {
  721. //initial_camera_position = initial_camera_position + initial_camera_direction*0.3;
  722. if (par_view.distance > 0) par_view.distance *= 1.2;
  723. else par_view.distance = 0.5;
  724. break;
  725. }
  726. case 'Q': // widok z góry
  727. {
  728. par_view.top_view = 1 - par_view.top_view;
  729. if (par_view.top_view)
  730. SetWindowText(main_window, "Włączono widok z góry!");
  731. else
  732. SetWindowText(main_window, "Wyłączono widok z góry.");
  733. break;
  734. }
  735. case 'E': // obrót kamery ku górze (wzglêdem lokalnej osi z)
  736. {
  737. par_view.cam_angle_z += PI * 5 / 180;
  738. break;
  739. }
  740. case 'D': // obrót kamery ku do³owi (wzglêdem lokalnej osi z)
  741. {
  742. par_view.cam_angle_z -= PI * 5 / 180;
  743. break;
  744. }
  745. case 'A': // w³¹czanie, wy³¹czanie trybu œledzenia obiektu
  746. {
  747. par_view.tracking = 1 - par_view.tracking;
  748. break;
  749. }
  750. case 'Z': // zoom - zmniejszenie k¹ta widzenia
  751. {
  752. par_view.zoom /= 1.1;
  753. RECT rc;
  754. GetClientRect(main_window, &rc);
  755. WindowSizeChange(rc.right - rc.left, rc.bottom - rc.top);
  756. break;
  757. }
  758. case 'X': // zoom - zwiêkszenie k¹ta widzenia
  759. {
  760. par_view.zoom *= 1.1;
  761. RECT rc;
  762. GetClientRect(main_window, &rc);
  763. WindowSizeChange(rc.right - rc.left, rc.bottom - rc.top);
  764. break;
  765. }
  766.  
  767. case 'F': // przekazanie 10 kg paliwa pojazdom zaznaczonym
  768. {
  769. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  770. {
  771. if (it->second)
  772. {
  773. MovableObject *ob = it->second;
  774. if (ob->if_selected)
  775. float ilosc_p = TransferSending(ob->iID, FUEL, 10);
  776. }
  777. }
  778. break;
  779. }
  780. case 'M':
  781. {// rozpoczęcie zaznaczania metodą maguw ognia
  782. if (zaznaczony_id != -1) {
  783. Frame frame;
  784. frame.frame_type = ZAPRASZALAK;
  785. frame.iID_receiver = zaznaczony_id;
  786. frame.transfer_type = 0;
  787. frame.transfer_value = 0;
  788. frame.iID = my_vehicle->iID;
  789. multi_send->send((char*)&frame, sizeof(Frame));
  790.  
  791. }
  792.  
  793. break;
  794. }
  795. case 'G': // przekazanie 100 jednostek gotowki pojazdom zaznaczonym
  796. {
  797. for (map<int, MovableObject*>::iterator it = network_vehicles.begin(); it != network_vehicles.end(); ++it)
  798. {
  799. if (it->second)
  800. {
  801. MovableObject *ob = it->second;
  802. if (ob->if_selected)
  803. float ilosc_p = TransferSending(ob->iID, MONEY, 100);
  804. }
  805. }
  806. break;
  807. }
  808.  
  809. case 'L': // rozpoczęcie zaznaczania metodą lasso
  810. L_pressed = true;
  811. break;
  812.  
  813.  
  814. } // switch po klawiszach
  815.  
  816.  
  817. break;
  818. }
  819.  
  820. case WM_KEYUP:
  821. {
  822. switch (LOWORD(wParam))
  823. {
  824. case VK_SHIFT:
  825. {
  826. SHIFT_pressed = 0;
  827. break;
  828. }
  829. case VK_CONTROL:
  830. {
  831. CTRL_pressed = 0;
  832. break;
  833. }
  834. case VK_MENU:
  835. {
  836. ALT_pressed = 0;
  837. break;
  838. }
  839. case 'L': // zakonczenie zaznaczania metodą lasso
  840. L_pressed = false;
  841. break;
  842. case VK_SPACE:
  843. {
  844. my_vehicle->breaking_degree = 0.0;
  845. break;
  846. }
  847. case VK_UP:
  848. {
  849. my_vehicle->F = 0.0;
  850.  
  851. break;
  852. }
  853. case VK_DOWN:
  854. {
  855. my_vehicle->F = 0.0;
  856. break;
  857. }
  858. case VK_LEFT:
  859. {
  860. if (my_vehicle->if_keep_steer_wheel) my_vehicle->steer_wheel_speed = -0.5 / 4;
  861. else my_vehicle->steer_wheel_speed = 0;
  862. my_vehicle->if_keep_steer_wheel = false;
  863. break;
  864. }
  865. case VK_RIGHT:
  866. {
  867. if (my_vehicle->if_keep_steer_wheel) my_vehicle->steer_wheel_speed = 0.5 / 4;
  868. else my_vehicle->steer_wheel_speed = 0;
  869. my_vehicle->if_keep_steer_wheel = false;
  870. break;
  871. }
  872.  
  873. }
  874.  
  875. break;
  876. }
  877.  
  878. } // switch po komunikatach
  879. }
  880.  
  881. /********************************************************************
  882. FUNKCJA OKNA realizujaca przetwarzanie meldunków kierowanych do okna aplikacji*/
  883. LRESULT CALLBACK WndProc(HWND main_window, UINT message_type, WPARAM wParam, LPARAM lParam)
  884. {
  885.  
  886. // PONIŻSZA INSTRUKCJA DEFINIUJE REAKCJE APLIKACJI NA POSZCZEGÓLNE MELDUNKI
  887.  
  888. MessagesHandling(message_type, wParam, lParam);
  889.  
  890. switch (message_type)
  891. {
  892. case WM_CREATE: //system_message wysyłany w momencie tworzenia okna
  893. {
  894.  
  895. g_context = GetDC(main_window);
  896.  
  897. srand((unsigned)time(NULL));
  898. int result = GraphicsInitialization(g_context);
  899. if (result == 0)
  900. {
  901. printf("nie udalo sie otworzyc okna graficznego\n");
  902. //exit(1);
  903. }
  904.  
  905. InteractionInitialisation();
  906.  
  907. SetTimer(main_window, 1, 10, NULL);
  908.  
  909. return 0;
  910. }
  911. case WM_KEYDOWN:
  912. {
  913. switch (LOWORD(wParam))
  914. {
  915. case VK_F1: // wywolanie systemu pomocy
  916. {
  917. char lan[1024], lan_bie[1024];
  918. //GetSystemDirectory(lan_sys,1024);
  919. GetCurrentDirectory(1024, lan_bie);
  920. strcpy(lan, "C:\\Program Files\\Internet Explorer\\iexplore ");
  921. strcat(lan, lan_bie);
  922. strcat(lan, "\\pomoc.htm");
  923. int wyni = WinExec(lan, SW_NORMAL);
  924. if (wyni < 32) // proba uruchominia pomocy nie powiodla sie
  925. {
  926. strcpy(lan, "C:\\Program Files\\Mozilla Firefox\\firefox ");
  927. strcat(lan, lan_bie);
  928. strcat(lan, "\\pomoc.htm");
  929. wyni = WinExec(lan, SW_NORMAL);
  930. if (wyni < 32)
  931. {
  932. char lan_win[1024];
  933. GetWindowsDirectory(lan_win, 1024);
  934. strcat(lan_win, "\\notepad pomoc.txt ");
  935. wyni = WinExec(lan_win, SW_NORMAL);
  936. }
  937. }
  938. break;
  939. }
  940. case VK_F4: // włączanie/ wyłączanie trybu edycji terrainu
  941. {
  942. terrain_edition_mode = 1 - terrain_edition_mode;
  943. if (terrain_edition_mode)
  944. SetWindowText(main_window, "TRYB EDYCJI TERENU F2-SaveMapToFile, F1-pomoc");
  945. else
  946. SetWindowText(main_window, "WYJSCIE Z TRYBU EDYCJI TERENU");
  947. break;
  948. }
  949. case VK_ESCAPE: // wyjście z programu
  950. {
  951. SendMessage(main_window, WM_DESTROY, 0, 0);
  952. break;
  953. }
  954. }
  955. return 0;
  956. }
  957.  
  958. case WM_PAINT:
  959. {
  960. PAINTSTRUCT paint;
  961. HDC context;
  962. context = BeginPaint(main_window, &paint);
  963.  
  964. DrawScene();
  965. SwapBuffers(context);
  966.  
  967. EndPaint(main_window, &paint);
  968.  
  969.  
  970.  
  971. return 0;
  972. }
  973.  
  974. case WM_TIMER:
  975.  
  976. return 0;
  977.  
  978. case WM_SIZE:
  979. {
  980. int cx = LOWORD(lParam);
  981. int cy = HIWORD(lParam);
  982.  
  983. WindowSizeChange(cx, cy);
  984.  
  985. return 0;
  986. }
  987.  
  988. case WM_DESTROY: //obowiązkowa obsługa meldunku o zamknięciu okna
  989. if (lParam == 100)
  990. MessageBox(main_window, "Jest zbyt późno na dołączenie do wirtualnego świata. Trzeba to zrobić zanim inni uczestnicy zmienią jego state.", "Zamknięcie programu", MB_OK);
  991.  
  992. EndOfInteraction();
  993. EndOfGraphics();
  994.  
  995. ReleaseDC(main_window, g_context);
  996. KillTimer(main_window, 1);
  997.  
  998. PostQuitMessage(0);
  999. return 0;
  1000.  
  1001. default: //standardowa obsługa pozostałych meldunków
  1002. return DefWindowProc(main_window, message_type, wParam, lParam);
  1003. }
  1004.  
  1005. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement