Istoria Sistemului de Operare Ios

Cuprins

Introducere2

Capitolul 1: Istoric

1.1 Istoria sistemului de operare iOS

1.2 Istoria magazinului online AppStore

Capitolul 2:Tehnologii folosite

2.1 Kit­ul de dezvoltare Apple(Apple SDK)

//2.2 Motorul grafic Cocos2d

//2.3 Motorul de simulare a fizicii Box2d

Capitolul 3: Lucrare Practică

3.1 Jocul Dream Tim

3.2 Design

3.3 Implementare

3.4 Finisare și testare

3.5 Lansare în Appstore

3.6 Statistici Appstore

Concluzii

Bibliografie

Introducere

Domenii abordate și obiective generale

Domeniul abordat de către acest proiect este acel al dezvoltării de software pentru sistemul de operare iOS.

Jocul „Dream Tim” este destinat dispozitivelor mobile care folosesc sistemul de operare iOS , sistem aparținând companiei Apple. La acest moment , există patru astfel de dispozitive : iPhone , iPod Touch, iPad si iPad mini, toate produse de Apple.

Aplicațiile destinate sistemului de operare iOS sunt scrise într­un limbaj de programare orientat pe obiecte , dezvoltat de către Apple , denumit „Objective­C”. Mediul integrat de dezvoltare (IDE) folosit este Xcode, de asemenea un produs al companiei Apple.

Scurtă descriere a conținutului licenței

În primă parte se va prezenta istoria sistemului de operare iOS împreună cu platforma digitală de distribuție a aplicațiilor dezvoltată si întreținută de Apple, Appstore.

În partea a doua se vor descrie tehnologiile dezvoltate de Apple pentru crearea aplicațiilor specifice acestei platforme. De asemenea se va vorbi și de tehnologii create pentru platforma iOS precum motorul grafic Cocos2d și motorul de simulare al fizicii Box2d, doua librării extrem de folosite și des întâlnite în aplicațiile existente în AppStore.

În partea a treia va fi prezentat jocul Dream Tim, de la detalii tehnice despre codul sursa pana la lansarea lui în AppStore si evoluția lui pe o perioada de un an.

Specificații generale joc Dream Tim

Jocul Dream Tim face parte din categoria jocurilor infinite, insemnand ca scopul jucatorului este de a obtine un scor si a parcurge o distanta cat mai mare, jocul neavand nivele. Pentru a parcurge o distanta cat mai mare, jucatorul trebuie sa elibereze calea eroului distrugand inamici sau obstacole care ii apar in cale folosind gesturi de glisare pe ecran.

Jocul Dream Tim prezinta povestea lui Tim a carui iubita a fost rapita, intreg jocul are ca scop salvarea ei. Acest lucru se intampla de­a lungul a 4 capitole, fiecare capitol avand un filmulet de prezentare a evenimetelor. Pentru a avansa in capitole juctorul trebuie sa indeplineasca o serie de misiuni, astfel desi modul de joc este repetitiv, jucatorul este supus unor incercari diferite de fiecare data, acestea avanseaza in dificultate odata cu avansarea prin capitole.

Pentru a ajuta jucatorul, Dream Tim prezinta un magazinul virtual de unde pot fi cumparate diverse abilitati noi sau puteri pentru erou, astfel sarcina este usurata. Drept sistem monetar jocul foloseste valuta „Coins” acestia se gasesc si pot fi adunati in timpul jocului, de asemenea ei pot fi cumparati si pe bani reali folosind sistemul de In­App Purchases, aceasta fiind una din modalitatile principale de monetizare a jocului. De asemenea jucatorul poate primi banuti si uitandu­se la reclame cu o durata de pana la 15s, astfel desi jocul este oferit gratis, acesta continte mai multe metode de monetizare, de la afisarea de reclame la oferirea de banuti acelor care sunt dispusi sa plateasca extra pentru a avea un avantaj.

Capitolul 1

Istoric

1.2 Istoria sistemului de operare iOS

Sistemul de operare disponibil pe dispozitivele Apple, poarta denumirea de iOS(fig.1.5), si se trage din sistemul de operare disponibil pe computerele personale Apple, OSX.

● iOS 1.0

a fost lansat cu primul iPhone, deși versiunile mai recente sunt printre cele mai avansate pe piață. Prima versiune a fost destul de rudimentară, aceasta venind cu câteva aplicații

preinstalate printre care un browser web Safari,

hărți Google, tastatură virtuală,etc.

● iOS 2.0

a fost lansat cu iPhone3Gcare printre multele îmbunătățiri aduse , a introdus AppStore­ul astfel aplicații care nu aparțineau companiei Apple puteau fi instalate. De asemenea odată cu el a fost introdus kitul de dezvoltare Apple, cu care dezvoltatorii putea produce aplicații.

● iOS 3.0

a fost lansat odată cu iPhone3Gs la care printre îmbunătățiri se numără posibilitatea de a da copy și paste, MMS­uri, notificații de tip push, o funcție de căutare cu ajutorul căreia utilizatorii puteau căuta în tot telefonul.

● iOS 4.0

a fost lansat odată cu iPhone4, lansare care a însemnat renunțarea suportului pentru dispozitivele mai vechi. Această versiune a introdus suportul pentru multitasking, foldere pentru aplicații, verificarea scrisului, FaceTime și suport pentru ecranul retina. FaceTime permite userului să facă convorbiri video prin intermediul rețelei wifi.

● iOS 5.0

a fost lansat cu iPhone 4S si odată cu el s­a renunțat la suportul pentru dispozitive mai vechi, în cazul acesta la iPhone3G. Acesta a adus multe îmbunătățiri prin care un centru de notificări regândit, iMessage, un sistem de mesagerie text între useri de iPhone fără costuri. Apple a introdus și iCloud, fiecare client Apple având acces la 5Gb de stocare cu opțiunea de

a mări spațiul de stocare contra cost. De asemenea telefoanele ce rulează iOS5 au posibilitatea de a funcționa ca router wireless putând să se conecteze prin intermediul lui până la 5 calculatoare la internet.

● iOS 6.0

A fost lansat odata cu iPhone 5, deoarece noul dispozitiv a venit cu un ecran mai mare si anume de 4 inch, noul sistem de operare a venit cu multe imbunatatiri care sa beneficieze de noul ecran, de asemenea si de o serie de librarii noi care sa ajute dezvoltatorii sa actualizeze aplicatiile pentru noul ecran. Pe langa acestea sistemul de operare a adus noi functii de socializare precum suport pentru Facebook si Twitter, abilitatea de a face poze Panoramice, harti noi cu abilitatea de a afisa orasele in mod 3D si multe altele

● iOS7

A fost lansat cu iPhone 5s si reprezinta cea mai semnificativa schimbare la sistem de operare iOS, designul fiind complet schimbat si fiind introduse o sumedenie de functii noi. Odata cu noul sistem de operare s­a renuntat la skeumorfism si a fost introdus un design modern plat. Printre cele mai importante functii noi se numara, centrul de control, care permite acum setarea mai multor functii a telefonului de oriunde din sistemul de operare, precum luminozitate, bluetooth, wireless, desi controlarea muzicii si multe altele. Centrul de notificari a fost schimbat complet el fiind capabil sa afiseze informatii despre toate notificarile din telefon, precum si calendar si memouri. Camera a fost imbunatatita din nou, introducand un mod nou de filmare in slow motion. De asemenea cea mai importanta functie este deblocarea telefonului si efectuarea de plati folosind amprenta utilizatorului. Cititorul de amprenta fiind introdus odata cu iPhone 5s.

● iOS8

Aceasta versiune a sistemului de operare pe langa multe functii noi pentru userii normali el a a fost dedicata in mare masura dezvoltatorilor de aplicatii. In aceasta versiune au fost

introduse Health Kit, un serviciu ce permite citirea semnelor vitale pentru folosirea in aplicatii de fitnes sau de sanatate, Home Kit, ce permite automatizarea caselor utilizatorilor sau Cloud Kit ce permite stocarea de informatii in cloud. De asemenea cu aceasta versiune a fost

introdus si un limbaj nou de programare numit Swift, acesta fiind de 10 ori mai rapid ca vechiile limbaje de programare precum Objective­C.

1.3 Istoria magazinului online AppStore

Appstore­ul(fig.1.6) este o platforma digitală de distribuție a aplicațiilor dezvoltată si întreținută de Apple. Serviciul permite utilizatorilor să caute și să descarce aplicații care au fost concepute cu kitul de dezvoltare Apple.În magazin se găsesc aplicații atât gratis cât și contra cost. Aplicațiile pot fi descărcate direct pe dispozitiv sau pe calculator prin intermediul programului iTunes.

Appstore­ul a fost lansat în 2008 odată cu lansarea sistemului de operare iOS 2.0

printr­un update a programului iTunes.La foarte scurt timp, Appstore a devenit cel mai mare magazin digital de aplicații înregistrând descărcări record.În momentul lansării magazinul conținea 500 de aplicații din care 25% erau gratis, domeniul aplicațiilor se întindea de la jocuri, la aplicații de afaceri.În primul weekend de la lansare s­au descărcat în jur de 10 milioane de unități. În 23 aprilie 2009 Apple a anunțat descărcarea cu numărul 1 miliard. În momentul de față au fost descărcate mai mult de 40 de miliarde de aplicații, iar în magazin sunt disponibile peste 1.000.000 de aplicații.

dezvoltatorilor.

Pentru a putea avea aplicațiile create disponibile pe App Store(fig.1.7) , dezvoltatorii trebuie să fie înregistrați în programul “Apple Developer” , ceea ce presupune plata unei taxe anuale de

99$, iar înainte ca aplicația să fie adăugată platformei de distribuție , ea va fi supusă unui proces de testare, realizat de Apple. În cadrul testelor se caută memory leak­uri, crash­uri și ca aplicația să respecte ghidul de interacțiune cu utilizatorul, furnizat

de către Apple. 30% din venitul total generat de aplicații revine lui Apple, restul de 70% fiind alocat

Deoarece numarul de aplicatii este extrem de mare si este din ce in ce mai greu de a iti face aplicatiile sau jocurile descoperite, in iOS8 au fost introduse o multime de unelte noi pentru a ajuta dezvoltatorii. Pe langa metodele traditionale de promovare precum capturi ale ecranului aplicatiei sau o descriere cat mai detaliata, au fost introduse capturi video, ce ofera dezvoltatorilor posibilitatea de a oferii videouri scurte de pana la 30 de secunde cu aplicatia in

actiune asfelt avand o modalitate in plus de a convinge utilizatorul sa o achizitioneze. De asemenea au fost introduse si o sumedenie de elemente ce au ca scop ajutarea utilizatorilor sa gaseasca ceea ce cauta, precum termeni generati in baza preferintelor lor, sau afisarea celor mai populare cautari.

În momentul de față există mai multe platforme digitale de distribuție a aplicațiilor competitive cu cea a companiei Apple. Una este magazinul Google Play, creat special pentru sistemul de operare Android, magazinul AppWorld creat pentru aplicațiile BlackBerry, Apps for Windows, un magazin pentru

Capitolul 2

Tehnologii folosite

2.1.Kit­ul de dezvoltare Apple

