This is an old revision of the document!


Tema 1 - Joc de dame

  • Responsabili: Maria-Anca Băluțoiu, Andrei Cristian Lambru, Andrei Lăpușteanu
  • Lansare: 25 noiembrie 2021
  • Termen de predare: 15 decembrie 2021, ora 23:55
  • Notă: Orice informație ce nu a fost acoperită în acest document este la latitudinea voastră!

În cadrul acestei teme va trebui să implementați un joc simplu de dame. Un demo ce înfățișează o posibilă implementare îl puteți viziona în continuare:

Logica jocului

Regulile pe care le aveți de implementat nu trebuie să acopere toate mecanicile folosite în jocul real de dame, ci doar un subset de mișcări simple. Jocul începe într-o configurație prezentată în imaginea de mai jos.

Pentru simplitate, ambele seturi de piese vor fi controlate de către jucător (nu trebuie să implementați un algoritm pentru adversar). În fiecare tură, jucătorul poate deplasa o singură piesă. Scopul jocului este capturarea tuturor pieselor adversarului. Subsetul de mișcări pe care le aveți de implementat sunt:

  • Deplasarea normală (fără capturare): Piesele pot fi deplasate numai pe diagonală, în căsuțele adiacente (cele mai apropiate), atât timp cât respectivele căsuțe nu sunt ocupate de alte piese. Deplasarea se va realiza numai în față (către piesele adversarului), astfel încât nu vor exista mișcări valide pe diagonelele din spatele piesei.

  • Capturarea pieselor: Jucătorul poate captura piesele adversarului care sunt situate în căsuțele adiacente pe diagonalele din față (relativ la piesa selectată). Piesa jucătorului trebuie să sară peste piesa adversarului (deplasare 2 căsuțe pe diagonală), iar capturarea se poate realiza atât timp cât locația destinație nu este ocupată de altă piesă. În urma capturării piesei, aceasta dispare de pe tabla de joc.

Nu trebuie să implementați atacuri multiple sau alte reguli de joc pentru funcționalitățile obligatorii.

Mecanica pentru deplasarea pieselor

  • Selectarea pieselor de joc

Pentru a selecta o piesă de joc se va folosi butonul stânga de la mouse. Mai jos se vor descrie detaliile tehnice pentru a implementa această selecție. În momentul în care o piesă a fost selectată, aceasta primește un “highlight” realizat prin schimbarea culorii piesei. De asemenea, toate căsuțele disponibile pentru mutare vor fi marcate printr-un “highlight”, realizat tot prin colorare.

  • Deplasarea pieselor de joc

În momentul în care a fost selectată căsuța destinație (prin click-stânga), piesa se va deplasa pe o traiectorie definită de voi (de exemplu sinusoidală, vezi demo). Deplasarea se va realiza printr-o animație continuă. Atât timp cât piesa își desfășoară animația de mișcare, jucătorul nu va putea selecta/deplasa alte piese de pe tabla de joc.

Obiectele 3D

Obiectele pe care trebuie să le realizați sunt tabla de joc și piesele pentru fiecare adversar.

  • Generarea tablei de joc

Tabla de joc va avea un layout de 8×8 (64 de căsuțe). Va trebui să implementați un mecanism pentru selectarea și deplasarea pieselor folosind cursorul, așadar fiecare căsuța va fi realizată plecând de la un mesh de quad. Căsuțele vor fi colorate alternativ și translatate corespunzător configurației.

  • Generarea pieselor de joc. Suprafețe de rotație

Pentru generarea pieselor de joc se vor folosi cel puțin 3 suprafețe de rotație. Două exemple de astfel de suprafețe pot fi văzute în imaginea de mai jos. Acestea reprezintă geometria pieselor din demo. Cele 3 suprafețe de rotație care compun geometria obiectului sunt marcate prin culori diferite. Curba utilizată pentru obținerea suprafeței se află în stânga fiecărei imagini. Pentru a calcula pozițiile punctelor de control ale curbei bezier se pot folosi aplicații online, precum cea de aici: https://www.desmos.com/calculator/d1ofwre0fr.

Nu trebuie să fie create piesele din demo. Aveți libertate asupra geometriei finale a acestora. Singura observație este că fiecare piesă trebuie să conțină cel puțin 3 suprafețe de rotație.

Procesul de selecție a obiectelor din scenă

Se va asocia fiecărui obiect un ID unic, care va fi desenat pe ecran împreună cu informația de culoare, în canalul de alpha. Acest canal nu este în final vizibil, astfel că el va fi folosit doar ca sursă de informație. Pe lângă informația de culoare RGB din fiecare fragment, se va păstra în componenta alpha ID-ul asociat obiectului desenat:

	out_color.a = id / 255.0f; // id este o valoare intre 0 si 255.

Un exemplu de vizualizare a acestor ID-uri, sub forma de nuanțe de gri (vec3 (id / 255.0f, id / 255.0f, id / 255.0f)) poate fi cel de mai jos. ID-ul este alocat aleator pentru fiecare piesă și căsuță a tablei de joc.

