Sunteți pe pagina 1din 46

UNIVERSITATEA DIN BACU FACULTATEA DE INGINERIE SPECIALIZAREA : TEHNOLOGIA INFORMAIEI

NDRUMAR DE PROIECT1

Proiect la Programare orientat pe obiecte


- Joc de (numele tipului jocului)

ndrumtor: Student:

2013

Coninutul referatului de proiect, Aceasta este prima fila din cadrul proiectului 3

Pe urmtoare fil se scrie Tema proiectului Anume cerinele minimale pentru ca aplicaia s se comporte ca fiind acel joc, anume S se realizeze o aplicaie software de tip joc care s aib urmtoarele specificaii de aspect i funcionalitate:. Apoi s se prezinte un istoric al jocului nsoit de exemple de jocuri similare, eventual un Print Screen al ferestrei de joc exemplu. S se realizeze o descriere funcional a jocului adic cine cu ce interacioneaz i n ce condiii. De exemplu: Comportament la ciocniri ntre diferite elemente ale jocului paleta, minge, blocuri, bombe, nave, proiectile, meteorii; n ce condiii se termin jocul; Cum arat nceputul jocului; Care sunt condiiile de ctigare a jocului sau de trecere la un nou nivel .a. Urmtorul subiect de tratat sunt mijloacele de realizare a jocului anume mediul de programare i proiectarea algoritmului jocului. Trebuie abordate urmtoarele subiecte: Structura pe clase i obiecte a jocului adic noiuni generale despre declararea claselor, specificatori de acces, motenire, constructor, destructor aplicate la structura specific a claselor prin care este construit jocul; Elemente de lucru cu pointeri pentru interconectarea claselor; Construcia i lucrul cu clase n mediul Visual C++ - adic cum se creeaz o clas generic, cum se adaug variabile i funcii membre; Cum se creeaz o aplicaie simpl, implicit SDI (Single Document Interface); Tratarea evenimentelor de sistem ce este un eveniment, ce este un mesaj generat de un eveniment, cum se creeaz n general n Visual C++ a funcie asociat unui mesaj; Mecanismul de temporizare s se descrie mesajul WM_TIMER, funcia asociat lui i funcia de specificare a unei temporizri SetTimer.; Mecanismul intrrilor de la tastatur s se descrie mesajele WM_CHAR, WM_KEYDOWN i WM_KEYUP, utilizarea lor i descrierea parametrilor funciilor asociate; Mecanismul intrrilor de la mouse s se descrie mesajele WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MOUSEMOVE, utilizarea lor i descrierea parametrilor funciilor asociate; Funciile grafice asociate dispozitivului de context CDC:

Primitive grafice, penie, pensule, fonturi Rectangle, Ellipse, LineTo, CPen, CBrush, CFont, TextOut i alte funcii folosite n cadrul proiectului pentru realizarea graficii de nivel de baz a jocului; Funcii pentru afiarea de bitmapuri, tehnici de animaie folosind bitmapuri (desenarea unui bitmap pe un fundal i excluderea fondului bitmapului afiat), eliminarea efectului de plpire a imaginii prin folosirea unui buffer de desenare pstrat ntr-un bitmap i a funciei InvalidateRect, ncrcarea unei resurse de tip bitmap;

Elemente de practic a programrii i algoritmic. Analiza fiecrui segment n parte al jocului cu exemple de cod prin care se realizeaz: Secvena de cod pentru calculul ciocnirilor; Secvena de cod pentru tratarea grafic a ciocnirilor de ex. explozii, dispariia navei, a proiectilului, sudarea pieselor de tetris de restul depus, dispariia rndurilor complete la tetris, dispariia blocurilor lovite de minge la tenis. Secvena de cod pentru iniializarea sau resetarea elementelor de joc; Secvena de cod pentru afiarea sfritului de joc, nceputului unui nou joc, sau mesajul de ctigare a jocului; Secvenele de cod pentru interfaarea cu utilizatorul a elementelor de joc; Secvenele de cod pentru desenarea fiecrui element de joc n parte. Algoritmi de realizare a unor elemente de funcionalitate a jocului descrii n cuvinte. Anex: Codul Jocului: Print screen al arborelui de clase, de resurse i de fiiere asociat jocului; Coninutul fiierelor C###View.h/.cpp Coninutul fiierelor n care se pstreaz clasele jocului - ###.h i ###.cpp.

Crearea unei aplicaii MFC - Single Document


1. Deschiderea meniului File
2. . Selectare New.

3. Selectarea tabului Projects i selectarea tabului - MFC AppWizard(.exe) - pentru crearea unei aplicaii MFC i generarea unui fiier executabil.

4. Scriem numele proiectului n caseta ncercuit cu rou.

5. Apsm OK dup scrierea numelui proiectului i alegem Single Document n urmtoarea


fereastr:

6. La urmtoarele ferestre apsm Next i la fereastra de la pasul 4 deselectm

7. La pasul 6 apsm Finish. Apare o fereastr care ne precizeaz c va fi creat structura schelet
a aplicaiei. Apsm butonul de OK.

8. Apare fereastra de gestionare a aplicaiei:

ncercuit cu rou n partea stng se afl arborii de gestionare a aplicaiei exist un arbore pentru gestionarea claselor (Clas View), un arbore pentru gestionarea resurselor (Resource View) i unul pentru gestionarea fiierelor (File View). Nodurile arborelui pot fi expandate prin apsarea csuei plus din dreptul fiecruia dintre ei. Prin apsarea csuei minus din dreptul unei ramuri expandate se produce contragerea ei. Adugarea de variabile noi unei clase Pentru a aduga variabile noi unei clase se face clic dreapta pe clasa respectiv i se allege opiunea Add Member Variable.

Apare fereastra de adugare a unei variabile la o clas: n caseta de sus se specific tipul. (n exemplul ales double)

n caseta de mijloc se specific numele variabilei ( xxx dat ca exemplu dar poate fi orice denumire valid). Jos se specific prin butoane radio tipul de acces la acea variabil. Cnd toate au fost stabilite trebuie apsat OK.

Se observ c variabila a fost adugat la clasa CZzzzzzView.(Sgeata roie). Adugarea unei funcii membre, adic metode se face tot prin clic dreapta pe numele clasei din arborele de clase. Se alege opiunea Add Member Function

Apare csua de dialog de precizare a funciei: Prima rubric este tipul returnat de funcie. A doua rubric este prototipul funciei adic numele i lista de parametri. Obs. Nu se pune ; dup funcie. Se alege tipul de acces i dac este alocat static sau virtual la apelare. i desigur dac toate opiunile sunt cele dorite se apas OK.

10

Se observ definiia funciei adugate le arborele clasei. Subliniat i indicat cu o sgeat roie. Pentru a aduga o funcie de tratare a unui mesaj se folosete opiunea Add Windows Message Handler .

11

n partea stnga se afl lista mesajelor Windows care sunt tratate de clasa respectiv. n partea dreapt se afl lista mesajelor adugate (WM_CREATE, WM_KEYDOWN, WM_TIMER). i se apas OK pentru confirmare.

n fereastra cu arborele clasei vor apare funciile asociate mesajelor. (OnCreate, OnKeyDown, OnTimer)

Adugarea unei clase generice. Pentru a crea i aduga o clasa generic, adic o clas care nu motenete nici o alt clas, se va folosi urmtoarea secven de pai. Avnd clasa de forma:

12

class Minge { double x,y; double vitezax,vitezay; double raz; void init(int x0, int y0); void desenare( ); } Vom proceda astfel: 1. Cream o aplicaie MFC single document. 2. Alegem din meniul Insert opiunea New Class pentru a insera o clas nou n arborele de clase.

3. Din lista expandabil alegem Generic Class, iar la caseta de editare scriem numele clasei Minge . Se va genera automat un fiier care va conine codul surs al clasei Minge minge.cpp i un fiier header care va conine declaraia clasei. Apsm butonul Change (Schimb) pentru a modifica numele acestor fiiere, dac dorim. Apsm OK pentru a crea clasa, care va fi o clas deocamdat fr coninut.

4. Se observ c s-a creat clasa minge clas care conine doar un constructor i un

13

Folosind mecanismul de adugare de date( variabile) membre i funcii membre crem clasa cu structura dorit. La final clasa va avea urmtoarea structur. Pentru a ajunge la locul de definire a funciei n fiierul surs facem un dublu-clic pe numele funciei din arborele clasei.