Kit­ul de dezvoltare Apple (fig. 2.1) permite dezvoltatorilor de aplicații să creeze software special pentru dispozitivele companiei Apple. Kit­ul permite dezvoltarea aplicațiilor destinate atât sistemului de operare iOS cât și sistemului de operare OS X. Kit­ul este scris în totalitate în limbajul de programare orientat pe obiecte "Objective­C" iar mediul integrat de dezvoltare în care se pot folosii aceste librării se numește XCode.

Mediul integrat de dezvoltare XCode

Xcode este un mediu de dezvoltare integrat care conține o suita de unelte create de compania

Apple folosite la dezvoltarea aplicațiilor destinate sistemelor de operare iOS și OS X. Xcode integrează toate uneltele necesare, interfața unificată permite tranzițiile ușoare între compoziția codului sursă la funcțiile de depanare a acestuia și chiar la modificarea designului aplicației în timp real. Mediul de dezvoltare este alcătuit dintr­o singură fereastră(fig.2.2) care folosește mai multe elemente de interacțiune cu utilizatorul în așa fel încât zona de lucru sa nu fie înghesuită.

Fig.2.2 Mediul de dezvoltare Xcode

Printre cele mai importante caracteristici ale mediului integrat de dezvoltare Xcode se numără:

● Asistentul editor(fig. 2.3)

Acest buton împarte zona de lucru în două care în mod

automat afișează informațiile cele mai importante pentru utilizator bazându­se pe informații precedente.

● Editor cod sursa

Editorul codului sursă permite funcții de autocompletare și colorare a sintagmelor în funcție de scopul lor, afișează mesaje de eroare, atenționare în rând cu cai importante caracteristici ale mediului integrat de dezvoltare Xcode se numără:

● Asistentul editor(fig. 2.3)

Acest buton împarte zona de lucru în două care în mod

automat afișează informațiile cele mai importante pentru utilizator bazându­se pe informații precedente.

● Editor cod sursa

Editorul codului sursă permite funcții de autocompletare și colorare a sintagmelor în funcție de scopul lor, afișează mesaje de eroare, atenționare în rând cu codul. Codul este verificat în timp real, astfel dacă sunt erori, nu este necesară compilarea codului pentru ca Xcode să le afișeze.

● Interface Builder

Interface este o alta ramură a acestui mediu de dezvoltare care permite crearea designului aplicației. Aici se găsesc toate elementele de care un dezvoltator de aplicații are nevoie precum butoane, tabele pentru afișarea datelor, etichete, controllere segmentate, butoane de navigare, bara pentru afișarea progresului, butoane de tip switch, segmente pentru afișarea textului, a imaginilor, etc.

● Simulator iOS

Xcode are integrat și un simulator iOS, acesta simulează toate dispozitivele care rulează sistemul de operare iOS astfel utilizatorii pot testa aplicațiile direct pe computer înainte de a le introduce în dispozitiv.

● Organizer

Organizer este secțiune Xcode unde utilizatorii acestui mediu își pot organiza aplicațiile, pot crea arhive, aici sunt înregistrate toate dispozitivele pe care va putea fi adăugata aplicația pentru a putea fi testată. Numărul maxim de dispozitive permise este de 100. De asemenea Organizer se folosește pentru a trimite aplicațiile finisate în AppStore.

● Documentație completă

Xcode conține toată documentația kit­ului de dezvoltare Apple și permite căutarea informațiilor fie direct din codul sursă, fie folosind funcția de căutare.

O alta aplicație a mediului integrat de dezvoltare pe lângă Xcode este Instruments. Instruments permite vizualizarea statisticilor aplicațiilor în timp real, astfel acestea pot fi optimizate reducând șansele ca acestea să conțină erori sau pierderi de memorie. Instruments (fig.2.4) permite vizualizarea consumului de baterie, consumului memoriei ram, daca exista scăpări de memorie, câte procese folosește aplicația din CPU, etc.

Fig. 2.4.Tipuri Analize Instrumets

Odată selectat tipul de analiză la care se dorește supunerea aplicației, Instruments colectează datele și le afișează în timp real(fig.2.5). Daca se descoperă ceva în neregula în graficul performanței aplicației, Instruments permite inspectarea elementelor în cauză direct în codul sursă, astfel optimizarea se face mult mai rapid și mai eficient.

Fig.2.5 Analiza folosind Instruments

Când se creează un nou proiect, Xcode vine cu o serie de template­uri pre­definite pentru a ajuta dezvoltatori să seteze proiectul în funcție de nevoile lor (fig.2.6).

Fig.2.6 Template-uri pentru proiecte

Există mai multe tipuri de aplicații predefinite, printre acestea se numără aplicații tabelare care prezintă informația în tabele, aplicații openGL specifice jocurilor, aplicații utilitare și aplicații de paginare. Odată selectat tipul de aplicație care se dorește a fi creat, dezvoltatorul va folosii kit­ul de dezvoltare Apple pentru a obține acest lucru.

Kit­ul de dezvoltare iOS

Kit­ul de dezvoltare iOS funcționează doar pe computere Mac ce rulează de la sistemul de operare Mac OS X Leopard în sus. Fiecare versiune a kit­ului este valabilă pentru propria ei versiune de iOS. Deși kit­ul poate fi instalat gratis, pentru a putea beneficia de toate uneltele dezvoltatorii trebuie să se înroleze în programul de dezvoltatori Apple, acesta costă 99 de dolari pe an. Plătind această sumă , dezvoltatorii beneficiază de toate

uneltele necesare creări aplicațiilor, de asemenea și de dreptul de a le publica în AppStore. Kit­ul este scris în marea majoritate în "Objective­C" limbaj de programare orientat pe obiecte și poate fi împărțit în mai multe straturi (layers) (fig.2.7).

● Cocoa Touch Layer

Stratul Cocoa Touch conține

librăriile cheie necesare pentru construirea

aplicațiilor de tip iOS. Acest strat definește

infrastructura de baza a aplicației și prezintă suport pentru tehnologiile de baza precum multitasking, notificări de tip push , etc.

Printre cele mai importante librarii din Cocoa Touch (fig.2.8) sunt Fundation Kit care prezintă clasele te tip non­UI și librăria UIKit.Librăria Fundation prezintă clasele de bază din spatele fiecărei aplicație precum, folosirea memoriei, mutabilitatea și comportamentul obiectelor, notificări și multe altele. Această librărie conține clasa mama care este moștenită de toate celelalte clase NSObject. Pe baza acesteia se face programarea orientată pe obiecte.

Librăria UIKit prezintă toate elementele vizuale cu care interacționează utilizatorii, precum ferestre, butoane, dialoguri, meniuri, etc. Clasele Window, View și Application oferă librăriei UIKit funcționalitățile de bază. Fiecare clasa joacă un rol crucial în a prezenta utilizatorului informațiile corespunzătoare acțiunilor acestuia.

Pe lângă cele doua librării Cocoa Touch mai conține o colecție de librării care permit crearea de grafică 3D, sunet profesional, acces la cameră, GPS și accelerometru. Mai conține și librării care prin doar câteva linii de cod îndeplinesc funcții extrem de complexe precum, Core Animation, Core Audio, și Core Data.

● Media Layer

Stratul media conține tehnologiile grafice, audio și video orientate spre a crea o experiență multimedia cât mai bună posibilă.

1. Tehnologia Grafică

Cel mai simplu mod de a folosii grafică în aplicații este prin a folosii imagini predefinite sau sprite­uri, în cazul în care folosirea imaginilor predefinite nu este suficientă și se dorește o funcționalitate mai avansată, Apple pune la dispoziție o serie de librarii grafice. Printre cele mai importante librarii grafice se număra Core Graphics construită în așa fel încât să rendeze nativ imagini în doua dimensiuni. Core Animations folosit pentru a se crea animații. OpenGL ES și GLKit oferă suport pentru rendare de grafică în două dimensiuni și trei dimensiuni folosind interfața hardware, astfel grafica se generează programatic și nu prin folosirea pozelor.

În ceea ce privește grafica, sistemul iOS vine în doua dimensiuni, una normala și una retina. Dimensiunea retina prezintă o densitate dubla de pixeli fața de cea normală. Pentru ca aplicația să funcționeze corect pe toate dispozitivele, grafica trebuie creată în ambele formate.

2. Tehnologia Audio

Această tehnologie permite redarea și înregistrarea sunetului folosind o serie de librării. În funcție de librărie acestea pot fi mai ușor de folosit dar nu așa complexe. Librăria Media Player oferă acces ușorlibrăriei de muzică din iTunes putând să redea melodii și playlist­uri. Librăria AV Foundation oferă o modalitate ușoară de a reda sunetul și efectele în aplicații. Cea mai complexă librărie este Core Audio aceasta oferă posibilitatea de a reda și înregistra sunetul în aplicații, de asemenea poate reda și vibrații. Formatele suportate de tehnologia audio sunt:

AAC

Apple Lossless (ALAC) A­law

IMA/ADPCM (IMA4) Linear PCM

µ­law

DVI/Intel IMA ADPCM Microsoft GSM 6.10

AES3­2003 etc.

3. Tehnologia video

Această tehnologie este folosită pentru redarea fișierelor de tip video, de asemenea poate fi folosită pentru a filma și a integra acestea în aplicații proprii. Pentru o interfață standard de înregistrare video se folosește clasa din librăria UIKit, UIImagePickerController. Librăria Media Player oferă o serie de interfețe ușor de folosit

pentru a reda video­uri în aplicațiile proprii. Printre formatele suportate se numără .m4v,

.mp4, .mov, .3gp, etc.

● Core Services Layer

Acest strat prezintă serviciile fundamentale de care aplicațiile ar putea beneficia. Printre acestea se număra In­App Purchases, acest serviciu dă posibilitatea dezvoltatorului să vândă conținut și servicii din interiorul aplicației, precum valută virtuală. Acest serviciu se implementează folosind librăria StoreKit care conține infrastructura necesară pentru a procesa tranzacții financiare folosind contul utilizatorului de iTunes.

SQ­Lite iți oferă accesul la o bază de date din aplicație fără a fi nevoit să apelezi la un server.Din interiorul aplicației se pot crea baze de date locale care pot fi citite, scrise și actualizate.

Un alt serviciu este suportul fișierelor de tip XML, librăria Foundation prezintă o clasă NSXMLParser care returnează elemente dintr­un document de tip xml. O altă librărie importantă este Core Location, aceasta oferind aplicației informații în legătură cu locația dispozitivului folosind rețeaua telefonica, rețele wireless sau GPS.

Odată cu introducerea ultimului sistem de operare iOS 5, Apple a introdus conceptul de ARC(Automatic Reference Counting )(fig.2.9), acesta este o caracteristică la nivel de compilator care simplifică procesul de a administra timpul de viață a obiectelor de tip Objective­C.

Fig.2.9 Structura ARC

În loc să se ocupe manual dezvoltatorul, de reținerea și ștergerea obiectelor în aplicație, procedură care poate cauza ușor pierderi de memorie și bug­uri, ARC se ocupă automat.

● Core OS Layer

Acest strat conține caracteristicile care se găsesc la baza tuturor librăriilor din iOS. Chiar daca nu se lucrează direct cu ele în aplicații, acestea sunt cu siguranță folosite de celelalte librării. În cazul în care se dorește comunicarea dispozitivului cu elemente de tip hardware din exterior, acest lucru se face folosind acest strat.

Core Bluetooth este o librărie care lasă developer­ul să interacționeze cu accesorii de tip bluetooth, căști, boxe, etc. Interfața de tip Objective­C al acestei librării permite scanarea pentru accesorii, de asemenea conectarea și deconectarea în cazul în care se găsește accesorii compatibile și funcția de scriere și citire.

