Implementarea Jocului Fruits Slot

Cuprins

Introducere 3

1. Abordarea teoretică a jocului 5

1.1. Limbaje de programare utilizate în dezvoltarea jocurilor 5

1.1.1. Limbajul C 5

1.1.2. Limbajul C++ 6

1.1.3. Limbajul Java 7

1.1.4. Limbajul C# 8

1.1.5. Limbajul Objective-C 8

1.1.6. Limbajul HTML5 9

1.1.7. Limbajul Javascript 10

1.2. Particularități ale limbajelor de programare în dezvoltarea jocurilor pentru dispozitive mobile 12

1.2.1. Descrierea sistemelor de operare folosite pe dispozitivele mobile 13

1.2.2. Aplicații native versus aplicații hibrid 18

1.2.2.1. Aplicatii native 18

1.2.2.2. Aplicatii hibride 20

2. Tehnologii utilizate la crearea jocului 23

2.1. Platforma Unity 23

2.1.1. Noțiuni introductive 23

2.1.2. Editorul grafic 24

2.1.3. Modul de utilizare al resurselor grafice și audio 25

2.1.4. Modul de lucru cu scripturile 26

2.1.5. Interfața MonoDevelop 26

2.2. Limbaje de programare utilizate în Unity 28

2.2.1. Notiune introductive: Boo, UnityScript, C# 28

2.2.2. Scurtă comparație între limbajele folosite în Unity 28

3. Descrierea jocului Fruits Slot 31

3.1. Istoricul jocurilor de tip ”slot machine” 31

3.2. Descrierea funcționalității 32

3.2.1. Screen-tree-ul jocului 32

3.2.2. Design-ul jocului 33

3.2.2.1 Tutorialul jocului 37

3.2.2.2. Free Spins 38

3.2.2.3. Minigame-ul jocului 39

3.2.2.4. PayTable 41

3.3. Aplicabilitatea probabilităților matematice în jocurile de tip ”slot machine” 42

3.4. Utilizarea RNG-urilor în jocurile de tip ”slot machine” 46

4. Implementarea jocului Fruits Slot 49

4.1. Implementarea grafică 49

4.2. Implementarea funcționalității jocului 52

4.3. Crearea și testarea buidurilor pe platforma Android 61

Concluzii 63

Bibliografie 64

Anexa – Cod script Button.cs 65

Introducere

În momentul de față există un număr mare de platforme pentru care se dezvoltă jocuri, cum ar fi: PC, MAC, Linux, iOS, Android, BlackBerry, Windows Phone, Tizen, Xbox 360, XBox One, PS3, PS4, PS Vita, PlayStation Mobile, Nintendo, Web, Wii U, Oculus Rift, Gear VR, Android TV, Samsung SMART TV, Wearebles.

Aceste platforme pot fi împărțite în două mari categorii: platforme pentru dispozitive mobile (portabile – Android, iOS, BlackBerry, Windows Phone, Tizen, PlayStation Mobile) și pentru dispozitive fixe (PC, MAC, Linux, Xbox 360, WBox One, PS3, PS4, PS Vita, Nintendo, Web, Wii U, Oculus Rift, Gear VR, Android TV, Samsung SMART TV).

De-a lungul timpului, dezvoltatorii acestor platforme au încercat să își particularizeze produsul în funcție de cerințele fiecăruia și de noutățile aduse pe piață, iar dispozitivele au devenit din ce în ce mai performante Dacă ne gândim la faptul că acum 25 ani ne jucam Mario pe consolele celor de la Nintendo, acum am ajuns să jucăm Assasin's Creed pe un telefon mobil, în metrou, în drum spre locul de muncă.

Mi-am propus ca în acestă lucrare să abordez dezvoltarea unui joc pe o anumită platformă, mai exact platforma Android.

Jocul face parte din categoria jocurilor de noroc ”slot machine”, combinat puțin cu tipul de joc ”match three”. Ideea dezvoltării acestui joc mi-a venit într-o dimineață, mergând în drum spre muncă. Am observat că aproape în orice intersecție există câte un cazinou. De obicei, în cazinou, cele mai rulate și căutate jocuri sunt cele de tip slot machine. Ce am observat eu, este faptul că aceste aparate pe care sunt instalate jocurile de tip slot nu au evoluat prea mult. Noutățile aduse țin doar de interacțiunea cu aparatul și de design-ul aparatului. Dacă acum 25 ani se folosea o manetă pentru a juca, iar acum 10 ani se foloseau butoane fizice pentru interacțiune, acum se folosește touchscreen-ul. În schimb, această funcție a ecranului nu este ”exploatată” la maxim.

Pornind de la această observație, m-am gandit să combin acest tip de joc cu un concept foarte căutat în momentul de față pe telefoanele mobile: ”match three”. În capitolul dedicat descrierii jocului, voi detalia acest concept.

Lucrarea este structurată în 5 capitole, după cum urmează:

Abordarea teoretică – am prezentat câteva noțiuni despre limbajele de programare învățate în facultate și câteva noțiuni despre limbajele de programare folosite în dezvoltarea jocurilor;

Tehnologii utilizate la crearea jocului – o prezentare succintă a platformei Unity și a limbajelor de programare suportate de Unity;

Descrierea jocului – o introducere în jocurile de tip slot machine urmată de prezentarea descrierea funcționalității jocului, aplicabilitatea matematicii în implementarea jocurilor de acest tip, cât și utilizarea RGN-urilor;

Implementarea jocului Fruits Slot, implementarea grafică, codul sursă, crearea și testarea build-urilor;

Concluzii referitoare la dezvoltarea jocului.

1. Abordarea teoretică a jocului

În acest capitol voi prezenta noțiunile teoretice generale ale limbajelor de programare utilizate în dezvoltarea jocurilor și particularități ale limbajelor în dezvoltarea pentru telefoane mobile.

Pentru o înțelegere cât mai bună a ceea ce reprezintă limbajele de programare voi prezenta câteva definiții specifice programării calculatoarelor.

Un limbaj de programare este un set bine definit de expresii și reguli (sau tehnici) valide de formulare a instrucțiunilor pentru un computer. Un limbaj de programare are definite un set de reguli sintactice și semantice. El dă posibilitatea programatorului să specifice în mod exact și amănunțit acțiunile pe care trebuie să le execute calculatorul, în ce ordine și cu ce date. Specificarea constă practic în întocmirea/scrierea programelor necesare.

Limbajele de programare se pot clasifica după mai multe criterii: după paradigma programării, după nivelul de abstractizare și după vechime. După nivelul de abstractizare, există urmatoarele categorii:

limbajele cod-mașină;

limbajele de asamblare;