14

Crearea unei aplicaii simple interactive n Visual C++


Acest tutorial i propune iniiarea n folosirea mediului de programare Visual C++ 6.0. Dup parcurgerea lui se vor ti urmtoarele: cum se creaz o aplicaie simpl SDI; cum se deseneaz un dreptunghi n fereastr la coordonatele dorite; cum se adug variabile la o clas. cum se poate deplasa o figur cu mouse-ul, tastatura sau automat. Pentru nceput pentru a reea deschide mediul Visual C++, se va cuta urmtorul icon pe desktop Sau se va apela meniul Start-Programs - Microsoft Visual Studio 6.0 - Microsoft Visual C++ 6.0. 1 .Rulai aplicaia! Va aprea o fereastr de genul:

2. Creeai un proiect nou SDI (Single Document Interface) astfel:

15

Apsai - New sau Ctrl+N.

Alegei tabul - Projects. Alegei MFC AppWizard (.exe) Tastai un nume de proiect in caseta de editare incercuit cu albastru. Specificai o cale n caseta de editare ncercuit cu rou. Atenie ! Numele de proiect + Numele cii nu trebuie s depseasc 80 de caractere. Preferabil este s creai un director de proiecte propriu pe un drive altul dect cel de sistem. (Ex. D:\Studenti TII\POO Proiect\...) Apsai butonul OK. Alegei opiunea de aplicaie SDI i apsai Next

La urmtoare fereastr apsai Next, la fel i la urmtoarea. 16

Apsai Next n continuare. i la fereastra de mai jos apsai Finish.

2.5 Apsai butonul de confirmare la fereastra ce mai apare. n acest moment ar trebuie s avei o aplicaie SDI gata creat, care s arate ca mai jos:

Pentru a compila aplicaia se apas Ctrl+F7. Pentru a construi aplicaia se apas F7. 17

Pentru a rula aplicaia se apas F5. Aplicaia rulat arat astfel:

Atenie ! Pentru a putea programa mai departe trebuie nchis fereastra aplicaiei de mai sus. ( Anume cea care s-a deschis la apsarea tastei F5). Se poate desena un dreptunghi n fereastra de program astfel:

Trecei la vizualizarea clasei apsnd tabul Class [View...]. Expandai arborele de clase apsnd plusul din csu. Expandai ramura ( clasa) cu numele care se termin n ...View.

18

Facei dublu-clic pe ramura OnDraw.(functie a clasei sau metod). Va aprea fereastra de mai jos.

Scriei exact sub comentariu (rndurl scris cu verde) , pe locul subliniat cu rou, dar nu dup acolad. Linia de cod urmtoare: pDC->Rectangle(10,10,100,100); Fereastr de cod va trebui s arate astfel:

Rulai aplicaia (F5)! Ar trebuie s deseneze un dreptunghi astfel: 19

Pentru a face posibil animaia, micarea dreptunghiului parametrii lui nu trebuie s fie constante ( ex.10, 10, 100,100) ci variabile n funcie de , s zicem, un x i un y. Adugai o variabil clasei ce se termin n ...View astfel: Facei clic-dreapta pe ramura ce se termina n ...View ca n fereastra de mai jos:

Apsai pe opiunea - Add Member Variable ( Adug variabil membru.)

Tastai tipul variabilei : int n csua de sus. i numele variabilei: x n csua de jos. 20

La acces vei lsa bifat Public pentru a evita alte complicaii. Repetai operaia i pentru y. Ori de cte ori adugai o variabil la o clas vei proceda identic. Rulai aplicaia (F5)! Dai valori lui x i y la pornirea aplicaiei astfel: Facei dublu clic pe ramura cu acelai nume ca i clasa ce se termin n View. i scriei urmtorul cod imediat dup comentariul n verde: x= 100; y= 20; Astfel x i y vor primi valorile de mai sus.

Funcia n care am scris secvena de cod se numete constructorul clasei. Modificarea parametrilor dreptunghiului. Facei dublu-clic pe OnDraw. Modificai linia de cod introdus anterior ca mai jos: pDC->Rectangle( x, y, x+100, y+100 ); Rulai aplicaia (F5)! 7. Micarea automat a dreptunghiului. Introducei o funcie care se apeleaz periodic ( adic la un anumit interval de timp codul din funcie este rulat de aplicaie.) astfel:

21

Clic-dreapta pe ramura ce se termin n ...View. Apsai opiunea - Add Windows Message Handler - ( Adaug o funcie de tratare a mesajului, adic ce s-a precizat mai sus.)

Din fereastra din partea stng se alege tipul de interaciune dorit - adic mesajul asociat. Pentru apelarea la un anumit interval de timp se alege WM_TIMER , se face dublu-clic pe el sau se apas butonul Add Handler. Apoi se apas OK. Activai Temporizarea , adic apelarea funciei repetitive astfel: Adugai o funcie care se apeleaz la crearea ferestrei, folosind opiunea - Add Windows Message Handler de mai sus. Mesajul tratat se numete WM_CREATE. Funcia asociat ce se creeaz se numete OnCreate. Facei Dublu-Clic pe numele ei n fereastra din partea stng. Adugai linia de cod: SetTimer(1,20,0); Acest cod va activa apelarea repetat a funciei OnTimer , funcia creata mai sus (vezi WM_TIMER). Funcia OnTimer va fi apelat o dat la 20 de milisecunde, adic de 50 de ori pe secund. Fereastra de cod va arta astfel:

22

Pentru a mica automat dreptunghiul vei proceda astfel: Dublu-clic pe OnTimer. n funcia OnTimer sub linia de comentariu vei scrie dou linii de cod: x+=1; Invalidate( ); Rulai aplicaia! (F5) Vei vedea un dreptunghi n micare. 8. Miscarea dreptunghiului cu tastatura. Adugai o funcie OnKeyDown pentru tratarea mesajului WM_KEYDOWN . (Add Windows MEssage Handler ca mai sus). Dublu-clic pe numele funciei OnKeyDown. i nteriorul funciei dup comentariul n verde vei scrie urmtoarea secven de cod: if (nChar==VK_LEFT) x--; if (nChar==VK_RIGHT) x++; if (nChar==VK_UP) y--; if (nChar==VK_DOWN) y++; Invalidated; Atenie! Va trebuie s dezactivai aciunea din funcia asociata temporizrii. Pur i simplu comentai cele dou linii de cod ca mai jos: //x+=1; //Invalidate( ); Rulai aplicaia (F5)! La apsarea tastelor sgei dreptunghiul se va mica dup cum dorii. 9. Micarea dup mouse. Adugai funcia OnMouseMove, care trateaz evenimentul WM_MOUSEMOVE. Dublu-clic pe OnMouseMove i adugai n interiorul funciei dup linia de comentariu n verde codul de mai jos: x = point.x; y = point.y; Invalidate( ); Rulai aplicaia (F5)! Dreptunghiul va urmri cursorul mouselui in micare. Observaie: Funcia Invalidate ( ) determin redesenarea coninutului ferestrei, apelai-o ori de cte ori este necesar.

23

1.1 Laborator de proiect 1. 1.1.1 Introducere n proiectarea unei aplicaii


n cadrul acestui laborator se va urmri crearea unei aplicaii software complete folosind mediul vizual Visual C++. Pentru a face proiectul mai atractiv vom propune realizare de jocuri cu un cod relativ simplu. Acestea vor fi de patru tipuri: Joc de tenis, de spart crmizi gen Arkanoid; Joc de tetris, de realizat linii complete din blocuri de diferite forme; Joc gen Dyna, de explorare a unui labirint i distrugerea acestuia prin bombe; Joc gen Arcade Shooter, de distrugerea unor nave sau meteorii de ctre o nav cu micare pe orizontal. Studenii se pot grupa n echipe, astfel nct s-i coordoneze reciproc aciunile, si stabileasc sarcinile, s-i dezvolte astfel aptitudini de lucru n echip. La final vor prezenta o lucrare colectiv. Eventual se va prezenta aportul fiecruia la realiz area aplicaiei parte grafic, parte de codare, parte de algoritmi, parte de efecte sonore, grafice ale jocului, partea de scenariu etc. n aceast etap se vor stabili urmtoarele puncte: comportarea minimal a jocului adic cum trebuie s se desfoare un joc, ce opiuni de configurare i de stil de joc s fie disponibile; direcii de dezvoltare ale jocului adic la care anume element din joc s i se creasc complexitatea sau nivelul de interaciune cu utilizatorul; cutarea i analizarea unor jocuri deja fcute de tipul respectiv care s constituie o ludografie (echivalentul unei bibliografii dar n care n loc de cri ne vom referi la jocuri) i care s fie prezentate pe scurt (cele reprezentative), punnd accentul pe deosebiri i stabilind astfel un nucleu comun prin care s se defineasc acest tip de jocuri. se stabilesc care trsturi pot fi implementate n cadrul proiectului i la care trebuie s se renune, fie datorit complexitii, fie datorit volumului prea mare al muncii de implementare;