Pe lângă elementele de securitate ale sistemului de operare dezvoltatorii mai pot folosii librăria Security pentru a garanta securitatea datelor cu care lucrează aplicația dezvoltată. Această librărie oferă suport și pentru stocarea de certificate si chei criptate fiind un recipient securizat pentru informații sensibile.

Tot în acest strat dezvoltatorii pot avea acces la docul conector, la care se pot conecta accesorii folosind librăria External Accessory. Această librărie pune la dispoziție o modalitate de a obține informații de la dispozitivele externe compatibile pentru a se iniția o sesiune de comunicare. După ce s­a creat o conecțiune dezvoltatorul poate manipula dispozitivul extern direct folosind comenzile suportate de acesta

2.2 Motorul grafic Cocos2d

Cocos2d (fig.2.10) este o librărie grafică pentru crearea jocurilor sau aplicațiilor de tip grafic în două dimensiuniscrisă de

16

Ricardo Quesada. Această librărie este extrem de populară datorită faptului ca este gratis și open source, comunitatea dezvoltatorilor de aplicații care folosesc Cocos2d este extrem de numeroasă, librăria fiind folosită atât de dezvoltatori independenți cât și de companii mari precum Zynga sau Atari. În momentul de față sunt peste 2500 de aplicații care folosesc motorul grafic Cocos2d în AppStore, multe dintre ele reușind să devină aplicații de top.

Printre cele mai importante caracteristici se numără

integrarea ușoară cu motoare de simulare a fizicii precum Box2d și

Chipmunk. Librăria poate fi folosită atât pentru crearea aplicațiilor

mobile cât si pentru crearea aplicațiilor destinate sistemului de operare OS X(sistem de operare folosit de Mac­uri). Printre caracteristici se mai numără și tranziții predefinite între scene, acțiuni predefinite precum, acțiuni de mișcare, rotire, de modificare a scării elementelor. De asemenea Cocos2d vine cu funcții de pauză și reluare a jocului gata integrate și suportă texturi pe 8 biți, 16 biți și 32 biți. Limbajul de programare al librăriei este Objective­C.

Această librărie introduce câteva concepte importante care stau la baza fiecărei aplicație creată cu acest motor grafic.

● CCScene(Scena)

Prima este Scena, o scena (implementată cu clasa CCScene) este mai mult sau mai puțin o piesă independentă în aplicație, ea poate fi un meniu, un stagiu în joc, ecran de introducere, ecran pentru opțiuni, etc. O aplicație poate avea mai multe scene însă doar una poate fi activă în orice moment. Singurul caz în care doua scene sunt active este atunci când o a doua scenă este "împinsă" peste prima, caz în care prima este pusă pe pauză revenind la normal abia când a doua devine inactivă. Fiecare scenă poate fi programată separat față de celelalte însă ele

sunt conectate intre ele fiecare știind când trebuie să fie activă. De exemplu când se termină scena de intro se dezactivează și activă devine scena meniului, dacă utilizatorul a terminat cu succes stagiul 1 al jocului acesta este trimis la scena de tranziție câștigătoare , în caz contrar este trimis la scena de tranziție pierzătoare (fig.2.11).

Fig.2.11 Diagrama scene

O scenă este un obiect special care conține toate elementele vizibile pe ecran. În mod normal la crearea unui joc, se folosește o scenă pentru partea dedicată jocului propriu­zis și restul pentru meniul principal, opțiuni, pagina cu scoruri, etc. O scenă este activă dacă este vizibilă pe ecran, are acțiuni care progresează, etc.

O scenă este de asemenea un recipient care conține unul sau mai multe straturi (straturile sunt implementate folosind obiectul CCLayer), straturile se suprapun și au un număr de ordine. Dacă scena este responsabilă să prezinte straturile suprapuse în ordinea

corespunzătoare, straturile sunt responsabile să redea întreaga acțiune a jocului. Scenele

conțin mai multe tipuri de tranziții, acestea sun accesate folosind obiectul CCTransitionScene, obiect ce permite trecerea de la o scena la alta printr­o serie de tranziții predefinite.

Implementarea unei scene se face astfel:

+(CCScene *) scene

{

// se creează scena

CCScene *scene = [CCScene node];

// se creează stratul

HelloWorldLayer *layer = [HelloWorldLayernode];

// se adaugă stratul scenei

[scene addChild: layer];

// se returnează scene return scene;

}

● CCDirector(director­ul)

Un alt concept important este conceptul de director, CCDirector este componenta din spate care se asigură că trecerea de la o scenă la alta se face corect. Obiectul CCDirector este un obiect de tip singleton, el știe tot timpul ce scenă este activă și ce scenă urmează să fie activă astfel poate afișa scenele corespunzătoare acțiunilor utilizatorilor. În momentul în care se dorește schimbarea scenei, se accesează metoda din Director:

// înlocuiește scena actuală cu noua scenă

[[CCDirectorsharedDirector] replaceScene: [ScenăNouăLayerscene]];

Această sintagma oprește scena actuală și o înlocuiește cu noua scena. Pentru a pune pe pauză scena curentă și a accesa alta, se folosește sintagma "pushScene", pentru ca mai târziu pentru

a se reveni la prima scenă se folosește sintagma "popScene". Printre altele Directorul este responsabil cu punerea pe pauză și reluarea activității aplicației. În director se poate seta formatul de pixeli, cel standard este RGB565, o alta caracteristică importantă a directorului este faptul că prin el se poate schimba orientarea ecranului, orientarea standard fiind portret.

//stoparea activității

[[CCDirectorsharedDirector] pause];

//reluarea activitații

[[CCDirectorsharedDirector] resume];

//setarea orientării dispozitivului

[director setDeviceOrientation:kCCDeviceOrientationPortrait];

● CCLayer (stratul)

Unul din cele mai importante concepte introduse de cocos2d este stratul sau CCLayer, acesta este obiectul unde are loc desenarea întregului joc. Aceste straturi pot fi semi transparente, opace, să aibă găuri, etc. astfel permițând utilizatorului sa vadă și straturile din spatele lor. Straturile sunt acelea care definesc apariția și comportamentul jocului, astfel cea mai mare parte a programării va avea loc în subclase ale CCLayer care vor îndeplini toate cerințele. În figura de mai jos (fig.2.12) se poate observa o scenă care conține 3 straturi. Unul

pentru imaginea de fundal, unul pentru animația caracterului din joc și ultimul pentru butoanele de meniu.

Fig.2.12 Scena cu 3 straturi

În CCLayer se vor defini toate manipulatoarele de evenimente, evenimentele se vor propaga în toate straturile pana când unul din ele va răspunde evenimentului. Straturile pot conține elemente grafice de tip CCSprite. Implementarea unui strat se face astfel:

//se creează o instanță a stratului

CCLayer* strat=[ExempluStratnode];

//se stabilește poziția lui

[strat setPosition:ccp(screenSize.width/2, screenSize.height/2)];

//se adaugă sub formă de copil la stratul curent și se setează ordinea

[selfaddChild: strat z:2];

● CCSprite (imaginile)

Sprite­urile sunt imagini de tip 2d care pot fi mutate, animate, rotite, etc. Sprite­urile implementate folosind clasa CCSprite, pot conține mai multe imagini, când un sprite este modificat, toate imaginile conținute în acel sprite se modifică. Cel mai eficient mod de a lucra cu sprite­uri se face prin folosirea unui "Spritesheet" (fig.2.13). Spritesheet­ul este o colecție de sprite­uri care sunt împachetate într­un fișier mare. Cu cât sunt mai multe sprite­uri într­un fișier mare cu atât se folosește mai puțină memorie la redarea texturilor.

Adăugarea unui sprite se face astfel:

//se creează o instanță a imagini

CCSprite *tapet = [CCSpritespriteWithFile:@"bck.png"];

//se setează poziția

[tapetsetPosition:ccp(screenSize.width/2, screenSize.height/2)];

//se adaugă imaginea la stratul curent cu ordinul 0 (cel mai în spate) [selfaddChild: tapetz:0];

● CCNode( node­ul)

Toate aceste clase sunt subclasele obiectului CCNode, CCNode este elementul grafic principal, tot ce este desenat sau tot ce desenează pe ecran face parte din clasa CCNode. Cele mai populare subclase ale lui CCNode sunt, CCScene, CCLayer, CCSprite și CCMenu. CCNode poate conține alte instanțe de tip CCNode, poate programa timer­e periodice, poate executa acțiuni, de asemenea poate aplica transformări directe subclaselor lui, poate modifica poziția, seta mărimea, ordinul z, rotația în grade, etc.

Ca în fiecare motor de grafică, Cocos2d conține două metode de a actualiza și desena obiecte pe ecran. Prima metodă este metoda Draw, fiecare node are o metodă Draw, aceasta este accesată de 60 de ori pe secundă (Cocos2d rulează la 60 de frame­uri pe secundă) și singurul ei scop este acela de a actualiza node­ul și nimic altceva. A doua metodă este metoda update, implicit nici un node nu are metoda update implementată. Metoda update este folosită de fiecare programator în funcție de necesitate. Spre deosebire de Draw, aceasta trebuie implementată manual în node și este activă doar atâta timp cât node­ul se afla pe scenă. Metoda update nu se actualizează daca Directorul este pus pe pauză. Timpul delta este primit ca argument. Pentru a activa metoda Update se folosește [self scheduleUpdate], pentru a dezactiva o metoda update se folosește sintagma [self unscheduleUpdate].

//se face activarea metodei tick(aceasta va fi accesată de 60 de ori pe secundă) [selfschedule: @selector(tick:)];

­(void) tick: (ccTime) dt

{

//în această metodă are loc actualizarea jocului

}

● CCMenu (meniul)

O altă componentă importantă a motorului Cocos2d este CCMenu. Cocos2d permite ușor crearea meniurilor necesare navigării în aplicație. Crearea meniurilor se face folosind obiectul CCMenu. Meniurile (fig.2.14) sunt o modalitate familiară prin

care utilizatorii pot interacționa cu aplicația, de cele mai multe ori meniul comunica direct cu Directorul spunând­ui acestuia să schimbe scenele dar in același timp pot fi folosite drept controlle­re în joc. Cocos2d

dispune de mai multe tipuri de meniuri, singura diferență

între ele fiind modul de afișare, butoanele putând fi de tip text sau imagini. Meniurile permit selectarea unui target și a unei funcții care să fie chemată în momentul în care user­ul apasă

butonul. Obiectul CCMenu îți permite de asemenea mai multe modalități de afișare a butoanelor, acestea putând fi aliniate pe verticală sau pe orizontală, de asemenea se poate specifica distanța în pixeli dintre ele.

Crearea meniurilor se face astfel:

//crearea unui meniu cu butoane din poze

//se creează pozele pentru buton în ambele stări

CCSprite* butonApăsat=[CCSpritespriteWithFile:@"butonApăsat.png"]; CCSprite* butonNeapăsat=[CCSpritespriteWithFile:@"butonNeapăsat.png"];

//se adaugă imaginile la butonul meniului și funcția care va fi apelată în momentul apăsări CCMenuItemSprite *butonMeniu=[CCMenuItemSpriteitemFromNormalSprite:butonApăsat selectedSprite:butonNeapăsat target:selfselector:@selector(funcțieApelată)];