limbaje de nivel înalt: C(derivate din C- C++, Java, C#) Pascal, Fortran

limbaje neprocedurale, orientate pe rezolvarea unei anumite clase de probleme: SQL, ș.a;

limbaje utilizate în domenii precum logica fuzzy, inteligență artificială sau și rețele neuronale: Prolog, LISP, ș.a.

1.1. Limbaje de programare utilizate în dezvoltarea jocurilor

Cele mai des folosite limbaje de programare pentru dezvoltarea jocurilor sunt: C, C++, Java, C#, Objective-C, și mai nou, JavaScript, HTML5.

1.1.1. Limbajul C

Limbajul C este un limbaj de programare universal, caracterizat printr-o exprimare concisă, un control modern al fluxului execuției, structuri de date, și un bogat set de operatori. Acesta nu este un limbaj specializat pentru un anumit domeniu de aplicații. Absența restricțiilor și generalitatea sa îl fac un limbaj mai convenabil și mai eficient decît multe alte limbaje mai puternice.

Permite scrierea de programe bine structurate, datorită construcțiilor sale de control al fluxului: grupări de instrucțiuni, luări de decizii (if), cicluri cu testul de terminare înaintea ciclului (while, for) sau după ciclu (do) și selecția unui caz dintr-o mulțime de cazuri (switch). Limbajul C permite lucrul cu pointeri și are o aritmetică de adrese puternică.

            Nu are operații care prelucrează direct obiectele compuse cum sînt șirurile de caractere, mulțimile, listele sau masivele, considerate fiecare ca o entitate. Acest limbaj nu prezintă facilități de alocare a memoriei altele decît definiția statică sau disciplina de stivă relativă la variabilele locale ale funcțiilor. În sfîrșit, limbajul C nu are facilități de intrare-ieșire și nici metode directe de acces la fișiere. Toate aceste mecanisme de nivel înalt sînt realizate prin funcții explicite.

            C-ul este un limbaj agreabil, expresiv și elastic, care se pretează la o gamă largă de programe. C este un limbaj restrîns și se învață relativ ușor, iar subtilitățile se rețin pe măsură ce experiența în programare crește. Totuși, ramane un limbaj de programare procedurală.

1.1.2. Limbajul C++

Limbajul C++ este un limbaj de programare orientat pe obiecte. Programarea orientatã pe obiecte apelează la o modalitate nouă de gândire a unei probleme. Spre deosebire de programarea procedurală care se concentrează pe structuri de date și algoritmi, programarea orientată pe obiecte se concentrează pe definirea de obiecte care modelează problema ce trebuie rezolvată.

În programarea orientată pe obiecte (POO) un program are rolul de a simula stările și activitățile obiectelor lumii reale. Pe lângă structuri de date (care descriu stările obiectelor, atributele acestora) trebuie incluse și metodele asociate obiectelor, adică acele funcții care modifică atributele obiectelor și care descriu comportamentul lor.

Limbajul C++ este unul dintre cele mai utilizate limbaje de programare orientate pe obiecte; compilatoare, biblioteci și instrumente de dezvoltare a programelor C++ sunt disponibile atât pentru calculatoare personale cât și pentru cele mai dezvoltate sisteme și stații de lucru.

Scopul pentru care a fost creat C++ este același cu scopul pentru care este abordată în general programarea orientată pe obiecte: dezvoltarea și administrarea programelor foarte mari. Chiar dacă superioritatea limbajului C++ este evidentă în cazul dezvoltării programelor foarte mari, nu există limitări în a fi folosit în orice fel de aplicație, deoarece C++ este un limbaj tot atât de eficient ca și limbajul C.

1.1.3. Limbajul Java

Limbajul Java este un limbaj structurat și orientat pe obiecte, cu o sintaxă și filozofie derivate din C++. Aspectele inovatoare se referă mai mult la modificările mediului de programare. Aspectul esențial în Java este posibilitatea de a crea cod portabil pe platforme diferite. Înainte de explozia internetului, majoritatea programelor erau compilate și destinate utilizării pe un anumit procesor și sub un anumit sistem de operare. Programele scrise în C și C++ se compilau întodeauna până la cod mașină executabil. Codul mașină este legat de un anumit procesor și de un anumit sistem de operare. După apariția internetului problema portabilității a devenit foarte importantă. Java a realizat portabilitatea prin transformarea codului sursă al programului într-un cod intermediar numit bytecode. Acest format intermediar este executat apoi de asa numita mașină virtuală Java (JVM). Așadar, programele Java pot rula în orice mediu în care este disponibilă o JVM. Deoarece JVM este ușor de implementat, aceasta a fost imediat disponibilă pentru un număr mare de medii.

Caracteristicile de bază ale limnajului Java sunt următoarele:

este un limbaj simplu de folositȘ elimină supraîncărcarea operatorilor, moștenirea multiplă, pointerii;

este portabil;

este complet orientat obiectȘ elimină complet stilul de programare procedural;

este distribuit, având implementate biblioteci pentru lucrul în rețea;

este un limbajl cu securitate ridicată.

Tehnologiile Java sunt grupate în așa fnumitele platforme de lucru. Acestea reprezintă seturi de librării scrise în limbajul Java, precum și diverse programe utilitare, utilizate pentru dezvoltarea de aplicații sau componente destintate unei anume categorii de utilizatori. Există 3 mari platforme de Java:

J2SE (Standard Edition) – platforma standard de lucru ce oferă suport pentru crearea de aplicații independente și appleturi. De asemenea, aici este inclusă și tehmologia JavaWeb Start ce furnizează o modalitate extrem de facilă pentru lansarea și instalarea locală a programelor scrise în Java direct de pe Web, oferind cea mai comodă soluție pentru distribuția și actualizarea aplicațiilor Java.

J2ME (Micro Edition) – folosind Java, programarea dispozitivelor mobile este extrem de simplă, platforma de lucru J2ME oferind suportul necesar scrierii de program dedicate acestui scop.

J2EE (Enterprise Edition) – această platformă oferă API-ul necesar dezvoltării de aplicații complexe, formate din componente ce trebuie să ruleze în sisteme eterogene, cu onformațiile memorate în baze de date distribuite, etc. Tot aici găsim suportul necesar scrierii de program dedicate acestui scop.

1.1.4. Limbajul C#

Limbajul C# este de asemenea un limbaj de progranare orientat pe obiecte. Deși Java a rezolvat cu succes problema portabilității, există unele aspecte care îi lipsesc. Una dintre acestea este interoperabilitatea limbajelor diferite, sau programarea în limbaj mixt (posibilitatea codului scris într-un limbaj de a lucra în mod natural cu codul scris în alt limbaj) . Interoperabilitatea limbajelor diferite este esențială la realizarea sistemelor software de dimensiuni mari.

Ca parte a ansamblului strategiei .NET, dezvoltată de Microsoft, la finele anilor ’90 a fost creat limbajul C#. Limbajul este direct înrudit cu C, C++ și Java. “Bunicul” limbajului C# este C-ul. De la C, C# moștenește sintaxa, multe din cuvintele cheie și operatorii. De asemenea, C# construiește peste modelul de obiecte definit în C++. Relația dintre C# și Java este mai complicată. Java derivă la rândul său din C si C++. Ca și Java, însă C# a fost proiectat pentru a produce cod portabil. Limbajul C# nu derivă din Java. Între C# și Java există o relație similară celei dintre “veri”, ele derivă din același strămoș, dar deosebindu-se prin multe caracteristici importante. Limbajul C# conține mai multe facilități inovatoare, dintre care cele mai importante se referă la suportul încorporat pentru componente software. C# dispune de facilități care implementează direct elementele ce alcătuiesc componentele software, cum ar fi proprietățile, metodele și evenimentele. Poate cea mai importantă facilitate de care dispune C# este posibilitatea de a lucra intr-un mediu cu limbaj mixt.

1.1.5. Limbajul Objective-C

Limbajul Objective-C este o extensie a limbajului C pentru lucrul orientat pe obiecte, considerată uneori superioară C++. Spre deosebire de C++, pentru compilarea codului scris in Objective-C nu este necesar un compilator special. Objective-C constă ăntr-un preprocesor care translează codul Objective-C în cod C, urmând ca acesta să fie transformat în cod obiect de către un compilator standard C. Toate clasele sunt derivate în mod automat din clasa predefinită Object. Aceasta clasă poate fi referită prin intermediul identificatorului super. Fată de C++ sunt câteva deosebiri: nu se poate realiza mostenire multiplă, nu există nici un mecanism de control al accesului, etc.

1.1.6. Limbajul HTML5

HTML5 este un limbaj pentru structurarea și prezentarea conținutului pentru World Wide Web, o tehnologie nucleu pentru internet propusă inițial pentru software-ul Opera. Este a cincea revizuire a standardului HTML (creat în 1990 și standardizat ca HTML4 din 1997) și din octombrie 2011 este în curs de dezvoltare. Obiectivele sale principale au fost acelea de a îmbunătăți limbajul cu un suport pentru cele mai recente apariții multimedia în același timp menținândul ușor de citit de oameni și bine înțeles de computere și device-uri (browsere web, parsere, etc.).

HTML5 este un răspuns la observația că HTML și XHTML utilizate în comun pe World Wide Web sunt un amestec de caracteristici introduse de specificații diferite, împreună cu acestea mai sunt și caracteristicile diferite aduse de software, de browsere, și multe erori de sintaxă în documentele web existente. Astfel, HTML5 devine o încercare de a defini un singur limbaj de marcare care poate fi scris în oricare dintre sintaxele HTML sau/și XHTML. Acesta include modele detaliate de prelucrare pentru a încuraja mai multe implementări interoperabile; extinde, îmbunătățește și raționalizează disponibilitățile pentru documentele web și introduce marcarea și aplicații API (application programming interface) pentru aplicații web complexe. Din aceste motive, HTML5 este un posibil candidat pentru aplicațiile de platforme mobile. Multe caracteristici ale HTML5 au fost create din considerarea că va trebui să devină capabil să ruleze pe dispozitive cum ar fi smart-phonurile sau tabletele.

În special, HTML5 aduce multe noi caracteristici sintactice. Acestea cuprind elemente ca <video>, <audio>, <header> și <canvas> elemente HTML, precum și integrarea conținutului SVG care înlocuiește utilizarea tag-ului generic <object>. Aceste noutăți sunt proiectate pentru a facilita includerea și manipularea în web a conținuturilor multimedia și grafice fără a fi nevoie să se recurgă la proprietățile de plugin și API. Alte noi elemente ca <section>, <article>, <header>, și <nav> sunt proiectate să îmbunătățească conținutul semantic al documentelor. Noi atribute au fost introduse în același scop, în același timp unele elemente și atribute au fost îndepărtate. Unele elemente ca <a>, <cite> și <menu> au fost schimbate, redefinite și standardizate. API-urile și DOM-urile (document object model) sunt certitudini și sunt părți fundamentale în specificațiile HTML5. HTML5, de asemenea, definește în câteva detalii prelucrările necesare pentru documentele invalide, astfel încât sintaxa erorilor va fi tratată uniform de toate browserele cunoscute.

1.1.7. Limbajul Javascript

Limbajul JavaScript (JS) este un limbaj de programare orientat pe obiect, bazat pe conceptul prototipurilor. Este folosit mai ales pentru introducerea unor funcționalități în paginile web, codul Javascript din aceste pagini fiind rulat de către browser. Limbajul este binecunoscut pentru folosirea sa în construirea site-urilor web, dar este folosit și pentru acesul la obiecte încastrate (embedded objects) în alte aplicații. A fost dezvoltat inițial de către Brendan Eich de la Netscape Communications Corporation sub numele de Mocha, apoi LiveScript, și denumit în final JavaScript. Schimbarea numelui din LiveScript în JavaScript s-a făcut cam în același timp în care Netscape încorpora suport pentru tehnologia Java în browserul web Netscape Navigator.

Microsoft a implementat limbajul JavaScript sub numele de JScript, cu o serie de modificări și extensii față de implementarea Netscape. Pe platforma Windows, JScript este unul din limbajele executabile de către Windows Script și, deci, poate fi folosit pentru scriptarea aplicațiilor ce suportă Windows Script, de exemplu Internet Explorer sau chiar sistemul de operare Windows.

Cea mai des întâlnită utilizare a JavaScript este în scriptarea paginilor web. Programatorii web pot îngloba în paginile HTML script-uri pentru diverse activități cum ar fi verificarea datelor introduse de utilizatori sau crearea de meniuri și alte efecte animate.

În tabelele de mai jos, se poate observă evoluția utilizării limbajelor de programare – anul 2015 față de 2012 – analizată de Tiobe Software.

Tabelul 1. Evolutie utilizare limbaje de programare 2015 vs 2014

Tabelul 2. Evolutie utilizare limbaje de programare 2012 vs 2011

Făcând o comparație între cele două tabele, observăm că există o creștere categorică a limbajului Java, ca și utilizare, însă limbajul Objective-C, deși în anul 2012 a avut o creștere foatre mare, a scăzut foarte mult pentru că utilizarea lui are o piață destul de mică.

1.2. Particularități ale limbajelor de programare în dezvoltarea jocurilor pentru dispozitive mobile

În zilele noastre utilizarea dispozitivelor mobile inteligente, fie ele telefoane sau tablete, este într-o creștere permanentă(în mare parte datorită portabilității lor datorită portabilității lor). Din această cauză producătorii de dispozitive mobile sunt forțați să își îmbunătățească produsele hardware și să vină cu tehnologii noi și cât mai aproape de orice dorință a utilizatorilor, deși volumul vânzărilor de produse hardware de la companii gigant precum Microsoft, Apple, Samsung, BlackBerry sau Nokia este dat în bună parte, de numărul și calitatea aplicațiilor software pe care fiecare platformă îl pune la dispoziție utilizatorilor ei.

1.2.1. Descrierea sistemelor de operare folosite pe dispozitivele mobile

Această piață a dispozitivelor mobile a ajuns să folosească un număr foarte mare de sisteme de operare. În momentul de față cele mai importante sunt Android, iOS, BlackBerry 10, Windows Phone 8, Tizen, Fire OS (nu trebuie uitate nici Brew, Brew MP, J2ME, Symbian, Palm OS – aceste sisteme au devenit din ce în ce mai rar întâlnite). În continuare voi face o scurtă descriere a acestor OS-uri.

Firefox OS este un sistem de operare open-source bazat pe kernel-ul de Linux, creat pentru smartphone-uri (telefoane inteligente), tablete și Smart TV-uri, dezvoltat de Mozilla, o organizație non-profit cunoscută mai ales pentru browser-ul Firefox.

Firefox OS este conceput pentru a oferi un sistem alternativ complet, bazat pe comunitate pentru dispozitive mobile, folosind abordări și standarde deschise, cum ar fi aplicații HTML5, JavaScript, API-uri web deschise pentru a comunica direct cu hardware-ul telefonului mobil. Ca atare, acest OS concurează cu sisteme de operare comerciale dezvoltate cum ar fi Apple iOS, Google Android, Microsoft Windows Phone, BlackBerry 10 sau Samsung Tizen.

Cheia dezvoltării aplicațiilor pentru Firefox OS este că întreaga interfață a utilizatorului este o aplicație web, care poate afișa sau lansa alte aplicații. Ca și produs, Firefox OS oferă servicii de branding și suport pentru servicii în partea de sus a Boot to Gecko (B2G – numele de cod a sistemului de operare). Boot to Gecko este dezvlotat de o echipă de ingineri din interiorul Mozilla plus câțiva colaboratori externi.

În dezvoltarea unei aplicații pentru sistemul de operare Firefox OS trebuie avut în vedere pe ce platforme suportă dispozitivele pe care se va lansa aplicația. De asemenea, un aspect de luat in considerare este faptul că nu este la fel de simplu să faci update la versiunea platformei precum este la un desktop – utilizatorii fiind oarecum la mila furnizorilor de rețea. Prin urmare, trebuie dezvoltate versiuni diferite pentru fiecare platformă. Această problemă ar trebui sa dispara în curând, pe măsură ce apar din ce în ce mai multe dispozitive cu versiunile mai noi de Firefox OS.

Tizen este un sistem de operare deschis și flexibil construit de la zero pentru a răspunde nevoilor tuturor părților interesate de ecosistemul dispozitivelor mobile și conectate, inclusiv a producătorilor de telefoane, dezvoltatorilor de aplicații și furnizorilor de software independent. Tizen este dezvoltat de o comunitate de dezvoltatori, sub guvernare open-source și este deschisă tuturor membrilor care doresc să participe.

Sistemul de operare Tizen vine în mai multe versiuni pentru a servi cerințelor diferite din industrie. Actualele profile Tizen sunt Tizen IVI (in-vehicle-infotainment), Tizen mobile, Tizen TV și Tizen portabil. În plus, începând cu Tizen 3.0, toate versiunile au fost costruite având o infrastructură comună în partea de sus, împărtășită sub numele comun de Tizen.

Cu Tizen, un producător de dispozitive poate începe cu una dintre aceste versiuni și o poate modifica în funcție de nevoile sale sau poate folosi ca bază comună Tizen-ul, dezvoltând astfel o versiune nouă care să îndeplinească cerințele de memorie, puterea de prelucrare a oricarui dispozitiv și publicarea imediată pe piață. Operatorii de telefonie mobilă pot lucra cu partenerii ce dezvoltă dispozitivele pentru a persolaniza sistemul de operare și experiența utilizatorului pentru a satisface exact nevoile demografice ale utilizatorului.

Pentru dezvoltatorii de aplicații și ISV, Tizen oferă puterea de dezvoltare de aplicații native cu o flezibilitate de sprijin HTML5 foarte mare. Tizen oferă, de asemenea, pentru dezvoltatorii de aplicații potențial de a se extinde pe noile dispozitive inteligente care rulează Tizen, inclusiv wearables, electronice de consum (TV-uri, console de jocuri, DVR-uri, etc), mașini și ale aparate.

Proiectul Tizen face parte din Linux Foundation și este guvernat de un grup de coordonatori tehnici. Grupul este organul de decizie principal al proiectului open-source, cu accent pe dezvoltarea și livrarea platformei, împreună cu formarea de grupuri de lucru pentru a sprijini dispozitivele verticale.

Asociația Tizen a fost formată pentru a ghida rolul industrial al Tizen-ului, inclusiv colectarea de cerințe, indentificarea și facilitarea modelelor de servicii, și de marketing în industrie și educație.

BlackBerry este o linie de dispozitive inteligente și servicii comercializate de către Recearch In Motion, cunoscut anterior ca Research In Motion Limited (RIM). Primul dispozitiv RIM a fost Inter@ctive Pager 900, un dispozitiv de tip clamchell, care a permis paginarea în ambele sensuri. Odată cu trecerea timpului, cei de la RIM au lansat numeroase dispozitive adaptate la cerințele utilizatorilor, astfel că, s-a făcut trecerea de la tastatura fizică QWERTY la generația nouă bazată pe multi-touch și tastatură virtuală.

În ianuarie 2013 a fost lansat un nou sistem de operare, BlackBerry 10, având la vremea respectivă câteva funcționalități noi pe piață cum ar fi aparatul de fotografiat care avea posibilitatea de a derula cadru cu cadru, pentur a permite selectarea celei mai bune fotografii, o tastatură inteligentă predictivă, precum și o interfață de utilozator concepută în jurul ideii de ”flow”.

Sistemul de operare anterior dezvoltat pentru dispozitivele BlackBerry a fost BlackBerry OS, un mediu multitasking dezvoltat de RIM. Sistemul de operare este proiectat pentru utilizarea de dispozitive de intrare cum ar fi track wheel-ul, track ball-ul sau track pad-ul. Sistemul de operare oferă suport pentru Java MIDP 1.0 și WAP 1.2. Versiunile anterioare permiteau sincronizarea wireless cu Microsoft Exchange Server pentru e-mail și calendar, notițe, activități.

Dezvoltatorii third-party pot scrie software folosind Api-uri extenrne și API-uri BlackBerry. Orice aplicație care utilizează anumite funcționalități restrânse trebuie sa fie semnate digital astfel încât să poată fi asociată cu un cont de dezvoltator RIM. Această procedură de semnare garantează paternitatea unei cereri, dar nu garantează calitatea sau securitatea codului. RIM oferă instrumente pentru dezvoltarea de aplicații pentur BlackBerry. Aceste aplicații pot fi instalate pe telefoane folosind BlackBerry World, Over The Air (OTA), prin browser-ul mobil BlackBerry sau prin intermediul software-ului BlackBerry Desktop Manager.

Windows Phone 8 este a doua generație a sistemului de operare mobil Windows Phone de la Mocrosoft. Acesta a fost lansat în octombrie 2012, și la fel ca predecesorul său, este dotat cu o interfață plată de utilizator bazată pe limbajul de design Metro. Aceasta a fost urmat de Windown Phone 8.1, lansat în aprilie 2014.

Windows Phone 8 înlocuiește arhitectura Windows CE, pe baza căreia a fost construit Windows Phone 7, cu kernel-ul Windows NT, folosit și de sistemul de operare Windows 8 pentru PC-uri. Dispozitivele care rulează în momentul de față pe Windows Phone 7, nu pot rula noul sistem și nici nu pot rula aplicațiile dezvoltate pe Windows Phone 8. Dezvoltatorii pot crea aplicații pentru ambele sisteme direct din SDK-ul special ce se găsește in Visual Studio. Dispozitivele ce rulează acest sistem sunt fabricate de Microsoft Mobile (fosta Nokia), HTC, Samsung, și Huawei.

Acest sistem de operare adaugă îmbunătățiri în ceea ce privește sistemul de fișiere, drivere, componente de securitate, suport pentru grafică. Utilizând kernel NT, Windows Phone poate sprijini acum procesoarele multi-core de până la 64 de nuclee, precum și rezolutia full HD.

Spre deosebire de predecesorul său, Windows Phone 8 utilizează adevăratul multi-tasking, permițând dezvoltatorilor de creeze aplicații care pot rula în background și pot fi reluate imediat. Un utilizator poate comuta între sarcini ”active” Ținând apăsat butonul Back, dar orice aplicație din listă poate fi suspendată sau închisă, în anumite condiții, cum ar fi stabilirea unei conexiuni la rețea sau rularea având bateria telefonului aproape descărcată. O aplicație care rulează în background, poate fi oprită automat în cazul în care utilizatorul nu a mai deschis-o de o lungă perioadă de timp. Au fost adăugate o serie de funcționalități importante cum ar fi: NFC and Wallet, Driving Mode, Rooms, Syncing, Kids Corner,

Utilizatorii au lăudat, în general, capacitățile îmbunătățite ale sistemului de operare Windows Phone 8, dar au menționat faptul că există o gamă limitată de aplicații sau jocuri implementate pe telefoanele ce ruleaza acest sistem, în comparație cu Android sau iOS.

iOS este un sistem de operare creat de compania americană Apple Inc. pentru dispozitive inteligente precum:

iPhone – un smartphone de mare succes pe piața de telefoane mobile;

iPod touch – un player MP3;

iPad – o tabletă inteligentă

Apple TV – un aparat de tip Settop box

iOS este u sistem de operare de tip Unix, care încă de la prima sa versiune a conținut multe elemente din Mac OS X, tot un sistem de operare de tip Unix de la Apple.

Interfața din iOs este bazată pe conceptul de manipulkare directă, folosing gesturi multi-touch. Elementele de control ale interfeței constau în curosoare,, switch-uri și butoane.Interacțiunea cu sistemul de operare include gesturi cum ar fi swipe, tap, pinch și reverse pinch, toate având definiții diferite în contextul sistemului de operare ți interfeței multi-touch. Accelerometrele interne sunt utilizate de unele aplicații pentru a genera diferite evenimente, de exemplu agitarea/scuturarea telefonului (un eveniment comun este comanda undo) sau rotindu-l în 3 dimensiuni (pentru a genera event-ul de trecere de la portrait la landscape).

Primul SDK pentru dezvoltare de aplicații pe iOS a fost lansat in februarie 2008, având suport de dezvoltare la vremea respectivă pentru iPhone și iPod Touch, precum și testarea lot pe simulatorul iPhone. Cu toate acestea, pentru a instala o aplicație pe un iPhone trebuie ca dezvoltatorul sa-și creeze un cont de developer la Apple, cont ce costă 99$ anual. În lunie 2011 Apple a lansat IDE-ul Xcode. De la lansarea Xcode 3.1, Xcode este mediul de dezvoltare pentru iOS SDK, aplicații iOS, la fel ca și alte framework-uri high-level ți aplicații care fac parte din iOS și OS X, sunt scrise in Objective-C.

Există anumite framework-uri pe care iOS le împarte cu OS X, cum ar fi Core Foundation și Foundation; cu toate acestea, pentru partea de UI folosește instrumentul Cocoa Touch mai degrabă decât Cocoa folosit de OS X, astfel încât acesta furnizează framework-ul UIKit în loc de AppKit.

Versiunile majore ale iOS sunt lansate anual. Versiunea curentă, iOS 8.3 a fost lansată pe data de 8 aprilie 2015. În iOS, există 4 nivele de abstactizare: nivelul de bază de operare, nivelul pentru serviciile sistemului, nivelul Media și nivelul Cocoa Tocuh. Versiunea actuală a sistemului de operare dedică 1.3 – 1.5 GB din memoria flash a telefonului pentru partiția de sistem, folosinf aproximativ 800 MB din partiție (variind în funcție de model).

Deși din punct de vedere al funcționalităților iOS-ul pare sa fie un sistem de operare foarte atractiv,având și un store foarte bogat în aplicații și jocuri în comparație cu alte sisteme de operare folosite pe dispozitive mobile, are și părți mai puțin pozitive cum ar fi prețul foarte mare al dispozitivelor.

Android este o platformă software și un sistem de operare pentru dispozitive și telefoane mobile bazată pe nucleul Linux, dezvoltată inițial de compania Google, iar mai târziu de consorțiul comercial Open Handset Alliance. Android permite dezvoltatorilor să scrie cod gestionat în limbajul Java, controlând dispozitivul prin intermediul bibliotecilor Java dezvoltate de Google. Aplicațiile scrise în C și în alte limbaje pot fi compilate în cod mașină ARM și executate, dar acest model de dezvoltare nu este sprijinit oficial de către Google.

Lansarea platformei Android la 5 noiembrie 2007 a fost anunțată prin fondarea Open Handset Alliance, un consorțiu de 48 de companii de hardware, software și de telecomunicații, consacrat dezvoltării de standarde deschise pentru dispozitive mobile. Google a lansat cea mai mare parte a codului Android sub licența Apache, o licență de tip free-software și open source.

Începând cu 21 octombrie 2008, Android a fost disponibil ca Open Source. Google a deschis întregul cod sursă (inclusiv suportul pentru rețea și telefonie), care anterior era indisponibil, sub licența Apache. Sub licența Apache producătorii sunt liberi să adauge extensii proprietare, fără a le face disponibile comunității open source. În timp ce contribuțiile Google la această platformă se așteaptă să rămână open source, numărul versiunilor derivate ar putea exploda, folosind o varietate de licențe. Android a fost criticat că nu este software open source în totalitate, în ciuda a ceea ce a fost anunțat de către Google.

Deși este un produs de tip open source, o parte din dezvoltarea software pentru Android a fost continuată într-o ramură privată. În scopul de a face acest software public, a fost creată o ramură oglindă read only, cunoscută sub numele unui desert, anume cupcake. Se crede că numele vine de la Marissa Mayer, care are o pasiune pentru acesta Cupcake este în mod obișnuit interpretat greșit ca numele unei actualizări, dar după cum este declarat pe situl de dezvoltare al Google: „Cupcake este deocamdată în curs de dezvoltare. Este o ramură de dezvoltare, nu o versiune stabilă.” Modificări notabile la software-ul Android care vor fi introduse în cupcake includ modificări la download manager, platformă, Bluetooth, software-ul de sistem, radio și telefonie, instrumente de dezvoltare, sistemul de dezvoltare și câteva aplicații, precum și o serie de remedieri de probleme. Momentul exact al lansării rămâne neclar. Viitoarele versiuni Android vor folosi prezumptiv nume cod numite după deserturi: cupcake, donut, eclair, etc.

Aplicațiile de Android ce extind funcționalitatea telefoanelor, sunt adesea scrise in Java. Scrierea aplicațiilor este de asemenea suportată și de limbajul Go. SDK-ul include un set de instrumente de dezvoltare, inclusiv programe de debug, biblioteci software, un emulator de telefon bazat pe QEMU, documentatie, mostre de cod și tutoriale. Inițial IDE-ul suportat de Google a dost Eclipse, folisind pluginul ADT (Android Development Tools). În decembrie 2014, Google a lansat Andorid Studio, bazat pe IntelliJ IDEA, ca IDE principal pentru dezvoltarea de aplicații Android. Mai sunt disponibile și alte instrumente de dezvoltare, inclusiv un kit de dezvoltare nativ (NDK) pentur aplicații sau extensii în C sau C++, Google App Inventor, un mediu vizual pentru programatori începători, și diverse soluții cross-platform pentru aplicațiile web. Piața aplicațiilor și jocurilor pentru Android este într-o creștere foarte mare, cerințele utilizatorilor devenind din ce in ce mai mari.

1.2.2. Aplicații native versus aplicații hibrid

Platforme mobile precum Android, iOS, BlackBerry, Windows Phone, mai nou și Tizen, luptă pentru câștigarea atenției din partea dezvoltatorilor software care până la urmă au potențialul de a atrage sau chiar respinge utilizatori.

Dezvoltatorii de aplicații software, la rândul lor, caută să își facă loc în piețele de aplicații software mobile, un loc care să le asigure stabilitate pe termen lung. Pentru aceasta, dezvoltatorii sunt puși la încercarea de a alege între dezvoltarea aplicațiilor mobile utilizând cod nativ sau opțiunea de a dezvolta aplicații hibride.

1.2.2.1. Aplicatii native

Cand spunem aplicații/jocuri native ne referim la aplicații scrise în limbajul de programare specific platformei pentru care se dezvoltă. În Tabelul 1 de mai jos, puteți observa câteva din sistemele de operare mobile împreună cu limbajul de programare specific, platformele pentru dezvoltare precum și cu medii de dezvoltare folosite de către programatorii de aplicații mobile.

Tabelul 3. Tabelul corespunzător aplicatiilor native

Un utilizator de dispozitive mobile fidel poate face diferența foarte ușor între aplicațiile mobile native sau cele hibrid. Datorită timpului de răspuns superior și faptului că acesta are acces la diferite componente hardware ale dispozitivului (bluetooth, camera foto sau cea frontală, ledurile de notificare (Android) și altele), aplicațiile native pot fi destul de atractive pentru oricine.

Giganții piețelor de aplicații mobile sunt tot mai puși pe îmbunătățirea mediilor de dezvoltare și a șabloanelor de lucru, totul pentru a atrage de partea lor cât mai mulți dezvoltatori de aplicații mobile. Acesta este un lucru cât se poate de bun pentru un dezvoltator care poate profita de unelte gratuite menite să facă implementarea aplicației cât mai rapidă, câștigând mai mult timp pentru investirea în idei noi sau finisarea produsului.

O aplicație nativă care respectă regulile de dezvoltare specifice platformei pentru care este destinată, nu va folosi niciodată aceleași resurse grafice: butoane, icoane, fundaluri pentru liste, etc. pentru mai mult de o platformă. Aceasta din cauză că aplicațiile native trebuie să păstreze din comportamentul și designul sistemului de operare pe care rulează. Acestea trebuie să se integreze în platforma aleasă de utilizatorul final.

Aplicațiile native sunt foarte pretențioase când vine vorba de cunoștiințele de dezvoltare a programatorului. Aceasta deoarece fiecare platformă cere cunoașterea a cel puțin unui limbaj de programare diferit față de alta platformă iar la rândul lui și limbajul de programare vine cu un șablon de lucru care de obicei este destul de stufos. Pentru ca un produs "nativ" să poată fi rulat pe mai multe sisteme de operare, de obicei este nevoie de câte un programator pentru fiecare platformă în funcție de volumul de muncă, termene limită și alți factori.

Din punct de vedere al creativității, dezvoltatorul are frâu liber fiind limitat doar de resursele dispozitivului pe care aplicația va rula.

Dacă vorbim despre dezvoltare de aplicații pentru dispozitive mobile, nativ versus hibrid, suntem conștienți de faptul că există avantaje (posibilitatea de a accesa diferite componente hardware ale dispozitivelor (cum ar fi hardware grafic), timp mai scurt de răspuns pentru unele operații, programatorul are acces la ultimele API-uri apărute pe platformă încă de la versiunile beta, unelte de dezvoltare gratuite, mediile de dezvoltare vin de obicei cu unelte bune de testare a codului dar și de analiză a aplicației din punct de vedere a consumului de memorie și timpilor de răspuns) și dezavantaje (spre deosebire de aplicațiile web, distribuția aplicațiilor native este adesea limitată de forțarea acestora de a putea fi distribuite doar prin piețele de aplicații care pot impune diferite bariere (ex. Prin unele piețe de aplicații nu se pot vinde aplicații din anumite țări), dacă se urmărește lansarea produsului pe mai multe platforme, costurile cresc semnificativ, fiind nevoie de rescrierea codului pentru fiecare platformă în parte, de regulă specializarea programatorului pe o platformă poate dura ani de zile fapt ce duce și la o limitare a resurselor umane).

1.2.2.2. Aplicatii hibride

Aplicațiile mobile hibride sunt aplicații care de regulă sunt dezvoltate folosind tehnologii WEB (JavaScript, HTML, CSS) și nu numai. La ora actuală aplicațiile hibride încep să prindă rădăcini tot mai puternice datorită faptului că multe medii de dezvoltare devin tot mai stabile și oferă acces la tot mai multe funcționalități hardware ale dispozitivelor. În Tabelul 2 puteți urmări câteva dintre cele mai folosite medii de dezvoltare ale aplicațiilor hibrid:

Tabelul 4. Tabel corespunzator aplicatiilor hibrid

Este de ajuns să scrii codul de bază pentru o aplicație, pentru ca ulterior, ca prin magie aplicația să funcționeze pe mai multe platforme. Din această cauză dezvoltatorii de aplicații hibrid au mai mult timp pentru idei noi sau dezvoltarea unei noi aplicații.

Datorită faptului că majoritatea uneltelor de dezvoltare folosesc tehnologiile WEB pentru implementarea aplicației, găsirea unui programator pentru a duce la bun sfârșit o aplicație hibridă pentru dispozitive mobile, este un lucru mai puțin stresant. Volumul de lucru pe WEB a făcut ca tot mai mulți programatori să învețe tehnologii precum JavaScript, HTML și CSS. Acest lucru duce la o tranziție relativ ușoară către lumea programării de aplicații hibrid pentru dispozitive mobile.

Există și în cazul dezvoltării aplicatiilor hibride avantaje (timp de dezvoltare mic pentru o acoperire largă de sisteme de operare, învățarea mai rapidă a tehnologiilor de dezvoltare, fiind vorba în principiu de tehnologi WEB, aplicația are o vizibilitate mai mare pe platforma unde este lansată datorită faptului că este distribuită prin piețele de aplicații folosite de majoritatea utilizatoriilor de dispozitive mobile) și dezavantaje (dependență față de dezvoltatorii uneltelor de lucru, fapt ce poate întârzia lansarea aplicației care să funcționeze pe o versiune nouă a unui sistem de operare sau întârzieri în repararea problemelor tehnice ce pot apărea mai ales la versiuni noi ale sistemelor de operare pentru mediile mobile, performanță mai scăzută în unele locuri, pierdere de timp pe repararea problemelor găsite în urma faptului că nu pe toate platformele aplicația o să ruleze la fel de bine).

Ambele modalități de dezvoltare sunt importante și trebuie luate în calcul în momentul în care se vrea să se dezvolte o aplicație pentru dispozitivele mobile. Important este să se decidă dacă aplicația trebuie să fie bogată din punct de vedere al animațiilor, dacă se dorește publicarea aplicației pe mai multe platforme sau cât de mare este bugetul alocat dezvoltării aplicației respective.

Alegeți dezvoltarea nativă a aplicației dacă timpul de dezvoltare și implicit bugetul nu este mic. Această opțiune poate aduce utilizatori fideli pe termen lung și review-uri pozitive. În același timp vă ajută să distribuiți clienților versiuni ale aplicației care poate rula pe cele mai noi versiuni ale sistemelor de operare pe care rulează încă de la lansarea acestora.

Alegeți dezvoltarea hibridă a aplicației dacă timpul de dezvoltare a aplicației si bugetul sunt mici. Această opțiune de dezvoltare se potrivește foarte bine și dacă doriți să experimentați o idee nouă de aplicație. Aplicațiile hibrid sunt foarte bune pentru un startup, acestea vă ajută să acaparați atenție pe mai multe platforme cu un minim de efort și la o calitate corectă.

În cazul dezvoltării jocurilor, problema se pune altfel. Un joc este mult mai complex decât o aplicație, are mult mai multe resurse (imagini, sunete), toate aceastea reflectându-se în faptul că jocul solicită partea hardware a telefonului mai intens.

Dacă de exemplu se dorește dezvoltarea unui joc pe mai multe platforme/console, este indicat folosirea unui engine sau a unui cross-platform (platformă ce poate compila pentru mai multe dispozitive – fixe sau mobile) astfel încât cele mai importante aspecte din dezvoltarea jocului să fie optimizate, precum: timpul de munca este mai redus, pot fi folosite aceleași resurse grafice pe toate dispozitivele, etc.

Există o multitudine de astfel de soluții pe piață, fiecare având plusuri si minusuri. Cele mai utilizate în dezvoltarea de jocuri sunt următoarele: Unreal Engine, Marmalade, Corona, Cocos2D JS, Unity. Toate aceste soluții au un număr (diferit) de platforme pe care le acoperă, însă Unity este platforma care acoperă cea mai mare parte a platformelor de pe piață.

2. Tehnologii utilizate la crearea jocului

În capitolul precedent am prezentat câteva limbaje de programare folosite în dezvoltarea de jocuri și câteva solutii de dezvoltare. În acest capitol o să prezint soluția folosită pentru dezvoltarea jocului Fruits Slot.

2.1. Platforma Unity

Cross-platform-ul ales este Unity.

Am ales Unity pentru portabilitatea foarte mare pe care o are acest cross-platform (dispozitive mobile, browsere web, desktopuri și console) și pentru că toate tool-urile necesare dezvoltării sunt gratuite.

2.1.1. Noțiuni introductive

Unity este o engine și un framework flexibil și puternic ce oferă un sistem pentru proiectarea și crearea jocurilor 2D și 3D, chiar și aplicațiilor. Unity permite interacțiunea nu numai prin cod, ci și prin componente vizuale, pe care le exportă pe orice platformă mobilă majoră (gratuit).

Există, de asemenea o versiune pro (Unity Pro) care este destul de complexă, dar nu este gratuită. Unity suportă toate aplicațiile 3D importante și multe formate audio, și chair înțelege formatul PSD Photoshop, astfel încât se poate face drag-and-drop a unui fișier PSD direct în proiectul de Unity. Acest framework permite importarea și integrarea assets-urilor, scriere de cod pentru a interacționa cu obiectele, crearea sau importarea animatiilor, oferă uun sistem avansat prin care se pot crea animații.

Platforma Unity a fost dezvoltată de Unity Technologies, prima versiune fiind anunțată doar pentru Mac OS, la Apple's Worldwide Developers Conference în 2005, a fost extinsă la mai mult de 15 platforme, iar momentan este SDK-ul default pentru Wii U. De principiu există două versiuni de Unity (Pro și Personal), însă se mai plătește câte o licență pentru unele platforme (cum ar fi Android, iOS).

Jocurile sunt create prin manipularea obiectelor 3D și atașarea diferitelor componente la obiecte. Chiar și jocurile 2D trebuie manipulate în 3D. Unity este bazat pe un engine C++ nativ, iar scripturile sunt scrise in C# (recomandat), Boo sau UnityScript (o versiune de JavaScript modificată/adaptată pentru Unity). Codul rulează pe Mono sau Microsoft.NET Framework, care este compilat JIT (Just-in-Time), excepție făcând iOS-ul – nu permite cod JIT și este compilat de Mono pentru cod nativ folosing compilare AOT (Ahead-of-Time).

2.1.2. Editorul grafic

Pentru partea vizuală, Unity folosește un editor grafic ilustrat în Figura 1, de mai jos.

Figura 1. Editorul grafic din Unity

Practic, jocul este creat în acest editor, iar pentru implementarea game-play-ului se folosesc scripturile care se atașează la obiecte. Jocurile, în general, sunt create ca fiind mai multe scene, afișate cursiv în funcție de design-ul jocului. Observăm în partea de sus a editorului câteva taburi: Hierarchy, Animation, Scene, Game, Animator.

Dacă selectăm tab-ul Hierarchy, va apărea lista cu obiectele prezente in scena respectivă, iar dacă selectăm un obiect din scenă, în partea dreaptă a editorului va aparea lista cu componentele atașate obiectului respectiv.

Tab-ul Animation este utilizat la crearea animațiilor, Scene este folosit pentru editarea scenei (așezarea obiectelor în scenă), Game este folosit în momentul în care jocul este rulat in editor, iar Animator este tab-ul unde apare interfața ce controlează mecanismul animațiilor din sistem.

În partea de jos a editorului apar doua tab-uri: Console și Project. Selectând tab-ul Control, în momentul rulării jocului din editor, putem vedea mesajele pe care le-am tratat in cod sa apară (debug-ul). Cel de-al doilea tab, Project, este tab-ul unde putem vedea structura folderelor din proiect.

În partea de sus a editorului mai există o serie de butoane, fiecare buton având o anumită funcționalitate

2.1.3. Modul de utilizare al resurselor grafice și audio

În dezvolatrea unui joc este foarte important să știm de la început cum trebuie să arate jocul și pentru ce dispozitive dezvoltăm astfel încât să stabilim exact ce tipuri de resurse folosim. Telefoanele mobile au început sa aibă rezoluții din ce în ce mai mari, apropiindu-se de cele ale computerelor, însă există o problemă destul de majoră in ceea ce privește memoria telefonului (RAM-ul). Din acest motiv, resursele trebuie optimizate la maxim ca să putem obține o calitate grafică bună a jocului. Pe partea de imagini, am folosit fomatul PNG, iar pentru audio am folosit formatul WAV.

Datorită faptului că imaginile sunt 2D, am gândit animațiile jocului ca fiind o succesiune de imagini, adăugate într-un atlas (o textură) de sprite-uri(un sprite este o imagine dintr-o textură). În același mod am creat atlasuri pentru restul resurselor, pentru bakground si celelate obiecte din scenă. În momentul în care am creat un obiect vizual, i-am atașat ca și componentă sprite-ul specific, ca backgorund.

Pe partea audio am folosit doar două resurse (două sunete mai exact), unul pentru linia caștigatoare si un sunet de background care se play-ează doar când rolele se învârt.

2.1.4. Modul de lucru cu scripturile

Scripturile reprezintă o parte importantă în dezvoltarea jocului. Oricât de simplu sau complicat este jocul, avem nevoie de scripturi pentru a răspunde la input-ul utilizatorului și pentru a aranja eventurile să se întâmple exact cum ar trebui. De asemenea scripturile pot fi folosite pentru a crea efecte grafice, a controla comportamentul fizic al obiectelor, etc. Aceste scripturi sunt atașate de asemenea obiectelor, precum celelalte resurse.

Un script poate fi creat din meniul editorului selectând Assets -> Create -> C# Script (sau Javascript). Structura unui script creat inițial arată în felul următor:

using UnityEngine;

using System.Collections;

public class NewBehaviourScript: MonoBehaviour {

// Use this for initialization

void Start () {

}

// Update is called once per frame

void Update () {

}

}

Cele două metode, Start() și Update() sunt metode create default pentru orice script ce derivă (depinde de limbaj) din MonoBehaviour.

2.1.5. Interfața MonoDevelop

MonoDevelop este un IDE (Integrated Development Environment) instalat odată cu Unity.

Este utilizat pentru editarea scripturilor și pentru compilarea lor. Înainte de toate trebuie verificat dacă MonoDevelop este setat ca editor pentru scripturile externe în preferințe (meniu: Unity->Edit->Preferences->External Tools). Odată setată această opțiune, Unity va lansa MonoDevelop si îl va folosi ca editor default pentru toate scripturile. Pentru a activa debug-ul MonoDevelop la nivel de sursă, trebuie să verificăm mai întâi dacă opțiunea Editor Attaching este activată din panoul Preferences->External Tools. Apoi trebuie sincronizat proiectul din Unity cu cel din MonoDevelop (meniu: Assets->Sync MonoDevelop Project). De asemenea, ne asigurăm că build-ul de development și debug-ul pe scripturi sunt activate pentru platforma pe care compilăm (meniu: File->Build Settings).

În Figura 2, de mai jos se poate vedea cum arată acest IDE.

Figura 2. MonoDevelop IDE

Pentru a folosi debuggerul din acest IDE, tot ceea ce trebuie sa facem este sa apăsăm butonul din stânga sus . La apăsarea acestui buton, va apărea o fereastră ”Attach to process”, iar din lista de mai jos selectăm instanța către jocul nostru. Dacă inserăm un breakpoint în MonoDevelop, în momentul rulării jocului în editorul de Unity, jocul se va opri când va ajunge la execuția liniei de cod pe care am pus breakpoint-ul. Există și opțiunea punerii unei condiții pe brakpoint ca și la alte IDE-uri. Aceată operație se face cu un click dreapta pe breakpoint, selectând opțiunea Breakpoint Properties. Va apărea o fereastră în care putem seta condiția pentru breakpoint cât și acțiunea în momentul în care breakpoint-ul este atins.

2.2. Limbaje de programare utilizate în Unity

Platforma Unity oferă, pe partea de scripturi, suport pentru 3 limbaje de programare Boo, UnityScript și C#.

2.2.1. Notiune introductive: Boo, UnityScript, C#

Linbajul de programare Boo este un limbaj orientat pe obiect. Este dezvoltat din anul 2003, iar in 2011 a apărut o versiune oarecum stabilă. În mod implicit, în Boo trebuie specificate tipurile de date sau tipurile de date ale obiectului. Nu este un limbaj foarte ”user-friendly”, depinde foarte mult de cunoștințele de python, pentru că se aseamană mult.

Când vine vorba de UnityScript, toată lumea crede că vorbim despre JavaScript, însă diferențele sunt foarte mari. În timp ce JavaScript este doar un nume generic și ar putea face referire la oricare dintre implementarile ECMAScript, limbajul ”.js” din Unity nici măcar nu se apropie de aceste specificații și nici măcar nu încearcă. UnityScript este un limbaj proprietate și nici nu urmează vreo precizare concretă; acesta este modificat la dorința dezvoltatorilor Unity.

Marea majoritate a librăriilor (bibliotecilor) din JavaScript nu vor funcționa doar prin copierea sau importarea lor în Unity. JavaScript-ul din Unity este mai aproape de JScript.NET de la Microsoft, deși nu sunt identice. De aceea eu cred că nu trebuie să confundăm JavaScript cu UnityScript. Unii oameni consideră acest lucru ca fiind ”doar semantică” dar atunci când oamenii confudă numele de UnityScript cu numele ”JavaScript”, devine mult mai greu de căutat pe internet soluții sau ajutor pentru scripting în UnityScript.

Limbajul C# este limbajul recomandat pentru Unity, fiind și cel mai folosit de utilizatorii acestui framework.

2.2.2. Scurtă comparație între limbajele folosite în Unity

După cum am specificat în capitolul anterior, orice script creat derivă din scriptul MonoBehaviour. Dacă folosim JavaScript, orice script derivă automat din MonoBehaviour, iar în cazul în care folosim C# sau Boo, trebuie sa specificăm explicit ca derivă din MonoBehaviour.

Am prezentat, mai jos, implementarea unui script în toate cele 3 limbaje pentru a putea vedea diferențele sintaxă dintre cele 3 limbaje..

Boo Script

import UnityEngine

import System.Collections

public class ExampleSyntax(MonoBehaviour):

private myInt = 5

private def MyFunction(number as int) as int:

ret as int = (myInt * number)

return ret

UnityScript

#pragma strict

var myInt : int = 5;

function MyFunction (number : int) : int

{

var ret = myInt * number;

return ret;

}

C# Script

using UnityEngine;

using System.Collections;

public class ExampleSyntax : MonoBehaviour {

int myInt = 5;

int MyFunction (int number) {

int ret = myInt * number;

return ret;

}

}

Observăm că în C# apare declarația de clasă, insă in UnityScript declarația este ascunsă, însemnând ca orice cod va fi scris, va fi în interiorul clasei.. Declarația unei variabile în C# începe cu tipul variabilei, urmată de numele variabilei și de o valoare default (opțională). În UnityScript, declararea unei variabile începe cu cuvântul cheie ”var”, urmat de numele variabilei, apoi optional de tipul variabilei și de o valoare default. În cazul nostru, folosind ”#pragma strict” la începutul scriptului, suntem obligați sa specificăm tipul variabilei.

În C#, declararea unei funcții (metode) începe cu tipul de dată returnat de funcție, urmat de numele funcției și de lista de parametri (argumente). În UnityScript, declararea unei funcții începe cu cuvântul cheie ”function” urmat de numele funției și de lista de parametri. Pentru a specifica tipul de dată returnat de funcție, folosim ”:” urmat de tipul returnat.

O altă diferență importantă între C# și UnityScript este accesul default al variabilelor: în C# accesul este Private, pe când în UnityScript accesul este Public.

Dacă ne uităm la scriptul scris in Boo, observăm că apare declarația de clasă, ca și în C#.

O funcție este declarată începând cu specificarea accesului la metodă, urmată de cuvântul chie ”def”, numele funcției, lista de parametri ți tipul returnat de funcție. Declarația de variabilă este facută similar cu C#-ul, însă accesul variabilei este specificat expres.

3. Descrierea jocului Fruits Slot

În Introducere, am vorbit succint despre conceptul jocului, combinația între ”slot machine” și ”match three”. După cum știm, cei de la King au făcut o mare afacere cu jocul Candy Crash, deși pe piață sunt nenumărate jocuri de tipul ”match three”. Jucând acest joc și observând cât de mult se poate extinde conceptul acesta de a potrivi 3 sau mai multe simboluri, am ales această combinație știind faptul că jocurile de tip slot sunt destul de căutate, dar ar fi și mai interesante dacă ar avea ceva în plus față de game-play-ul obișnuit, cum ar fi interacțiunea cu simbolurile afișate pe ecran.

Înainte de a trece la descrierea jocul implementat de mine, aș vrea sa vă prezint un scurt istoric al conceptului de ”slot machine”.

3.1. Istoricul jocurilor de tip ”slot machine”

Un joc mecani/electronic/video de tip ”slot machine” (American English), ”păcănele” (română) este un aparat de joc de noroc constând inițial în trei sau mai multe roți (role) cu imagini care se rotesc independent când un buton e apăsat sau o manetă laterală e acționată ca la primele aparate apărute. Mașina oferă un câștig jucătorului când pe panoul de afișare sau intr-o zonă delimitată a ecranului video apar anumite tipuri prestabilite de configurații de imagini rezultate din „rotirea” independentă, cu viteză (pseudo)aleatoare a tamburilor,și respectiv fixarea unora de către jucător, tip de acțiune transmis și echivalentelor ne-mecanice moderne exploatate public sau simulatoarelor pentru calculator instalate local sau online .

Acest gen de aparat este cel mai popular mod de distracție în cazinouri și ”săli de joc” asigurând 70% din veniturile acestora.

Primul aparat ”slot” simplu a fost conceput in 1887,de Charles Fey of San Francisco, California, U.S., Avea trei roti cu cinci simboluri – potcoave, diamante, săbii, inimi și un clopot ( Liberty Bell) – de unde numele inițial, astfel încât s-a putut realiza un mecanism automat de plată în caz de câștig. Invenția a avut succes și a declanșat o ”febră” a industriei de ”aparate de joc” încât în unele state aceste a au fost prohibite. Sittman și Pitt din Brooklyn, New York, U.S. au realizat un aparat de joc in 1891 precursor al celor moderne cu cinci cilindri rotitori (”roți”) și un total de 50 imagini bazat pe jocul de poker . O altă mașinărie furniza câștigătorilor gumă de mestecat cu aroma fructelor din imaginile de pe roți, în cazul alinierii, de unde sau transmis în actualitate popularele imagini ”cireașa”, ”lămâie”, ”căpșună”. În 1963, Bally a dezvoltat cu succes primul aparat electromecanic Money Honey, încât maneta de antrenare a devenit o relicvă . Primul ”slot” video a fost realizat in 1976 la scară industrială in Kearney Mesa, CA de N. Cerracchio, R. Greene, W. Beckman, J. Reukes, și L. Black pentru Fortune Coin Co., Las Vegas, NV.

De când piața jocurilor pe dispozitive mobile a început sa crească, dezvoltatorii s-au orientat și către această nișă a jocurilor de tip ”slot”. Diferența între un slot pe aparate și unul pe telefon constă în faptul că nu este permis jocul pe bani reali pe telefon (există doar câteva țări în care este permis acest lucru, limitat chiar la anumite platforme). Totuși ne întrebăm de unde vin banii dacă jocurile de pe telefoane sunt gratuite (altfel este foarte greu sa fie vândute) și nu se joacă pe bani reali. Aici intervin IAP-urile (In-App Purchase), reprezentate prin tot felul de pachete de credite, puncte de experientă, etc, iar aceste IAP-uri nu mia sunt gratuite (se plătesc în funcție de ”puterea” lor).

3.2. Descrierea funcționalității

În acest subcapitol voi prezenta schema (screen-tree-ul) și design-ul jocului creat.

3.2.1. Screen-tree-ul jocului

Primul lucru la care am lucrat înainte de a începe jocul efectiv, a fost crearea scree-tree-ului (structura jocului). Am ales ca numărul de ecrane din joc sa fie cât mai mic, pentru a mențiune utilizatorul cât mai concentrat asupra locului. În Figura 3 este prezentată schema jocului.

Figura 3.Schema jocului

Primul ecran al jocului este ecranul cu logo-ul de la Unity. Acest ecran apare doar în jocurile implementate cu versiunea free de Unity. Al doilea ecran, este unul de selecție, din care se selectează jocul pe care dorim să-l jucăm. În situația de față este oarecum inutil deoarece un astfel de ecran se folosește în momentul în care există mai multe opțiuni de selecție. Eu l-am implementat dintr-un singur motiv: am vrut să existe cel puțin 2 scene în joc. Următorul ecran, este ecranul principal de joc, din care se poate ajunge în ecranul de Free Spins sau de Minigame.

Jocul conține și câteva poup-uri (ecrane intermediare) cum ar fi: Free Spins Win Popup, Minigame Win Popup, Paytable Pop.

3.2.2. Design-ul jocului

Mecanismul jocului are la bază 5 role, fiecare rolă având 32 simboluri; există 10 linii de câștig posibile. Din cele 32 de simboluri, doar 3 sunt vizibile pe ecran. În Figura 4 am ilustrat rolele și liniile de câștig.

Figura 4. Rolele și liniile de câștig

Similar jocurilor de pe aparate, rolele se învârt la o simplă apăsare de tastă sau un swipe pe zona specifică acestei mișcări. Această mișcare poartă denumirea ”spin”. Rolele se opresc la un index generat aleator din toate cele 32 de poziții de pe rolă. În momentul în care s-au oprit toate rolele, se calculează și apoi se afișează liniile câștigatoare (dacă există). Trebuie să menționez faptul că liniile nu sunt linii propriu-zise, ci sunt formații de simboluri respectând niște ltrasee predefinite, care încep neapărat cu un simbol de pe prima rolă.

Jocul are 11 simboluri, împărțite în două categorii:

simboluri normale, în număr de 8: cireașa, strugurele, portocala, lămâia, pepenele, pruna, mărul și șeptarul – pentru care se primesc doar credite în momentul în care se formează o linie caștigatoare cu aceste simboluri;

simboluri speciale, în număr de 3: Wild, Bonus, Scatter. Simbolul Wild, reprezentat grafic printr-un coș cu fructe, are rolul de joker (înlocuiește orice simbol într-o linie), Bonus, reprezentat printr-o pară cu o față zâmbitoare, este un simbol cu care se poate ajunge în minigame (detaliile despre minigame în secțiunea 3.2.2.3. Minigame-ul jocului), iar Scatter-ul, reprezentat grafic printr-o stea, oferă userului un anumit număr de spinuri gratuite (fără să consume din credite). De menționat că Wild-ul nu înlocuiește Bonus-ul sau Scatter-ul, iar Scatter-ul este un simbol special care este platit (userul primește credite în momentul în care pe ecran apar cel puțin 3 simboluri Scatter) – de altfel singurul simbol special plătit.

La început, userul pornește cu un anumit număr de credite (10000), care va crește sau va scădea în funcție de acțiunile jucătorului. La orice spin, userul va consuma un număr de credite egal cu bet-ul setat. Bet-ul setat reprezintă o valoare pe care userul vrea să o parieze la spin-ul respectiv, pentru o linie de câștig. De exemplu, dacă userul vrea să joace cu un bet de valoare 5 și 8 linii de câștig, va cosuma 40 credite. Modul de caștig este prezentat în secțiunea 3.2.2.4. PayTable.

În partea de jos a ecranului de joc se află zona care conține butoane sau label-uri de text (Figura 5).

Figura 5. Zona de butoane

Zonele de text sunt următoarele:

Win/Last win – reprezintă creditele câștigate la fiecare spin/creditele de la ultimul spin câștigător;

Credits – creditele pe care le are userul;

Bonus – numărul de simboluri bonus adunate (detalii în secțiunea 3.2.2.3. Minigame-ul jocului);

Zona de mesaje – este zona centrală unde apar diferite hint-uri (indicii) din joc.

Butoanele care apar în această figură sunt:

Bet – este folosit in momentul în care userul vrea sa modifice bet-ul pentru urmatorul spin. La apăsarea btonului de bet, va apărea în zona de jos un popup peste zona de text, ca în Figura 6. Din acest popup de bet se poate modifica atât bet-ul cât și numărul de linii cu care vrea să joace userul în continuare.

Minigame – apare peste zona de text Bonus în momentul în care minigame-ul devine activ (detalii în secțiunea 3.2.2.3. Minigame-ul jocului).

Figura 6. Popup-ul de bet

Până aici, am prezentat funcționalitatea similară cu cea a jocurilor de pe aparate. În continuare, voi prezenta adaptarea conceptului ”match three” în jocul Fruits Slot pe Android.

Există o oarecare similitudine între conceptul ”slot machine” și ”match tree”: în ambele cazuri userul trebuie să formeze linii din minim 3, maxim 5 simboluri, de același tip. Diferența constă în faptul că la un slot userul nu poate să-și formeze singur aceste linii (el doar apasă un buton), pe când în celălalt caz userul interacționează cu simbolurile. Ceea ce am implementat, și nu am văzut încă la niciun joc de tip slot, este interacțiunea userului cu simbolurile. Aceste interacțiuni le voi denumi ”mutări”.

Interacțiunea userului cu simbolurile se poate face în 3 moduri, fiecare mod reprezentând un nivel:

Swipe pe o rolă – constă în rotirea unei singure role, celelalte rămânând nemișcate;

Switch între două role alăturate – constă în schimbarea a două role alăturate. Această mutare se face dând click consecutiv pe cele două role care trebuie schimbate;

Switch între două simboluri tangente – constă în schimbarea a două simboluri pe 6 direcții: diagonale plus stânga și dreapta. Această mutare se face prin drag de pe un simbol pe altul.

O mutare poate fi facută după fiecare spin, dar nu mai mult de una. Aceste mutări se fac fără credite și doar în momentul în care userul are energie. In Figura 7 este ilustrat ecranul de joc, inclusiv zona din dreapta unde apar câteva elemente pe care nu le-am descris până acum.

Figura 7. Ecranul de joc

În partea dreaptă, se pot observa mai multe elemente grafice:

Zona de swipe – userul poate face swipe, acțiune echivalentă apăsarii botonului de spin;

Spin – la apăsarea acestui buton userul face spin (rolele se învârt). Acest buton poate fi setat pe ”autostart” ținând apăsat timp de o secundă pe buton. În momentul în care butonul este setat pe autostart, rolele se învârt automat, fară intervenția userului, la un interval scurt între spin-uri, caz in care userul nu mai poate face mișcări speciale. Acest buton de spin, este denumit Collect în momentul în care userul are caștig. La apăsarea butonului Collect, creditele caștigate se vor aduna la numărul total de credite ale userului după care butonul va reveni la funcția de spin.

Energy Bar – zona vizuală de feedback pentru user în care vede exact câtă energie are;

Simbolurile pentru mutări – îi arată userului ce mutări poate să facă folosind energia disponibilă.

Fiecare dintre cele 3 mutări pe care poate sa le facă userul au un anumit cost, aceste costuri fiind delimitate vizual pe bara de energie (1, 2 și 3). Dacă, de exemplu, userul are bara de energie plină (nivelul 3) el poate sa facă oricare dintre cele 3 mutări, dar nu este obligat să facă vreo mutare sau sa facă direct mutarea de nivelul 3.

Energia se câștigă în timpul jocului, astfel că, la fiecare spin folosit, userul primește o unitate de energie. Dacă bara de energie a ajuns la nivelul 3 și userul nu face nicio mișcare, la următorul spin nu va mai primi energie deoarece nivelul 3 este nivelul maxim.

Dacă userul a făcut o mutare caștigătoare (a reușit să formeze una sau mai multe linii), iar caștigul obținut este mai mare decât caștigul inițial de după spin, în zona centralî de mesaje o să apară două texte:

Old win – câștigul de după spin;

Extra win – caștigul de după mutare.

În Figura 8 am ilustrat un asemenea caz.

Figura 8. Caștig suplimentar din mutare specială

3.2.2.1 Tutorialul jocului

Pentru ca userul să înțeleagă cât mai bine cum funcționează jocul, mai ales partea cu mișcările speciale, am implementat la începutul jocului un tutorial care să-i explice userului cum să folosească mutările speciale și ce înseamnă o linie câștigătoare.

La primul spin efectuat de către user, va primi o linie câstigătoare. Începând cu al doilea spin, userul va primi hint-uri vizuale care îi vor explica exact cum să folosească mutările speciale astfel încât să realizeze linie sau linii câștigătoare. Pentru prima mișcare specială va apărea o imagine cu o mână care îi arată userului să faca swipe pe o rolă. Pe același principiu, în momentul în care userul a adunat nivelul doi de energie, apare mâna și îi arată că poate să facă click pe două role alăturate tot pentru a realiza o linie câștigătoare, iar pentur a treia mutare specială apare mâna făcând drag pe două simboluri tangente. De menționat că în tutorial trebuie execute mutările speciale exact pe simbolurile sau rolele indicate de mână. În Figura 9 este un exemplu cu hint-ul pentru prima mutare specială.

Figura 9. Hint mișcare specială de nivelul 1

3.2.2.2. Free Spins

În momentul în care pe ecran apar minim 3 simboluri de scatter, pe lângă creditele aferente câștigului, userul primește un număr de spin-uri gratuite astfel: dacă apar 3, 4 sau 5 simboluri Scatter, userul primește 10, 15 sau respectiv 20 de free spin-uri. Iarăși trebuie precizat că în cazul simbolului Scatter simbolurile nu trebuie sa urmeze un anumit traseu pentru a forma o linie ci pur și simplu trebuie să apară un număr de minim 3 simboluri în același timp pe ecran.

Un lucru la fel de important este faptul că, în timp ce userul joacă aceste spin-uri gratuite, bet-ul nu poate fi schimbat, va juca folosind bet-ul setat anterior primirii spinurilor gratuite. De asemenea, butonul Minigame este blocat in acest caz (dacă este activat).Pentru a ști exact câte spin-uri gratuite a primit sau câte spin-uri gratuite mai are de jucat, în partea de sus a ecranului o zona de text ce va afișa exact counter-ul spin-urilor (Figura 10).

Figura 10. Zona de text pentru spin-uri gratuite

În momentul în care userul nu mai are spin-uri gratuite, va apărea un popup în care va fi afișat caștigul din spin-uri gratuite și apoi userul se va întoarce în jocul obisnuit.

3.2.2.3. Minigame-ul jocului

Jocurile de tip slot de pe aparate au implementat diferite moduri de caștig diferite de caștigul obișnuit din joc. Acest tip de caștig este numit de unii ”Jackpot” sau ”Speciala”. Acest caștig este foarte mare în unele cazuri, dar apare foarte rar. Poate fi dat în funcție de o combinație de simboluri de pe ecran sau pur și simplu aleator. Pentru a suplini oarecum acest aspect, am implementat un minigame.

Minigame-ul este o parte importantă din acest joc. Pentru a activa acest minigame userul trebuie să colecteze un număr de 5 simboluri Bonus. Dacă pe ecran vor apărea mai mult de un Bonus, se va contoriza doar unul. Odată devenit activ, minigame-ul poate fi jucat oricând de către user prin simpla apăsare a butonului Minigame. Activarea este evidențiată prin buton, ce va apărea peste zona de text Bonus (ca în Figura 9), unde în mod normal este afișat contorul minigame-ului.

După ce userul apasă butonul Minigame, pe ecran va apărea un popup cu 4 simboluri Wild (Figura 11).

Figura 11. Popup-ul de intro minigame

Acele coșuri cu fructe sunt de fapt butoane. În momentul în care userul apasă pe unul dintre coșuri, se generează aleator, din cod, un număr din intervalul [2,5]. Imediat după ce userul a ales unul dintre coșuri, va apărea un mesaj în care se specifică exact câte mutări speciale poate sa facă după fiecare spin (Figura 12).

Figura 12. Mesajul cu numărul de mutări

În minigame userul joacă fără să consume credite, avînd un număr de 5 spin-uri gratuite. Pentru fiecare spin, are dreptul sa facă mai multe mutari (în jocul normal poate face o singură mutare după un spin). Acest număr de mutări este egal cu numărul generat la apăsarea unuia dintre coșuri.

După ce userul a ales să continue minigame-ul, rolele se vor roti automat la primul spin.

În partea de sus a ecranului va apărea o zonă cu text unde userul poate să vadă exact câte spin-uri mai are și câte mutări speciale mai are pentru spin-ul curent (Figura 13).

Figura 13. Mesajele din Minigame

Iî momentul în care userl nu mai are free spin-uri gratuite și nici mișcări speciale pentru ultimul spin, va apărea un popup în care i se va specifica userului căt a câștigat în minigame.

Se poate observa în Figura 13 un buton nou, ”PayTable”. Funcționalitatea și utilitatea acestui buton o voi prezenta în următoarea secțiune.

3.2.2.4. PayTable

Vorbeam într-un capitol anterior despre faptul că jocul are 10 linii de câștig posibile. În Figura 14 este ilustrată o linie de câștig.

Figura 14. Linia de câștig cu numărul 8

Linia de câștig din figură este o linie cu 5 simboluri. Însă există linii câștigătoare de 3, 4 sau 5 simboluri de același fel. În funcție de numărul de simboluri de pe linia câștigătoare, userul primește un anumit număr de credite. În fereastra de PayTable userul poate vedea exact sistemul de plată pentur fiecare linie, în funcție de fiecare simbol. Această fereastră apare în momentul în care userul apasă butonul PayTable. În Figura 15 se poate vedea fereastra. De notat faptul că în această fereastră userul are două butoane de scroll stânga-dreapta pentru a parcurge toate simbolurile, ele fiind prezentate în funcție de categorie: normale sau speciale.

Figura 15. PayTable

Payout-ul userului (modul de plată al userului) este foarte bine definit de obicei și este calculat în funcție de un algoritm gândit astfel încât userul să nu câștige niciodată mai mult decât a investit.

3.3. Aplicabilitatea probabilităților matematice în jocurile de tip ”slot machine”

Jocurile de tip slot încă sunt unele dintre cele mai căutate jocuri de noroc, deși există un motiv pentru care atractivitatea ar fi trebuit sa fie mai scazută: lipsa de transparență. Jocătorii nu stiu nimic despre configurațiile parametrice ale aparatelor pe care joacă, informație care expusă foarte rar. De exemplu jucătorii de cărți știu compoziția pachetului în tipul jocului, jucătorii de ruletă știu numerele de pe roată, jucătorii de loto stiu numerele din care se extrag, însă in cazul sloturilor jucătorii nu sunt informați asupra parametrilor esențiali ai acestora, cum ar fi numărul de stopuri de pe role, numărul de simboluri și distribuția lor de pe role.

n mod evident, lipsa de date privind configurația parametrică a unui aparat împiedică pe oricine să calculeze șansele de a câștiga și alți indicatori matematici, deoarece formulele probabilității au ca variabile acei parametri. Fișele PAR (Probability Accounting Report), care conțin acești parametri ai aparatelor și probabilitățile asociate cu combinațiile câștigătoare, nu sunt expuse publicului și pot fi obținute numai cerându-le producătorilor jocului, de obicei prin intervenție juridică (de exemplu, prin FIPPA, Freedom of Information and Protection of Privacy Act).

În ceea ce privește posibilele motive ale producătorilor de jocuri de a ține fișele PAR departe de public, există un motiv declarat exprimat de către producătorii care au refuzat cereri, în apelul lor la hotărârile judecătorești, anume faptul că fișele PAR conțin informații considerate a fi secrete comerciale în industria jocurilor de noroc și constau în formule matematice și ecuații elaborate de inginerii lor, precum și că informațiile pot leza semnificativ poziția lor în competiția economică.

Există dezbateri asupra faptului dacă un astfel de motiv este justificat sau nu, iar oponenții susțin că acesta este în contradicție cu generalitatea formulelor și ecuațiilor matematice – deși detaliile parametrice variază de la joc la joc, rezultatele matematice referitoare la probabilitate, speranța matematică și alți indicatori statistici sunt doar aplicații ale unor formule generale, care sunt accesibile oricui în matematică și comune tuturor aparatelor de sloturi, astfel că nici un organism individual sau corporativ nu poate pretinde dreptul de proprietate asupra unor astfel de modele sau formule; oponenții susțin, de asemenea, că motivul lezării poziției competitive este în contradicție cu posibilitatea deschisă tuturor producătorilor de jocuri de sloturi de a configura, testa și folosi orice design parametric pentru aparatele lor, iar producătorul poate manipula parametrii de joc, inclusiv schema câștigurilor, în mod nelimitat, pentru a obține indicatorii statistici doriți.

Un alt motiv posibil este teama ipotetică de a pierde jucătorii care află care sunt șansele reale și alți indicatori statistici ai jocurilor preferate, idee care este criticabilă prin așteptările a priori ale jucătorilor cu privire la șansele scăzute și foarte scăzute de câștig induse de experiența secretului fișelor PAR, dar și prin exemplul loteriei, unde jucătorii continuă să joace în ciuda faptului că au de-a face cu cele mai mici șanse de a câștiga dintre toate jocurile de noroc (lucru bine cunoscut), datorită efectului altor elemente de dependență, prezente în forme diferite și la jocurile de sloturi.

Studii curente dezbat aspectele etice ale expunerii faptelor matematice din spatele jocurilor de noroc și dacă expunerea trebuie limitată la configurația parametrică, rezultatele numerice de bază (precum probabilitățile evenimentelor câștigătoare de bază și speranța matematică), sau la rezultate matematice mai avansate și interpretările acestora.

Matematica are rolul său în această problemă și contribuția sa principală nu este doar aceea de a fi un alt argument împotriva raționalității secretizării fișelor PAR, ci una practică: matematica oferă jucătorilor și profesioniștilor unele metode statistice de recuperare a acestor date lipsă. Având aceste date împreună cu formulele matematice, oricine poate genera fișa PAR a oricărui aparat de sloturi.

Configurația unei role se referă la distribuția de simboluri pe stopurile acelei role. Notând cu t numărul de stopuri și cu p numărul de simboluri distincte aflate pe rolă, iar cu numărul de simboluri de pe rolă (), atunci vectorul se numește distribuția simbolurilor pe rolă. Fiecare rolă are propria sa distribuție de simboluri. Putem presupune că avem același număr de simboluri distincte pe fiecare rolă (p) printr-o convenție: dacă un simbol nu apare pe o rolă, putem considera distribuția sa pe acea rolă ca fiind zero. Un blank este considerat ca fiind un simbol distinct în cadrul modelului matematic.

Aproximarea brută. Această metodă se bazează pe rezultatul bine-cunoscut din teoria probabilităților, numit teorema lui Bernoulli, care afirmă că, într-un șir de experimente independente efectuate în condiții identice, frecvența relativă de apariție a unui eveniment este convergentă către probabilitatea acelui eveniment.

Aplicat la jocurile de sloturi, acest principiu spune că dacă N este numărul de rotiri ale unei role cu t stopuri, la care observăm ca rezultat un anumit simbol S, plasat pe c stopuri ale rolei, iar n(N) este numărul de apariții ale S după cele N rotiri, atunci șirul este convergent către probabilitatea de apariție a lui S, și anume P(S) = c/t.

Raportul n/N este frecvența relativă a apariției lui S. Rezultă că, pentru valori mari ale lui N, frecvența relativă a apariției lui S aproximează probabilitatea de apariție a lui S. Cu cât N este mai mare, cu atât această aproximare este mai exactă. Evident, numărul de rotiri N trebuie să fie suficient de mare pentru obținerea unor aproximări bune ale rapoartelor , iar aceasta este principala problemă a acestei metode. Cum teoria nu ne furnizează instrumente de alegere a lui N pentru o marjă de eroare dată, tot ceea ce avem este principiul “cu cât N este mai mare, cu atât este mai bine.”

După cum se poate observa, această metodă de aproximare bazată pe observarea statistică este supusă erorilor provenite din idealizări și ipoteze diverse, iar marjele de eroare nu sunt nici măcar cuantificabile. Observați că metoda descrisă ne oferă aproximări ale rapoartelor (valori etichetate de obicei în fișele PAR prin “frecvența apariției/hit frequency”) și nu ale parametrilor individuali ai configurației (c și t). Cu toate acestea, cunoașterea probabilităților de bază este suficientă pentru efectuarea oricărui calcul probabilistic pentru un joc de sloturi. O aproximare mai exactă a rapoartelor și chiar a numerelor și t individual este totuși posibilă prin observare statistică, folosind o metodă prin care putem rafina estimările brute obținute prin metoda descrisă anterior. O astfel de metodă este descrisă pe scurt în cele ce urmează.

Metoda de potrivire a numitorului. Notăm cu numărul de apariții ale simbolurilor până la respectiv, după N rotiri ale unei role. Există o corelație slabă între valorile înregistrate pentru numere mari de rotiri N. În baza acestei corelații, putem rafina estimarea rapoartelor obținute prin metoda anterioară și putem găsi, de asemenea, estimări pentru și t, prin recunoașterea unui pattern numeric peste unele secvențe de fracții obținute printr-o selecție criterială a raporturilor dintre valorile posibile pentru c și t.

Metoda de potrivire a numitorului se bazează pe analiza numerică a fracțiilor și pe un algoritm în cinci pași, descris pe scurt în acest articol și explicat pe larg în ultima mea carte, The Mathematics of Slots: Configurations, Combinations, Probabilities.

Scriem fiecare fracție ca pe un lanț de fracții egale, având numărători de la 1 în sus și numitori nu neapărat întregi, pentru fiecare i de la 1 la p. Dintre aceste p lanțuri de fracții egale, alegem pe cel cu lungimea minimă (fie m lungimea minimă). Apoi, peste cele p lanțuri de fracții egale, extragem m secvențe de fracții (câte o fracție din fiecare lanț de egalitate) având numitorii cei mai apropiați de numitorii lanțului minim de egalitate respectiv. Din cele m secvențe de fracții obținute, alegem o secvență de p fracții prin aplicarea succesivă a următoarelor criterii de filtrare: numitori cât mai aproapiați ca valoare unul de altul, cel mai mare număr de instanțe ale aceluiași numitor, numitorul cu cele mai multe instanțe este număr întreg. La ultimul pas, ajustăm numitorii secvenței finale de fracții, printr-un algoritm de aproximare prin care se obține un singur numitor pentru toate fracțiile, anume suma numărătorilor, după cum este și relația dintre t și numerele.

Această metodă ne oferă cel mai probabil număr t de stopuri și cea mai probabilă distribuție de simboluri pe o rolă, într-un anumit câmp de probabilitate; marja de eroare a acestei aproximări este cuantificabilă în termeni de probabilitate.

În ceea ce privește aplicarea practică a metodelor prin observare statistică, aceasta este în mod evident o sarcină dificilă, deoarece avem de urmărit și înregistrat rotiri de ordinul miilor.

Orice informație dobândită despre t în afara metodelor de estimare statistice prezentate este utilă în ceea ce privește exactitatea aproximării, deoarece poate oferi un indiciu cu privire la cât de mare ar trebui să alegem N pentru a evita obținerea de rezultate irelevante (de exemplu, dacă t = 100, putem intui că alegerea nu este suficient de mare pentru obținerea de rezultate relevante). Pe lângă metodele bazate pe observarea statistică, există și o metodă de estimare a lui t prin măsurători fizice, aplicabilă unor anumite tipuri de aparate de sloturi. Această metodă exploatează informațiile furnizate de imaginea aparentă a rolei pe ecran. După cum știm, doar o mică parte din rolă (fizică sau virtuală) este vizibilă pe ecran și această parte poate fi văzută ca fiind formată din unul sau mai multe stopuri adiacente (de obicei de la 3 la 5). Deci putem vizualiza de la 1 până la 5 stopuri consecutive ale rolei simultan. Dacă imaginea acestei părți a rolei este tridimensională (lucru posibil atât pentru rolele fizice cât și pentru cele virtuale), prin măsurarea unor parametri ai acestei imagini, putem deduce o estimare a numărului de stopuri ale acelei role (t).

În mare, lungimea aparentă a stopurilor vizibile ne dă informații complete privind curbura rolei, care duce apoi la o estimare a numărului întreg de stopuri, deoarece numărul de stopuri pe lungimea circulară a rolei vizibile este proporțional cu numărul total de stopuri pe lungimea circulară a întregii role. Această metodă se poate aplica numai la acele role care prezintă cel puțin două stopuri consecutive în vizualizare tridimensională pe ecran. Metoda este inaplicabilă rolelor virtuale care prezintă mai multe stopuri consecutive în imagine plată. Ca și în cazul metodei anterioare de observare statistică, aplicarea practică a metodei prin măsurători fizice ridică probleme.

Pot apărea probleme tehnice privind dobândirea poziției corecte pentru măsurare sau la plasarea instrumentului de măsurare pe suprafața aparatului. O alternativă pentru această metodă poate fi aceea în care observatorul face fotografii și apoi efectuează măsurătorile pe fotografiile obținute. Desigur, există posibilitatea ca operatorul aparatului să nu permită măsurarea directă și/sau fotografierea aparatului.

Momentan se află în proiect crearea unei unități matematice care să folosească metoda potrivirii numitorului la înregistrări statistice, pentru aflarea configurațiilor parametrice ale aparatelor de sloturi existente pentru care nu există expuse aceste date, și care să genereze rezultatele probabilistice pentru acestea.

În ceea ce privește gamblingul problematic, studiile empirice efectuate au constatat că aflarea șanselor nu schimbă semnificativ comportamentul jucătorilor în sens de scădere, dar cu toate acestea o concluzie clară nu a fost încă trasă. Cu privire la jocul de sloturi în sine, șansele și alte rezultate matematice contează ca informație într-un sens strategic trivial: E ca și cum cineva vă propune să pariați că puteți sări de la o anumită înălțime și ateriza în picioare; desigur, este un avantaj să știți în avans înălțimea de la care urmează să săriți sau să o măsurați înainte de a accepta pariul, deoarece pentru o anumită măsurătoare puteți refuza pariul sau puteți propune un altul, iar acest lucru înseamnă decizie.

3.4. Utilizarea RNG-urilor în jocurile de tip ”slot machine”

De regulă, jocurile de tip slot machine au în spate un algoritm de distribuție al rolelor bine gândit. Marja de payment a sloturilor este cuprinsă între 92 și 96%. Adică jucătorul investește 100 lei și poate primi înapoi pană la 96 lei. Acești algoritmi sunt creați astfel încât jucătorii să primească acest procent de payment după un anumit număr de spin-uri. Pot exista cazuri în care, la un anumit aparat un jucător să piardă foarte mult, iar următorul jucător care va juca la același aparat să câștige foarte mult. Totusi, volatilitatea unui astfel de algoritm trebuie sa fie mare pentru a fi cât mai greu de descifrat.

Există o convingere comună cu privire la cotele unei mașini de slot în sensul că au legătură cu numărul fiecarui fel de simbol pe fiecare rolă, dar la mașinile de slot moderne acest lucru nu mai este valabil. Mașinile de slot moderne sunt computerizate, astfel incăt cotele arată exact așa cum sunt programate sa fie. La mașinile de slot moderne, sulurile și maneta sunt prezente pentru motive istorice și pentru divertisment numai. Pozițiile în care se vor opri rolele sunt alese de un Ramdom Number Generator (RNG), un generator de numere aleatoare care este conținut de software-ul mașinii de slot.

Ramdom Number Generator (RNG) este creierul unei mașini de slot. În timp ce majoritatea jucătorilor știu că există un chip al computerului care alege numerele, ei nu înțeleg pe deplin cum funcționează acesta și acest lucru poate duce la unele din multele mituri și la concepții greșite despre o mașină de slot. Una dintre cele mai comune mituri este că o mașină de slot are un ciclu de apariții al simbolurilor care l-ar putea ajuta pe jucător să-și dea seama, atunci când este cazul să iasă un câștig.

În interiorul mașinii de slot este un microprocesor similar cu cel al unui calculator obișnuit. În loc să ruleze Word sau Excel, rulează un program special, de RNG, care generează numere care să corespundă cu simbolurile de pe rola mașinii de slot. S-ar putea spune că RNG este în continuă mișcare. Atâta timp cât mașina de slot este alimentată cu curent selectează constant numere aleatoare la fiecare milisecundă. RNG-ul generează o valoare între 0 și 4 miliarde (număr aproximativ), care este apoi tradusă într-un set specific de numere pentru a corespunde cu simbolurile de pe role. Rezultatul fiecărei rotiri este determinat de numărul selectat de RNG. Acest număr este ales atunci cand apăsați butonul pentru rotire sau introduceti o monedă. RNG generează constant numere aleatoare, la o rată de sute sau poate mii pe secundă. În momentul în care butonul Spin este apăsat, cel mai recent număr aleator este utilizat pentru a determina rezultatul. Aceasta înseamnă că rezultatul variază în funcție de momentul exact când jocul este jucat. O fracțiune de secundă mai devreme sau mai târziu, iar rezultatul va fi diferit.

Ramdom Number Generator (RNG) utilizează o formulă cunoscută ca un algoritm care reprezintă o serie de instrucțiuni pentru a genera numerele. Domeniul de aplicare a prezentului algoritm este dincolo de cele mai multe cunoștințe matematice ale noastre, dar care pot fi verificate pentru exactitate. Acest lucru este făcut de laboratoare de testare pentru a se asigura că programul funcționează așa cum ar trebui, astfel că jucătorul să nu fie înșelat.

Vechile mașini de slot mecanice au avut un anumit număr de role, care conțineau un anumit număr de simboluri, fiecare la fel de probabil să apară pe linia de plată după fiecare rotire. În anii 80’, cu toate acestea, producătorii de mașini de slot au încorporat o tehnologie electronică în produsele lor și le-a programat o greutate specifică fiecarui simbol. Astfel, probabilitățile de apariție a simbolurilor pe linia de plată au devenit disproporționate față de frecvența lor actuală de apariție pe rolele fizice. În anul 1984, Inge Telnaes a primit un brevet pentru un dispozitiv intitulat, 'Electronic Gaming Device Utilizing a Random Number Generator for Selecting the Reel Stop Positions'. International Gaming Tehnologie IGT a cumpărat brevetul lui Telnaes și acum toți producătorii mașinilor de slot, care utilizau ceea ce a ajuns să fie cunoscut sub numele de cartografierea Talneas sau cartografierea rolelor trebuiau să se licențieze la IGT. În 1984 în materie de brevete acordate pe această tehnologie (United States Patent No. 4 448 419) prevedea: ”Este important să se facă o mașină care să fie concepută pentru a prezenta șanse mai mari de profit decât are de fapt în cadrul limitelor legale pe care jocurile de noroc trebuie să le respecte”.

Un alt avantaj al unei role virtuale are de a face cu numărul de opriri. Mașina de slot originală a avut trei role fizice cu 10 simboluri pe fiecare rolă. Deși numărul de opriri a crescut de-a lungul anilor la circa 22, dispozitivul mecanic limita încă numărul de rezultatele posibile. O rolă virtuală bobină avea până la 256 opriri virtuale pentru o rolă. Rola fizică are doar 103 = 1000 de combinații posibile. Producătorul este limitat din punct de vedere al sumei maxime de plată pe care o poate oferi, deoarece s-ar putea întâmpla la fiecare 1000 rotiri. În cazul în care jackpotul plătit are cota 100:1 atunci mașina va trebui să folosească deja 10% din rezultatul acestui câștig. Mașina originală păstrează 25% ca limită a casei. Rola virtuală cu 256 opriri virtuale are 2563 = 16.777.216 poziții finale. Producătorul ar putea alege să ofere un milion câstigătorului, el știind că acest caștig se va întâmpla doar o dată la 16.7 milioane de rotiri.

În cazul jocurilor de tip slot machine pentru dispozitive mobile, nu se utilizează astfel de RNG-uri deoarece userul nu joacă pe bani reali. Rata de câștig este mult mai mică față de jocurile de pe mașinile slot astfel ca userul să cumpere credite sau alte pachete pentru a juca mai mult.

4. Implementarea jocului Fruits Slot

În acest capitol voi prezenta implementarea jocului Fruits Slot în Unity, atât partea grafică cât și partea de scripturi (codul sursă), dar și partea de testare a jocului.

4.1. Implementarea grafică

Partea grafică a acestui joc presupune o serie de texturi în format png, ce conțin mai multe sprite-uri, în funcție de dimensiunile sprite-urilor. Toate texturile au ca dimensiune puteri ale lui 2 (1024×1024, 2048×2048), acest lucru fiind o constrângere a faptului că am folosit versiune gratuită de Unity.

Unity are o modalitate specială de a trata texturile și de a identifica sprite-urile din texturi folosind propriul Sprite Editor. Pentru a prelucra o textură, selectăm textura din proiect, iar colțul top-right al editorului, în Inspector, vor apărea proprietățile texturii respective (Figura 16).

Figura 16. Proprietățile unei texturi

Proprietățile unei texturi sunt următoarele:

Texture Type – tipul texturii, în cazul nostru este o textură 2D;

Sprite Mode – modul cum se prelucrează textura (single sau multiple) – în cazul nostru este Mutiple pentru că are mai multe sprite-uri;

Packing Tag – numele tag-ului cu care va fi arhivată textura (nu se aplică în cazul nostru);

Pixels Per Unit – este un factor de scalare al pixelilor în funcție de unitatea scenei, 75 în cazul nostru;

Generate Mip Maps – folosită pentru a genera texturi mai mici, nu se aplică;

Filter Mode – modul de filtrare al texturii, Bilinear;

Max Size – dimensiunea maximă a texturii, 2048;

Format – formatul de compresie al texturii, Compressed (unele texturi vor folos i formatul Truecolor – nu vor fi compresate deloc);

Tot aici se găsește și butonul Sprite Editor. Prin apăsarea acestui buton se va deschide o nouă fereastră în care se pot prelucra texturile (Figura 17).

Figura 17. Sprite Editor-ul din Unity

Se poate observa în Figura 17 modul în care a fost deschisă textura și cum se prelucrează. În coțul top-left apare un submeniu avînd cîteva opțiuni:

Type – modul cum va fi împărțită textura (Automatic sau Grid), în cazul acestei texturi vas fi Grid pentru că toate sprite-urile trebuie s aiba o dimesiune egală, iar textura nu este plină.

Pivot – se folosește pentru a specifica unde se poziționează pivotul, în cazul nostru este pe centru;

Method – metoda prin care se împart aceste sprite-uri: Delete Existing, Smart sau Safe.

Slice – în urma apăsării acestui buton textura va fi împărțită în sprite-uri. În colțul bottom-right al ferestrei apare o altă fereastră în care se introduc dimensiunile sprite-urilor.

Textura prezentă în Figura 17 este o textură cu sprite-uri ale simbolurilor. Aceste simboluri au mai multe sprite-uri ce se folosesc în momentul în care userul a caștigat o linie (sau mai multe linii). La câștigarea fiecarei linii, în jurul fiecărui simbol ce face parte din linia câștigătoare, apare un chenar pentru a arăta exact care este linia câștigătoare, dar și o animație creată din sprite-ri. Practic folosind aceste sprite-uri se simulează vizual o rotire/mișcare a simbolului. Animația este creată folosind editorul de animații din Unity. O animație de acest tip este formată din 6 frame-uri (6 sprite-uri).

Pe lângă animația de rotire/mișcare a simbolului, există o altă animație crată tot din sprite-uri, cu particule albe. O astfel de animație putea fi făcută dinrect din Unity, folosind un emițător de particule.

Mai există două animații construite pe același principiu, una pentru zona de swipe, iar cealaltă pentru butonul de spin.

Background-ul ecranului principal din joc are o dimensiune de 1920×1520 pixeli pentru a acoperi cât mai multe rezoluții și formate (16/9, 4/3, etc.). Pentru a putea implementa rotirea rolelor, background-ul a fost creat inițial ca o imagine, ca apoi sa fie decupat mijlucul imaginii, exact zona prin care trec simbolurile de pe role când se rotesc. Astfel, rolele de fapt se învârt printre background-ul exterior si cel interior (din mijloc), toate aceste lucruri putând fi făcute cu ajutorul layer-elor din Unity Editor. Practic zona de joc este ca o fereastră, iar dacă te uiți prin ea vezi doar simbolurile care cad.

Pentru zona de mijloc, există 3 imagini diferite, acest lucru ajutându-l pe user să distingă mai ușor în ce mod de joc este în momentul respectiv – free spins, minigame sau jocul normal.

În lateralele zonei de mijloc (stanga, respectiv dreapta) apar 10 căsuțe fiecare având o anumită cifră (de culori diferite) în interior. Aceste căsuțe îi arată userului de unde pornește fiecare linie câștigătoare și unde se oprește (am specificat mai sus că sunt de fapt niște trasee, nu neapărat linii drepte).

Pe partea vizuală mai există anumite animații, care sunt statice cum ar fi cea pentru bara de energie. Acolo sunt 4 sprite-uri folosite: un sprite cu bara ede energie goală și 3 sprite-uri cu bara de energie umplută pentru fiecare nivel (1, 2 sau 3).

4.2. Implementarea funcționalității jocului

Am descris în subcapitolul precedent cum am implementat partea grafică. În acest subcapitol voi prezenta implementarea funcționalității jocului.

Pentru a realiza funcționalitatea jocului am scris 13 scripturi: Button.cs, FlipScript.cs, GameEventsArgs.cs, GameIcon.cs, GameManager.cs, GameModeManager.cs, Glow.cs, Reel.cs, SaveManager.cs, TextLayer.cs, TutorialScript.cs și WinningLine.cs. Voi detalia în continuare fiecare script în parte.

Scriptul Button.cs este scriptul ce crează obiecte de tip buton și conține următoarele metode:

Awake() – această metodă este apelată când este încărcată instanța către script. De obicei, în această metodă se face inițializarea de variabile sau stările jocului înainte de a porni jocul. În cazul nostru, se face stabilește ordinea layer-elor pentru fiecare obiect care are atașat acest script;

SetInactive() – dezactivează animația butonului de spin;

SetActive() – activează animația butonului de spin;

Click() – se tratează click-ul pe butoane, în funcție de fiecare buton și se apelează eventul de click pentru fiecare tip de event în parte;

LongPress() – aceeași implementare ca și metoda Click(0, doar că se tratează apăsarea lungă a butonului.

Acest script este atașat tuturor butoanelor. Fiind prea mare, l-am introdus în Anexa 1.

FlipScript.cs este un script implementat pentru a putea face flip iindependent pe anuite texturi. Conține o singură metodă, Flip(), în care se face flip pe axa X.

using UnityEngine;

using System.Collections;

public class FlipScript : MonoBehaviour {

bool facingRight = true;

public void Flip()

{

if (facingRight)

{

transform.localScale = new Vector2 (-1, 1);

}

else

{

transform.localScale = new Vector2 (1, 1);

}

facingRight = !facingRight;

}

}

GameEventsArgs.cs este implementat pentru a ști exact câte tipuri de event-uri avem. Scriptul are un enum cu tipurile de event și un constructor. Nu este atașat vreunui obiect pentru că se folosește doar în cod.

using UnityEngine;

using System.Collections;

using System;

public class GameEventsArgs : System.EventArgs {

public enum Events {NONE,

INCREMENT_LINE,

DECREMENT_LINE,

INCREMENT_BET,

DECREMENT_BET,

CLOSE_BET_POPUP,

SPIN,

AUTO_SPIN,

FRUITS_SLOT,

LEFT_SCROLL,

RIGHT_SCROLL};

private Events mEvent;

GameEventsArgs(Events newEvent)

{

mEvent = newEvent;

}

}

GameIcon.cs este scriptul ce crează obiecte de tip GameIcon și doar două metode: EndSpinAnim() – metodă ceapelează event-ul de terminare a animației și SetTargetPos(Vector2 pos) – metodă ce setează o poziție pentru un simbol.

using UnityEngine;

using System.Collections;

using System;

public delegate void EndAnimEventHandler(GameObject sender, EventArgs e);

public class GameIcon : MonoBehaviour {

public event EndAnimEventHandler EndAnimEvent;

public Vector2 targetPos;

private void EndSpinAnim()

{

if (EndAnimEvent != null)

EndAnimEvent (gameObject, EventArgs.Empty);

}

public void SetTargetPos(Vector2 pos)

{

targetPos = pos;

}

}

GameModeManager.cs este folosit pentru a face tranziții între scene și conține 4 metode:

Start() – setează orientarea ecranului pe landscape și încarcă obiectul pentru butonul din ecranul de selecție;

Update() – se tratează event-ul pentru tasta Back a telefonului;

processInputEvent() – procesează event-ul de tocuh pe butonul de selecție al jocului;

ProcessGameEvents(GameObject sender, GameEventsArgs.Events gameEvent) – în această metodă se încarcă instanța către scriptul ce se ocupă cu managementul salvărilor din joc și se încarcă scena următoare.

using UnityEngine;

using System.Collections;

public class GameModeManager : MonoBehaviour {

private Button mSelectedButton;

public GameObject lazyButtonObject;

// Use this for initialization

void Start () {

Screen.orientation = ScreenOrientation.Landscape;

lazyButtonObject.GetComponent<Button> ().ClickEvent += new ClickEventHandler(ProcessGameEvents);

}

// Update is called once per frame

void Update () {

if (Input.GetKeyDown(KeyCode.Escape))

{

Application.Quit();

}

processInputEvent ();

}

void processInputEvent(){

if (Input.GetMouseButtonDown(0))

{

Vector3pos = Camera.main.ScreenToWorldPoint (Input.mousePosition);

RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero);

if (hit && hit.collider != null) {

mSelectedButton = hit.transform.gameObject.GetComponent<Button>();

}

else

{

mSelectedButton = null;

}

}

else if (Input.GetMouseButtonUp(0))

{

Vector3 pos = Camera.main.ScreenToWorldPoint (Input.mousePosition);

RaycastHit2D hit = Physics2D.Raycast(pos, Vector2.zero);

if (hit && hit.collider != null) {

if (mSelectedButton == hit.transform.gameObject.GetComponent<Button>())

{

if(mSelectedButton != null)

{

mSelectedButton.Click();

}

}

}

}

}

private void ProcessGameEvents(GameObject sender, GameEventsArgs.Events gameEvent)

{

if(gameEvent == GameEventsArgs.Events.FRUITS_SLOT)

{

SaveManager.instance.mSaveData.selectedMode = GameManager.Mode. FRUITS;

Application.LoadLevel ("MainGame");

}

}

}

Glow.cs l-am scris pentru a manipula animația de pe zona de swipe și contine o singură metodă, StartAnim(), ce tratează event-ul de start al animației.

using UnityEngine;

using System.Collections;

public delegate void StartAnimEventHandler(GameObject sender, GameEventsArgs.Events e);

public class Glow : MonoBehaviour

{

public event StartAnimEventHandler StartAnimEvent;

public void StartAnim()

{

StartAnimEvent (gameObject, GameEventsArgs.Events.NONE);

}

}

Reels.cs – este scriptul în care este implementată o rolă (obiecte de tip rolă) și conține următoarele metode:

Reel(GameIcon[] reels, float cellWidth, float cellHeight, float spinSpeed, float startX, float startY, int visibleCells) – este constructorul clasei de tip Reel

Update() – este metoda care se ocupă cum update-ul ep fiecare rolă, în funcție de starea în care se află rola;

Spin() – setează starea rolei pe starea de SPINNING;

SetMovingIcons(int[] indexes) – setează simbolurile pe starea de SWITCH (starea în care se află simbolurile când userul le schimbă poziția pe ecran);

SetMovingReel(int index) – setează starea rolelor pe REEL_SWITCH (starea în care se află simbolurile când userul schimbă două role alăturate);

SetState(State reelState) – setează starea rolei.

SaveManager.cs este un script implementat pentru lucrul cu rms-ul (record management system). Conține urmatoarele metode:

Awake() – inițializează instanța pentru salvări. În această metodă se apelează metoda Load();

Save() – metodă se salvează în fișier;

Load() – metodă ce încarcă salvările existente.

using UnityEngine;

using System.Collections;

using System;

using System.Runtime.Serialization.Formatters.Binary;

using System.IO;

public class SaveManager : MonoBehaviour {

public static SaveManager instance;

[HideInInspector]

public SaveData mSaveData;

private static readonly string SAVE_FILE = "saveData.bin";

private static readonly float START_CREDITS = 1000f;

void Awake()

{

if (instance == null)

{

DontDestroyOnLoad(gameObject);

instance = this;

Load();

}

else if (instance != this)

{

Destroy(gameObject);

}

}

public void Save()

{

BinaryFormatter bf = new BinaryFormatter ();

FileStream fs = File.Create (Application.persistentDataPath + "/" + SAVE_FILE);

bf.Serialize (fs,mSaveData);

fs.Close ();

}

public void Load()

{

if (File.Exists(Application.persistentDataPath + "/" + SAVE_FILE))

{

BinaryFormatter bf = new BinaryFormatter ();

FileStream fs = File.Open (Application.persistentDataPath + "/" + SAVE_FILE, FileMode.Open);

mSaveData = (SaveData)bf.Deserialize (fs);

fs.Close ();

}

else

{

mSaveData = new SaveData();

mSaveData.credits = START_CREDITS;

}

}

}

[Serializable]

public class SaveData

{

public float credits;

public int keys;

public int energy;

[NonSerialized]

public GameManager.Mode selectedMode;

}

TextLayer.cs este un script creat pentru a lucra mai ușor cu layer-ele de texte deoarece sunt situații în care avem mai multe obiecte suprapuse care au atașate texte și trebuie să stabilim o ordine în care sunt tratate click-urile pe obiecte. Scriptul are o singură metodă, Awake() în care se face managementul pe layere.

using UnityEngine;

using System.Collections;

public class TextLayer : MonoBehaviour {

private SpriteRenderer mSpriteRenderer;

void Awake ()

{

mSpriteRenderer = gameObject.GetComponent<SpriteRenderer> ();

GameObject child;

for(int i = 0; i < transform.childCount; i++)

{

child = transform.GetChild(i).gameObject;

child.renderer.sortingLayerName = gameObject.renderer.sortingLayerName;

child.renderer.sortingOrder = gameObject.renderer.sortingOrder+1;

}

}

}

TutorialScript.cs este scriptul cu ajutorul căruia se crează obiecte pentru partea de tutorial a jocului. Acest script conține următoarele metode:

SetPosTargetPos(float startX, float startY, float targetPosX, float targetPosY, string trigger, MovementType move) – setează o poziție la care trebuie sa ajungă un obiect, având ca parametri pozișia de start și de final, trigger-ul (event-ul de click) și tipul mișcarii care se face pentru a ajunge în poziția finală;

Update() – metoda în care se face mișcarea efectivă a obiectului;

GoToTargetPos() – metodă în care se specifică exact mutarea obiectului.

using UnityEngine;

using System.Collections;

public class TutorialScript : MonoBehaviour {

private Vector2 mInitialPos;

private Vector2 mTargetPos;

private readonly float SPEED = 6f;

private float mSpeedX;

private float mSpeedY;

private readonly float DELAY_TIME = 0.6f;

private float mCounter;

private Animator mAnimator;

private string mAnimTrigger;

private MovementType mMovementType;

public enum MovementType

{

MOVE,

TELEPORT

};

public void SetPosTargetPos(float startX, float startY, float targetPosX, float targetPosY, string trigger, MovementType move)

{

mInitialPos = new Vector2(startX, startY);

transform.position = mInitialPos;

mTargetPos = new Vector2(targetPosX, targetPosY);

mCounter = DELAY_TIME;

mAnimator = gameObject.GetComponent<Animator>();

mAnimTrigger = trigger;

mMovementType = move;

float distanceX = Mathf.Abs(targetPosX – startX);

float distanceY = Mathf.Abs(targetPosY – startY);

if(distanceX > distanceY)

{

mSpeedY = SPEED;

mSpeedX = SPEED * distanceX / distanceY;

}

else

{

mSpeedX = SPEED;

if (distanceX == 0)

{

mSpeedY = SPEED;

}

else

{

mSpeedY = SPEED * distanceY / distanceX;

}

}

Debug.Log("mSpeedX = " + mSpeedX);

Debug.Log("mSpeedY = " + mSpeedY);

}

// Update is called once per frame

void Update ()

{

if (mMovementType == MovementType.MOVE)

{

mCounter -= Time.deltaTime;

if(mCounter <= 0)

{

float x = Mathf.MoveTowards(transform.position.x, mTargetPos.x, mSpeedX * Time.deltaTime);

float y = Mathf.MoveTowards(transform.position.y, mTargetPos.y, mSpeedY * Time.deltaTime);

transform.position = new Vector2 (x, y);

if(transform.position.x == mTargetPos.x && transform.position.y == mTargetPos.y)

{

transform.position = mInitialPos;

mCounter = DELAY_TIME;

if (mAnimTrigger != null)

{

mAnimator.SetTrigger(mAnimTrigger);

}

}

}

}

}

public void GoToTargetPos()

{

if (mMovementType == MovementType.TELEPORT)

{

if (transform.position.x == mInitialPos.x && transform.position.y == mInitialPos.y)

{

transform.position = new Vector2 (mTargetPos.x, mTargetPos.y);

}

else

{

transform.position = new Vector2 (mInitialPos.x, mInitialPos.y);

}

}

}

}

WinningLine.cs este un script implementat pentru crearea obiectelor de tip WinningLine, folosite în construirea și afișarea liniilor caștigătoare din joc, având metodele:

Init() – metodă folosită pentru inițializarea obiectelor ce formează linii cîștigătoare;

ShowLine() – arată linia câștigătoare;

HideLine() – ascunde linia câștigătoare;

ClearLine() – șterge liniile câștigătoare salvate;

SetWinCount(int winCount) – setează câștigul pe linie;

AddIcon(GameIcon icon) – adaugă simboluri în linia câștigătoare.

Codul scriptului se regăsește în anexă.

Am lăsat la urmă scriptul GameManager pentru că este scriptul cel mai stufos și cel mai important al jocului. Practic, în acest script se crează toate obiectele necesare jocului, acest script făcând totodată și managementul jocului.

Datorită dimensiunii mari a scriptului, o sa descriu doar cele mai importante metode din acest script.

Start() – face majoritatea inițializărilor obiectelor din joc și a variabilelor. De asemenea, în această metodă se setează anumite obiecte ca fiind vizibile sau nu;

UpdateMeshText (TextMesh text, string value) – este o metodă care face update-ul vizual al textelor;

processInputEvent() – procesează toate event-urile de touch pe simboluri ale jocului: drag, swipe. click;

Spin(System.Object sender, GameEventsArgs.Events e) – în această metodă se tratează funcționalitatea legată de butonul Spin, idiferent de starea în care se află jocul;

InitReel(int index) – metodă ce face inițializarea unei role din distribuția inițială cu 32 de simboluri;

public SwipeDirection Swipe(Vector2 mFirstPressPos, Vector2 mSecondPressPos) – calculează direcția în care userul a făcut swipe (există 8 direcții de swipe);

checkLines() – calculează liniile în funcție de payout-ul din PayTable;

endLineResult(int energy) – această metodă calculează numărul de credite câștigat după de userul a facut o mutare specială, primind ca parametru valoarea energiei consumate corespunzătoare mișcării efectuate.

Scriptul conține și alte metode ce implementează afișarea tuturor popup-urilor și închiderea lor, metode care fac update pe bara de energie, background-ul din mijloc.

De asemena, sunt metode implementate pentru tratarea oricărui event, pentru partea de tutorial. În tutorial, de exemplu, sunt implementate metode de calcul astfel încât userul să primească garantat linii câștigătoare.

Dimensiunea scriptului este mult prea mare deoarece am concentrat toate metodele legate de game-play și de celelalte funcționalități în acest script. Teoretic ar fi trebuit să fac mai multe scripturi, tratând într-un script separat event-urile de touch, în altul verificarea liniilor câștigătoare ș.a.m.d.

4.3. Crearea și testarea buidurilor pe platforma Android

Pentru a face un build (indiferent că e Android, Windows Phone 8 sau iOS), Unity pune la dispoziția utilizatorilor o interfață ușor de utilizat. Am ales să fac acest joc pe platforma Android deoarece este gratuit să faci build-uri., spre deosebire de alte platforme unde ai nevoie de cont de developer (iOS, Windows Phone 8, etc.).

Accesând din Unity File->Build Settings, se va deschide o fereastră pentru creare de build-uri (Figura 18).

Figura 18. Fereastra pentru crearea build-urilor

Se poate observa în partea de sus a ferestrei că am selectat scenele pe care doresc sa le includ în această versiune, exact în ordinea în care vor apărea în joc. În partea de jos, îb stânga este putem vedem lista cu platformele pe care le suportă Unity. Am selectat din lista respectivă platforma Android, iar din dreapta am selectat modul de compresie al texturilor din joc.

Dacă apăsăm butonul Player Settings, va apărea o altă fereastră în care putem face setările specifice platformei alease. În cazul acestui joc am completat doar câteva setări cum ar fi numele companiei, numele jocului, câteva setări specifice de Android, Graphics Level (ce versiune de Open GL sa folosească), Device Filter (tipuri de procesoare pe care sa le suporte) și alte setări prea puțin importante.

Observăm că în Figura 18, în partea de jos, apar două butoane: Build și Build And Run. Dacă folosim butonul Build, Unity va crea un build local, pe când folsind celalalt buton, Unity va crea un build și îl va instala pe telefon, în cazul în care avem un telefon conectat la computer.

Odată instalat buildul pe telefon, am început testarea efectivă. Au fost foarte multe build-uri pe care le-am făcut până am ajuns cu jocul în stadiul actual, deși nu e un build fară buguri.

Concluzii

Dezvoltarea jocurilor, în general, a condus la apariția unui număr impresionant de aplicații și jocuri pentru dispozitivele mobile. Aceste jocuri abordează o topică variată. În domeniul jocurilor de noroc pentru dispozitive mobile există de asemnenea, varietate, corelată cu o cerere crescută. Acesta este un lucru oarecum neașteptat ținând seama că în jocurile de pe dispozitivele mobile nu se joacă pe bani reali. Ideea de a implementa un joc de tip slot machine pentru dispozitive mobile a venit în urma observației că acest tip de jocuri nu a suferit schimbări semnificative din punct de vedere al funcționalităților.

Crearea unui joc este o activitate complexă și nu este suficient să știi un limbaj de programare ca să poți crea un joc. Lucrând la acest joc, am fost nevoit să gândesc jocul din toate punctele de vedere (design, programare etc). Reflectând la jocul pe care am ales să-l creez (Fruits Slot) și la platforma de dezvoltare pe care am ales-o (Unity cu C# pe partea de scripting), pot să spun că am făcut cea mai bună alegere.

Platforma Unity este ușor de folosit pentru cei ce nu au o experiență foarte mare în dezvoltarea de jocuri și poți alege și OS-ul pe care vrei sa ruleze jocul. De asemenea, un alt avantaj îl reprezintă varietatea limbajelor de programare care se pot utiliza în Unity: Boo, UnityScript și C#. Limbajul de programare C# a devenit un limbaj din ce în ce mai folosit pentru dezvoltare de software, utilizat pe partea de web, mobile și desktop.

Deși, la prima vedere, jocul pare a fi complet, în structura jocului ar trebui adăugate următoarele:

un loading înainte de a intra în joc deoarece durează mult încărcarea jocului;

un meniu al jocului;

secțiunea Help, în care să fie detaliate instrucțiunile de joc;

opțiunea Settings în care userul să aibă posibilitatea de a face anumite setări (de exemplu: opțiune de sound on/off);

modul de comunicare între jucători – pe partea de social (Facebook, Google Plus).

În dezvoltarea acestui joc am îndeplinit următoarele obiective:

învațarea unui nou limbaj de programare: C#;

familiarizarea cu platforma Unity;

asimilarea unor cunoștințe legate de designul jocurilor.

Bibliografie

I. Cărți, articole și studii

Blackman, Sue, Beginning 3D Game Development with Unity 4, Second Edition, Apress, 2013

Dăscălescu, Ana Cristina, Programare Orientată pe obiecte C++ – suport curs pentru forma de învățământ ID, 2013

Dăscălescu, Ana Cristina, Programarea în Java – suport curs pentru forma de învățământ ID, 2013

Harris, Tom, "How Slot Machines Work", HowStuffWorks, 2010

Hejlsberg Anders, Torgersen Mads, Wiltamuth Scott, Golde Peter, The C# Programming Language, Fourth Edition, Addison-Wesley Professional, 2010

Henson Creighton, Ryan, Unity 4.x Game Development by Example, PACKT Publishing, 2013

Kelly, Jack, “Slots: Perfecting a machine to take away your money”, American Heritage of Invention and Technology-Online, 2010

Murphy, Mark, The Busy Coder's Guide to Android Development, CommonsWare, 2015

Okita, Alex, Learning C# Programming with Unity3D, CRC Press, 2014

II. Surse online

http://developer.android.com/support.html http://en.wikipedia.org/wiki/Unity_%28game_engine%29

http://enterta​inment.howstuffworks​.com/slot-machine.ht​m

http://forum.unity3d.com/

http://okita.com/Unity/

http://ro.wikipedia.org/wiki/Android_%28sistem_de_operare%29

http://ro.wikipedia.org/wiki/HTML5

http://ro.wikipedia.org/wiki/JavaScript

http://ro.wikipedia.org/wiki/Limbaj_de_programare

http://ro.wikipedia.org/wiki/Slot_machine

http://sqlandplsql.com/2012/06/02/tiobe-programming-index-for-may-2012/

Revealing slots secrets: Generating a PAR sheet through statistical methodsSecretele jocurilor de sloturi pot fi dezvăluite: Generarea unei fişe PAR prin metode statistice

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

http://www.todaysoftmag.ro/article/542/dezvoltarea-aplicatiilor-mobile-intre-nativ-si-hibrid

Community

Anexa – Cod script Button.cs

using UnityEngine;

using System.Collections;

using System;

public delegate void ClickEventHandler(GameObject sender, GameEventsArgs.Events e);

public delegate void LongClickEventHandler(GameObject sender, GameEventsArgs.Events e);

public class Button : MonoBehaviour {

private SpriteRenderer mSpriteRenderer;

private State mState;

private enum State {ACTIVE, INACTIVE};

public event ClickEventHandler ClickEvent;

public event LongClickEventHandler LongClickEvent;

public Sprite inactiveSprite;

// Use this for initialization

void Awake ()

{

mSpriteRenderer = gameObject.GetComponent<SpriteRenderer> ();

mState = State.ACTIVE;

GameObject child;

for(int i = 0; i < transform.childCount; i++)

{

child = transform.GetChild(i).gameObject;

child.renderer.sortingLayerName = gameObject.renderer.sortingLayerName;

child.renderer.sortingOrder = gameObject.renderer.sortingOrder + 1;

}

}

public void SetInactive()

{

//mSpriteRenderer.sprite = mInactive;

if (gameObject.tag.Equals("SpinButton"))

{

Animator anim = gameObject.GetComponent<Animator>();

anim.Play("Spin_inactive",0,0);

}

else

{

mSpriteRenderer.material.color = Color.gray;

}

mState = State.INACTIVE;

}

public void SetActive()

{

if (gameObject.tag.Equals("SpinButton"))

{

Animator anim = gameObject.GetComponent<Animator>();

anim.Play("Spin_active",0,0);

}

else

{

mSpriteRenderer.material.color = Color.white;

}

mState = State.ACTIVE;

}

public void SetInactiveAnim()

{

Animator anim = gameObject.GetComponent<Animator>();

anim.Play("Spin_inactive",0,0);

}

public void Click(){

if (mState == State.INACTIVE){

return;

}

switch (gameObject.tag){

case "SpinButton":

ClickEvent (gameObject, GameEventsArgs.Events.SPIN);

break;

case "BetPlus":

ClickEvent (gameObject, GameEventsArgs.Events.INCREMENT_BET);

break;

case "BetMinus":

ClickEvent (gameObject, GameEventsArgs.Events.DECREMENT_BET);

break;

case "LinePlus":

ClickEvent (gameObject, GameEventsArgs.Events.INCREMENT_LINE);

break;

case "LineMinus":

ClickEvent (gameObject, GameEventsArgs.Events.DECREMENT_LINE);

break;

case "LeftArrowButton":

ClickEvent (gameObject, GameEventsArgs.Events.LEFT_SCROLL);

break;

case "RightArrowButton":

ClickEvent (gameObject, GameEventsArgs.Events.RIGHT_SCROLL);

break;

case "LazyButton":

ClickEvent (gameObject, GameEventsArgs.Events.FRUITS_SLOT);

break;

case "SwipeButton":

break;

default:

ClickEvent (gameObject, GameEventsArgs.Events.NONE);

break;

}

}

public void LongPress(){

if (mState == State.INACTIVE){

return;

}

switch (gameObject.tag)

{

case "SpinButton":

LongClickEvent (gameObject, GameEventsArgs.Events.AUTO_SPIN);

break;

case "BetPlus":

ClickEvent (gameObject, GameEventsArgs.Events.INCREMENT_BET);

break;

case "BetMinus":

ClickEvent (gameObject, GameEventsArgs.Events.DECREMENT_BET);

break;

case "LinePlus":

ClickEvent (gameObject, GameEventsArgs.Events.INCREMENT_LINE);

break;

case "LineMinus":

ClickEvent (gameObject, GameEventsArgs.Events.DECREMENT_LINE);

break;

case "LeftArrowButton":

ClickEvent (gameObject, GameEventsArgs.Events.LEFT_SCROLL);

break;

case "RightArrowButton":

ClickEvent (gameObject, GameEventsArgs.Events.RIGHT_SCROLL);

break;

case "LazyButton":

ClickEvent (gameObject, GameEventsArgs.Events.FRUITS_SLOT);

break;

case "SwipeButton":

break;

default:

ClickEvent (gameObject, GameEventsArgs.Events.NONE);

break;

}

}

}

Similar Posts