Când se apasă butonul stânga de la mouse, se obține poziția mouse-ului pe ecran și se interoghează textura din framebuffer pentru a obține ID-ul obiectului din canalul de alpha:

	// x si y reprezinta pozitia mouse-ului pe ecran, in pixeli.
	unsigned char data[4];
 
	y = window->props.resolution.y - y;
 
	glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
 
	int id = data [3];

Pentru a se vedea ID-urile obiectelor, se va implementa, la apăsarea unei taste un proces de toggle între desenarea scenei și desenarea ID-urilor, similar cu imaginea de mai sus.

Reflexia tablei și a pieselor de joc

Mediul înconjurător va fi vizibil în scenă sub forma unui cubemap. Acesta se va reflecta pe suprafața tablei și a pieselor de joc. Pentru simplitate, reflexia se va realiza utilizând numai acest cubemap (nu trebuie să implementați reflexia dintre piese sau self-reflection).

Ca să aplicați atât culoarea piesei, cât să reușiți să mapați și reflexia mediului înconjurător pe suprafețele generate, puteți folosi funcția mix (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/mix.xhtml).

Pentru a se calcula reflexia pieselor de joc, este necesar să se calculeze în geometry shader poziția și normala în spațiul lume a fiecărui vertex de pe suprafața de rotație. Pentru a se calcula normala unui vertex se va folosi vectorul perpendicular pe triunghiul din care face parte vertexul:

	// pos1, pos2 si pos3 reprezinta pozitiile vertecsilor care formeaza un triunghi.
	vec3 v1 = normalize (pos2 - pos1);
	vec3 v2 = normalize (pos3 - pos1);
 
	vec3 normal = cross (v1, v2);

Sistem de particule

Capturarea unei piese va fi recompensată de un efect de “spulberare”. Pentru a obține acest efect, în momentul în care piesa adversarului dispare (la finalizarea animației de capturare), va trebui să implementați un sistem de particule care să emită din poziția piesei capturate și pe direcția normală la tabla de joc.

Notare (150p)

  • Mecanică selecție și deplasare piese (40p)
    • Selecția obiectelor (10p)
      • Highlight piesă selectată (5p)
      • Detecție și highlight căsuțe valide pentru mutare (5p)
    • Detecția la click stânga a unei mutări simple validă + animație piesă (15p)
    • Detecția la click stânga a unei mutări de capturare validă + animație piesă + dispariție piesă capturată (15p)
  • Obiecte (55p)
    • Tabla de joc (10p)
    • Piesele primului jucător, generare folosind suprafețe de rotație (20p)
    • Piesele celui de-al doilea jucător, generare folosind suprafețe de rotație (20p)
    • Cer (5p)
  • Detecția obiectului selectat (20p)
    • Scrierea și recuperarea corectă a ID-ului din pixel (10p)
    • Toggle afișare scenă/ID-uri obiecte (10p)
  • Reflexia (20p)
    • Tablei de joc (5p)
    • Pieselor de joc (15p)
  • Efect capturare piese (sistem de particule) (15p)

Bonusuri Posibile

  • Reguli de joc mai avansate
  • Logica de joc (AI) pentru adversar
  • Model de reflexie mai complex, de exemplu Screen Space Reflections (SSR)
  • Animația formei/texturii piesei (folosing shadere) căt timp este selectată.
  • Implementarea unui skydome în locul skybox-ului
  • Alte efecte de post-procesare, exemple: Depth of Field (DoF), Bloom, Screen Space Ambient Occlusion (SSAO)

Indicații Suplimentare

Tema va fi implementată în OpenGL și C++. Este indicat să folosiți framework-ul și Visual Studio.

Pentru implementarea temei, in folderul src/lab_m2 puteti crea un nou folder, de exemplu Tema1, cu fisierele Tema1.cpp si Tema1.h (pentru implementare POO, este indicat sa aveti si alte fisiere). Pentru a vedea fisierele nou create in Visual Studio in Solution Explorer, apasati click dreapta pe filtrul lab_m2 si selectati Add→New Filter. Dupa ce creati un nou filtru, de exemplu Tema1, dati click dreapta si selectati Add→Existing Item. Astfel adaugati toate fisierele din folderul nou creat. In fisierul lab_list.h trebuie adaugata si calea catre header-ul temei. De exemplu: #include “lab_m2/Tema1/Tema1.h”

Arhivarea proiectului

  • In mod normal arhiva trebuie sa contina toate resursele necesare compilarii si rularii
  • inainte de a face arhiva asigurati-va ca ati curatat proiectul Visual Studio:
    • click dreapta pe proiect in Solution ExplorerClean Solution
    • si stergeti folderul /build/.vs (daca nu il vedeti, este posibil sa fie ascuns)
  • SAU stergeti complet folderul /build
  • in cazul in care arhiva tot depaseste limita de 50MB (nu ar trebui), puteti sa stergeti si folderul /deps sau /assets intrucat se pot adauga la testare. Nu este recomandat sa faceti acest lucru intrucat ingreuneaza mult testarea in cazul in care versiunea curenta a librariilor/resurselor difera de versiunea utilizata la momentul scrierii temei.

spg/teme/2021/01.1637785864.txt.gz · Last modified: 2021/11/24 22:31 by andrei.lambru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0