//se creează meniul care este defapt un array de butoane CCMenu* meniu = [CCMenu menuWithItems:butonMeniu,nil];

//se setează poziția

[meniusetPosition:

ccp(screenSize.width/2, screenSize.height­140)];

//se adaugă la strat cu numărul de ordine

[selfaddChild:meniuz:2];

● CCActions( acțiuni)

Acțiunile sunt principalul mod în care elementele prezente pe scenă sunt transformate. Scopul acestora este în mare parte de a modifica atributele obiectelor ca și poziție, rotație, etc. dacă transformarea acestora are loc în timp, ele poartă denumirea de CCIntervalAction, daca acestea au loc instant poartă denumirea de acțiuni CCInstantAction. Spre exemplu acțiunea CCMoveTo schimbă poziția obiectului în timp, de unde rezultă ca este o acțiune de tip CCIntervalAction.

//se definește tipul de acțiune dorită cu parametrii precum durație și pozițieacțiune =

[CCMoveToactionWithDuration:0.5fposition:ccp(60, screenSize.height/2)];

//se aplica acțiunea obiectului dorit

[obiectrunAction:acțiune];

Toate acțiunile relative precum CCMoveTo sau CCMoveBy, suportă o acțiune de tip reverse, care execută aceeași acțiune asupra obiectului dar în sens opus. Printre cele mai importante tipuri de acțiuni se numără, CCMoveBy, CCMoveTo, CCJumpBy,CCJumpTo,etc.

Cocos2d este o librărie într­o continua dezvoltare, astfel pe lângă numeroasele caracteristici care se găsesc acum în librărie, multe altele sunt adăugate constant. Cocos2d poate fi folosit atât pentru dezvoltarea aplicațiilor dedicate platformei iOS iPhone și iPad, cât și pentru dezvoltarea aplicațiilor destinate sistemului de operare Mac OS X.

2.3.Motorul de simulare al fizicii Box2d

Box2d (fig.2.15) este o librărie de simulare a fizicii pentru corpuri în jocuri. Dezvoltatorii pot folosi aceasta librărie pentru a face obiectele din jocuri să se miște într­un mod cât mai convingător și asemănător cu lumea reală.

Box2d este scris în limbajul de programare C++, majoritatea claselor începând cu prefixul "b2". Box2d folosește concepte de fizică precum forțe, masă, accelerație și impulsuri. Librăria este printre cele mai des întâlnite în jocurile 2d, printre exemple numărându­se și cel mai bine vândut joc al momentului, Angry Birds dezvoltat de Rovio.

Box2d este alcătuit din 3 module (fig.2.16), modulul comun, dinamic si de coliziune.

Modulul comun conține cod pentru alocare de memorie, calcule matematice și setări. Alocarea memoriei se face folosind un sistem denumit SOA (small object allocator) astfel box2d alocă blocuri de memorie de dimensiuni diferite încât atunci când se face o cerere de memorie, SOA returnează un bloc de memorie care este cel mai apropiat de dimensiunea cereri de memorie. Pentru calcule matematice box2d folosește vectori de dimensiuni reduse si matrici.

Modulul de coliziune definește forma corpurilor și funcțiile care operează asupra lor. Modulul de coliziune este creat în așa fel încât să poată fi folosit înafara modulului dinamic.

Astfel librăria poate fi utilizată și doar pentru detectarea coliziunii fără a fi necesară simularea fizicii. Formele corpurilor descriu geometria coliziunii și pot fi folosite independent de simularea fizicii. Se pot face mai multe operații cu ele:

● se poate testa daca un punct se suprapune cu o forma

● se poate calcula masa formei

● se pot calcula coordonatele formei

Formele pot fi cercuri sau poligoane(fig.2.17), singura condiție este ca poligoanele sa fie convexe, astfel daca se aleg doua puncte în poligon linia dintre ele nu are voie sa se intersecteze cu nici o latură a formei.

Un poligon se poate crea prin implementarea unei colecții de vertebre astfel:

//se creează colecția de vertebre b2Vec2 vertices[3];

vertices[0].Set(0.0f, 0.0f);

vertices[1].Set(1.0f, 0.0f);

vertices[2].Set(0.0f, 1.0f);

int32 count = 3;

//se creează poligonul, în acest caz un triunghi b2PolygonShape polygon;

polygon.Set(vertices, count);

Box2d vine cu multe forme predefinite precum cercuri, triunghiuri, pătrate, segmente liniare pentru a crea terenul din joc, etc. Modulul de coliziune conține și o serie de funcții bilaterale care iau o pereche de forme și calculează mai multe proprietăți precum:

● punctele de contact

● distanța între ele

● daca se suprapun

● timpul rămas până la impact

Modulul dinamic pune la dispoziție simularea lumii fizice, a corpurilor, proprietațiilor și constrângerilor. Modulul dinamic este cel mai important modul, el combinând atât modulul comun cât și cel de coliziune.

Modulul dinamic conține cele mai importante clase

● b2Shape (forma obiectului)

Un obiect în doua dimensiuni precum un cerc sau un poligon.

// forma corpului se definește cu o subclasa a clasei b2Shape b2PolygonShape boxDef; boxDef.SetAsBox(boxWidth,boxHeight);

● rigid Body (corp rigid)

Copurile rigide sunt atât de puternice încât distanța dintre oricare doua puncte ale acestui corp este constantă.

● b2Fixture(proprietăți)

Prin acest obiect se adaugă corpurilor box2d proprietăți precum formă, densitate, forță de frecare și restituție.

//se creează o instanța a clasei b2Fixture b2FixtureDef fixtureDefBox;

//prima proprietate este forma fixtureDefBox.shape = &boxDef;

//densitatea fixtureDefBox.density = 1.0F;

//forța de frecare(daca valoarea e 0.0f, corpul nu are frecare)

fixtureDefBox.friction = 0.3f;

//elasticitatea(daca valoarea e 0.0f, corpul nu este deloc elastic)

fixtureDefBox.restitution = 0.5f;

//se adaugă proprietațiile corpului boxBody­>CreateFixture(&fixtureDefBox);

Această funcție creează proprietațiile și le atașează corpului.Printre aceste proprietăți se numără:

⇒ densitatea(density)

­este folosită pentru a se calcula masa corpului și poate fi mai mare sau egala cu zero.

⇒ fricțiune(friction)

­ este folosită pentru a face corpurile sa alunece unul pe lângă celălalt într­un mod

realist.Puterea frecării este proporțională cu forța normala ce acționează asupra corpurilor. Parametrul fricțiuni poate avea valori între 0 și 1 , valoarea 0 înseamnă ca acel corp nu are frecare.

⇒ restituția(restitution)

­ este folosită pentru a stabili elasticitatea obiectelor.

Printre alte proprietăți care pot fi atașate corpurilor se numără și filtrarea după categorii, astfel corpurile vor intra în coliziune doar cu corpuri din aceeași categorie, corpurile pot fi setate și ca senzori, astfel ele sunt simulate normal doar ca ele nu răspund fizic coliziunii detectând doar faptul ca se intersectează.

● Constraints (constrângeri)

Corpurilor le putem impune constrângeri, astfel mișcarea lor în lumea 2d este limitată (corpurile au 3 feluri de libertate de mișcare, două de translație și una de rotație). Dacă luam un pendul, acesta este constrâns doar să se rotească.

● b2Joint( jointuri)

Un element important în box2d este articulația sub denumirea de "joint", scopul fiind acela de a lega două sau mai multe corpuri unul de altul. Există mai multe tipuri de joint­uri printre care joint prismatic, de distanță, de revoluție, etc. Unor tipuri de joint­uri se pot defini proprietăți precum, limita de mișcare și accelerația în cazul în care este un joint mobil(fig.2.18).

//se creează o instanță a clasei b2RevoluteJoint

//acesta este un joint de mișcare (fig.111)

b2RevoluteJointDef leftJointDef;

//se inițializează jointul intre corpuri

leftJointDef.Initialize(body1, body2, body2­>GetWorldCenter());

//se activează motorul joint­ului( jointul este de rotație, deci are mișcare)

leftJointDef.enableMotor = true;

//viteza lui

leftJointDef.motorSpeed = 0.0f;

//accelerația lui

leftJointDef.maxMotorTorque = 1000.0f;

//se creează jointul world­>CreateJoint(&leftJointDef);

● b2World( lumea unde are loc simularea)

Pentru a putea beneficia de simulările box2d, înainte de toate se definește lumea folosind sintagma "world", lumea fiind o colecție de corpuri proprietăți și constrângeri care interacționează împreună. Lumea fizica conține un obiect denumit "solver' scopul lui fiind acela de a avansa timpul simulării și de a rezolva contactele dintre obiecte, joint­uri și constrângeri. Acesta avansează corpurile în timp folosind pași de timp discret, dacă nu se folosesc pași de timp egali se poate crea efectul de "tunneling"(fig.2.19) între corpurile care se mișcă extrem de repede adică mișcarea unor corpuri nu poate fi calculata

și acestea se intersectează în loc sa intre în coliziune.

Box2d conține algoritmi speciali pentru a evita efectul de

tunneling, în primul rând avem algoritmul de coliziune care

poate interpola mișcarea a două corpuri astfel încât să calculeze timpul primului impact, în al doilea rând exista un timp secundar care mișca acele corpuri la primul timp al impactului și apoi rezolvă coliziunea.

Inițializarea lumii unde are loc simularea se face astfel:

//se setează forța de gravitate, în cazul acesta nu avem forță de gravitate b2Vec2 gravity = b2Vec2(0.0f,0.0f);

//acest boolean permite corpurilor inactive sa nu fie simulate, astfel se folosește mai puțină memorie bool doSleep = true;

//se creează lumea

world = newb2World(gravity, doSleep);

După cum se știe box2d nu este un motor grafic și nu știe sa redea imagini, astfel corpurile box2d au fost făcute să funcționeze sub forma unor panouri pe care se lipesc imagini. Lumea este un container pentru corpuri, contacte și jointuri. Toate aceste elemente pot fi accesate în orice moment al simulării și pot fi folosite, astfel putem accesa poziția tuturor corpurilor box2d și putem actualiza poziția pozelor să fie aceeași cu a corpurilor.

//prin această funcție for, se interoghează toate corpurile din lume for(b2Body *b=world­>GetBodyList(); b!=NULL; b=b­>GetNext()) {

//se verifică dacă acele corpuri au imagini atașate if (b­>GetUserData() != NULL) {

//daca da, se echivalează rotația și poziția imaginilor cu cea a corpurilor

Box2DSprite *sprite = (Box2DSprite *) b­>GetUserData();

sprite.position = ccp(b­>GetPosition().x * PTM_RATIO, b­>GetPosition().y * PTM_RATIO);

sprite.rotation = CC_RADIANS_TO_DEGREES(b­>GetAngle() * ­1);

}

}

Box2d lucrează cu unități de tipul metri­kilometri­secunde. Librăria a fost creată în

așa fel încât simularea să funcționeze bine cu obiecte între 0.1 și 10 metri. Asta însemnând că acele corpuri dinamice între dimensiunea unei conserve și a unui autobuz sunt simulate cel mai bine. Obiectele statice pot fi până la dimensiunea de 5 tri.

