Soft Interactiv Pentru Dezvoltarea Atentiei Si Aptitudinilor Intelectuale

Cuprins

Introducere 4

I.Notiuni introductive jocuri 4

II. Generalitati 6

2.1.Introducere in limbajul de programare C++ 6

2.2Imbunatatiri ale limbajului C introduse de C++ 10

III.Elemente folosite in dezvoltarea aplicatiei 10

3.1.Programarea orientata pe obiecte(OOP) 12

3.2..Interfata grafica WIN32 API 14

IV. Descrierea aplicatiei 20

4.1.Introducere 25

4.2.Structura aplicatiei 30

4.3.Simulare 35

Concluzii 40

Bibliografie 45

Introducere

Am ales aceasta tema de licenta deorece imi place

I.Notiuni introductive jocuri

Jocurile sunt aplicatii software destinate distractiei.Exista mai multe categorii de jocuri printre care:

-Strategie

-Actiune

-Actiune-aventura

-Aventura

-Simulatoare

-Alte categorii(Sport,Jocuri de carti,Puzzle si altele)

In ceea ce priveste mediul de rulare a acestea pot fi pentru calculator, pentru consola,telefoane mobile si alte suporturi electronice.

Termenul joc pentru calculator se refera la un joc care presupune interactiunea dintre jucator si un calculator personal ,unde monitorul este principalul mijloc de feedback,joc care foloseste ca dispozitiv de intrare fie un joystick,fie combinatia tastatura si mouse.

Termenul joc pentru consola se refera la un joc care se poate juca pe un sistem conceput special pentru acel tip de joc,unde acest sistem se poate conecta fie la un monitor fie la un televizor.

Aplicatiile pentru telefoanele mobile sunt aplicatii compatibile cu smartphone-urile,dispozitive digitale portabile,tablete ,calculatoare.

Istoria jocurilor video dateaza din anul 1952 cand A.S.Douglas si-a scris teza de doctorat la Universitatea Cambridge in legatura cu Interactiunea dintre Om si Calculator.Atunci,el a creat primul joc grafic pentru calculator,Tic-Tac-Toe. Jocul era programat pe un calculator EDSAC care avea ca display un Tub catodic.

Dupa 6 ani,William Higinbotham a creat Tennis for two(„Tenis in doi”)care se juca pe osciloscopul din Brookhaven National Laboratory.In 1962 Steve Russel a creat SpaceWar(„Razboi in spatiu”) considerat de multi a fii primul joc pentru calculator in adevaratul sens al cuvantului.Inspirati de creatia lui Steve Russel,Nolan Brushnell impreuna cu Ted Dabney au lansat in 1971 primul joc arcade ,Computer Space urmad ca imediat dupa un an sa lanseze jocul Pong,un simulator de tenis.Cei doi au creat in acelasi an compania Atari Computers .

Prima consola,The Odyssey(„Odisea”) a fost lansata in 1972 de catre Magnavox si creata de catre Ralph Baer.

In 1980 Atari a lansat primele 2 jocuri inregistrate cu drepturi de autor.

In 1983 a avut loc o mare prabusire a pietei jocurilor video datorata multor jocuri aparute pe piata,piata mutandu-se de la americani la japonezi.In timp ce aceasta prabusire a distrus industria jocurilor pentru console,piata jocurilor pentru calculator nu a fost afectata aproape deloc.

Au urmat noi generatii de console dominate de japonezi.Incercarile americanilor si europenilor la a patra generatie de console au fost un esec.Deabi la a sasea generatie de console o companie americana a lansat consolele Xbox si Play Station 2 care au avut un succes enorm.

In prezent s-a ajuns la a opta generatie,prin lansarea Play Station 4 si Xbox One.Tot acum a fost posibila vizionarea jocurilor 3D cu ajutorul consolei Nintendo 3DS.

II.Generalitati

2.1 Introducere in limbajul de programare C++

C++ este un limbaj de programare compilat,creat pentru a scrie soft intr-o varietate de domenii.Originile acestuia sunt direct legate de predecesorul sau si anume limbajul C.

Limbajul C a aparut in 1970 fiind dezvoltat de Brian Kerningham si Dennis Ritchie.Acesta a fost creat cu scopul rescrierii sistemului de operare Unix ,facandu-l disponibil pe toate platformele.Spre deosebire de alte limbaje de programare,C era un limbaj foarte flexibil permitand programarea atat la nivel inalt cat si la un nivel scazut.