1.1.2 Comportarea minimal a jocului


Se are n vedere ca jocul s accepte intrri de la tastatura i/sau mouse. S prezinte o interfa grafic care s poat fi scalat ntr-o fereastr de tip Windows i s accepte modurile grafice disponibile n Windows.(nu se va lucru cu BGI). Se va avea n vedere producerea unei animaii de calitate fr plpiri ale ecranului i care s respecte legile bunului sim. Se vor folosi bitmapuri care vor fi integrate n resursele aplicaiei vizuale, eventual este permis folosirea unor biblioteci specializate de ncrcare a imaginilor. Se vor integra un minim de efecte sonore prin utilizarea wav- urilor disponibile n Windows sau a unora disponibile gratis pe internet. Parametrii de configurare i datele referitoare la scorurile record obinute vor fi 24

pstrate i rencrcate din fiiere. Fiecare joc va avea un meniu standard n care va fi inclus un fiier de ajutor i o opiune despre. Se va avea n vedere un engine de joc care s consume ct mai puine resurse pentru ca jocul s poat fi jucat n configuraii ct mai minimale, eventual se vor stabili prin meniuri diferite opiuni de grafic, sau configurare care s reduc resursele alocate.

1.1.3 Direcii de dezvoltare a jocului:


Se va avea n vedere n primul rnd cretere play-abilitii jocului, anume comenzile s fie executate rapid i fidel. n al doilea rnd, ca direcie de dezvoltare, se va urmri adugarea de noi funcionaliti elementelor de joc, de exemplu nivele suplimentare, bonusuri noi, aciuni noi ale utilizatorului odat cu trecere la noi nivele sau achiziionarea de bonusuri. n al treilea rnd se va urmri creterea calitii i a esteticii elementelor grafice i dac se poate i a celor audio. n al patrulea rnd se vor crea scenarii ct mai atractive, pentru c se tie c un scenariu bun d mai mult sens jocului, chiar dac acesta nu are o grafic prea grozav sau se repet aceeai i aceeai pai. n al cincilea rnd mbuntirea strategiilor jocului prin creare unor IA mai evoluate.

1.1.4 Studiul unei ludografii i stabilirea complexitii


Se va cuta, sau se vor cerceta din jocurile de gen propuse, pentru a se vedea ce elemente vehiculeaz acestea, ce este nou la unele jocuri. Dac studentul nu are cunotin despre aceste jocuri le va ncerca, jucnd cel puin 10 minute jocul vizat, sau dac are experien va expune n ludografie jocurile de gen experimentate, srind peste altele mai obscure. n final dup ce i-a fcut o opinie despre elementele din ludografie va expune diferenele, respectiv nucleul comun al acestor jocuri i ce anume poate fi implementat n cadrul proiectului sau este capabil s implementeze n cadrul proiectului. Eventual va sugera elemente noi, inovative n concepie jocurilor de genul respectiv.

25

1.2 Laborator de proiect 2. 1.2.1 Structurile de date i obiectele jocului


n acest laborator echipele de studeni vor lucra la crearea structurilor primare ale jocurilor, dup ce i-au fcut o idee despre ce trebuie inclus neaprat. Astfel sa va defini o clas global,adic care s conin toate elementele jocului. Fiecare sub-element al jocului va fi declarat ca obiect al clasei globale. Acest subelement poate fi n funcie de joc unul din urmtoarele: la jocul de tenis mingea, paleta, crmida, bonusul, suprafaa de joc, caseta de afiat scorul; la jocul de tetris blocul de construcie care cade, suprafaa de joc, tabela de scor, tabela ce anun piesa urmtoare; la jocul gen dyna omuleul care exploreaz labirintul , bomba, explozia, bonusul, montrii, peretele din labirint, tabela de scor, tabela de stare a bonusului; la jocul genul Arcade Shooter - nava, proiectilul, explozia, navele inamice sau meteoriii, bonusurile, tabela de scor, tabela de stare de nivel. La toate jocurile va fi o structur n care se vor pstra datele de configurare specific fiecrui joc n parte, o structur general n care se va pstra numele juctorului, scorul obinut, durata jocului i data cnd s-a nceput jocul. Dac este permis salvarea jocului n mijlocul acestuia se va specifica i o structur prin care s se salveze i s se reia jocul dorit, din starea n care s-a rmas. Structura va fi demonstrativ, de abia n starea final se va putea declar o structur general valabila. Toate structurile definite vor fi flexibile ele putnd fi modificate n funcie de cum evolueaz crearea jocului. n acest laborator se va pune la punct declararea, structurilor i a claselor, lucrul cu fiierele, declararea funciilor membre. Se va lucra cu Visual Studio crendu-se o aplicaie gen SDI (Single Document Interface) se va configura meniul jocului, se vor declara variabilele, funciile membre.

1.2.2 Creare de tipuri proprii din tipuri vechi


Atunci cnd se dorete o personalizare a unor tipuri de date deja definite pentru a fi mai sugestiv programarea se folosete cuvntul cheie typedef cu urmtoarea sintax: typedef tip_vechi nume_tip_nou; exemplu: typedef int numar; numar n1,k,a;

1.2.3 Crearea de tipuri noi struct


O alt modalitate de creere de tipuri personale este crearea unei grupri de tipuri, de date simple ntr-o structur. Vom folosi pentru aceasta cuvntul cheie struct cu urmtoarea sintax: 26

struct numestructura{ tip1 var1; tip2 var2; tipn varn,varnn; }; exemplu: struct persoana{ char nume[50]; int varsta; char cnp[20]; char adresa[100]; float salariu; };

1.2.4 Creare unei enumerri enum


Atunci cnd dorim s avem o mulime de elemente a crei constitueni s le dm un nume vom folosi enumerrile care au urmtoare sintax: Enum numeenumerare{element1,element2,element3,elementn}; Putem folosi enumerarea astfel> numeenumerare p; p=elementk; if (p= = elementm) {}

1.2.5 Crearea de clase class


Definirea unei clase se face astfel: class nume_clasa{ tip1 data1; tip2 data1[10]; tipn datan; specificator1: nume_clasa(); ~nume_clasa(); tip1 functie1(); specificator2: tip2 functie2(); tipn functien(): } [obiect1],[obiect2]; Aceasta este structura general de definire a unei clase. Se observ cuvntul cheie class de la nceput, acesta se va regsi n toate definiiile de clase. Specificator1n sunt specificatori de acces care stabilesc accesul la membrii clasei cei care se gsesc dup el fiind afectai, pn ce apare un nou specificator de acces. 27