Când se creează corpuri de tip box2d acestea trebuie definite, aceste definiții conținând toate informațiile pentru a fi construit corpul și simulat corespunzător. Deoarece box2d nu este o librărie grafică, aceasta permite atașarea prin proprietatea "userData" a imaginilor corpurilor, astfel spre exemplu unui corp box2d rotund se poate atașa imaginea unei roate de noroc cu premii (fig.2.20) de aceeași dimensiune.

Corpurile pot fi de trei feluri:

● copuri statice (b2_staticBody)

­ acestea nu se mișcă sub influența simulării și se comportă ca și când ar avea masă infinită.

// se definește corpul de tipul static b2BodyDef bodyDef; bodyDef.type = b2_staticBody;

● corpuri cinematice (b2_kinematicBody)

­ aceste corpuri se mișca în timpul simulării în funcție de viteză, ele nu răspund forțelor, acestea pot fi mutate manual de user, dar de obicei se mișcă doar datorită vitezei.

// se definește corpul de tipul static b2BodyDef bodyDef;

bodyDef.type = b2_kinematicBody;

● corpuri dinamice (b2_dynamicBody)

­ acestea sunt simulate pe deplin, ele se mișca datorită forțelor care acționează asupra lor, acestea intră în coliziune cu toate celelalte tipuri de corpuri, au masa finită diferită de zero.

// se definește corpul de tipul static b2BodyDef bodyDef;

bodyDef.type = b2_dynamicBody;

Inițial corpurilor li se definește poziția și unghiul, de asemenea se poate defini și amortizarea aceasta este folosită pentru a reduce viteza corpului în timp, este diferită de forța de frecare deoarece aceasta apare când nu are loc frecarea între obiecte.

Mai jos putem vedea crearea completă a unui cerc folosind box2d:

// se definește corpul b2BodyDef bodyDef;

//tipul lui

bodyDef.type = b2_dynamicBody;

//poziția

bodyDef.position.Set(self.position.x/32.0f, self.position.y/32.0f);

//corpul se atașează unui obiect bodyDef.userData = self;

//se creează corpul în lume

_body = _world­>CreateBody(&bodyDef);

//se definește forma b2CircleShape circleShape;

circleShape.m_radius = (self.contentSize.width/2)/32;

//se definesc proprietățiile corpului b2FixtureDef fixtureDef;

//se atașează forma corpului fixtureDef.shape = &circleShape;

// se setează nivelul de elasticitate a corpului fixtureDef.restitution=0.2;

//se setează forța de frecare fixtureDef.friction=0.0;

//se setează densitatea fixtureDef.density=0.5;

//corpul va fi un senzor fixtureDef.isSensor=TRUE;

//se atașeazăproprietațile corpului creat

_body­>CreateFixture(&fixtureDef);

Odată creată lumea și corpurile, avem nevoie de o clasă care să răspundă la toate evenimentele ce au loc în această lume și anume la contacte. Box2d conține o clasa specială pentru contacte denumită b2Contact. Termenii asociați cu contactele sunt:

● punct de contact

­ punctul în care are loc contactul dintre două corpuri

● normala contactului

­ normala dintre corpurile care sunt în contact

● contacte multiple

­ când doua poligoane complexe intră în contact în mai multe puncte, aceste puncte au aceeași normala și sunt grupate într­un contact manifold

● impuls tangențial

­ forța tangentă generată la un punct de contact pentru a se putea simula forța de frecare

● separarea contactului

­ separația este negativă atunci când corpurile sunt în contact

Pentru a se putea obține date în urma contactului între corpuri, box2d pune la dispoziție o clasă denumită b2ContactListener. Această clasă poate returna începutul contactului, sfârșitul, înainte de început și informații în legătură cu impulsul coliziunii.

class MyContactListener : publicb2ContactListener {

public:

void BeginContact(b2Contact* contact) {

// această funcție este chemată când începe contactul

}

void EndContact(b2Contact* contact) {

// această funcție este chemată când se termină contactul

}

void PreSolve(b2Contact* contact, constb2Manifold* oldManifold) {

// această funcție este chemată când se detectează coliziunea dar înainte ca ea să se termine

}

void PostSolve(b2Contact* contact, constb2ContactImpulse* impulse) {

// în această funcție se strâng informații în legătură cu impulsul coliziunii

}

}

Chiar dacă box2d nu lucrează cu imagini, această librărie conține o clasă denumită b2DebugDraw(fig.2.21), rolul acesteia fiind acela de a desena detaliat elementele lumii fizice. Elementele ce pot fi desenate sunt forme, jointuri, centru de masa, etc.

//deoarece avem nevoie de dimensiunea in pixeli și box 2d lucrează în metri, se folosește rația de 32 în cazul iPhone­ului

m_debugDraw = newGLESDebugDraw(32);

//se inițializează funcția debug draw world­>SetDebugDraw(m_debugDraw);

//se setează elementele care se doresc a fi vizualizate pe ecran,în acest caz forme și jointuri m_debugDraw­>SetFlags(b2DebugDraw::e_shapeBit);

m_debugDraw­>SetFlags(b2DebugDraw::e_jointBit);

Capitolul 3

Jocul "Dream Tim"

3.1. Jocul "Dream Tim"

Proiectul constă în realizarea jocului "Dream Tim" pentru sistemul de operare iOS ce rulează pe dispozitivele mobile Apple. Jocul este destinat utilizatorilor de toate vârstele nivelul de dificultate crescând treptat, astfel modul de joc este accesibil tuturor.

Jocul a fost făcut folosind kit­ul de dezvoltare Apple, în combinație cu motorul grafic Cocos2d și motorul de simulare al fizicii Box2d. Jocul este o aplicație nativă iOS făcută în totalitate în mediul de dezvoltare Xcode, limbajul de programare folosit fiind Objective­C respectiv C++ în cazul librăriei Box2d.

Arhitectura generală a aplicației afișata în figura 3.1 prezintă felul în care sunt structurate ferestrele jocului și modul în care se navighează în aplicație.

Fig.3.1 Arhitectură joc Dream Tim

3.2.Design

Designul este cel mai important element într­o aplicație, elementele vizuale fiind primele lucruri cu care utilizatorii interacționează astfel daca designul nu este unul plăcut și intuitiv șansele sunt foarte mari ca utilizatorii să nu mai acceseze aplicația.

Odată accesat jocul, primul lucru afișat este ecranul de incarcare, acesta poate conține orice informatii, fiind o modalitate convenabilă de a

afișa logo­ul companiei, video­uri de introducere sau

animații.

În cazul jocului Dream Tim (fig.3.2), ecranul de loading prezintă într­o manieră minimalistă numele și logo­ul dezvoltatorului jocului.

După ce toate resursele au fost încărcate jocul prezintă direct fereastra meniului principal(fig.3.3). Această fereastră are rolul de a introduce imediat jucatorul in atmosfera jocului, deoarece actiunea are loc in visul eroului, in meniul principal ne este prezentata camera unde acesta doarme. De asemenea de aici se poate controla volumul sunetului si se pot accesa mai multe pagini ale jocului, precum pagina cu detalii despre creatorii jocului, pagina cu clasamentul mondial sau pagina cu filmuletele de prezentare a povestii jocului (fig.3.4). Pentru opțiuni(fig.3.5) și statistici s­a hotărât folosirea ferestrelor modale, acestea apar din partea stângă animat. Pentru design­ul celor două ferestre modale s­a ales modelul meniului găsit în restaurante astfel să se mențină tema jocului.

Fig.3.3 Meniu Principal Fig.3.4 Pagina de prezentare a povestii jocului

Fereastra de prezentare a povestii jocului prezinta cate o imagine pentru fiecare capitol, daca oricare din imagini este apasata atunci incepe rularea filmuletului corespunzator imaginii

respectiv a capitolului. Aceste filmulete nu sunt disponibile de la incepu ci ele trebuie mai intai deblocate prin completarea jocului. Fiecare filmulet prezinta evolutia povestii eroului. Scopul lor este acela de a semnala jucatorului ca a accesat un nou capitol si ca a avansat cu povestea.

După ce se apasă pe ecran si jocul este inceput pentru prima data, jucatorului ii este rulat primul filmulet corespunzator capitolului 1 care are rolul de a introduce jucatorul in povestea jocului(fig.3.5). Filmuletele de prezentare sunt semnalate prin aparitia a doua bari negre deasupra si in josul ecranului avand scopul de a simula ecranul unui cinematograf.

incheie rularea

Dupa ce se

filmuletului jucatorul, acesta incepe prima runda de joc(Fig.3.6), unde este intampinat de un tutorial avand scopul de a familiariza jucatorul cu modul de joc. Acesta invata toate modalitatiile in care poate interactiona cu jocul, astfel i se ofera toate informatiile necesare pentru a putea obtine un scor cat mai mare.

O runda se incheie in momentul in care jucatorul moare, fiind un joc infinit, jucatorul nu v­a putea castiga niciodata, el reusind doar sa obtina un scor doar mai mare. Dupa ce se incheie runda jucatorului ii este prezentat ecranul de final. Aici sunt prezentate mai multe informatii de interes pentru jucator precum scorul obtinut in ultima runda, scorul maxim obtinut vreodata la acest joc, numarul de banuti stransi in joc de asemenea numarul total de banuti pe

care jucatorul ii detine. Este prezentat si un mic clasament in care se afla doar prietenii jucatorului astfel acesta poate vedea instant unde se afla in comparatie cu restul. Din acest ecran jucatorul poate sa reintre in joc sau poate sa se duca la roata cu premii(Fig.3.8). De asemenea daca a strans suficienti banuti el poate intra in magazin pentru a achizitiona diverse puteri care sa ii dea un avantaj in fata jocului.

Roata cu premii are scopul de a oferii sansa jucatorului de a castiga orice premiu, indiferent

de pretul acestuia, pentru o suma de banuti fixa, 400. Astfel riscul jucatorului poate fi rasplatit prin castigarea pentru 400 de banuti a unui premiu care in mod normal costa 2000 de banuti.

Daca jucatorul nu doreste sa riste acesta poate accesa magazinul virtual al jocului de unde acesta poate cumpara orice putere. Magazinul virtual(Fig.3.9) este alcatuit dintr­o lista scrolabila ea continand toate puterile extra care pot fi cumparate

de jucator. Cand o putere este selectata in pozitia din dreapta listei

obiectul este afisat si acesta poate fi achizitionat. Fiecare obiect disponibil pentru cumparare

prezinta ca informatie numele sau, descrierea si pretul. Elementele din

magazin sunt de mai multe feluri, ele putand fi temporare sau permanente. O viata extra este temporara, insa o arma noua este permanenta. Pretul elementelor permanente este multa mai mare decat a celor temporare. Daca jucatorul nu are suficienti banuti pentru a achizitiona o anumita putere, acesta are opiunea de a se reintoarce in joc si a strange suficienti banuti sau el poate intra in magazinul cu banuti unde in schimbul banilor reali el poate achizitiona cantitati semnificative de banuti in joc.

Magazinul de banuti contine o lista scrolabila cu mai multe pachetele de banuti, astfel jucatorul poate alege valoarea cea mai potrivita pentru el. Pe langa metodele de a obtine banuti prin inregistrarea in retelele sociale ale jocului, in agest magazin exista si 5 pachete de banuti la 5 preturi diferite, cel mai mare pachet de 500.000 de banuti fiind oferit la pretul de 11 euro. Odata

achizitionate jucatorii pot cheltui banutii cumparand puteri din magazin sau jucandui la roata