Deoarece programele au devenit din ce in ce mai complexe,a fost nevoie de aparitia altor limbaje de programare,de aici pornind si ideea gruparii structurii de date dand nastere la notiunea de obiect sau clasa.

Bjarne Stroustroup a fost cel care a conceput in 1980 limbajul initial numit C with Classes(C cu Clase).

S-a inceput prin adaugarea conceptului de clasa care este caracteristica definitorie a limbajului C++,apoi au fost adaugate functiile virtuale,mostenirea multipla,sabloane(templateuri),exceptii.Standardizarea limbajului s-a facut in 1998,dar continuaindu-se dezvoltarea limbajului s-a ajuns la standardul C++ 14.

C++ a fost baza multor limbaje de programare,printre cele mai importante enumerandu-se Java si C#.

2.2Imbunatatiri ale limbajului C incluse in C++

2.2.1Transmiterea parametrilor

Parametrii,in c++,pot fi transmisi catre o functie in doua feluri:

-prin valoare

-prin referinta

In ceea ce priveste transmiterea parametrilor prin valoare,acest mecanism este implicit in C.

Prin parametrii referinta,C++ a eliminate artificiul din C si anume utilizarea parametrilor formali pointeri,cand dorim ca modificarile facute in interiorul functiei asupra parametrilor sa ramana si dupa revenirea din procedura.

Exemplu:

//Varianta in C

void functie(int *a,int *b)

{

int x=*a;

int y=*b;

}

…apel

int a=2,b=3;

functie(&a,&b);

//Varianta in C++

void functie(int&a,int&b)

{

int x=a;

int y=b;

}

..apel

int a=2,b=3;

functie(a,b);

De mentionat este ca transferul parametrilor prin referinta este util atunci cand parametrul are o dimensione foarte mare(class,struct)si crearea in stiva a unei copii are reduce viteza de executie si ar incarca stiva.

2.2.2Functii inline

Aceasta tehnica este foarte utila cand se folosesc multe functii de dimenstiuni foarte mici,apelul acestora consumand mult timp in comparatie cu timpul de executie al functiei propriu-zise.

In momentul apelarii functiei inline,compilatorul genereaza codul din aceasta functie in pozitia apelului,in loc sa genereze secventa de apel.

2.2.3Parametrii care au valori implicite

Exemplu:

void functie(int,int a=5);

void main()

{

functie(2);//In mod implicit,al doilea parametru este 5

}

2.2.4Supraincarcarea functiilor

Prin supraincarcarea functiilor se intelege existenta si folosirea mai multor functii cu acelasi nume.Cand se intalneste o astfel de functie,compilatorul selecteaza in functie de tipul si numarul argumentelor ce functie va fi apelata.

Exemplu:

void functie(int a)

{

cout<<a;

}

void functie(float a)

{

cout<<a;

}

void main()

{

float a=2.1

functie(2.1)//se apeleaza ce-a de-a doua functie deoarece parametrul este de tip float

}

2.2.5Alocarea dinamica folosind operatorii new si delete

Acesti operatorii sunt similari operatorilor malloc si free din C dar superiori.

Exemplu de apelare a operatorului new:

int *a;

a=new int //a este o variabila intreaga neinitializata

a=new int[5] //a este un vector de 5 elemente

a=new int(1) //a este o varibila intreaga initializata cu valoarea 1

Mai mult,operatorul new poate fi folosit si pentru alocarea dinamica a obiectelor.

In ceea ce priveste operatorul delete,acesta se foloseste pentru dezalocarea memoriei dinamice allocate.

2.2.6Operatorul de rezolutie

Operatorul de rezolutie permite accesul la un obiect sau variabila intr-o zona in care acesta nu este vizibil din cauza unei alte declaratii.

Exemplu:

int a=2;

void main()

{

int a=3;

scrie(a) //va afisa 3

scrie(::a) //va afisa 2,reprezentand variabila globala a accesata prin operatorul de rezolutie

}

III. Elemente folosite in dezvoltarea aplicatiei

3.1 Programare orientata pe obiecte(OOP)

Programarea orientata pe obiecte este o metoda foarte puternica de a rezolva problemele din lumea reala.

Conceptele programarii pe obiecte sunt urmatoarele:

-Clase

-Obiecte

-Incapsulare

-Abstractizare

-Polimorfism

-Mostenire

3.1.1Clase

