În cadrul temei 2, veți avea de implementat un joc similar cu World of Tanks, însă single player.
Jocul se desfășoară pe un plan orizontal ce conține tancuri și clădiri. Scopul jocului este ca tancul jucătorului să distrugă cât mai multe tancuri inamice într-un timp limită (cel puțin 1 minut). Pentru fiecare tanc distrus jucătorul primește puncte. Tancurile se deplasează înainte, înapoi și își pot roti corpul. Pentru a ținti după inamici turela tancului poate fi rotită (cerință avansată). Proiectilele sunt lansate din vârful tunului și se deplasează rectiliniu și uniform pentru o durată de timp până când lovesc clădiri sau tancuri. Fiecare tanc rezistă la un număr de minim 3 lovituri de proiectil. Cu cât sunt mai avariate tancurile cu atât vor fi desenate mai deformate și mai înnegrite. Odată scurs timpul de joc, scena va ingheța; doar rotația turelei și a tunului vor mai fi posibile.
Tancurile inamice se vor mișca pe hartă fie pe un traseu predefinit (cerință de bază) fie pe un traseu aleator (cerință avansată). Tancurile inamice își rotesc turela în direcția jucătorului în scopul de a trage proiectile înspre acesta.
Un tanc complet avariat este imobil.
Jocul se termină fie când limita de timp este atinsă, fie când tancul jucătorului este distrus. În cazul în care timpul a expirat, în consolă se va afișa scorul. Scorul acumulat se consideră doar dacă timpul de joc a expirat. Dacă tancul jucătorului este distrus, atunci se afișează în consolă un mesaj corespunzător.
Un tanc este format dintr-un corp, turelă, tun și șenile. Corpul este paralelipipedul cel mare. Atașat de corp este turela formată tot dintr-un paralelipiped. Turela este atașată de corp și se rotește stânga dreapta după metoda descrisă în capitolul Rotație Turelă Tanc. Atașat de turelă este un tun format dintr-un cilindru. Atașat de corp se găsesc două paralelipipede care reprezintă șenilele tancului. Tancul va fi desenat în 3 culori pentru a distinge elementele sale. Astfel corpul vor avea o culoare, turela altă culoare iar tunul și șenilele altă culoare. Tunul și șenilele au aceeași culoare.
O cerință avansată este ca tancul să aibă forme mai complexe. Aveți 2 exemple date în imaginile de mai sus. Puteți importa modele create prin programe software cât timp se păstrează separate componentele tancului (corpul, turela, tunul și șenilele). Aceste componente vor fi desenate cu aceleași culori ca în capitolul Tanc de bază.
Dacă rezolvați această cerință se consideră rezolvată și cerința cu tancul de bază.
Camera va fi poziționată în spatele tancului așa cum apare în figura de sus (camera este ilustrată cu piramida neagră). Mai exact, camera este atașată de corpul tancului la o anumită distanță și se uită înainte. Astfel camera se deplasează după cum se deplasează corpul tancului. Când corpul tancului se rotește camera va orbita în jurul corpului pentru a fi în continuare în spatele camerei. Vederea camerei este în figura de jos.
Mediul de joc este format dintr-o suprafață plană ce reprezintă pământul.
Pe suprafața de joc, vor fi amplasate aleator clădiri reprezentate prin paralelipipede aliniate cu axele. Cladirile se pot intersecta. Atunci când vor fi create tancul jucătorului și tancurile inamice acestea nu trebuie să se intersecteze cu clădirile. Clădirile vor fi colorate diferit de restul elementelor pentru a fi distinse.
Pentru a mișca tancul jucătorul controlează mișcarea relativ la poziția și rotația tancului (în loc de mișcare față de perspectiva camerei). Acest mod de control se numește “controluri de tanc”😄.
Astfel:
Vitezele de deplasare și rotație sunt la alegerea voastră.
Camera poate fi rotită folosind click dreapta și mișcând mouse-ul similar cu rotațiile third person din laboratorul 5. Atunci când nu este apăsat click dreapta mișcările mouse-ului vor conduce la rotația turelei descrisă în capitolul Rotație Turelă Tanc.
Turela se va roti stânga dreapta prin mișcarea mouse-ului în stânga și în dreapta. Rotația este în jurul centrului propriu al turelei pe planul local xoz.
Atenție! Poziția camerei nu se modifică când se rotește turela pentru că aceasta este atașată de corp.
Tancul trage cu proiectile atunci când utilizatorul dă click stânga. Proiectilele sunt sfere negre, încep din vârful tunului și au mișcare rectilinie și uniformă după cum este prezentat în animație. Direcția de deplasare este în direcția indicată de tunul tancului când s-a tras proiectilul. Proiectilul va fi șters atunci când se întâmplă cel puțin una dintre situații:
Viteza inițială a proiectilului și timpul de viață al proiectilului sunt la alegerea voastră. Fiecare tanc nu poate trage proiectile la un interval mai mic de 1 secundă.
Tancurile inamice vor avea alte culori decat cel al jucătorului.
Cerință de bază
Tancurile se vor mișca înainte și înapoi pe un traseu predefinit (de-a lungul unei linii, intr-un cerc etc).
Cerință avansată
Inamicii vor fi amplasati aleator pe harta (fie pe toata suprafata, fie într-o anumită zona de început - la libera alegere), si se vor plimba aleator.
Puteti face orice fel de miscare doriti, atat timp cat aceasta este naturală și continuă (inamicii nu se teleporteaza, nu se invart instantaneu etc)
Atunci cand jucătorul este destul de aproape de un inamic, turela inamicului se va învârti către jucător si va trage spre acesta.
Pentru coliziuni obiectele vor fi aproximate astfel:
Atunci cand o coliziune dintre un tanc și un proiectil este detectata, proiectilul va disparea si tancului ii se va scadea HP-ul.
Când 2 tancuri intră în coliziune, acestea vor fi deplasate astfel încât să nu mai fie în coliziune. Metoda de a calcula deplasarea necesară este următoarea:
Daca Distanta_Intre_Tancuri < Raza_Tanc_1 + Raza_Tanc_2, atunci acestea s-au ciocnit.
Si se suprapun cu o distanta egala cu |P| = ( Raza_Tanc_1 + Raza_Tanc_2 - Distanta_Intre_Tancuri )
pentru a evita suprapunerea lor, trebuie sa mutam tancurile în direcții opuse astfel încât distanța dintre acestea sa creasca cu |P|.
Directia in care trebuie sa le deplasam poate fi calculata astfel:
Dif = ( Centru_Tanc_2 - Centru_Tanc_1 ) P = |P| * glm::Normalize( Dif ) Centru_Tanc_1 += P * -0.5f; Centru_Tanc_2 += P * 0.5f;
Pentru coliziunea tanc clădire, va fi necesar un calcul similar cu cel prezentat la coliziunile tanc-tanc (calculat deplasamentul necesar unui tanc pentru a îl scoate din clădire).
Obiectele ce reprezintă tancurile inamice (cu sau fără turelă, la libera alegere) se vor deforma în funcție de gradul de avarie al fiecăruia (HP); acesta va fi trimis către vertex shader, acolo unde se va realiza deformarea.
Deformarea va fi o funcție matematică (la libera alegere) ce va primi gradul de avarie (un număr) și coordonatele locale ale unui vertex (un vector), si va calcula un deplasament (un vector) care va fi aplicat coordonatelor locale ale respectivului vertex (înainte de aplicarea matricilor MVP).
Operația va fi deterministă, adică pentru aceeași pereche <grad de avarie, coordonate locale vertex> se va calcula întotdeauna același deplasament. Motivul este de a evita fluctuații nenaturale de la un cadru la altul.
Obiectele ce reprezintă tancurile inamice (cu sau fără turelă, la libera alegere) își vor schimba culoarea în funcție de gradul de avarie al fiecăruia. Schimbarea culorii se va realiza în fragment shader.
Schimbarea culorii va fi o funcție matematică (la libera alegere) ce va primi gradul de avarie (un număr) și culoarea inițială (un vector), și va calcula culoarea nouă.
Operația va fi deterministă, adică pentru aceeași pereche <grad de avarie, culoare inițială> se va calcula întotdeauna același deplasament. Motivul este de a evita fluctuații nenaturale de la un cadru la altul.
Tunul se va roti pentru a ținti în sus și jos prin mișcarea mouse-ului în sus și jos. Rotația este în jurul pivotului indicat de figură pe planul local zoy sau xoy (depinde care direcție este considerată cea din față). Pivotul este punctul galben și planul de rotație este cel ce conține cercul roșu. În animație sunt prezentate cum lucrează cele două rotații pentru ca tancul să poată ținti oriunde.
Proiectilul va avea mișcare balistică după cum este prezentat în animație. Se aplică legea gravitației. Astfel viteza inițială a proiectilului este direcția tunului înmulțită cu o constantă. În fiecare cadru algoritmul următor descrie mișcarea proiectilului:
În acest caz proiectilul nu va mai fi șters după o perioadă de timp. În schimb proiectilul va fi șters atunci când ajunge sub planul pământului (pozitie.y < 0) Dacă se implementează mișcarea balistică se consideră rezolvată cerința de bază cu mișcarea rectilinie și uniformă.
Va exista un viewport aditional, așezat în unul din colțurile ferestrei, care va contine o proiecție ortografică a hărții, văzută de sus. Jucătorul se va menține centrat în mijlocul viewport-ului.
Pentru întrebări vom folosi forumurile de pe moodle. Orice nu este menționat în temă este la latitudinea fiecărui student!
Baremul este orientativ. Fiecare asistent are o anumită libertate în evaluarea temelor (de exemplu, să dea punctaj parțial pentru implementarea incompletă a unei funcționalități sau să scadă pentru hard coding). Același lucru este valabil atât pentru funcționalitățile obligatorii, cât și pentru bonusuri.
Tema va fi implementată în OpenGL și C++. Este indicat să folosiți framework-ul și Visual Studio.