de premii. Sistemul de plata se face prin intermediul companiei Apple, astfel desi

sunt folositi bani reali si cartile de credit ale utilizatorilor, tranzactia este extrem de sigura si rapida. Daca metodele traditionale nu functioneaza, jucatorii mai pot primii banuti uitandu­se la reclame video. Astfel pentru o reclama

video de 15s jucatorul primeste 100 de banuti.

Odata cumparate puteri extra jucatorii au abilitati noi ei putand sa obtina scoruri mai mari intr­un mod mai usor. Desi jocul este infinit jucatorii pot avansa cu povestea indeplinind misiuni, misiunile

vin in manunchiuri de 3(Fig.3.10), odata indeplinite toate 3 misiunile acestea se schimba, la

12 misiuni trecute jucatorul este avansat in urmatorul capitol, jocul avand in total 60 de misiuni si 5 capitole. Pentru a rasplatii jucatorii care indeplinesc misiunile si avanseaza in nivel a fost introdusa o sectiune speciala de premii(Fig.3.11), astfel jucatorului i se ofera sansa de a deschide 3 cutii cu banuti , desi toate au banuti in ele, unele au foarte multi altele au foarte putini. De asemenea pentru a rasplatii jucatorii care avanseaza in capitole, odata cu

trecerea intr­un capitol nou, jocul adauga noi premii pe roata(Fig.3.12) cu premii

scopul fiind acela de a oferii acestor jucatori si mai multe modalitati de a obtine puteri care sa le dea un avantaj in fata prieteniilor. Exista 5 roti cu premii in total, ultima roata avand 18 sectiuni, din care 4 sunt pierzatoare, iar restul difera de la arme noi la puteri, toate premiile

castigate la roata cu premii sunt temporare ele fiind disponibile pentru doar o runda de joc, astfel chiar daca un element castigat la roata poate fi cumparat permanent in magazin, acesta este disponibil doar o runda.

Grafica intregului joc combina culori cu o tenta mai inchisa combinata cu culori vii, stilul ales simuleaza pictura cu acuarele pe foaie, astfel in moemntul jocului ai impresia ca intreaga actiune are loc intr­un tablou. Intreaga grafica a fost facuta in programe speciale precum Photoshop, toate elementele grafice din joc fiind de tip .png (Portable Network Graphics).

Deoarece memoria disponibilă pe dispozitivele Apple este limitată, folosirea texturilor poate deveni destul de costisitoare mai ales în cazul în care se folosește un număr mare de texturi. Cu cât se folosește mai puțină memorie cu atât rulează mai bine jocul. Aceste dispozitive știu să citească texturi doar cu dimensiuni de ordin doi, adică dacă o imagine de 129 x129 pixeli este folosită, dispozitivul v­a aloca o memorie cât pentru o textură de 256 x 256 pixeli deoarece este dimensiunea cea mai mică de ordin doi și cea mai apropiată de valoarea de 129 (fig.3.13).

Fig.3.13 Textură de 129px salvată într­o textură de 256px

Pentru a se evita astfel de pierderi de memorie, au fost introduse atlasele de texturi. Aceste atlase pot sa aibă dimensiuni de până la 2048 x 2048 pixeli. Folosind un atlas de texturi, problema memoriei irosite se elimină deoarece în acestea se pot introduce texturi astfel încât spațiul irosit sa fie cât mai mic. Un alt avantaj este că pentru a se desena o textură individuală pe ecran se apelează clasa OpenGL ES, ceea ce poate fi foarte costisitor mai ales în cazul în care este necesară desenarea mai multor texturi individuale pe ecran, apelarea clasei făcându­se pentru fiecare în parte. Daca se folosește un atlas de texturi (fig.3.14), este nevoie de o singură apelare pentru a desena toate texturile din atlas. Pentru a crea un atlas de texturi se pot folosi programe open source precum Zwoptex sau TexturePacker. Acestea generează un fișier de tip .pvr.ccz și unul de tip .plist unde se găsesc informații despre fiecare textură din atlas inclusiv nume, poziție, dimensiune, etc.

Fig.3.14 Atlas de texturi

Odată cu apariția noilor modele de telefoane iPhone, Apple a introdus ecranul retina. Ecranul retina are o densitate de pixeli de 326 per inch, având o rație de contrast de 800:1. Astfel rezoluția noilor dispozitive, începând cu iPhone 4 s­a dublat. Daca versiunile inițiale aveau o rezoluție de 320 x 480 px, dispozitivele retina vin cu o rezoluție dublă. În materie de dezvoltare a aplicațiilor asta a însemnat că fiecare element grafic a trebuit adăugat de două

ori, odată la dimensiunea normala și o dată la dimensiunea dublată retina, astfel în funcție de dispozitiv se folosea grafica corespunzătoare (fig.3.15).

Fig.3.15 Element în joc de la stanga la dreapta: normal și retina.

Datorită existenței accelerometrului, aplicațiile pot fi afișate în funcție de cum ține utilizatorul telefonul în mană, astfel chiar dacă îl rotește aplicația își va menține poziția corectă. Modurile în care pot fi afișate aplicațiile sunt, Portret, Portret cu susul în jos, Peisaj Dreapta sau peisaj Stânga. Jocul Dream Tim are suport pentru doar două moduri de afișare, Peisaj Stanga și Peisaj Dreapta.

3.3.Implementare

Jocul Dream Tim a fost creat în totalitate folosind mediul integrat de dezvoltare Xcode. Limbajul de programare folosit a fost Objective­C și C++ pentru clasele responsabile cu simularea fizicii în joc. Clasele folosite în xcode sunt alcătuite din doua fișiere, unul de tip.h denumit și header unde are loc definirea variabilelor, claselor și a proprietațiilor și un fișier de .m unde are loc implementarea clasei. Deoarece s­a folosit librăria Box2d scrisă în C++ toate clasele unde s­a făcut referire la această librărie trebuie notate cu terminația .mm, astfel compilatorul știe că limbajul de programare existent va fi Objective­C++.

În momentul în care jocul este rulat, prima clasă apelată este AppDelegate.h, aceasta este o clasă de tip delegat care este activă pe tot parcursul rulării jocului și este responsabilă cu inițializarea și configurarea tuturor elementelor existente în joc. Pași urmați de această clasa sunt:

// 1. Inițializează fereastra pe care vor rula scenele COCOS2D

window = [[UIWindowalloc] initWithFrame:[[UIScreenmainScreen] bounds]];

// 2. Inițializează directorul COCOS2D

CCDirector *director = [CCDirectorsharedDirector];

// 3. Adaugă fereastra directorului COCOS2D

EAGLView *glView = [EAGLViewviewWithFrame:[windowbounds]

pixelFormat:kEAGLColorFormatRGB565

depthFormat:0];

[director setOpenGLView:glView];

// 4. Se verifică daca dispozitivul are suport pentru retina, dacă da atunci se folosește grafica corespunzătoare

if( ! [director enableRetinaDisplay:YES] )

// 5. Se impune orientarea dispozitivului

[director setDeviceOrientation:kCCDeviceOrientationPortrait];

// 6. Se adaugă prima scena, scena meniului principal

[[CCDirectorsharedDirector]runWithScene:[MainMenuScene scene]];

Tot în această clasă se tratează evenimentele generate de primirea unui apel telefonic, erori cauzate de indisponibilitatea memorie ram și evenimentele generate de terminarea aplicației caz în care se poate salva stadiul jocului, se pot elimina procesele din memorie, etc.

//Jocul este pus automat pe pauză când se iese din aplicație

­ (void)applicationWillResignActive:(UIApplication *)application { [[CCDirectorsharedDirector] pause];

}

­ (void)applicationDidBecomeActive:(UIApplication *)application { [[CCDirectorsharedDirector] resume];

}

//În cazul în care se primește avertismentul de memorie, aceasta este eliberată forțat automat

­ (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { [[CCDirectorsharedDirector] purgeCachedData];

}

//În cazul în care aplicația este închisă se eliberează memoria

­ (void)applicationWillTerminate:(UIApplication *)application { CCDirector *director = [CCDirectorsharedDirector];

[[director openGLView] removeFromSuperview]; [viewControllerrelease];

[windowrelease]; [director end]; }

Jocul propriu­zis are loc in clasa PlayLayer aici se creaza lumea box 2d care asigura ca toate elementele se misca corespunzator lumii reale, sau asemanator lumii realea. In clasa PlayLayer mai are loc si initializarea tuturor obiectelor care pot aparea in acest joc precum eroul, inamicii, obstacolele, acestea sunt reprezentate fiecare de clasa ei, astfel clasa PlayLayer le acceseaza in functie de cum are nevoie.

In clasa Hero are loc crearea personajului principal, a eroului, aceasta clasa stie in orice moment in ce stare se afla jucatorul, stie sa afiseze animatiile corespunzatoare fiecarei stari si sa dea feedback jucatorului in functie de actiunile aceastuia de asemenea stie cum ii este permis eroului sa se miste si ce sa faca.

Initializarea eroului se face prin setarea imaginii de inceput de asemenea i se aplica niste proprietatii precum cate vieti are eroul si daca are abilitati speciale sau nu.

//prin aceasta functie se seteaza imaginea initiala a eroului

[self setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"ti1.png"]];

//aceasta functie creeaza corpul box2d al eroului pentru a putea fi adaugat in lumea box2d

[self createBodyWithLocation:location];

//aceasta clasa initializeaza toate animatiile

[self initAnimations];

//aici se seteaza proprietatiile eroului in functie de ce puteri a cumparat utilizatorul lifes=[[WheelPrizes sharedWheelPrizes]heroLifes];

magnetOn=[[WheelPrizes sharedWheelPrizes]magnetPu]; doubleMoney=[[WheelPrizes sharedWheelPrizes]doubleMoney]; headStart=[[WheelPrizes sharedWheelPrizes]headStart];

Dupa initializare eroul este introdus in prima stare, starea de fuga, iar in functie de interactiunea lui cu lumea inconjuratoare el trece de la o stare la alta.

//prima stare, cea de alergare porneste animatia corespunzatoare fugii case kStateRun: {

[self setDisplayFrame:[[CCSpriteFrameCache

sharedSpriteFrameCache] spriteFrameByName:@"ti1.png"]];

action =[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:runAnim restoreOriginalFrame:YES]];

}

//starea de zbor porneste animatia corespunzatoare zborului si ii comunica eroului ca are permisiunea sa zboare

case kStateFlying: {

action =[CCAnimate actionWithAnimation:flyAnim restoreOriginalFrame:NO];

runOn=NO;

break;

}

//starea de boost, in aceasta se intra folosind puteri cumparate din magazin, pentru cateva secunde

eroul este nemuritor si alearga cu o viteza mult mai mare decat cea normala

case kStateBoost: {

action =[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:boostAnim restoreOriginalFrame:YES]];

break;

}

//ultima stare este aceas de moarte, aceasta comunica eroului ca jocul a luat sfarsit case kStateDead: {

[[SimpleAudioEngine sharedEngine] playEffect:sunetHeroDeadh pitch:1 pan:0.0 gain:0.4];

break;

}

Clasa inamiciilor este modelata dupa clasa eroului, la fel ca si eroul ei au mai multe stari si de asemenea au implementata inteligenta artificiala. Inamicii sunt de mai multe feluri si fiecare are abilitati speciale si diferite fata de restu, au o rezistenta crescatoare si necesita actiuni unice din partea jucatorului pentru fiecare pentru a putea fi distrusi. Crearea lor se face asemanator eroului ei sunt creati la locatii aleatorii insa crearea lor se face pe baza respectarii unor reguli, astfel sa nu se creeze situatii imposibile din care jucatorii sa nu mai poata iesi.