O clasa reprezinta un tip de date definit de utilizator.Odata ce am definit o clasa,putem creea cate obiecte dorim,acestea reprezentand instante ale clasei respective.

In aceasta figura,Entitate reprezinta o clasa ,iar Persoana este o instanta a clasei Entitate.

Prin definirea unei clase se specifica urmatoarele:

-numele clasei

-membrii clasei(date si functii)

-clasele de baza din care clasa e derivate(daca exista)

In acest exemplu,forma clasei va fii:

class Entitate

{

//membrii(funcii sau date)

//date

char nume;

int varsta;

int inaltime;

//functii

void afiseaza_nume();

void afiseaza_varsta();

void afiseaza_inaltime();

};Persoana

Optional,exista si etichete de permisiune(public,private,protected)astfel:

-public:membrii clasei sunt accesibili de oriunde clasa este vizibila

-private:membrii clasei sunt accesibili doar de membrii aceleiasi clase sau din clase prietene

-protected: membrii clasei sunt accesibili de membrii aceleiasi clase sau din clase prietene dar si de membrii din clasele derivate

-Membrii statici ai unei clase

Cand definim un membru static al unei clase,insteamna ca indiferent de cate obiecte ale clasei respective sunt create,exista doar o singura copie a membrului static.

Toate datele de tip static,sunt initializate cu 0 cand primul obiect este creat,daca nu exista alta initializare.Devreme ce membrii static nu se pot initializa in definitia clasei,vom initializa membrii static in afara clasei folosind operatorul de rezolutie :: ca in urmatorul exemplu.

class cutie

{

public:

static int numar;

cutie()

{

numar++;

}

};

int cutie::numar=0;

void main()

{

cutie();

cutie();

cout<<”nr obiecte”<<cutie::numar;//va afisa 2 si nu 1 deoarece numar este o variabila statica
}

-Clase si functii friend

Functiile prietene sunt functii care pot folosii membrii private ai unei clase,cu toate ca ele nu fac parte din clasa respectiva.

Functiile prietene se declasa ca o functie normala doar ca inainte functiei au specificatorul friend.

-Supraincarcarea operatorilor

Prin supraincarcarea operatorilor se permite atribuirea de noi semnificatii operatorilor uzuali.De exemplu,putem folosi operatorul + si la adunarea a doua numere,si la alipirea a doua siruri,adunare de matrici etc.

Exemplu de supraincarcarea operatorului +

class Vector

{

public:

int x,y;

Vector()

{

x=0;

y=0;

}

Vector(int a,int b)

{

x=a;

y=b;

}

Vector operator +(Vector &rhs)

{

Vector rezultat;

rezultat.x=x+rhs.x;

rezultat.z=y+rhs.y;

return rezultat;

}

};

void main()

{

Vector x(1,2);

Vector y(2,3);

Vector suma=x+y;
}

In acest exemplu ,am supraincarcat operatorul +.

-Constructori si destructori

Constructorii sunt functii special folosite care se apeleaza automat la crearea obiectelor.Scopul acestora este de a initializa variabile

Destructorii sunt tot niste functii special care se apeleaza la distrugerea obiectelor si sunt folositi pentru dezalocarea memoriei.

3.1.2Obiecte

Un obiect reprezinta abstractizarea unei entitati din lumea reala.Acesta contine data si functionalitate.

Poate reprezenta orice informatie care poate fi modelata.

In exemplul anterior,Persoana este un obiect al clasei Entitate.

3.1.3.Mostenirea.Clasele derivate

Mostenirea este atunci cand mai multe clase impartasesc aceeasi structura si comportament.

Clasa care mosteneste o clasa de baza poarta numele de clasa derivate.

Un obiect mostenit contine toate informatiile obiectului sau obiectelor de la care a mostenit.

Totusi este posibil daca se vrea sa se redefineasca implementarea anumitor functii mostenite.

Exista mai multe tipuri de mostenire,cele mai folosite fiind mostenirea simpla (clasa derivata mosteneste o singura clasa parinte)si cea multipla(clasa derivata mosteneste mai multe clase parinte).

Exemplu:

class Figura

{

public:

void setare_lungime(int l);

{

lungime=l;

}

private:

int lungime:

};

class Patrat:public Figura

{

public:

int afiseaza_arie(){return lungime*lungime};

};

void main()

{

Figura patrat;

patrat.setare_lungime(3);

patrat.afiseaza_arie();

}

