TEHNOLOGII FOLOSITE PENTRU IMPLEMENTAREA JOCURILOR PE CALCULATOR [305642]
UNIVERSITATEA “DUNĂREA DE JOS” [anonimizat]: Absolvent: [anonimizat]. dr. [anonimizat] 2018
Introducere
Jocurile pe calculator constituie o categorie de aplicații software destinată amuzamentului. [anonimizat], în perioada anilor 1970, [anonimizat] a evoluat, astfel că putem vorbi cu ușurință de multe evenimente de prezentare a jocurilor, cum ar fi E3 [anonimizat] (ESL).
Odată cu această evoluție a industriei, cererea pentru jocuri a [anonimizat], [anonimizat], [anonimizat]-un număr mic de persoane sau chiar format dintr-o singură persoană ce se ocupă cu acest lucru. Spre exemplu: [anonimizat], Unturned, Banished sunt jocuri ce au fost create de o singură persoană.
Deși multă lume vede crearea unui joc de către o singură persoană a [anonimizat] a dezvolta un joc pe calculator (desigur că aceleași tehnici pot fi folosite si pentru crearea jocurilor pentru android/console, însă necesită anumiți pași in plus).
Lucrarea este structurată în 4 capitole:
Capitolul I este o descriere a [anonimizat] a [anonimizat].
Capitolul II este reprezentat de partea tehnică a jocului. În acest capitol vom descrie platforma folosită (Unreal Engine 4) și sistemul de codare (metoda BluePrint).
Capitolul III descrie partea practică unde este explicat exact procesul de construire a jocului. În acest capitol vom explica fiecare model în parte dar și alte elemente folosite cu ajutorul platformei Unreal Engine 4.
Capitolul IV reprezintă un exemplu de cod creat în C#, dar și o mică descriere a spațiului de lucru Microsoft Visual Studio pentru a vedea diferența între metoda BluePrint si metoda clasică de cod.
Capitolul 1
Adobe Photoshop
1.1 Ce este Adobe Photoshop?
[anonimizat] [1, 11].
1.2 [anonimizat], [anonimizat], [anonimizat]. Photoshop este un program cu o interfață intuitivă și care permite o multitudine extraordinară de modificări necesare în mod curent profesioniștilor și nu numai: [anonimizat], focalizare, aplicare de efecte pe imagine sau pe zone (selecții), [anonimizat], suport de canale de culoare pe 8, 16 sau 32 biți, [anonimizat]. [anonimizat], [anonimizat], Photoshop este efectiv indispensabil.
Alături de aplicația Photoshop (ajuns la versiunea CC, succesorul versiunii CS6), este inclusă și aplicația ImageReady, cu un impresionant set de instrumente web pentru optimizarea și previzualizarea imaginilor, prelucrarea pachetelor de imagini cu ajutorul sistemului droplet (mini-programe de tip drag and drop) și realizarea imaginilor rollover (imagini ce își schimbă aspectul la trecerea cu mouse-ul peste), precum și pentru realizarea de GIF -uri animate.
1.3 Istoric
Prima versiune a programului a fost distribuită în februarie 1990 de către frații Knoll, Thomas și John.
Povestea începe cu tatăl lor, profesorul de liceu Glenn Knoll, pasionat de fotografie. Cei doi băieți au ajuns cu timpul să aibă oarecare interese în domeniu. În plus, atât tatăl cât și cei doi copii au ajuns să fie pasionați de calculatoare încă din 1978 când au cumpărat un calculator produs de Apple Computer. În 1987 Thomas a cumpărat unul dintre modelele noi de Apple, un Apple Macintosh Plus, pentru a-l ajuta la scrierea lucrării de doctorat, "prelucrarea imaginilor digitale". Dezamăgit de faptul că nu putea afișa tonurile de gri din imagini, Thomas a început să scrie un cod care să le simuleze pe afișaj. În vacanța pe care au petrecut-o împreună, fratele său John a fost fascinat de rezultatele muncii lui Thomas în această privință, mai ales că aceste rutine semănau în mod izbitor cu uneltele de editare deja existente în programul Pixar – John lucra la Industrial Light and Magic. Acest interes comun s-a concretizat în decizia celor doi de a încerca să creeze un pachet grafic pentru calculatoare personale.
Prima versiune a rezultatului muncii celor doi frați se numea "Display"; încet-încet, datorită necesităților apărute pe parcurs, chiar această primă versiune includea import-export de diverse formate. În 1988 acest pachet a ajuns să se numească "ImagePro", și cei doi au început să încerce să creeze o bază comercială pentru crearea unei afaceri: soția lui Thomas deja aștepta un copil, iar el încă lucra cu fratele său la dezvoltarea acestui program în continuare personal. La începutul lui 1988, Thomas a decis să-și mai acorde șase luni pentru a finaliza o versiune beta a acestui program înainte de a-și căuta o slujbă, urmând ca John să-și încerce apoi norocul în Silicon Valley pentru a-l vinde unei firme suficient de mari ca să asigure distribuția și dezvoltarea ulterioară. În general, companiile din Silicon Valley nu au fost foarte interesate de acest pachet: o singură companie, BarneyScan a arătat ceva interes și a distribuit programul, deja numit "Photoshop", pe termen scurt, împreună cu scanerele lor, fără costuri suplimentare pentru clienți. În total 200 de copii ale programului au fost distribuite în acest fel. Firma SuperMac a refuzat colaborarea cu cei doi fiindcă nu li s-a părut că Photoshop ar aduce ceva nou față de propriul lor program de editare, PixelPaint [11].
Abia în septembrie 1988 frații Knoll au reușit să-și atingă scopul: au trezit interesul firmei Adobe după o prezentare a programului și acestora le-a plăcut. Au semnat un contract de licențiere a Photoshop către Adobe, iar după încă zece luni de dezvoltare au apărut, în februarie 1990 Photoshop 1.0.
Thomas încă este implicat în proiectul Photoshop – n-a reușit să-și termine niciodată teza de doctorat. John și-a continuat cariera la ILM, participând printre altele la proiecte mari ale acestora, incluzând părți din proiectele Mission Impossible, Star Trek și Star Wars. Tatăl lor continuă să fie profesor.
1.4 Avantaje
Principalele elemente prin care Photoshop se diferențiază de aplicațiile concurente și prin care stabilește noi standarde în industria prelucrării de imagini digitale sunt:
Selecțiile
Straturile (Layers)
Măștile (Masks)
Canalele (Channels)
Retușarea
Optimizarea imaginilor pentru Web
1.5 Scopul programului Photoshop în jocul creat
Ăn crearea jocului, Adobe Photoshop, a jucat un rol important legat de tot ce ține de grafică. Personajul, fiecare copac, fiecare floare, fiecare bucățică de pământ a fost desenată si retușată atent în acest program. Motivul principal pentru care am ales Adobe Photoshop și nu GIMP, spre exemplu, ar fi interfața și utilitățile bonus din Photoshop. O piesă puternică ce ne ajută să realizăm arta pe care am folosit-o sunt straturile (Layers). Ca să ințelegem mai bine straturile, o să vă dau un exemplu concret: Să ne imaginam o bucată de sticlă pe care vom desena un om. Ca să iasă bine personajul, niciodată nu vom incepe cu toate detaliile deodată, ci vom face mai întâi o mâzgâlitură, numită sketch. În momentul în care avem acea mâzgâlitură adăugăm încă o bucată de sticlă (un strat), iar pe stratul pe care l-am adăugat vom contura omul și vom finisa anumite trăsături, apoi vom adăuga alt strat, și așa mai departe până când vom ajunge la ultimul strat în care avem desenat omul nostru exact ca în viziunea artistică pe care am avut-o.
La fel ca și în exemplul de mai sus am procedat când am creat personajul principal din joc. La început nu aveam nicio idee despre cum va arăta personajul, apoi mi-a venit o idee vagă căreia am incercat să îi dau viață în photoshop, și așa încet-încet și cu multă răbdare, adăugând strat peste strat, am reușit să creez personajul principal. Desigur, au fost multe unelte importante de care m-am folosit în photoshop, dar cea mai demnă de evidențiat a fost opțiunea de straturi (Layer).
În primul strat avem linia de orientare. Deși pare cel mai simplu element dintre cele 5 straturi, aceasta reprezintă echilibrul, fiindcă în funcție de linia de orientare, în stratul al doilea ne vom ocupa de proporțiile personajului. În cel de-al 3-lea strat începem să dăm contur membrelor superioare/inferioare, iar în cel de-al 4-lea strat dăm o formă hainelor. Stratul cu numărul 5, reprezintă finisarea detaliilor. Desigur, acestea sunt doar 5 straturi pentru prezentare. Desenarea acestuia fiind mai complexă, necesitând o foarte mare atenție la detalii.
1.6 De la foaie și creion în mediul virtual?
Am tot vorbit mai sus despre interfața în care mi-am desenat gândurile si despre uneltele principale folosite, dar oare cum am reușit eu de la foaie și creion să desenez într-un mediu virtual? Răpunsul este unul simplu: Tabletă Grafică.
1.7 Ce este o tabletă grafică?
O tabletă grafică este un dispozitiv periferic de intrare pentru computere, care permite introducerea imaginilor desenate manual asemenea celor realizate cu un instrument de scris pe hârtie. Aceste tablete pot fi folosite pentru a introduce date cum ar fi semnăturile de mână. Totodată pot fi folosite pentru a înregistra o imagine de pe o bucată de hârtie atașatǎ suprafeței tabletei. Capturarea datelor în acest fel se realizează prin reprezentarea conturului/marginilor imaginii și se numește digitalizare.
O tabletă grafică (denumită și penpad, digitizer sau suprafață de digitalizare) este alcătuită dintr-o suprafață pe care utilizatorul poate „desena” sau contura o imagine cu un stylus, un instrument similar unui pix special conceput pentru acest aparat. Imaginea nu apare în general pe suprafața tabletei, ci pe monitorul calculatorului. Unele tablete vin cu funcționalitatea secundară de a se comporta ca un ecran tactil în loc de monitor al calculatorului, interacționând cu stylus-ul. Alte tablete au funcția de a înlocui mouse-ul, devenind un dispozitiv primar de selectare și navigare pentru calculator. Există tablete care în loc de stylus, au un dispoztiv-puc (ca forma unui puc) care poate fi plimbat pe suprafața tabletei și care, pentru captare, dispune de un reticul (goniometric) ce identifică diferențiat pozițiile locațiilor de pe tabletă.
Vârful stylusului sau dispozitivului-puc, mișcate pe tabletă, transmit impulsuri prin care tableta primește informații corespondente despre apăsarea/prezența stylusului sau dispozitivului-puc pe poziția respectivă de pe tabletă. La modelele mai perfecționate pot fi recunoscute și informații precum: înclinația pixului, rotirea lui, apăsarea degetelor sau se lucrează simultan cu mai multe dispozitive (stylus, puc).
Stylusul conține o bobină care poate produce un câmp magnetic direcționat sau unul variabil. Bucle conductive din tabletă identifică poziția dispozitivului pe tabletă comparând amplitudinea/tăria semnalelor induse.
Wacom Intuos Pro Medium
Dimensiune: M (medie)
Suprafața activă este de 224 x 140 mm
Nivel presiune creion: 2048
Aceasta este tableta grafică pe care o folosesc în desenarea peisajelor. Mă ajută foarte mult, deoarece în lateral dupa cum se poate vedea are două serii a câte 4 butoane pe care le pot seta să îndeplinească anumite funcții (spre exemplu, am atașate funcții precum radieră/luminozitate/imagine/mod decupare/setarea pensulei pe care o folosesc etc).
Creionul care vine la pachet cu această tabletă grafică conține 2048 de nivele de presiune și asigură un control creativ redând astfel fiecare mișcare în mod natural asemenea uneltelor tradiționale (creionul). Însă tableta este foarte mare și atunci când vreau să desenez altceva în afară de piese de mediu, voi rămâne cu mult spațiu gol, neutilizat, îngreunându-mi astfel munca.
Wacom Intuos Comic Pen
Dimensiune: S (Mică)
Suprafața activă este de 152x95mm
Nivel de presiune creion: 1024
Pe aceasta o folosesc în special atunci când vreau să desenez personaje sau orice alt tip de ființă. Datorită dimensiunii o pot folosi peste tot și îmi ușurează munca atunci când vreau să desenez un personaj. De exemplu, atunci când vreau să desenez un mediu/o hartă, am nevoie de o tabletă pe care să am un spațiu de lucru mare, însă atunci când vreau să desenez un personaj/un animal/etc, am nevoie de un spațiu mai restrâns pentru a putea detalia caracteristicile acestuia.
Capitolul 2
Unreal engine 4
2.1 Ce este Unreal Engine 4?
Unreal Engine este un motor grafic dezvoltat de firma Epic Games, prima dată folosit pentru jocul Unreal în 1998. Scopul principal al motorului grafic creat de cei de la Epic Games a fost în special pentru dezvoltarea jocurilor de tip first-person shooter, însă a fost folosit si in crearea altor tipuri de jocuri, precum strategii sau jocuri de luptă [5,6].
2.2 Două motoare grafice care domină piața
În momentul de față, piața este dominată de două motoare grafice, și anume: Unity si Unreal Engine 4 (versiunea actuală de Unreal Engine). Pentru a putea publica un joc pe internet creat cu ajutorul Unity atunci ar trebui să cumpărăm versiunea Unity Pro care ar ajunge undeva intre 2.000 si 45.000 de lei. La fel ca și Unity obișnuia să fie si Unreal Engine 4 cerând astfel o sumă substanțială de bani ce trebuia plătită lunar pentru a putea folosi motorul grafic, însă de curând (din anul 2014) a fost făcut gratis – doar că la momentul publicării jocului, Unreal va încasa un procent de până la 15% din profiturile aduse de jocul tău, procent ce este folosit în continuarea intreținerii platformei [12].
Pe lângă sistemul inteligent de încasare a profitului, Unreal Engine 4 mai are încă un plus ce revoluționează ideea de codare și anume BluePrints (metodă ce stă la baza creției jocului nostru).
2.3 Ce este un BluePrint?
Sistemul de codare vizuală din Unreal Engine este un sistem complet de codare a scenariului de joc bazat pe folosirea unei interfețe structurată în bază nod pentru crearea elementelor din scenariul jocului direct din editorul Unreal. În general, după cum se întâmplă și cu alte limbaje de codare, este folosit pentru a defini clasele orientate pe obiect (OO) sau obiecte în motorul grafic. În mod familiar, obiectele definite prin folosirea BluePrint-ului sunt cunoscute ca "BluePrints".
Cum funcționează BluePrint-urile?
In forma lor de bază, BluePrint-urile sunt extensii codate vizual adăugate jocului dezvoltat. Creearea de elemente complexe în cadrul jocului este realizabilă prin conectarea nodurilor (Nodes), evenimentelor (Events), funcțiilor (Functions) si variabilelor (Variables) prin conectori (Wires) [4].
BluePrint-urile funcționează prin folosirea de noduri în diverse scopuri – precum creearea obiectelor, atribuirea funcțiilor individuale și în general evenimente din scenariul jocului – care sunt specifice fiecărui stadiu al BluePrint-ului pentru a se implementa comportamente de acțiune și alte funcționalități.
Capitolul 3
Arhitectura jocului
3.1 Meniul
În absolut orice joc am intra, prima dată vom fi întâmpinați de un meniu. Orice meniu trebuie să conțină o serie de butoane care să aibe funcțiile de: imagine de fundal, pornirea jocului, opțiuni alături de rezoluții si ieșirea din joc. Acestea sunt elementele cheie ce se află în absolut orice meniu de întâmpinare a jucătorului.
Pentru a creea acest meniu de care am vorbit va trebui să creăm o hartă goală, căreia să îi atașăm o interfață grafică ce va conține toate elementele cheie ale meniului. Această interfață grafică poartă denumirea de widget in Unreal Engine 4, denumire de care ne vom folosi pe parcursul acestei prezentări.
Aceasta este harta goală (după cum se poate vedea in panoul din mijloc nu conține nimic, este complet neagră).
Acesta este widget-ul de care avem nevoie. În el am adăugat imaginea de fundal, două panouri ce conțin toate butoanele de care avem nevoie (start, opțiuni, ieșire, rezoluții). În momentul de față este doar o interfață grafică fără funcționalitate. Desigur că, atunci cand jocul pornește vom vrea să apară doar panoul ce conține start/opțiuni/ieșire joc și vom vrea ca atunci când apăsăm pe opțiuni să apară butoanele de rezoluții. Însă pentru a face toate acestea vom avea nevoie de o serie de BluePrint-uri.
Explicarea codului: În momentul în care butonul opțiuni va fi apăsat, vom seta vizibilitatea primului panou și îl vom face invizibil cu ajutorul funcției “set visibility”, apoi vom face vizibil al doilea panou care conține toate butoanele de rezoluții.
Acum că am intrat în opțiuni și vedem rezoluțiile, cum ne întoarcem la meniul principal ca să pornim jocul sau să ieșim?
Explicarea codului: Avem butonul cu denumirea “meniu principal” iar în momentul în care va fi apăsat vom face panoul cu rezoluții să devină invizibil folosindu-ne de funcția “Set visibility”, iar panoul cu opțiuni (start/opțiuni/ieșire joc) vizibil.
Pentru ieșire, vom apela funcția quit game, astfel că atunci când apăsăm butonul ieșire vom ieși din joc și vom ajunge la desktop. Pentru start, vom invoca funcția open level iar în chenarul din ea vom scrie denumirea hărții (în cazul acesta: Level1Creatia) pe care vrem să o pornim atunci când apăsăm pe butonul start.
Explicarea codului: Rezoluțiile standard pe care le-am folosit sunt: 1920×1080, 1280×720, 640×480. Pentru a le face funcționale va trebui să invocăm o funcție numită “execute command console” în care să adaugăm comanda “r.setres 1920×1080/1280×720/640×480”. Această comandă va schimba rezoluția în momentul apăsării butonului.
Avem harta goală, avem widget-ul care arată și funcționează cum ne-am dorit, dar cum îi vom atașa hărții noastre widget-ul creat? Pentru asta, va trebui să integrăm un cod vizual în interiorul hărții. Acest cod va face legătura dintre hartă și widget, astfel că atunci când harta va fi pornită, widget-ul, de asemenea se va încărca.
Explicarea codului: Ne vom folosi de evenimentul cu denumirea “Event Begin Play”, eveniment ce are loc atunci când se accesează harta. În momentul accesării hărții, vom integra widget-ul cu ajutorul funcției “create widget”, funcție căreia îi vom atașa widget-ul nostru creat mai devreme și prin intermediul funcției “Add to Viewport” îl vom face vizibil. În momentul în care widget-ul este disponibil, vom avea nevoie de mouse pentru a naviga; astfel, am setat vizibilitatea cursorului iar prin funcția “Get Player Controller” înregistrez mișcările făcute de către utilizator pentru a reda ce dorește.
3.2 Elementele primului nivel/Crearea hărții
Pentru a putea crea primul nostru nivel, vom avea nevoie de elementele pe care le-am desenat în photoshop (pământul, copacii, păsările, personajul, plantele). Pentru a le putea integra în Unreal Engine, am creat separat câte un sprite pentru fiecare element. Un sprite este defapt o foaie artistică în care îmi voi pune mai multe elemente care au aceași însemnătate.
Exemplu:
Sprite-ul ce conține norii
Sprite-ul ce conține plante
Sprite-ul ce conține copaci
Sprite-ul ce conține pământul
Fiecare sprite creat in photoshop, îl vom adăuga în Unreal Engine, iar de acolo prin opțiunea “Extract Sprites”, le vom extrage individual.
În momentul în care ele s-au extras, vom accesa fiecare bucățică de pământ/copac/nor etc și vom seta coliziunea. Coliziunea reprezentând nivelul de interacțiune personaj/mediu. De exemplu, atunci când mergem pe stradă putem păși, deoarece există coliziune – este o forță ce rezistă greutății noastre și ne susține la suprafață. Daca nu ar fi coliziune între noi si pamant, atunci probabil că am cădea într-un infinit abis.
Exemplul cu setarea cutiei de coliziune pe o bucată de pământ:
După ce extragem fiecare element din sprite-uri și setăm coliziunile, putem să ornăm harta cu aceste elemente. (Elementele se așază astfel, în funcție de viziunea artistică în panou, însă trebuie să avem grijă la coordonate.)
3.3 Elementele necesare creării personajului
În momentul de față personajul principal reprezintă doar poze (puse într-un sprite), însă pentru a schimba asta și pentru a-i da viață, ne vom folosi de opțiunea creării unui flipbook (carte de animații). După cum se poate observa, în sprite-ul de mai sus, caracterul are mai multe stări (mers, sărit, lovit etc). Când vom extrage în particular fiecare stare, o vom trece apoi în opțiunea de “create flipbook” prin intermediul căreia îi vom oferi animații.
Așadar, în stânga avem 4 cadre, numerotate de la 0 la 3. Fiecare cadru este o imagine diferită a personajului, iar puse cap la cap vor oferi senzația de mișcare a acestuia. Viteza de redare a cadrelor se schimbă în dreapta, la opțiunea de “Frames per second”.
Mai jos avem toate flipbook-urile create pentru fiecare stare a personajului:
Acum că avem flipbook-urile create și setate în funcție de viteza de redare pe care o dorim noi, suntem gata să începem crearea personajului.
3.4 Crearea personajului
Partea I
Primul lucru pe care trebuie să îl facem este sa creăm o clasă BluePrint, căreia ii vom atașa numele TimTest (Tim este numele personajului iar Test reprezintă stadiul pe care îl atribui) și o listă de enumerație unde am să trec toate stările personajului
Clasa creată:
Enumerația creată cu numele de “characterStates”:
Primul lucru pe care va trebui să îl facem atunci când intrăm în clasa noastră, este să creăm o funcție invocată atunci când este nevoie de o anumită animație.
Explicarea codului:Mai întâi am creat o variabilă numită “state” căreia i-am atribuit ca și valoare lista de enumerație creată mai sus. Prin intermediul funcției “update animation”, vom conecta, printr-un nod, comanda “switch on characterStates”, comandă ce ia deja valorile de la variabila “state” creată anterior. În momentul în care am făcut legătura dintre variabila “state” creată și comanda “switch on charaterStates” vom observa că în interiorul comenzii avem toate stările pe care le-am trecut în lista de enumerație. Acum, printr-un nod, vom lua fiecare stare în parte și vom folosi funcția “Set Flipbook”, funcție în care vom pune flipbook-urile noastre.
Urmează să facem diferența între mișcarea și staționarea personajului; pentru aceasta, vom detecta viteza utilizând funcția “get velocity” pe care mai apoi o vom compara cu 0. Această comparație cu 0 reprezintă condiția noastră. Dacă viteza este mai mare decat 0, atunci înseamnă că personajul se mișca și vom seta flipbook-ul de mers. Dacă viteza este 0, atunci înseamnă că personajul nostru nu se mișcă și vom seta flipbook-ul de inactivitate.
Următorul pas va fi să elaborăm sistemul care să ințeleagă dacă personajul nostru se mișcă în stânga sau în dreapta(pozitiv sau negativ pe axa x).
Explicarea codului: Aici am creat o variabilă de tip boolean căreia i-am dat numele de “bisMovingRight”. Prin funcția “inputAxisMoveRight”, vom compara valorile primite cu 0, iar dacă valoarea primită este mai mare decât 0 pe axa x, înseamnă că personajul nostru se mișcă dreapta, așa că vom seta variabila noastră pe care am creat-o mai devreme ca și adevărată. Dacă valoarea primită este mai mică decât 0 pe axa x, înseamnă că personajul nostru se mișcă in stânga, așa că vom seta variabila noastră create anterior ca fiind negativă. Valorile obținute le vom adăuga în funcția “Add Movement Input”, funcție cu rolul de a salva datele primite.
Acum că ne-am setat variabila în codul precedent, va trebui să îi oferim funcționalitatea!
Explicarea codului: Ce va trebui sa facem prin urmare, este sa reînnoim animațiile personajului în funcție de coordonatele pe care acesta le folosește ca să se miște. Vom sparge (break) vectorul de coordonate x,y,z și vom lua doar valorile corespondente axei x, iar în momentul în care variabila creată de noi anterior va fi adevărată (x = +1), vom lăsa rotația neatinsă. Însă dacă variabila este falsă, iar personajul se mișcă negativ pe x, atunci vom roti 180 de grade pe axa x.
Partea a II-a
În momentul de față avem animațiile integrate în clasa creată de noi și de asemenea, le putem folosi. Va trebui să integrăm o alertă vizuală prin care să urmărim starea acestuia, astfel că atunci cand este lovit, să se inregistreze evenimentul si să rezulte alt eveniment (spre exemplu, când viața scade la 0, acesta să joace animația de moarte).
Primul lucru pe care va trebui să îl facem, este să creăm un widget în care să integrăm o bară de progresie, bară ce va reprezenta viața personajului.
După ce am creat acest widget, va trebui să îl adăugăm și să facem vizibil widget-ul in clasa “TimTest”.
Explicarea codului: Pentru a integra widget-ul ne-am folosit de evenimentul “event begin play” și am inițializat o secvență, integrându-l în clasa “TimTest”. Apoi am creat o variabilă “HealthBar” căreia i-am atribuit widget-ul și prin comanda “add to viewport”, l-am făcut vizibil.
Partea a III-a
Sistemul de viață este creat, însă în momentul de față acesta nu face nimic altceva decât să arate bara de progresie pe care am implementat-o anterior. Pentru a o face să inregistreze date, este necesar sa creăm o metodă de evidență a loviturilor primite.
Explicarea codului: Am creat o variabilă “isHit” de tip boolean, ce are rolul de a raporta dacă personajul a fost sau nu lovit. De asemenea, și o variabilă “HealthCurrent” de tip float, care reprezintă viața curentă a personajului. În momentul în care apăs tasta “/” , atunci vom seta “isHit” ca fiind adevărată, astfel că prin funcția “Disable Input” luăm controlul jucătorului și mai apoi determinăm viața curentă, scădem din ea 0.25 și adaptăm bara. Apoi ca să facem distincția dintre lovitură și moarte, vom compara valoarea finală cu 0, astfel că dacă viața personajului este mai mare decat 0, vom seta flipbook-ul pe care îl dorim, ca mai apoi prin funcția “Add Force” să aplicăm o forță pe axa X si Z care să ne ridice de la sol personajul (pentru a se vedea mai clar că a fost lovit). Dacă viața personajului atinge valoarea 0, atunci vom seta flipbook-ul de moarte, iar pentru a nu se repeta la infinit animația, vom invoca funcția “Set Looping”, astfel că animația să fie rulată o singură dată. Prin funcția “Disable Input” luăm controlul jucătorului și mai apoi adăugăm meniul de final, specific încheierii prin opțiunea “Create Widget”. Îi oferim o întârziere de 0.25 secunde prin intermediul funcției “Delay“ ca să putem vedea animația complete. În final prin “Add To Viewport” vom seta vizibilitatea.
Explicarea codului: Acum va trebui să facem diferența dintre aterizarea personajului în urma unei sărituri și aterizarea personajului în urma unei lovituri. Acesta va sări atunci când apăsăm tasta “space” si ne vom folosi de funcțiile “ jump “, “stop jump” (sare/oprește săritura), astfel, când apăsăm tasta, vom porni funcția “jump” și vom rula flipbook-ul specific. În urmatoarea instanță vom avea nevoie de evenimentul “event on landed” și de variabila “isHit” care înregistrează dacă personajul este sau nu lovit, întrucat atunci când acesta atinge pământul, variabila “isHit” va fi falsă și vom rula flipbook-ul necesar stării de inactivitate reînnoind animația. Dacă “isHit” este adevărată, vom utiliza animația dorită, iar prin funcția “delay” vom da o întarziere în redarea controlului de la tastatură urmând să resetăm variabila “isHit” ca fiind falsă.
Acesta este widget-ul pe care l-am creat pentru a fi rulat atunci când personajul nostru rămâne fără viață (moare). Este un widget format din două blocuri de text și două butoane.
Butoanelor le-am atribuit funcțiile de “Open Level”, adică atunci când vor fi apăsate, ele vor deschide unul din nivelele create. Atunci când apăs da, va restarta nivelul curent, atunci când apăs nu, mă va duce în meniul principal.
Să presupunem că persoana ce va juca jocul are o problemă și este în mijlocul nivelului însă nu vrea să inchidă, ci doar să pună pauză. Pentru asta va trebui să creăm un meniu funcțional pe care mai apoi să îl atașăm clasei personaj.
Din nou am creat un widget, în care am pus o imagine de fundal transparentă, pentru a da un anumit efect plăcut și am adăugat două butoane: “continuă joc” și “meniul principal”.
Explicarea codului: În momentul în care jucatorul va apăsa tasta “meniu principal” vom dori ca acesta să fie trimis către meniul de întâmpinare, așa că ne vom folosi de funcția “Open Level”. Atunci când va apăsa “Continuă Joc” trebuie să revină în exact același moment în care a pus pauza, astfel la atingerea butonului “continuă joc “, se va invoca funcția “Set Game Paused” și o vom seta drept fals, urmând ca prin funcția “remove from parent”, meniul de pauză să dispară, iar prin “cast to TimTest” vom relua controlul personajului.
Acum am integrat widget-ul creat în clasa personaj, invocând evenimentul “inputActionPause” și am creat o variabilă “isScreenShown” de tip boolean (pentru a verifica dacă este sau nu deja pusă pauză). În momentul în care variabila noastră este falsă, atunci vom implementa widget-ul și vom seta prin funcția “Set Game Paused” pauza.
3.5 Un actor pe scena noastră?
Nu, nu este vorba despre un clasic actor uman, ci este vorba despre o clasă din Unreal Engine 4 ce poartă numele de actor. Acesta, la fel ca și un actor de pe o scenă dintr-un teatru oarecare, va trebui să joace rolul pe care regizorul jocului, i-l voi da. În cazul de față, actorul nostru va fi o platformă ce se va mișca in direcția pe care o voi seta din momentul în care pornesc jocul, până îl inchid.
Așa arată actorul nostru din punct de vedere grafic, acestuia atașându-i unul din sprite-urile pe care le-am extras. Însă acum va trebui să îi oferim rolul pe care vrem sa îl joace.
Explicarea codului: Primul lucru pe care vom dori să îl facem atunci când lucrăm cu clasele de tip actor este sa creăm o variabilă de tip vector pe care eu am denumit-o “Location”. Folosindu-mă de evenimentul “begin play”, îi voi oferi vectorului creat prin funcția “GetActorLocation” locația exactă. Urmatoarea variabilă pe care am creat-o are denumirea de “start” și este o variabilă de tip boolean. Atunci când vectorul nostru primește locația exactă a actorului nostru, atunci vom putea inițializa începerea scenetei [8,9].
Urmatorul pas constă in crearea scenariului pe care actorul îl va urma. În momentul în care s-a inițializat variabila “start”, vom avea nevoie de comanda “timeline” în care vom trece modul în care vrem ca acesta să se deplaseze. Desigur că apoi va trebui sa reînoim locația actorului, folosindu-ne de adunarea dintre vectori urmând să o actualizăm ca fiind noua noastră poziție “new location”.
Acesta este graficul din comanda timeline (scenariul). Am setat timpul scenetei ca fiind de 5 secunde, astfel că actorul va porni din punctul x=0 și va urca pe axa z timp de 2.5 secunde 200 de unități, ca mai apoi în restul de timp rămas până la 5 secunde să scadă tot atâtea unități până va ajunge la valoarea inițială.
Capitolul 4
Detalii de implementare în C#
În capitolele precedente am prezentat modul în care poate fi creat un joc folosind metoda BluePrint. Acest capitol va conține alternativa la această tehnică, și anume programararea în C#, folosind Microsoft Visual Studio 2017.
Microsoft Visual Studio reprezintă un IDE creat de Microsoft, in care se pot face jocuri, site-uri, aplicații web, servicii web, aplicații pentru mobil folosind o varietate de limbaje de programare (36, mai exact), precum: C++, Java, Python, Ruby, Node.js etc.
În continuare, vom prezenta structura pe care trebuie să o aibă un proiect ce utilizează Microsoft Visual Studio, folosind C#:
Următoarea secvență de cod reprezintă o modalitate de creare a stărilor personajului și a camerei, precum și a legăturilor dintre ele în funcție de comenzile jucătorului (mișcarea spre dreapta, statul nemișcat, săritura) [2].
Atest1Character::Atest1Character()
{
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = true;
bUseControllerRotationRoll = false;
// Capsula de coliziune
GetCapsuleComponent()->SetCapsuleHalfHeight(96.0f);
GetCapsuleComponent()->SetCapsuleRadius(40.0f);
//Legatura personaj/camera
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
CameraBoom->SetupAttachment(RootComponent);
CameraBoom->TargetArmLength = 500.0f;
CameraBoom->SocketOffset = FVector(0.0f, 0.0f, 75.0f);
CameraBoom->bAbsoluteRotation = true;
CameraBoom->bDoCollisionTest = false;
CameraBoom->RelativeRotation = FRotator(0.0f, -90.0f, 0.0f);
// Crearea camerei
SideViewCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("SideViewCamera"));
SideViewCameraComponent->ProjectionMode = ECameraProjectionMode::Orthographic;
SideViewCameraComponent->OrthoWidth = 2048.0f;
SideViewCameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
CameraBoom->bAbsoluteRotation = true;
SideViewCameraComponent->bUsePawnControlRotation = false;
SideViewCameraComponent->bAutoActivate = true;
GetCharacterMovement()->bOrientRotationToMovement = false;
// CConfiguratia miscarii personajului
GetCharacterMovement()->GravityScale = 2.0f;
GetCharacterMovement()->AirControl = 0.80f;
GetCharacterMovement()->JumpZVelocity = 1000.f;
GetCharacterMovement()->GroundFriction = 3.0f;
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
GetCharacterMovement()->MaxFlySpeed = 600.0f;
GetCharacterMovement()->bConstrainToPlane = true;
GetCharacterMovement()->SetPlaneConstraintNormal(FVector(0.0f, -1.0f, 0.0f));
GetCharacterMovement()->bUseFlatBaseForFloorChecks = true;
GetSprite()->SetIsReplicated(true);
bReplicates = true;
}
// ANIMATII
void Atest1Character::UpdateAnimation()
{
const FVector PlayerVelocity = GetVelocity();
const float PlayerSpeedSqr = PlayerVelocity.SizeSquared();
// miscare sau stationare, inclusive adaugarea animatiilor
UPaperFlipbook* DesiredAnimation = (PlayerSpeedSqr > 0.0f) ? RunningAnimation : IdleAnimation;
if( GetSprite()->GetFlipbook() != DesiredAnimation )
{
GetSprite()->SetFlipbook(DesiredAnimation);
}
}
void Atest1Character::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
UpdateCharacter();
}
// Input-ul primit de la jucator
void Atest1Character::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// SARITURA/Miscarea spre dreapta
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("MoveRight", this, &Atest1Character::MoveRight);
PlayerInputComponent->BindTouch(IE_Pressed, this, &Atest1Character::TouchStarted);
PlayerInputComponent->BindTouch(IE_Released, this, &Atest1Character::TouchStopped);
}
void Atest1Character::MoveRight(float Value)
{
// adaugarea input-ului pentru miscare dreapta
AddMovementInput(FVector(1.0f, 0.0f, 0.0f), Value);
}
void Atest1Character::TouchStarted(const ETouchIndex::Type FingerIndex, const FVector Location)
{
Jump();
}
void Atest1Character::TouchStopped(const ETouchIndex::Type FingerIndex, const FVector Location)
{
// oprirea sariturii, in momentul apasarii tastei space
StopJumping();
}
void Atest1Character::UpdateCharacter()
{
UpdateAnimation();
// adjustarea rotatiei pe axa X (negativ/pozitiv ///// stanga/dreapta)
const FVector PlayerVelocity = GetVelocity();
float TravelDirection = PlayerVelocity.X;
if (Controller != nullptr)
{
if (TravelDirection < 0.0f)
{
Controller->SetControlRotation(FRotator(0.0, 180.0f, 0.0f));
}
else if (TravelDirection > 0.0f)
{
Controller->SetControlRotation(FRotator(0.0f, 0.0f, 0.0f));
}
}
}
Concluzii
Jocurile video sunt varianta virtuală a jocurilor de societate. În zilele noastre acestea au o grafică atractivă și pot fi ușor accesate de mai mulți jucători în mediul online. De multe ori, aceste jocuri au în spate și povești captivante. Jocurile video pot stimula și dezvolta gândirea critică și strategică prin diferite elemente, unele dintre ele pot antrena și reflexele. De asemenea, ele pot fi un bun liant social, fiind distractive și reprezentând o modalitate interactivă de a petrece timpul cu prietenii.
Indiferent de genul său, indiferent de platforma pe care acesta este lansat (PC, XBOX, PS4, NINTENDO etc), fiecare joc va avea aceeași structură. Desigur că vor fi și alte elemente dar baza și modul de gândire ale acestuia vor fi la fel. Singurele aspecte ce diferă de la joc la joc sunt: obiectivul, arta, metoda de codare și genul (shooter/mmorpg/rpg etc). În rest, toate au aceleasi elemente de bază ca și cele prezentate pe parcursul acestei lucrări.
Acestă lucrare și-a propus să prezinte cele mai noi tehnologii care pot fi utilizate pentru crearea jocurilor pe calculator. Prima parte descrie modul în care grafica unui joc poate fi realizată în Adobe Photoshop. Jocul pe care l-am propus are la bază sistemul BluePrint, o metodă recent aparută – BluePrint-urile sunt extensii codate vizual. Creearea elementelor complexe în cadrul jocului este realizabilă prin conectarea nodurilor, evenimentelor, funcțiilor și a variabilelor. Evenimentele din scenariul jocului sunt specifice fiecărui stadiu al BluePrintului. Pentru a spori complexitatea aplicației, în ultimul capitol am arătat cum funcțiile jocului pot fi create folosind limbajul C#. Ambele metode sunt utilizate în crearea aplicațiilor, însă metoda BluePrint este folosită în special la jocurile 2D.
Considerăm că lucrarea poate fi un ghid util celor care sunt pasionați de acest domeniu al programării deoarece prezintă în detaliu toate etapele creării unui joc pe calculator.
Bibliografie
Radu Biris, Adobe Photoshop CS6 – Curs oficial Adobe Systems, Editura Teora, Bucuresti, 2012.
Liviu Negrescu, Lavinia Negrescu, Limbajul C# pentru incepatori. Volumul VI – Mediul de programare Visual Studio C#, Editura Albastră, Cluj-Napoca, 2011.
https://www.udemy.com/the-ultimate-drawing-course-beginner-to-advanced/ (accesat la 10.11.2017)
https://www.youtube.com/watch?v=1M3S3eiJK5I&list=PLL0cLF8gjBpqDdMoeid6Vl5roMl6xJQGC (accesat la 15.02.2018)
https://docs.unrealengine.com/latest/INT/Engine/BluePrints/ (accesat la 02.01.2018)
https://docs.unrealengine.com/latest/INT/Engine/BluePrints/UserGuide/Timelines/Creation/index.html (accesat la 22.02.2018)
https://docs.unrealengine.com/latest/INT/Engine/BluePrints/UserGuide/Timelines/Editor/index.html (accesat la 24.02.2018)
https://docs.unrealengine.com/latest/INT/Engine/BluePrints/UserGuide/Types/LevelBluePrint/index.html (accesat la 05.04.2018)
https://docs.unrealengine.com/latest/INT/Engine/BluePrints/UserGuide/MathNode/index.html (accesat la 06.04.2018)
https://docs.unrealengine.com/latest/INT/Engine/BluePrints/UserGuide/Types/Interface/index.html (accesat la 07.04.2018)
https://en.wikipedia.org/wiki/Adobe_Photoshop (accesat la 10.04.2018)
https://en.wikipedia.org/wiki/Unreal_Engine (accesat la 13.04.2018)
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: TEHNOLOGII FOLOSITE PENTRU IMPLEMENTAREA JOCURILOR PE CALCULATOR [305642] (ID: 305642)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