Printre inamici se numara, scheleti, acestia apar doar pe pamant, nu au abilitati speciale, inamicii zburatori, acestia zboara in aer in forma sinusoidala, viermi giganti, acestia sunt pe pamant, necesita un numar mare de lovituri pentru a putea fi ucisi, elicoptere, acestea au abilitatea de a arunca bombe, necesita un numar mare de lovituri pentru a fii distruse. Inamicii apar in functie de dificultate astfel un inamic mai usor apare la inceputul jocului pe cand unul puternic apare mai tarziu in joc.

Deoarece jocul este infinit, iar memoria dispozitivelor este finita si limitata de multe ori inamicii folositi in joc sunt reutilizati, asta insemnand ca la inceputul jocului se creaza un numar finit de inamici iar acestia sunt folositi prin rotatie.

bubbleArray = [[SpriteArray alloc] initWithCapacity:10 spriteFrameName:@"bila.png" batchNode:batch world:world shapeName:@""];

flyingGerbilGreenArray = [[SpriteArray alloc] initWithCapacity:10 spriteFrameName:@"zbv1.png" batchNode:batch world:world shapeName:@""];

skeletonGreenArray = [[SpriteArray alloc] initWithCapacity:10 spriteFrameName:@"sc1.png" batchNode:batch world:world shapeName:@""];

wormArray = [[SpriteArray alloc] initWithCapacity:2 spriteFrameName:@"vrm1.png" batchNode:batch world:world shapeName:@""];

shipArray = [[SpriteArray alloc] initWithCapacity:3 spriteFrameName:@"nav1.png" batchNode:batch world:world shapeName:@""];

bombArray = [[SpriteArray alloc] initWithCapacity:10 spriteFrameName:@"bmb1.png" batchNode:batch world:world shapeName:@""];

//fiecare colectie de obiecte necesita numarul de obiecte, imaginea obiectului, textura din care face parte imaginea si lumea box2d conform careia se misca inamicul

In liniile de cod de mai sus se observa fiecare tip de inamic creat si cantitatea de inamici creata, astfel s­a folosti un numar de 10 pentru scheleti deoarece apar intr­un numar mai ridicat iar la elicoptere un numar de 3 deoarece frecventa lor de aparitie in timpul jocului este mult mai mica.

Deoarece in joc se gasesc mai multe tipuri de obstacole si medii, s­a creat o clasa speciala denumita Environment(Mediu) aceasta este responsabila cu crearea lumii in care alearga eroul, lumea contine 3 sectiuni sectiunea de teren cu inamici, sectiunea cu o pestera plina de bogatii si sectiunea cu lava unde eroul trebuie sa zboare. Astfel la fel ca celelalte elemente mediul se poate gasii in una din cele 3 stari, in functie de stare jucatorul trebuie sa indeplineasca actiuni diferite pentru a putea trece.

Mediul este generat tot timpul cu o distanta de 2 ecrane in fata jucatorului si este distrus cu 2 ecrane in spatele jucatorului, astfel se salveaza foarte multa memorie si in acelasi timp da impresia jucatorului ca lumea este continua. Pentru aceasta s­a folosit un offset global care tine in memorie punctul in care a ajuns mediul si punctul din care trebuie sa porneasca constructia urmatoarei sectiuni a mediului.

// se verifica pozitia eroului fata de offsetul global al mediului, daca acesta se apropie de capatul sectiunii actuale, se construieste o sectiune noua aleatorie

if(hero.position.x>enviroment.offset­2*screenSize.width && hero.position.x<enviroment.offset ){

[self selectGameTypeWithValue:randomType];

}

­(void)selectGameTypeWithValue:(int)value{

// in functie de valoarea obtinuta de la 1 la 100 se alege urmatoarea sectiune, procentual ele fiind 60% joc normal, 30% zbor peste lava si 10% pestera cu banuti

if(value <=60){

[enviroment normalPlayWithDistance:4];

}else if(value >60 && value <=90){ [enviroment flyAwayWithDistance:4];

[self makeGerbilWithJetpack];

}else{

[enviroment normalCavePlay]; [self makeCave];

}

}

Pe langa inamici si teren, in joc se mai gasesc si obiecte ajutatoare precum banuti si puteri, care au scopul de a usura munca jucatorului. Aceste obiecte se creaza pe acelasi principiu precum inamicii, ele la randul lor tinand cont de lumea inconjuratoare si respectand aceleasi reguli de creatie. Deoarece banutii sunt cei mai predominanti in joc, la inceputul jocului se creeaza o colectie de 200 de obiecte de tip banut.

coinArray = [[SpriteArray alloc] initWithCapacity:200 spriteFrameName:@"bav1.png" batchNode:coinsBatch world:world shapeName:@""];

Odata ce terenul, inamicii si obiectele ajutatoare au fost generate, trebuie sa oferim jucatorului o modalitate de a interactiona cu aceastea, din moment ce interactiunea se face prin atingere, tot in PlayLayer are loc implementarea functiilor responsabile cu detectia atingerilor

ecranului.

­ (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

// aceasta metoda este chemata cand incepe atingerea ecranului

­ (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event ;

// aceasta metoda este chemata cand atingerea se misca

­ (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

// aceasta metoda este chemata cand atingerea a luat sfarsit

­ (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

// aceasta metoda este chemata cand atingerea a fost oprita fortat, de un apel telefonic de exemplu.

In acest joc metoda care ne­a interesat cel mai mult a fost acea de detectie a miscarii atingerii

„ccTouchesMoved” deoarece ne intereseaza cand utilizatorul gliseaza cu degetul pe ecran, in aceasta metoda detectam daca atingerea se intersecteaza cu inamicii sau obiectele ajutatoare, daca da, atunci actionam asupra lor corespunzator.

// dupa ce a inceput detectia atingerii, se itereaza in toate obiectele si daca atingerea corespunde cu corpul obiectului acesta este distrus

CGPoint location = [self convertTouchToNodeSpace: [touches anyObject];];

locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);

for (b2Body *b = world­>GetBodyList(); b; b = b­>GetNext())

{

b2Fixture *f = b­>GetFixtureList();

Box2DSprite *sprite =(Box2DSprite *) b­>GetUserData();

if(sprite != NULL &&(sprite.tag==kTagSkeletons|| sprite.tag==kTagGerbil))

{

if(f ­> TestPoint(locationWorld))

{

// aici are loc distruferea inamiciilor

[enemy destroyEnemy:sprite];

}

}else if(sprite != NULL &&sprite.tag==kTagCoins)

{

if(f ­> TestPoint(locationWorld))

{

// aici are loc colectarea banutiilor

[coins destroyCoins:sprite];

}

}else if(sprite != NULL &&sprite.tag==kTagWorm){

if(f ­> TestPoint(locationWorld))

{

// aici are loc distrugerea viermelui

[enemy wormHit:sprite];

}

}else if(sprite != NULL &&sprite.tag==kTagShip){

if(f ­> TestPoint(locationWorld))

{

// aici are loc distrugerea navetei

[enemy shipHit:sprite];

}

}else if(sprite != NULL &&sprite.tag==kTagBomb){

if(f ­> TestPoint(locationWorld))

{

// aici are loc distrugerea bombei

[enemy destroyEnemy:sprite];

}

}

// aici are loc colectarea puterilor oferite in timpul jocului

else if(sprite != NULL &&(sprite.tag==kTagSlowMo ||sprite.tag==kTagHeart ||sprite.tag==kTagBoom

||sprite.tag==kTagBoost ||sprite.tag==kTagMegaBoost )){

if(f ­> TestPoint(locationWorld))

{

[inGamePU destroyPowerUps:sprite];

}

}

}

Cea mai importanta functie din clasa PlayLayer este functia Update, aceasta este chemata de

60 de ori pe secunda si aceasta are rolul de a actualiza pozitia si starile tuturor obiectelor. Aici are loc distrugerea obiectelor, detectarea coliziuni dintre obiecte,punerea in miscare a obiectelor, crearea sectiunilor lumii, calcularea distantei alergate de erou, practic este motorul care tine in miscare intreg jocul.

­(void)update:(ccTime)dt {

// functia step are rolul de a actualiza lumea box2d

[self step:dt];

// in aceasta bucla, pozitiile imaginilor obiectelelor sunt echivalate cu cele ale corpurilor box2d for(b2Body *b=world­>GetBodyList(); b!=NULL; b=b­>GetNext()) {

if (b­>GetUserData() != NULL) {

Box2DSprite *sprite = (Box2DSprite *) b­>GetUserData();

sprite.position = ccp(b­>GetPosition().x * PTM_RATIO, b­>GetPosition().y * PTM_RATIO);

sprite.rotation = CC_RADIANS_TO_DEGREES(b­>GetAngle() * ­1);

}

}

// eroul, obstacolele, inamicii si lumea sunt actualizate in functie de timp

[hero updateStateWithDeltaTime:dt]; [self updateObstaclesWith:dt];

[coins updateCoins:dt];

[enemy updateEnemiesWithTime:dt]; [parallax updateParallax];

// distanta curenta alergata este calculata inmultind viteza cu timpul if(hero.characterState!=kStateDead && !gameOver){ distance+=hero.body­>GetLinearVelocity().x*dt;

[self updateDistanceWithDistance:distance];

}

// crearea unei sectiuni noi in joc are loc tot in functia update if(hero.position.x>enviroment.offset­2*screenSize.width && hero.position.x<enviroment.offset ){

int randomType=randomValueBetween(1, 2); [self selectGameTypeWithValue:randomType];

}

}

Odata ce toate elementele sunt in loc si utilizatorii pot colecta banuti si avansa in lume, a

venit momentul sa afisam aceste informatii, precum distanta parcursa in timp real, numarul de banuti colectati, abilitatiile dobandite, numarul de vieti disponibile. Aceste informatii se afiseaza folosind o clasa noua si anume HudLayer, aceasta clasa se foloseste deoarece vrem

ca aceste informatii sa stea tot timpul pe ecran chiar daca actiunea este in miscare. Acest tip de clasa poarta denumirea de „Heads Up Display”. Pentru a putea functiona ca un Hud,

aceasta clasa vine asezata peste clasa PlayLayer, astfel desi intreaga actiune are loc in

PlayLayer, informatiile sunt afisate in HudLayer.

La initializare aceasta clasa adauga in memorie toate elementele necesare, astfel avem, numarul de banuti colectat, distanta parcursa, punctele de experienta adunate prin distrugerea inamicilor si numarul de vieti disponibile.

//initializarea elementelor ce vor afisa statisticile jocului

_statusLabel = [CCLabelBMFont labelWithString:@"0" fntFile:@"dreamFont.fnt"];

_coinLabel = [CCLabelBMFont labelWithString:@"0" fntFile:@"dreamFontYellow.fnt"];

_xpLabel = [CCLabelBMFont labelWithString:@"0" fntFile:@"dreamFontBlue.fnt"];

_xpLabelName = [CCLabelBMFont labelWithString:@"XP" fntFile:@"dreamFontBlue.fnt"];

Deoarece inimile sunt finite, s­au folosit imagini in loc de text, astfel avem doua imagini, locul care iti arata cate inimi maxim poti avea si imaginea inimii proriu­zise care vine in acel loc.