Va afisa aria patratului si anume 9.

3.1.4Abstractizarea

Abstractizarea reprezinta gruparea datelor si a metodelor de prelucrare specifice rezolvarii unei probleme.

typedef struct

{

int varsta;

int greutate;

}Animal;

Animal reprezinta un tip de date abstract.

Pentru instantierea tipului abstract Animal vom scrie:

Animal tigru={”20”,”400”};

3.1.5Incapsularea

Incapsularea este mecanismul care leaga impreuna functiile cu membrii clasei.Acest concept defineste apartenenta unor metode si propietati fata de un obiect.Principiul incapsularii consta in a ascunde informariile specifice clasei respective de codul care va folosii aceasta clasa,expunand doar esentialul.

De ce sa folosim incapsulare?

Sa presupune ca avem doua clase A ai B.Daca un membru al clasei A este folosit de clasa B si clasa A isi modifica comportamenul,poate creea incompatibiliate cu codul clasei B.

Pentru a incapsula complet o clasa,toti membrii clasei trebuie sa fie privati.

Pentru un design de calitate,trebuie tinut cont de ce informatii sa fie accesibile si care sa fie complet ascunse.

Voi exemplifica principiul de incapsulare prin urmatorul exemplu:

-clasa care nu este incapsulata

class Femeie

{

public:

void danseaza();

char nume;

};

-clasa incapsulata

class Femeie

{

public:

void danseaza();

void denumire(char nume){m_nume=nume;}

private:

char m_nume;

};

3.1.6Polimorfism

Polimorfismul presupune o singura interfata dar mai multe implementari.De exemplu putem avea functia scade().Daca facem aceasta functie o interfata sa faca scaderea a doua numere intregi va returna diferenta celor 2 numere de tip intreg.Daca introducem doua numere reale,va returna o diferenta de tip real.Asadar ,polimorfismul ne ajuta sa accesam diferite implementari ale unei functii folosind acelasi nume.

3.2 Interfata grafica WIN32 API

Interfata grafica Windows Api este creata programarii aplicatiilor pentru sistemul de operare Windows.

Aceasta interfata grafica este destinata in primul rand programarii in limbajul C datorita functiilor si structurilor detaliate in C.

Desi limbajul C nu are nici o notiune de programare orientata pe obiecte ,interfata Windows Api precum si sistemul Windows au fost deseori descrise ca orientate pe obiect.

Functiile oferite de Windows Api sunt:

-Servicii de baza

Acestea permit accesul la resursele importante ale sistemului de operare.

-Servicii avansate

Permit lucrul cu registrii din Windows,stingerea-aprinderea sistemului de operare,exploatarea conturilor de utilizator.

-Interfata grafica

Aceasta interfata permite afisarea continutului grafic catre monitor,printere si alte dispozitive de iesire.

-Interfata utilizatorului

Permite crearea si exploatarea ecranului,a elementelor de baza precum butoane si scrollbaruri,permite primirea inputului mouse-ului si al tastaturii.

-Libraria de control

Permite accesul la anumite functii precum toolbarurile,taburile,barele de status.

-Libraria casutei de dialog

Este utila la afisarea casutelor de dialog in deschiderea fisierelor,inchiderea acestora,alegerea fontului,culorilor.

-Servicii pentru internet

Permit accesul la internet

-Elemente multimedia

Microsoft a oferit accesul la Directx inca din anul 1995.Acesta intefata grafica este folosita la jocuri si include:

-Direct 2D(pentru grafica 2D)

-Direct 3D(pentru grafica 3D)

-DirectSound(pentru accesul la placa de sunet)

-DirectPlay(este o librarie de comunicatie creata in special pentru jocurile video)

-DirectInput(pentru comunicatia cu dispozitivele de intrare)

IV.Descrierea aplicatiei

4.1Introducere

Jocul creat este un remake al jocului Flappy Bird,un joc in care utilizatorul trebuie sa controleze o pasare,incercand sa treaca prin niste tuburi(stationare sau mobile) fara sa le atinga.

Defiecare data cand se apasa space,pasarea sare,iar atunci cand nu se apasa, aceasta cade datorita gravitatiei.

Scorul se calculeaza ca fiind numarul de tuburi trecute (neincluzant tubuzile distruse).

Jucatorul are la dispozitie o serie de abilitati pe care le primeste cand a trecut un anumit numar de tuburi.