nume_clasa() este o funcie constructor a clasei, se apeleaz automat cnd se declar un obiect de clasa respectiv. ~nume_clasa() este o funcie destructor a clasei, se apeleaz cnd s-a terminat lucrul cu obiectul definit, pentru a elibera memoria. Tipk functiek() este o funcie membru al clasei. Dup ce s-a definit clasa trebuie definite i funciile membre. n general pentru a accesa orice membru al unei clase pentru definire se folosete operatorul de specificare a domeniului :: . Exemplu: tipk nume_clasa::functiek() { // scriem continutul functiei return tipk; }

1.2.6 Lucrul cu fiierele


Pentru a lucra cu fiierele vom folosi intrrile ieirile standard pe baz de streamuri din C++. Vom folosi fiiere text pentru a salva configurrile i fiiere de tip dat cu acces aleatoriu pentru a salva ncrca starea jocului. Mai putem folosi biblioteci pentru ncrcarea de imagini ns acestea n general i gestioneaz singurele accesul la fiiere. Avem urmtoarele tipuri de tipuri de streamuri fiier: - ifstream pentru scriere n fiier; - ofstream - pentru citire din fiier; - fstream pentru scriere i citire din fiier; Deschidem streamul asociat fiierului cu funcia open() ce are urmtorul prototip: void open(const char *numefisier,int mod,int acces); n general vom avea nevoie doar de numele fiierului putnd scrie doar: ofstream iesire; iesire.open(test.txt ); Pentru a scrie/citi date din fiier vom folosi operatorii de extracie inserie cunoscui de la lucrul cu cin, cout numai c n locul acestora vom avea numele streamurilor fiier. Pentru a deschide n mod binar un stream de fiier vom utiliza specificatorul ios::binary. Exemplu: ofstream iesire; iesire.open(aut.txt,ios::out|ios::binary); iesire.put(a); iesire.close(); Pentru a scrie date dintr-o locatie de memorie folosim: istream &read(unsigned char *buf,int ncitit); ostream &write(const unsigned char *buf,int nscrisi); Pentru a ne poziiona n cadrul fiierelor deschise binar folosim: istream &seekg(streamoff offset,seek_dir origine); ostream &seekp(streamoff offset,seek_dir origine); Prin combinarea acestor funcii se poate scrie sau citi orice dat dorit din i n fiier.

28

1.3 Laborator de proiect 3. 1.3.1 Desenarea obiectelor, lucrul cu funciile grafice


Ne propunem s desenm obiectele care vor constitui elementele jocului. Unele imagini vom cuta s le generm, altele le vom desena cu uneltele oferite de editorul resurse,anume editorul de bitmapuri disponibil n Visual C++. Altele le vom crea prin mbinarea primitivelor grafice puse la dispoziie de Visual C++. Deci avem trei modaliti de abordare: - generarea imaginilor din puncte i primitive cu salvarea lor sub forma de bitmapuri; - crearea sau importarea de imagini prin editorul de resurse Visual C++. - cearea de imagini i interfee prin primitivele grafice puse la dispoziie de Visual C++. Cea mai eficient soluie i care cere cel mai puin de lucru este crearea imaginilor n afara mediului Visual C++, folosind editoare i unelte specializate de generare ale imaginilor. Alta ar fi lucrul cu Visual C++ pentru generarea unor imagini care vor fi salvate sub form de bitmapuri i reutilizate. Alta ar fi crearea de imagini prin editorul de resurse o soluie nu prea strlucit dar disponibil. Pentru a defini o resurs proprie de tip bitmap folosim urmtoarea secven de pai: 1. Avnd deja creat fiierul program vom seta modul de vizualizare pe resource view, n partea stng a ecranului; 2. Vom aduga un bitmap la resurse prin clic dreapta pe nodul rdcin, respectiv accesnd meniul insert; 3. Va apare o fereastr din care vom selecta Bitmap i vom apsa New; 4. Va fi creat o imagine bitmap fr coninut; 5. Vom face apel la sub-meniul Open din meniul File din meniul bar principal al mediului vizual de programare; 6. Setm tipul fiierelor ce vor fi deschise ca fiind - Image Files -. 7. Cutm i ncrcm imaginea dorit avnd grij s fie setat bitmapul fr coninut din arborele de resurse. 8. n locul imaginii necompletate va aprea imaginea dorit. Aceast imagine poate fi modificat sau se poate crea o imagine pornind de la zero folosind meniul de desenare:

29

Abordnd sistematic meniul de desenare fiecare rnd de la stnga la dreapta de sus n jos avem: opiunea de decupare a unui dreptunghi; opiunea de decupare dup un contur oarecare; opiunea de copiere a unei culori din imagine; opiunea de selectare a pointerului de tergere; opiunea de umplere a unui contur folosind culoarea selectat; opiunea de mrire a imaginii; opiunea de selectare a pointerului creion deseneaz cte un punct odat; opiunea de selectare a pointerului pensul deseneaz un grup de puncte de o anumit configuraie odat; opiunea de selectare a pointerului spray; opiunea de trasare a liniei; opiunea de trasare a unei curbe; opiunea de desenare a unui text; opiunea de desenare a unui dreptunghi gol, plin cu margine, plin fr margine; opiunea de desenare a unui dreptunghi rotunjit gol, plin cu margine, plin fr margine; opiunea de desenare a unei elipse gol, plin cu margine, plin fr margine; Mai jos este o caset de sub-opiune pentru alege grosimea liniei, forma pensulei, extinderea spray-ului, transparena fundalului textului etc. Iar sub aceasta este caseta din care se pot alege culorile. Pentru mai multe culori accesai meniul Image, apoi Adjust Colors. unde se poate seta n detaliu culoarea curent. Cealalt opiune ar fi desenare folosind funciile: - primitive tip linie: o MoveTo/ LineTo trasarea unei linii; o Arc/ ArcTo/ Angle Arc trasarea unui arc de cerc; o PolyDraw/ Polyline /PolyPolyline / PolylineTo trasare unei linii poligonale; o PolyBezier / PolyBezierTo trasarea unei curbe Bezier; - primitive tip figur umplut: o Chord pentru o regiune eliptic; o DrawFocusRect pentru un dreptunghi cu aspect focalizat; o Ellipse deseneaz o elips; o Pie deseneaz o regiune eliptic mrginit de dou raze; o Polygon / PolyPolygon deseneaz un polygon plin sau un set de poligoane; o Rectangle deseneaz un dreptunghi plin; o RoundRect deseneaz un dreptunghi avnd coluri rotunjite; - de afiare a textului: o TextOut / ExTextOut pentru afiarea unui text; o TabbedTextOut afieaz un text identat cu taburi; o DrawText deseneaz un text ncadrat ntr-o regiune dreptunghiular; o GetTextExtent / GetOutputTextExtent /GetTabbedTextExtent returneaz dimensiunile textului afiat; o GetTextAlign / SetTextAlign stabilete alinierea textului; o GetBkColor / SetBackColor se refer la culoarea de fundal a textului; o GetTextColor / SetTextColor se refer la culoarea efectiv a textului; 30

o GetBkMode / SetBKMode se refer la stilul n care este afiat fundalul; de afiare a bitmapurilor: o PatBlt / BitBlt / StretchBlt pentru a afia un bitmap din memorie; o GetPixel / SetPixel pentru a afia , respectiv citi un pixel de pe ecran; o Floodfill / ExtFloodFill pentru a umple un contur cu o anumit culoare; o MaskBlt / PlgBlt alte metode de afiare a unui bitmap; n combinaie cu aceste sunt clasele: CPen pentru specificarea peniei; CBrush pentru specificarea pensulei; CRect pentru specificarea unei regiuni rectangulare; CPoint pentru specificarea coordonatelor unui punct; CFont pentru a specifica parametrii unui font; CBitmap pentru a lucru cu o imagine de tip bitmap; CRgn pentru a specifica o regiune din fereastr; CPalette pentru a specifica o palet de culori; CDC pentru specificare general a unui dispozitiv de context; CPaintDC dispozitivul principal de context de desenare; CClientDC dispozitiv secundar de desenare apelabil din oricare metoda a clasei principale; CWindowDC dispozitiv de context asociat unei ferestre; CMetaFileDC dispozitiv de context asociat unui metafiier;

31

1.4 aborator de proiect 4. 1.4.1 Animarea elementelor de joc


n acest laborator se va aborda problema unei animaii folosind obiecte statice, folosirea unor fiiere video tip .avi., introducerea i integrarea de suport audio n aplicaie.

1.4.2 Animaia unor obiecte statice:


n laboratorul trecut s-a abordat generarea unor imagini statice. Pentru a le afia i pentru a da senzaia de micare trebuie folosit o metod care la intervale regulate de timp, extrem de scurte, dar ndeajuns de lungi ca ochiul s observe diferena, s afim o nou imagine, sau aceeai imagine dar la coordonate diferite. n acest sens avem nevoie de o funcie care s fie apelat la intervale constante de timp. Acest lucru se poate realiza folosind timere care genereaz la intervale de timp specificate un mesaj WM_TIMER cruia i pot fi asociate funcii. Precizia unui timer este de o milisecund. Dac de exemplu vrem o animaie cu 100 de cadre timerul va avea asociat o durata de 10 milisecunde. Pe ct de mare este numrul de cadre pe secund cu att se face apel la mai multe resurse, mai mult timp de procesare. Rezonabil ar fi cam 30 de cadre pe secund, deci o constant de timp de aprox. 30 de milisecunde. Declararea unui timer: UINT SetTimer( UINT nIDEvent, UINT nElapse, void (CALLBACK EXPORT* lpfnTimer)(HWND, UINT, UINT, DWORD) ); ,unde : - nIDEvent este ID-ul asociat timerului ; - nElapse este intervalul de timp n milisecunde la care este apelat timerul ; - urmtorul parametru se poate seta cu 0 ; Exemplu de folosire a unui timer :
void CMainFrame::OnStartTimer() { m_nTimer = SetTimer(1, 2000, 0);//creaz timerul } void CMainFrame::OnStopTimer() { KillTimer(m_nTimer); // distruge timerul } void CMainFrame::OnTimer(UINT nIDEvent) //corpul funciei associate //timerului { MessageBeep(0xFFFFFFFF); //functia asociat timerului va emite un //beep // Call base class handler. CMDIFrameWnd::OnTimer(nIDEvent)//timerul va fi recirculat }

32

Se poate crea un singur timer, toate elementele avnd normalizare temporal n limita constantei de timp a timerului. n funcia de timer se vor introduce bucile de cod ce vor fi animate , avnd specificate un contor de evoluie temporar care va putea genera fie poziii succesive pe o traiectorie, fie urmtorul cadru al animaiei. Se va constata pe parcurs c intrrile de la utilizator nu specific fiecare pas al animaiei ci doar iniiaz o secven de animaie. Astfel n cazul mingii la tenis utilizatorul nu poate aciona dect asupra paletei mingea fiind animat n mod continuu, paleta va fi micat nu direct de utilizator,ci cu anumite efecte ineriale. La micarea omuleului utilizatorul va preciza doar nceputul i sfritul deplasrii acestuia nu i cum se mic efectiv. La fel ca n cazul mingii montrii vor fi animai n mod continuu. La fel i cu meteoriii la Shooter. Un caz mai interesant este o micare semiautomat a crmizilor din tetris, cderea va fi automat dar rotirea va fi controlat de utilizator.

1.4.3 Evitarea plpirii imaginii


Pentru a face s dispar acest fenomen este indicat ca tot ce se deseneaz i se animeaz la un moment dat s fie desenat ntr-un bitmap, cnd desenarea obiectelor s-a ncheiat, bitmapul va fi afiat pe ecran. Preferabil ca ntreaga suprafa de joc s fi afiat printr-un bitmap. Aceast tehnic se numete double buffering n englez, i nu are o traducere echivalent, simpl n romn, dar semnificaia lui n mare este cea de mai sus.

1.4.4 Animaia pe baz de avi-uri


Visual C++ are o bibliotec care face apel la funcii multimedia. Un set de astfel de funcii i structuri este destinat pentru lucrul cu fiierele AVI. Pentru a lucra cu un fiier avi putem folosi urmtoare secven de cod:
// LoadAVIFile incarca si deschide fisiere AVI // // szfile numele fisierului // hwnd pointer gen indice al ferestrei // VOID LoadAVIFile(LPCSTR szFile, HWND hwnd) { LONG hr; PAVIFILE pfile; AVIFileInit(); // initializeaza biblioteca AVI

hr = AVIFileOpen(&pfile, szFile, OF_SHARE_DENY_WRITE, 0L); //deschide AVI if (hr != 0){ ErrMsg("Nu am putut deschide %s", szFile); return; } // // Aici se pun functiile care interactioneaz cu structura AVI //

33

AVIFileRelease(pfile); AVIFileExit();

// se inchide fisierul AVI // se elibereaz biblioteca AVI

} Pentru a deschide nite streamuri de prelucrare AVI folosim codul:


void InsertAVIFile(PAVIFILE pfile, HWND hwnd, LPSTR lpszFile) { int i; gcpavi = 0; //se deschid toate streamurile disponibile for (i = gcpavi; i < MAXNUMSTREAMS; i++) { gapavi[i] = NULL; if (AVIFileGetStream(pfile, &gapavi[i], 0L, i - gcpavi) != AVIERR_OK) break; if (gapavi[i] == NULL) break; } // Display error message-stream not found. if (gcpavi == i) { ErrMsg("Fisierul %s nu a fost gasit!", lpszFile); if (pfile) // daca fisierul a fost deschis acesta este inchis AVIFileRelease(pfile); return; } else { gcpavi = i - 1; }

Pentru procesarea streamurilor n continuare se folosete urmtoarea secven:


void StreamTypes(HWND hwnd) { AVISTREAMINFO avis; LONG r, lHeight = 0; WORD w; int i; RECT rc; // Parcurgem toate streamurile for (i = 0; i < gcpavi; i++) { AVIStreamInfo(gapavi[i], &avis, sizeof(avis)); if (avis.fccType == streamtypeVIDEO) { // Aici se fac prelucrarile secventelor video } else if (avis.fccType == streamtypeAUDIO) { // Aici se fac prelucrarile secventelor audio

34

} else if (avis.fccType == streamtypeTEXT) { // Aici se fac prelucrarile secventelor text } } }

Sunt disponibile urmtoarele funcii de lucru cu AVI-uri : - AVIBuildFilter - AVIClearClipboard - AVIFileAddRef - AVIFileCreateStream - AVIFileEndRecord - AVIFileExit - AVIFileGetStream - AVIFileInfo - AVIFileInit - AVIFileOpen - AVIFileReadData - AVIFileRelease - AVIFileWriteData - AVIGetFromClipboard - AVIMakeCompressedStream - AVIMakeFileFromStreams - AVIMakeStreamFromClipboard - AVIPutFileOnClipboard - AVISave - AVISaveOptions - AVISaveOptionsFree - AVISaveV - AVIStreamAddRef - AVIStreamBeginStreaming - AVIStreamCreate - AVIStreamEndStreaming - AVIStreamFindSample - AVIStreamGetFrame - AVIStreamGetFrameClose - AVIStreamGetFrameOpen - AVIStreamInfo - AVIStreamLength - AVIStreamOpenFromFile - AVIStreamRead - AVIStreamReadData - AVIStreamReadFormat - AVIStreamRelease - AVIStreamSampleToTime - AVIStreamSetFormat - AVIStreamStart - AVIStreamTimeToSample - AVIStreamWrite 35

AVIStreamWriteData CreateEditableStream EditStreamClone EditStreamCopy EditStreamCut EditStreamPaste EditStreamSetInfo EditStreamSetName

1.4.5 Lucrul cu fiiere audio


Apelarea funciilor audio va fi realizat tot n interiorul funcii temporizate. Cea mai simpl abordare este folosirea funciei avnd prototipul: BOOL PlaySound( LPCSTR numefisier, DWORD indicatori_de_redare ); HMODULE modul_deschidere,

,unde: - modul_deschidere este un pointer spre o resurs executabil care red fiierul n mod obinuit este NULL; - indicatori de redare specific modul cum va fi redat fiierul audio de tip WAV opiunea cea mai utilizat este : SND _ASYNC || SND_FILENAME. De exemplu pentru a reda fiierul explozie.wav fr a atepta terminarea acestuia (opiunea asincron) se utilizeaz urmtoarea apelare a funciei: PlaySound(explozie.wav , NULL, SND _ASYNC || SND_FILENAME); Mai sunt i alte opiuni de redare a fiierelor audio: o abordare fiind controlul direct al redrii prin mprirea pe buci a fiierului audio, cealalt metod este doar specificarea parametrilor de redare, ncredinarea gestionrii fluxului fiind acordat unui driver de redare.(Biblioteca MCI). Abordarea MCI pentru fiiere audio lungi este cea mai uor de implementat. Un exemplu de abordare MCI este urmtorul :
DWORD playWAVEFile(HWND hWndNotify, LPSTR lpszWAVEFileName) { UINT wDeviceID; DWORD dwReturn; MCI_OPEN_PARMS mciOpenParms; MCI_PLAY_PARMS mciPlayParms; // Se deschide dispozitivul MCI prin specificarea numelui //fisierului si a dispozitivului multimedia mciOpenParms.lpstrDeviceType = "waveaudio"; mciOpenParms.lpstrElementName = lpszWAVEFileName; if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)(LPVOID) &mciOpenParms))

36

{ //s-a produs o eroare la deschiderea fisierului return (dwReturn); } // Dispozitivul s-a deschis fara erori extragem ID-ul wDeviceID = mciOpenParms.wDeviceID; // Redam fisierul prin intermediul dispozitivului multimedia mciPlayParms.dwCallback = (DWORD) hWndNotify; if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)(LPVOID) &mciPlayParms)) { mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL); return (dwReturn); } return (0L);

37

1.5 Laborator de proiect 5. 1.5.1 Gestionarea interfeei cu utilizatorul tastatur i mouse


Pentru a interaciona cu jocul utilizatorul trebuie s foloseasc un dispozitiv de intrare. Cel mai utilizat este mouse-ul, iar pentru comenzi suplimentare tastatura. n unele jocuri avansate se mai folosesc joystickul cu sau fr feedback sau gamepad-ul sau volane cu feedback. n cazul jocurilor pe care le creem vom apela mai des la tastatur dect la mouse. Lucrul cu mouse-ul i tastatura presupune gestionarea unor mesaje i asocierea lor cu nite funcii rspuns. Pentru mouse avem urmtoarele mesaje: WM_LBUTTONDBLCLK trimis dac s-a fcut dublu-clic cu primul buton al mouselui; WM_LBUTTONDOWN trimis dac s-a apsat primul buton al mouseului; WM_LBUTTONUP trimis dac s-a eliberat al doilea buton al mouselui; WM_MBUTTONDBLCLK trimis dac s-a fcut dublu clic pe butonul din mijloc al mouseului; WM_MBUTTONDOWN trimis dac s-a apsat butonul mijlociu al mouselui; WM_MBUTTONUP trimis dac s-a eliberat butonul mijlociu al mouseului; WM_MOUSEMOVE trimis dac s-a deplasat mouseul; WM_MOUSEWHEEL trimis dac s-a rotit rotia de derulare a mouseuui; WM_RBUTTONDBLCLK trimis dac s-a fcut dublu clic pe butonul doi al mouselui (butonul din dreapta n mod standard); WM_RBUTTONDOWN trimis dac s-a apsat butonul al doilea al mouseului; WM_RBUTTONUP trimis dac s-a eliberat butonul al doilea al mouseului;

Asocierea unui mesaj cu o funcie se face prin adugarea unui gestionar (handler) de evenimente. Aceasta se poate face prin clic dreapta n clasa fereastr pe clasa cu numele CxxxView i alegerea opiunii Add Windows Message Handler de aici doar transferm mesajul dorit din lista din stnga n cea din dreapta i apoi facem dublu clic pe el, mediul de programare ne va poziiona n dreptul funciei asociate unde vom scrie aciunea dorit. Pentru aplicaii simple se pot trata separat fiecare eveniment generat d e mouse, dar vom observ c atunci cnd lucrurile se complic este necesar c fiecare din funciile asociate s formateze ntr-un mod comod datele ce parvin de la mouse i s le transmit mai departe unei funcii unice de gestionare a mouse-ului de exemplu MouseWork(int mb,int mx,int my,int aa,int kf) n care mb semnific starea butoanelor de mouse, mx,my coordonatele pointerului, aa deplasarea rotiei de scroll, kf starea butoanelor funcionale CTRL, SHIFT, ALT. Motivul abordrii mouselui n acest fel este c nu toi parametrii sunt n general actualizai de aceea starea lor trebuie reinut, i procesat atunci cnd apare o circumstan semnificativ pentru aplicaie. Acestor mesaje le sunt asociate urmtoarele funcii de gestionare: afx_msg void OnXButtonDblClk( UINT nFlags, CPoint point ); afx_msg void OnXButtonDown( UINT nFlags, CPoint point ); afx_msg void OnXButtonUp( UINT nFlags, CPoint point ); 38

afx_msg void OnMouseMove( UINT nFlags, CPoint point ); afx_msg BOOL OnMouseWheel( UINT nFlags, short zDelta, CPoint pt ); Unde X poate fi L,M sau R, nFlags reprezint nite indicatori de stare analizabili prin constantele:
MK_CONTROL - Setat dac tasta CTRL este apsat; MK_LBUTTON - Setat dac primul buton al mouseului este apsat; MK_MBUTTON - Setat dac butonul din mijloc al mouseului este apsat; MK_RBUTTON - Setat dac butonul al doilea al mouseului este apsat; MK_SHIFT - Setat dac tasta SHIFT este inut apsat;

Point reprezint poziia pointerului mouseului; zDelta reprezint deplasarea unghiular a rotiei de mouse.

1.5.2 Gestionarea mesajelor de tastatur


Pentru gestionarea mesajelor de tastatur se face apel la urmtoarele mesaje: WM_CHAR trateaz primul tip de intrri de tastatur fiind generat la apsarea unei taste de acest tip; WM_KEYDOWN generat la apsarea i inerea apsat a unei taste funcionale; WM_KEYUP generat la eliberarea unei taste funcionale;

Se observ c se face o diferen ntre taste tastele care returneaz un caracter ASCII genereaz n special mesajul WM_CHAR, pe cnd tastele funcionale numai mesajele WM_KEYDOWN i WM_KEYUP. Aceste mesaje au asociate funciile: afx_msg void OnChar( UINT nChar, UINT nRepCnt, UINT nFlags ); afx_msg void OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags ); afx_msg void OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags ); La OnChar nChar specific codul ASCII asociat caracterului generat de tasta respectiv ; La OnKeyDown,OnKeyUp nChar specific codul virtual al tastei funcionale ; nRepCnt numrul de repetri ale tastei ca urmare a inerii apsate a unei taste; nFlags sunt indicatori ale tipului de tasta (pentru OnKeyDown, OnKeyUp) : - biii de la 0-7 specific codul tastei specificat prin standardul OEM ; - bitul 8 dac este setat specific o tast extins, n cazul tastelor funcionale ; - bitul 13 indic dac tasta ALT este apsat ; - bitul 14 indic o stare anterioar a tastei 1 dac tasta era apsat naintea apelrii i 0 dac tast era liber ; - bitul 15 indic o stare de tranziie -1 dac tasta este eliberat, 0 dac este apsat ; Pentru OnChar nFlags are urmtoarea semnificaie : - biii 0-15 - specific numrul de repetiii ale tastei prin inerea ei apsat; - biii 16-23 - specific codul de scanare al tastei definit de OEM ; - bitul 24 specific o tast extins ; - ultimii trei bii (29,30,31) au aceeai semnificaie ca n cazul anterior ; Se mai poate lucra i cu acceleratorii care sunt una din resursele puse la dispoziie de Visual C++. Pe lng aceste mijloace mai sunt o serie de funcii de gestionare a 39

tastaturii n biblioteca Win32. Pentru o gestionare complet a tastaturii este recomandabil ca tuturor tastelor s li se asocieze un vector n care printr-o valoare 1 s se specifice c tasta a fost apsat i este inut apsat i cu 0 c tasta a fost eliberat. n urmtoarea secven de cod se prezint o gestionare elementar a tastaturii cu posibilitatea afirii tastelor curent apsate pe ecran. void CSs05View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default char s[100]; keys[nChar]=1; //tasta este apasata int i,j=0; CClientDC dc(this); //stergem zona de afisare a starii tastaturii dc.Rectangle(0,0,100,500); //afisam tastele care sunt apasate in momentul de fata for (i=1;i<=255;i++) if (keys[i]==1) { sprintf(s,"%d",i); dc.TextOut(10,10+(j%20)*15,s); j++; } CView::OnKeyDown(nChar, nRepCnt, nFlags); } void CSs05View::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) { // TODO: Add your message handler code here and/or call default char s[100]; //tasta este eliberata keys[nChar]=0; int i,j=0; CClientDC dc(this); //stergem suprafata de afisare dc.Rectangle(0,0,100,500); // afisam codul tastelor ce raman afisate for (i=1;i<=255;i++) if (keys[i]==1) { sprintf(s,"%d",i); dc.TextOut(10,10+(j % 20)*15,s); j++; } CView::OnKeyUp(nChar, nRepCnt, nFlags); } Vectorul de care vorbeam este keys[]. Se observ c se accepta apsare a mai mult de dou taste n acelai timp putndu-se ajunge pn la 6 - 7 taste apsate simultan, acest numr variaz n funcie de productorii de tastaturi. Vei vedea n jocuri c este necesar s se poat da mai multe comenzi simultan de la 40

tastatur i atunci cnd se joac n mod Single Player(un singur juctor), i atunci cnd joac dou persoane una mpotriva alteia, astfel nct comenzile s nu se bruieze reciproc. Este important de tiut numele codurilor virtuale ale tastelor. n lista de mai jos sunt codurile cele mai des utilizate : VK_BACK 08 BACKSPACE tasta VK_TAB 09 TAB tasta VK_CLEAR 0C CLEAR tasta VK_RETURN 0D ENTER tasta VK_SHIFT 10 SHIFT tasta VK_CONTROL 11 CTRL tasta VK_MENU 12 ALT tasta VK_PAUSE 13 PAUSE tasta VK_CAPITAL 14 CAPS LOCK tasta VK_ESCAPE 1B ESC tasta VK_SPACE 20 SPACEBAR VK_PRIOR 21 PAGE UP tasta VK_NEXT 22 PAGE DOWN tasta VK_END 23 END tasta VK_HOME 24 HOME tasta VK_LEFT 25 LEFT ARROW tasta VK_UP 26 UP ARROW tasta VK_RIGHT 27 RIGHT ARROW tasta VK_DOWN 28 DOWN ARROW tasta VK_SELECT 29 SELECT tasta VK_SNAPSHOT 2C PRINT SCREEN tasta for Windows 3.0 and later VK_INSERT 2D INS tasta VK_DELETE 2E DEL tasta VK_HELP 2F HELP tasta VK_0 30 0 tasta VK_1 31 1 tasta VK_2 32 2 tasta VK_3 33 3 tasta VK_4 34 4 tasta VK_5 35 5 tasta VK_6 36 6 tasta VK_7 37 7 tasta VK_8 38 8 tasta VK_9 39 9 tasta VK_A 41 A tasta VK_B 42 B tasta VK_C 43 C tasta VK_D 44 D tasta VK_E 45 E tasta VK_F 46 F tasta VK_G 47 G tasta VK_H 48 H tasta VK_I 49 I tasta 41

VK_J 4A J tasta VK_K 4B K tasta VK_L 4C L tasta VK_M 4D M tasta VK_N 4E N tasta VK_O 4F O tasta VK_P 50 P tasta VK_Q 51 Q tasta VK_R 52 R tasta VK_S 53 S tasta VK_T 54 T tasta VK_U 55 U tasta VK_V 56 V tasta VK_W57 W tasta VK_X 58 X tasta VK_Y 59 Y tasta VK_Z 5A Z tasta VK_NUMPAD0 60 Numeric keypad 0 key VK_NUMPAD1 61 Numeric keypad 1 key VK_NUMPAD2 62 Numeric keypad 2 key VK_NUMPAD3 63 Numeric keypad 3 key VK_NUMPAD4 64 Numeric keypad 4 key VK_NUMPAD5 65 Numeric keypad 5 key VK_NUMPAD6 66 Numeric keypad 6 key VK_NUMPAD7 67 Numeric keypad 7 key VK_NUMPAD8 68 Numeric keypad 8 key VK_NUMPAD9 69 Numeric keypad 9 key VK_MULTIPLY 6A Multiply key VK_ADD 6B Add key VK_SEPARATOR 6C Separator key VK_SUBTRACT 6D Subtract key VK_DECIMAL 6E Decimal key VK_DIVIDE 6F Divide tasta VK_F1 70 F1 tasta VK_F2 71 F2 tasta VK_F3 72 F3 tasta VK_F4 73 F4 tasta VK_F5 74 F5 tasta VK_F6 75 F6 tasta VK_F7 76 F7 tasta VK_F8 77 F8 tasta VK_F9 78 F9 tasta VK_F10 79 F10 tasta VK_F11 7A F11 tasta VK_F12 7B F12 tasta VK_F13 7C F13 tasta VK_F14 7D F14 tasta VK_F15 7E F15 tasta VK_F16 7F F16 tasta 42

VK_F17 80H F17 tasta VK_F18 81H F18 tasta VK_F19 82H F19 tasta VK_F20 83H F20 tasta VK_F21 84H F21 tasta VK_F22 85H F22 tasta VK_F23 86H F23 tasta VK_F24 87H F24 tasta VK_NUMLOCK 90 NUM LOCK tasta VK_SCROLL 91 SCROLL LOCK tasta Acum avei acces la marea parte a funciilor tastaturii i mouselui. n program nu vei conecta direct o aciune a elementului de joc manevrabil la tast ci vei construi o list gen FIFO n care vei pune comenzile urmnd ca acestea s fie tratate ori n funcia Timerului ori ntr-o funcie tampon de gestionare a aciunilor care s transmit timerului doar comenzi de animaie.

43

1.6 Laborator de proiect 6. 1.6.1 Integrarea elementelor precedente


n etapele precedente practic am realizat toate elementele eseniale ale unui joc dar nu le-am pus s lucreze mpreun. Esenialul ntr-un joc este ca un element s interacioneze cu altul iar prin aceasta juctorul s interacioneze cu mediul virtual al jocului. Vom aborda problema exemplificnd pentru fiecare joc n parte. La jocul de tenis mingea trebuie s interacioneze cu paleta i cu crmizile, att paleta ct i crmizile vor genera o ciocnire perfect elastic respingnd mingea. De asemenea minge mai interacioneaz i cu pereii laterali producndu-se de asemenea ciocniri elastice. Mingea nu trebuie s treac prin palet sau prin crmizi dect dac se dorete expres acest lucru. n timp ce paleta rmne intact, n urma ciocnirilor crmizile se sparg sau trec n alt stare. De asemenea bonusurile trebuie absorbite de palet dac aceasta st n calea lor. La jocul de tetris la fiecare micare a elementului de construcie se va verifica dac elementul are libertate de micare. Dac la cderea elementului se constat c acesta nu mai are loc unde s cad, se va mai lsa un interval de timp scurt pentru translaii pe orizontal apoi obiectul va fi cimentat n zid i altul va ncepe s cad. La jocul gen Dyna la fiecare micare o omuleului se va verifica dac calea este liber (nu este zid,nu este monstru,nu este bomb pus). Dac valul exploziei d peste omule sau micarea monstrului se intersecteaz cu cea a omuleului se d mesajul c omul a murit i n acel moment se declaneaz procedura de pierdere a unei viei sau de ncheiere a jocului. i montrii au interdicii de a trece prin ziduri sau peste bombe, n afar de cazul n care abilitile lor le permit acest lucru. La jocul gen Arcade Shooter proiectilele lansate de nava vor interaciona cu meteoriii. Meteoriii vor interaciona, dac nu sunt distrui i se ciocnesc cu nava, cu nava. Proiectilele lansate de nave inamice, inclusiv navele inamice, n eventualitatea unor ciocniri vor interaciona cu nava.

1.6.2 IA-ul jocului


Inteligena artificial asociat jocului n cazul de fa este doar una elementar sau redus la minim. La tenis va trebui doar s examinm nite ciocnire i unghiuri de deviaie. La tetris doar o suprapunere a unei matrici peste alta. La Shooter doar o intersectare dintre proiectile, nav, nave i meteorii. n schimb la Dyna, programarea micrii mon trilor poate constitui o tem inepuizabil de dezvoltare a IA-ului, dar pentru proiectul de fa ne vom propune s realizm nite montri nu prea istei, care nu fug dup omule, ci doar i iau o via dac traiectoria lor se intersecteaz cu cea o omuleului. Aceasta s-ar putea ntmpla fie c omuleul este prins la col, fie c monstrul este mai rapid i nu a putut fi evitat, fie din neatenia sau nesbuina juctorului. Un algoritm simplu de micare haotic a monstrului ar fi ca acesta s parcurg n linie dreapt un culoar pn ntlnete un obstacol, apoi s o ia pe urmtorul drum neexplorat, disponibil, altfel doar s se ntoarc napoi. Deci n mare parte vor aprea probleme de implementare a unor comportamente i efecte grafice corelate ntre ele i nu probleme efective de programare a IA-ului.

44

1.6.3 Construcia unui meniu despre


Se observ c Visual C++ deja a construit o fereastr despre. Aceasta poate fi accesat prin modul de gestionare a resurselor din ramura Dialog apoi fcnd clic pe IDD_ABOUTBOX.

Vom modifica iconul nlocuindu-l cu unul propriu, titlul ferestrei, cine a realizat jocul, copyright ul jocului, ocazia ce a dus la creare jocului.

1.6.4 Construcia unui meniu de ajutor


Vom crea un meniu de ajutor pentru a da detalii despre joc, neaprat vom descrie scopul jocului, strategii de mbuntire a performanei juctorului, tastele asociate comenzilor i semnificaia lor, tipurile de bonusuri, de montri, de nave inamice, de crmizi. Vom crea o nou fereastr de dialog prin clic dreapta pe ramura dialog din fereastr de resurse. Vom apsa meniul Insert Dialog. Va aprea un dialog standard la care vom aduga un control CRichEditCtrl pentru a afia un fiier RTF care va conine toate informaiile de ajutor. Fiierul RTF va fi creat cu WordPad sau alte editoare de RTF-uri i va fi ncrcat cu urmtoarea secven:
static DWORD CALLBACK MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb) { CFile* pFile = (CFile*) dwCookie; *pcb = pFile->Read(pbBuff, cb); return 0; } //pointer spre controlul de tip RichEdit extern CRichEditCtrl* pmyRichEditCtrl; // fisierul din care vom ncrca coninutul pt RichEdit CFile cFile(TEXT("ajutor.rtf"), CFile::modeRead); EDITSTREAM es; es.dwCookie = (DWORD) &cFile; es.pfnCallback = MyStreamInCallback; pmyRichEditCtrl->StreamIn(SF_RTF, es);

45

Aceast secven va fi introdus la iniializare programului. La apelare meniului de ajutor doar se va deschide fereastr, fiierul ajutor.rtf fiind deja ncrca.

1.6.5 Meniuri n limba romn


Vom accesa ramura Meniu iar de acolo IDR_MAINFRAME vom face clic pe fiecare element de meniu i-l vom redenumi.

1.6.6 Meniul scor record


Se va crea o opiune de meniu de vizualizare scoruri record i un dialog care va aprea doar atunci cnd juctorul a obinut un scor record n care acesta i va introduce numele. n fereastra de introducere a numelui va fi specificat scorul i locul ocupat n clasament alturi de caseta de editare n care i va introduce numele. Dup ce ferea stra de nregistrare a scorului record va fi nchis, va aprea tabela cu scoruri record. Scorurile record vor fi citite din fiier la intrarea n joc, vor fi modificate n timpul rulrii jocului i vor fi salvate la ieirea din joc.

1.6.7 nghearea, salvarea sau ncrcarea unui joc


Odat ce toate celelalte detalii importante au fost puse la punct i jocul este funcional se va ncerca crearea unei opiuni de meniu de oprire temporar a jocului, fr a se iei din joc, ca mai apoi jocul s poat fi reluat. De aceea tot ce este n funcia timerului va fi executat doar dac pauza nu este activ. Pentru a salva un joc vom lua n considerare toate variabilele de stare pe baza crora putem reconstitui jocul de unde acesta a fost salvat, fr totui a crea un fiier de salvare supradimensionat. La ncrcarea acestuia doar setm variabilele de stare la cele specificate n fiierul de salvare i resetm engine-ul jocului.

46

1.7 Laborator de proiect 7. 1.7.1 Testarea programelor. Beta-testing.


Jocul pare a fi pus la punct n momentul de fa, i totui treaba nu este terminat trebuie s l testm, ceea ce n englez se cheam beta - testing. nainte de a supune jocul acestei testri nu aveam dect o variant beta. Vom vedea dac putem face fa standardelor cerute de jocul pe care l jucm, vom observ c sunt momente n care jocul dei funcioneaz corect este foarte greu de parcurs n lipsa unui antrenament susinut. Totui proiectul nu-i propune ca cei care l-au creat s fie i buni - juctori ai jocului creat, de aceea vom recurge la triare prin introducere n codul jocului de bonusuri, viei infinite, invulnerabilitate, ncetinirea micrilor mingii, sau montrilor toate disponibile la tastarea unui cuvnt cheie. Astfel putem parcurge cap coad toate nivelele (nivelul) jocului depistnd defectele (bug-urile) care s-au strecurat n programarea jocului. Niciodat nu este prea trziu s se corecteze un defect, dar se urmrete ca prin beta -testing acestea s fie ct mai reduse. Cea mai frecvent eroare fatal este c s-a uitat s se aloce memorie pentru un pointer, sau acestui pointer nu i s-a specificat o zon de memorie alocat. O alt eroare este c n explorarea unui vector indexul s-a deplasat nafara zonei alocate acestuia. Alt eroare ar fi c s-a uitat un fiier deschis, sau c s-a apelat un fiier ce nu a fost deschis. Pot apare i erori specifice claselor cum ar fi accesul la membrii unei clase, dar aceste sunt de obicei semnalate de compilator. Alte erori de funcionare ar fi c varibilele nu au fost iniializate corect, sau au fost dar doar la o singur apelare a secvenei, la urmtoare fiind luate valorile precedente. Lista de erori ar putea continua, i aici vorbesc de erori care las programul s mearg pn n momentul n care seciunea incorect sau corect este apelat cu nite parametri coreci sau incoreci i se iese forat din joc sau mai mult se produce o cdere a sistemului i este nevoie resetarea calculatorului.

1.7.2 Direcii de dezvoltare


Dac un joc are succes la public sau pentru a avea mai mult succes la public atunci se dorete mbuntirea lui, nu att a engine-ului ct a elementelor de joc. Se caut o diversificare a elementelor de joc,o mbogire a scenariilor, o grafic mai bun, un IA mai performant i mai eficient. De obicei se pune mai puin accent pe grafic sau pe sunet i mai mult pe ideile vehiculate i atmosfera creat de joc, dac acestea sunt bune atunci se merit s se mbunteasc grafic, dac din start sunt perimate sau nefuncionale cel puin nu se lucreaz degeaba la creaia artistic. Uneori se practic i o grafic mai bun pentru jocuri btrne ceea ce uneori are succes. Cele mai multe jocuri de astzi permit jocul n echip, ceea ce a nceput s fie o trstur de baz pentru jocurile care se respect. Pentru jocurile din cadrul proiectului se pot sugera multe direcii de dezvoltare dac s-a luat n serios studierea ludografiei pentru acel joc. O serie de idei ar fi: Pentru jocul de tenis crmizile s fie de mai multe tipuri, s apar bonusuri la spargerea unei crmizi, un bonus s permit micare mai repede a paletei,un bonus s permit ca paleta s poat mpuca crmizile,altul se permit generarea mai multor 47

mingi, altul s genereze mingi care sa aib alte tipuri de efecte distructive, n funcie de tipul mingii crmizile s fie distruse ntr-un anumit fel. Pentru jocul de tetris se poate mbunti aspectul grafic al blocurilor de la simple conglomerate rectangulare la diferite aspecte stilizate, dispariia unui rnd complet de crmizi s fie nsoit de un efect grafic special. Pentru jocul de Dyna s fie introduse bonusurile, s fie mai multe tipuri bombe, unele bonusuri s pun la dispoziie i pistoale omuleului cu care doar s imobilizeze, s rneasc montri, sau s-i distrug, s se creeze specii de montri mai inteligeni. Pentru Shooter s se introduc nave inamice care s atace nava juctorului, s se introduc bonusurile, pentru mbuntirea armelor navei, a sistemelor de propulsie, a scutului.

1.7.3 Concluzii. Utilitatea proiectului.


S-a dorit ca crearea unei aplicaii de tip joc s fac mai atractiv proiectul. Dei proiectul a fost un joc, creare jocului nu a fost o joac. S-a pus accentul pe lucrul n echip, dar i pe studiul individual. Cu ocazia aceasta s-a creat un stil de lucru, un mod de abordare a unui limbaj de programare din perspectiva unei finaliti practice. Lucrrile de laborator au urmrit s ghideze studentul nu s-i ofere o soluie complet sau definitiv. Studentului i s-au sugerat anumite soluii i s-au trasat anumite etape obligatorii pe care trebuie s le parcurg ca n final s obin o aplicaie funcional dar i cu aspect comercial i chiar profesional. S-a dorit ca aceasta s fie un punct de pornire pentru viitori programatori profesioniti sau doar o mbuntire a stilului de programare sau un simplu exerciiu pentru cine stpnete arta programrii unei aplicaii serioase.

48