­(void)createHeartsWith:(int)lives{

CGSize winSize = [CCDirector sharedDirector].winSize;

//se creaza imaginile locasului inimilor

for(int i=0; i<[WheelPrizes sharedWheelPrizes].heartSlots ; i++){ CCSprite * liveSlot=[CCSprite spriteWithFile:@"sloti.png"]; [self addChild:liveSlot z:0 tag:300+i];

liveSlot.position=ccp(winSize.width*0.025+i*17,winSize.height*0.87);

}

//se creaza imaginea inimilor in functie de cate are cumparate jucatorul, cu cat are mai multe cu atat poate

primi mai multe lovituri for(int i=0; i<lives ; i++){

CCSprite * live=[CCSprite spriteWithFile:@"inimmic.png"]; [self addChild:live z:1 tag:400+i]; live.position=ccp(winSize.width*0.025+i*17,winSize.height*0.87);

}

}

Cand jocul ia sfarsit sunt afisate informatiile de final si in acelas timp are loc inregistrarea scorului obtinut de jucator in clasamentul global. Pentru clasamentul global al scorurilor s­a folosit librăria Apple, GameKit denumită și GameCenter, cu ajutorul ei se pot implementa clasamente mondiale. Librăria se ocupă de tot, inclusiv de autentificarea și logarea userilor. Interfața clasamentelor este predefinită de Apple și nu poate fi modificată iar conținutul se afișează folosind ferestre modale. Înregistrarea scorului se face folosind funcția:

[[GCHelpersharedInstance] reportScore:kLeaderboardDistancescore:totalScore];

Pentru afișarea clasamentului se apelează funcția showLeaderBoards, deoarece clasamentul se poate afișa doar pe o fereastră modală, pentru a­l putea afișa trebuie să apelăm delegatul și să creăm o nou fereastra:

­(void)showLeaderBoards{

//delegatul este rugat sa afiseze o noua fereastra de tip Gkleaderboard si o prezinta intr­un mod modal

AppDelegate *delegate =(AppDelegate*)[UIApplication sharedApplication].delegate; GKLeaderboardViewController *leaderboard=[[GKLeaderboardViewController alloc]init];

if(leaderboard!=NULL){

leaderboard.leaderboardDelegate = self;

[delegate.window.rootViewController presentModalViewController:leaderboard animated:YES];

}

}

Fig.3.16 Clasament Dream Tim

Librăriile folosite în proiectul Dream Tim au fost:

● GameKit.framework

● StoreKit.framework

● Security.framework

● Social.framework

● AdSupport.framework

● PassKit.framework

● CFNetwork.framework

● CoreGraphisc.framework

● Foundation.framework

● OpenGLES.framework

● QuartzCore.framework

● UIKit.framework

● AudioToolbox.framework

● OpenAL.framework

● AVFoundation.framework

● libcocos2d libraries.a

Dream Tim conține 40 de efecte sonore și două melodii, una pentru meniu și una care rulează în timpul jocului. Pentru a folosi sunete Cocos2d conține o clasă de tip singleton denumită SimpleAudioEngine. Aceasta permite redarea sunetului, oprirea sunetului, schimbarea vitezei de redare, punerea pe pauză și încărcarea sunetelor în fundal astfel când se dorește redarea unui efect acesta să nu cânte cu întârziere sau distorsiuni.

// pre­încărcarea efectului sonor

[[SimpleAudioEnginesharedEngine] preloadEffect: sunetCoinPickUp];

// redarea efectului sonor

[[SimpleAudioEnginesharedEngine] playEffect: sunetCoinPickUp];

// redarea melodiei care va cânta în background indiferent de scena în care se afla utilizatorul

[[SimpleAudioEnginesharedEngine] playBackgroundMusic:@"dream_tim_dreamy.mp3"loop:YES];

// oprește melodia de pe fundal

[[SimpleAudioEnginesharedEngine] stopBackgroundMusic];

3.4.Finisare și testare

Odată terminată perioada de implementare urmează perioada de optimizări și testare a produsului final. Jocul Dream Tim a fost testat îndelungat pentru a se asigura inexistența erorilor și funcționarea în parametrii normali astfel experiența utilizatorilor să fie cât mai plăcută.

Pentru testarea jocului s­a folosit serviciul TestFlight (fig.3.18), un serviciu online gratuit care permite dezvoltatorilor să distribuie varianta beta a aplicației utilizatorilor pentru a fi testată și îmbunătățită. Pentru a putea distribui varianta beta, Apple permite dezvoltatorilor să ruleze aplicația pe maxim 100 de dispozitive de teste. Pentru a putea testa aplicația pe un dispozitiv dezvoltatorii au nevoie de id­ul acestuia. Odată colectate toate id­urile dispozitivelor, se va construi o variantă a acelei aplicații care să le conțină și prin intermediul serviciului TestFlight acestea sunt distribuite tester­ilor.

Testeri pot fi din întreaga lume iar comunicarea cu ei se face prin intermediul funcțiilor de feedback care pot fi incluse direct în aplicație. Serviciul este extrem de util deoarece testări pot instala aplicația direct de pe telefon astfel nu este nevoie de un computer

pentru a instala aplicația, rezultatele testelor , feedback­ul și rapoartele sunt primite în timp real astfel timpul de teste se scurtează considerabil.

Fig.3.17 Serviciul de teste TestFlight

3.5.Lansare în Appstore

Pentru a putea distribuii aplicațiile în App Store , dezvoltatorii trebuie să fie

înregistrați în programul “Apple Developer”, ceea ce presupune plata unei taxe anuale de 99$. Apple are dreptul la 30% din prețul fiecărei aplicații vândute.

Odată înscris în acest program, gestionarea contului de developer Apple se face prin modulul iTunesConnect. Aici se crează recipientul aplicației unde se introduc toate datele inclusiv nume, preț, capturi din aplicație, descrierea aplicației, țările în care va fi distribuită, etc. Odată introduse toate datele, folosind mediul de dezvoltare Xcode, se uploadează aplicația în recipient și starea ei se modifică din Waiting for Upload în Waiting for Review. Următoarele stări ale aplicației sunt In Review și Ready for Sale.

Fig.3.18 Dream Tim Ready For Sale

Odată aprobată aplicația, dezvoltatorul are posibilitatea să o lanseze în Appstore pe loc sau să seteze o dată în viitor. În cazul Dream Tim, lansarea s­a făcut la două săptămâni după aprobare, perioadă în care s­a încercat promovarea jocului. Promovarea s­a făcut prin trimiterea de comunicate de presă site­urilor de specialitate precum www.toucharcade.com, www.slidetoplay.com, www.148apps.com, etc. Un alt fel de promovare s­a făcut postând pe forumuri specializate în jocuri pentru iOS sau folosind rețele de socializare precum Facebook, Twitter și Youtube. Deși toate aceste modalități de promovare au un impact destul de bun asupra vânzărilor, nici una nu se compară cu promovarea oferită de Apple.

Odată încheiată perioada de promovare, la data stabilită jocul devine disponibil și poate fi achiziționat de utilizatori.

3.6.Statistici Appstore

Raportul vânzărilor sau a descărcărilor apare tot timpul cu o zi întârziere. Acestea pot fi văzute în iTunesConnect în secțiunea Sales And Trends.

Jocul Dream Tim a fost descarcat de 186.412 de ori în întreaga lume si a fost jucat de peste

1.546.243 ori pe perioada unui an. (Fig.3.19).

Fig.3.19 Numar de descarcari Dream Tim pe parcursul unui an

Jocul a primit peste 200 de recenzii cu o medie de 4 stele din 5:

Fig.3.23 Recenzii Dream Tim

Concluzii

Platforma Apple a deschis o cu totul nouă piață pentru dezvoltatorii de aplicații mobile. O piață care a crescut enorm în ultimi ani și a pornit un nou trend, evoluția tehnologiei îndreptându­se spre dispozitivele portabile, mobile. Dacă înainte crearea și publicarea aplicaților era costisitoare și inaccesibilă, acum oricine are cunoștințe în domeniu poate crea și distribuii aplicații la costuri infime.

Prin crearea jocului Dream Tim, s­a aprofundat și mai mult limbajul de programare orientat pe obiecte Objective­C, s­a aprofundat utilizarea mediului integrat de dezvoltare Xcode și s­au experimentat noi metode de monetizare a jocurilor în Appstore. Deși mai sunt multe de învățat, această platformă prezintă un potențial uriaș pentru creatorii de software, singura condiție pentru succes fiind crearea unui produs inovator sau de o calitate superioară.

Pe lângă faptul că aplicațiile pot fi distribuite în Appstore, mai există o întreagă piață de liberi profesioniști pentru vânzarea, cumpărarea și crearea aplicațiilor. Prețul mediu de pornire a unei aplicații fiind de aproximativ 3000$, astfel această industrie poate oferii un mediu de viața destul de ridicat.

Pentru prima oara numarul de utilizatori activi pe dispozitive mobile a intrecut acela pe desktopuri si laptopuri, astfel se poate observa ca aceast trend nu este unul trecator ci din potriva este unul in continua crestere.

Bibliografie

[1] Stephen G. Kochan, Programming in Objective­C (2rd Edition) , Addison­Wesley

Professional , Jan 2009

[2] Rod Strougo, Ray Wanderlich, Learning Cocos2D: A Hands­On Guide to Building iOS Games with Cocos2D, Box2D, and Chipmunk, , Addison­Wesley, Jul2011

[3] Steffen Itterheim, Learn iPhone and iPad cocos2d Game Development, Appress, Feb

2011

[4] Dave Wooldridge with Michael Schneider, The Business of iPhone and iPad App

Development, Apress, 2011

[5] http://www.raywenderlich.com/ [6]https://developer.apple.com/ [7]http://www.cocos2d­iphone.org/wiki/doku.php/ [8]http://box2d.org/documentation/ [9]http://mobiledevelopertips.com/ [10]http://www.iforce2d.net/b2dtut/ [11]http://iforce2d.net

[12] http://itunesconnect.apple.com [13]http://www.cocos2d­iphone.org/forum/ [14] http://devforums.apple.com

[15] http://www.iphonedevsdk.com/forum/iphone­sdk­development/

so

Bibliografie

[1] Stephen G. Kochan, Programming in Objective­C (2rd Edition) , Addison­Wesley

Professional , Jan 2009

[2] Rod Strougo, Ray Wanderlich, Learning Cocos2D: A Hands­On Guide to Building iOS Games with Cocos2D, Box2D, and Chipmunk, , Addison­Wesley, Jul2011

[3] Steffen Itterheim, Learn iPhone and iPad cocos2d Game Development, Appress, Feb

2011

[4] Dave Wooldridge with Michael Schneider, The Business of iPhone and iPad App

Development, Apress, 2011

[5] http://www.raywenderlich.com/ [6]https://developer.apple.com/ [7]http://www.cocos2d­iphone.org/wiki/doku.php/ [8]http://box2d.org/documentation/ [9]http://mobiledevelopertips.com/ [10]http://www.iforce2d.net/b2dtut/ [11]http://iforce2d.net

[12] http://itunesconnect.apple.com [13]http://www.cocos2d­iphone.org/forum/ [14] http://devforums.apple.com

[15] http://www.iphonedevsdk.com/forum/iphone­sdk­development/

Similar Posts