Daca acesta considera ca jocul este prea dificil,se poate regla dificultate din meniu.

In continuare voi prezenta cum am creat acest joc,respectiv principalele functii din el.

4.2 Structura aplicatiei

Jocul a fost creat in limbajul de programare C++ ,folosind interfata grafica Windows Api(interfata grafica destinata programarii in Windows).

Ca ofice joc,acesta contine niste gamestate-uri(stari) astfel:

-Gameplay state(starea cand efectiv interactionam cu mediul).

-Menu state(starea cand ne aflam in meniul jocului)

-Submenu state(starea cand ne aflam in submeniu)

-Gameover state(starea cand jocul s-a terminat)

-Alte stari

Fiind un joc dificil,am dat ocazia utilizatorului sa-si aleaga din 3 dificultati astfel:Easy(dificultate usoara),Normal(dificultate normala)si Hard(dificultate grea).

Ca orice joc ,contine o bucla infinita unde, in principal se executa urmatoarele 3 actiuni:

-ProcessInput(Procesare intrari),pentru detectare inputului.

-Update(Actualizare),unde se executa logica jocului

-Draw(Desenare),unde se randeaza imaginile pe ecran

Pentru cea mai buna performanta,ordinea de apelare a acestor functii este exact in aceasta ordine.

In continuare voi prezenta pe scurt fiecare dintre aceste 3 functii importante din orice joc,in cazul jocului meu.

ProcessInput(Procesare intrari)

Aceasta functie dupa cum sugereaza numele este folosita pentru detectarea si manipularea intrarilor(mouse,tastatura etc).

Aceasta functie va testa daca s-a apasat o anumita tasta sau un anumit click, daca ne aflam deasupra unui meniu anume(pentru a putea selecta ce dorim),si daca s-a selectat un meniu anume.

Practic detecteaza inputul mouse-ului si al tastaturii.

Update(Actualizare)

In aceasta functie se executa practic logica jocului.

Aceasta contine la randul ei urmatoarele functii”

-UpdatePlayer(ActualizareJucator)

-UpdateTubes(ActualizareTuburi)

-CheckMechanics(VerificareMecanici)

-Update Projectiles(ActualizareProiectile)

Am ales ca toate functiile de actualizare sa contina un parametru dt(delta time),concept folosit de toti programatorii de jocuri,reprezinta timpul scurs de la ultima actualizare. Toate jocurile au nevoie de aceasta deoarece exista miscare,schimbare de pozitii,viteze etc care se schimba pentru realizarea animatiilor.

-UpdatePlayer (ActualizareJucator).

Pentru actualizarea jucatorului voi controla 3 elemente:pozitia acestuia,viteza acestuia si un element exterior si anume gravitatia .

In aceasta functie am actualizat jucatorul astfel:

-am creat un vector pentru acceleratia gravitationala,deoarece dupa cum am spus

la inceput ,la apasarea butonului space pasarea se ridica ,dupa care coboara din cauza gravitatiei.

-am modificat noua pozitie in functie de viteza curenta,acceleratia gravitationala si timpul scurs

-am modificat noua viteza in functie de acceleratia gravitationala si timpul scurs

Cu aceste 3 elemente pot actualiza jucatorul in orice moment de timp.

-UpdateTubes(ActualizareTuburi)

In ceea ce priveste tuburile,am modificat doar 1 singur element si anume viteza acestora.Deoarece ele sunt create dinainte dar nu se vad pe ecran,am modificat doar viteza cu care se indreapta spre jucator.

Pozitia acestora va depinde doar de viteza cu care se deplaseaza si de timpul scurs.

Dealtfel,toate elementele din joc pe care jucatorul nu le controleaza efectiv(precum tuburile,acestea miscandu-se cum le-am programat dar fara sa le controlez miscarea)vor avea actualizarea pozitiei in functie de viteza si timp(pozitia=viteza*dt).

In cadrul acestei functii,am parcurs toate tuburile din joc si pentru fiecare i-am actualizat noua viteza In functie de progresul jucatorului(cu cat jucatorul a avansat mai mult in joc) cu atat tuburile se deplaseaza mai repede sau au si alte miscari.

-CheckMechanics(VerificareMecanici)

In aceasta functie am programat mecanicile jocului si anume:

-PlayerTubeCollision(ColiziuneaJucatorTuburi)

-Score(Sistemul de punctaj)

-RefillAmmunition(ReincarcareAmunitie)

PlayerTubeCollision(ColiziuneaJucatorTuburi)

Am folosit aceasta functie pentru a detecta coliziunile din joc.

In cadrul functiei am realizat urmatoarele:

-Am parcurs toate tuburile

-Am testat pentru fiecare tub daca a avut loc coliziunea acestuia cu pasarea

-Daca a avut loc o coliziune:

-starea jocului(a se vedea la inceput starile jocului)se schimba in starea Gameverstate(JocSfarsit).

-se pune pauza

-se reda un sunet pentru a evidentia coliziunea

Pentru a detecta coliziunea,se apeleaza o alta functie universala pentru coliziuni care functioneaza astfel:

-Functia primeste doi parametrii,reprezentand doua obiecte.

-Se salveaza cele 8 pozitii(4 pentru fiecare obiect)in felul urmator:

-Salvam partea din stanga a primului obiect (coordonatele din stanga de tot ale obiectului) ca fiind pozitia curenta(am ales pentru toate obiectele ca pozitia curenta sa fie exact in mijlocul obiectului)minus latimea obiectului impartita la 2.

-Salvam partea din dreapta a primului obiect(coordonatele din dreapta de tot ale obiectului) ca fiind pozitia curenta plus latimea obiectului impartita la 2.

-Salvam partea de sus a primului obiect(coordonatele de sus de tot ale obiectului) ca fiind pozitia curenta minus inaltimea obiectului impartita la 2.

-Salvam partea de jos a primului obiect(coordonatele de jos de tot ale obiectului) ca fiind pozitia curenta plus inaltimea obiectului impartita la 2.

Am procedat similar pentru cel de-al doilea obiect.

Avand toate aceste 8 pozitii,am calculat coliziunea in felul urmator:

-Am testat daca partea din stanga a primului obiect se suprapune peste partea din dreapta a celui de-al doilea obiect

-Am testat daca partea din dreapta a celui de-al doilea obiecte se suprapune cu partea din stanga a primului obiect

-Am testat daca partea de jos a primului obiect se suprapune cu partea de sus a celui le-al doilea obiect

-Am testat daca partea de sus a celui de-al doilea obiect se suprapune cu partea de jos a primului obiect

Daca sunt respectate toate aceste patru regului inseamna ca a avut loc o coliziune intre cele doua obiecte,deoarece coordonatele acestora se suprapun.

-Score(Sistemul de punctaj)

Sistemul de punctaj este foarte simplu.

-Se parcurg toate tuburile

-Se testeaza pentru fiecare tub daca pozita pe axa orizontala a pasarii este mai mare ca pozitia tubului si nu s-a mai trecut prin acel loc,atunci scorul se mareste si se salveaza numarul de obiecte depasite pentru a stii cat s-a facut scorul(un tub trecut inseamna 1 punct).

-RefillAmmunition(ReincarcareAmunitie)

Am introdus aceasta functie deoarece am creat un sistem prin care jucatorul are la dispozitie un anumit numar de abilitati (in acez caz dispune de “amunitie”)pe care le primeste pe masura ce avanseaza in joc.

Am stabilit ca dupa cate 10 tuburi depasite,jucatorul sa primeasca o ablilitate.

-Update Projectiles(ActualizareProiectile)

Functia lucreaza in felul urmator:

-Pentru fiecare tub am verificat daca a avut loc coliziune cu “amunitia”,daca da atunci am eliminat tubul si amunitia.Daca nu se trece mai departe

-Avand o alta subfunctie care “lanseaza”aminitia si in care am specificat viteza acesteia si pozitia la lansare,am actualizat noua pozitie dupa formula pozitia=viteza*timp.

Cea de-a treia functie importanta in orice joc dupa cum am mai spus este functia Draw(Desenare sau Randare).

Pentru un design mai frumos si o refolosire mai usoara a codului,am grupat mai multe tipuri de desenari astfel:

-DrawGameplayState

Aici am desenat toate elementele din timpul jocului(caractere,fundal,mediu etc).

Mai specific,am desenat tuburile,pasarea,fundalul,proiectilele,scorul.

-DrawMenustate

Aici am desene doar meniul

-DrawSubmenustate

Aici am desenat doar submmeniurile

-DrawGameoverstate

Aici am desemat elementele ce apar in momentul in care jocul se terminat(mesaje de final,imagini).

-DrawDifficultymenustate

In aceasta zona am desenat cele trei butoane cu dificultatile(easy,normal,hard).

Dupa cum sugereaza si numele,am ales sa randez pe ecran imaginile in functie de starea actuala in care ne aflam(in meniu,in joc efectiv,submeniuri.final etc).

Pe langa aceste trei functii de le-am discutat(ProcessInput,Update si Draw) am folosit in constructorul jocului functii pentru crearea obiectelor si pentru initializarea variabilelor astfel:

In functia Init(Initializare) am initializat toate variabilele necesare precum:

-variabile pentru a stii daca jocul a fost pus pe “pauza”

-variabile necesare in detectare mouse-ului(sa stim daca s-a apasat mouse-ul,daca s-a eliberat clickul,sa stim ultima oara cand s-a apasat)

-un vector in care am salvat scorurile

-un timer necesar pentru a reda anumite sunete cand doresc eu

-numarul de proiectile disponibile

-coordonatele ecranului pentru a stii daca am deposit ecranul

-distanta dintre tuburi

-numarul de tuburi peste care am trecut

Tot in constructorul jocului,am apelat functie BuildObjects(CreareObiecte)care contine:

-fundalul

-tuburile

-pasarea

-butoanele(meniurile)

In ceea ce priveste butoanele,acestea au 3 stari pentru a evidentia cand s-a apasat,cand se tine deasupra unui buton sau cand s-a eliberat butonul.

In ceea ce priveste tubutile aceastea le-am pus unu peste altul,distata dintre ele pe axa verticala fiind legata de dificultatea aleasa(cu cat dificultatea este mai mare ,cu atat distanta dintre ele este mai mica).

Am pornit de la o pozitie aleasa.In functie de acea pozitie am creat tuburi la distante egale intre ele pe axa orizontala plasate aleatoriu.

De exemplu primul tub l-am plasat la pozitiile 400 pe axa orizontala.

Urmatorul l-am creat la o pozitie aleatoare dar cuprinsa intre anumite coordinate astfel:

pozitie_verticala=-150+rand()%(100+150)

Aceasta expresie imi plaseaza tubul la coordinate cuprinse intre -150 si 99

Generic:

a+rand()%(b+1-a) genereaza un numar aleator cuprins intre a si b.

Ca orice aplicatie continand clase,am creat un destructor pentru a elibera memoria.

Deoarece am dat posibilitatea jucatorului sa puna pauza in timpul jocului,am creat 2 functii:

pause(pauza),pentru a pune pauza

unpause(reluare),pentru a continua jocul

Functia pause(pauza) pentru a pune pauza am realizat-o astfel:

-Am testat daca ma aflu in joc(daca nu ma aflu in joc nu am practic la ce sa pun pauza).Daca da,variabila care tine cont daca s-a pus pauza se face true,se afiseaza cursorul si se schimba starea jocului in meniustate(submeniu))

-Daca starea jocului este diferita de gameplaystate(starea cand efectiv ma aflu in joc ,nu in meniu sau altundeva), variabila care tine cont daca s-a pus pauza se face true,se afiseaza cursorul dar starea ramane aceeasi.

Am facut aceasta deoarece cand jocul s-a terminat de exemplu,as vrea automat sa se puna pe pauza.Dar punandu-l pe pauza ,automat m-ar trece in stare de submeniu ceea ce nu vreau.

In functia de unpause(continuare,reluare)am realizat urmatoarele:

Functia unpause am creat-o dupa principiul

-Daca nu ma aflu in meniu sau in stare de joc terminat,functia este valida,astfel variabila care tine cont de pauza se face false,cursorul se ascunde,si stare se schimba in gameplaystate(starea de joc)

Am gandit in acest fel deoarece nu vreau sa mi se dea voie sa reiau(sa continui de unde am ramas) jocul cand ma aflu in meniu(nu am ce relua in meniu evident) sau dupa ce jocul s-a terminat(trebuie inceput altul deci nu se mai poate continua jocul current).Vrea doar sa pot contina jocul cand efectiv ma interactionez cu jocul.

Ca orice joc,la inceput cand se incepe un joc nou trebuie sa resetez totul.Astfel am creat o functie ResetAllObjects(Resetaretoateobiectele) in care am apelat:

-functia de initializare

-am sters pasarea

-am creat din nou pasarea

-am ster tuburile

-am creat din nou tuburile

-am eliberat vectorul de proiectile

Similar Posts