Ako napísať svoju prvú hru pre Android v jazyku Java

Autor: John Stephens
Dátum Stvorenia: 1 Január 2021
Dátum Aktualizácie: 19 Smieť 2024
Anonim
Ako napísať svoju prvú hru pre Android v jazyku Java - Aplikácie
Ako napísať svoju prvú hru pre Android v jazyku Java - Aplikácie

Obsah


Existuje veľa spôsobov, ako vytvoriť hru pre Android, a jedným z dôležitých spôsobov je urobiť ju od nuly v aplikácii Android Studio s Java. Získate tak maximálnu kontrolu nad tým, ako chcete, aby vaša hra vyzerala a chovala sa, a proces vás naučí zručnosti, ktoré môžete použiť v rade ďalších scenárov - či už vytvárate úvodnú obrazovku pre aplikáciu, alebo chcete iba pridať nejaké animácie. Z tohto hľadiska vám tento tutoriál ukáže, ako vytvoriť jednoduchú 2D hru pomocou Android Studio a Java. Všetky kódy a zdroje nájdete na serveri Github, ak ich chcete nasledovať.

Nastavenie

Aby sme mohli vytvoriť našu hru, musíme sa zaoberať niekoľkými konkrétnymi pojmami: herné slučky, vlákna a plátna. Najskôr spustite Android Studio. Ak ho nemáte nainštalovaný, prečítajte si náš úplný úvod do aplikácie Android Studio, ktorá prechádza procesom inštalácie. Teraz začnite nový projekt a uistite sa, že ste vybrali šablónu „Prázdna aktivita“. Toto je hra, takže samozrejme nepotrebujete prvky, ako je napríklad tlačidlo FAB, ktoré komplikuje záležitosti.


Prvá vec, ktorú chcete urobiť, je zmena AppCompatActivity na aktivita, To znamená, že nebudeme používať funkcie panela akcií.

Rovnako tak chceme, aby bola naša hra na celej obrazovke. Pridajte nasledujúci kód do onCreate () pred volaním setContentView ():

getWindow (). setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); this.requestWindowFeature (Window.FEATURE_NO_TITLE);

Upozorňujeme, že ak napíšete nejaký kód a bude podčiarknutý červenou farbou, pravdepodobne to znamená, že musíte importovať triedu. Inými slovami, musíte Android Studio povedať, že chcete používať určité vyhlásenia a sprístupniť ich. Ak kliknete kdekoľvek na podčiarknuté slovo a stlačíte Alt + Enter, urobí sa to automaticky za vás!


Vytvorenie pohľadu na hru

Možno ste zvyknutí na aplikácie, ktoré používajú skript XML na definovanie rozloženia zobrazení, ako sú tlačidlá, obrázky a štítky. To je to, čo riadok setContentView robí pre nás.

Je to však opäť hra, čo znamená, že nemusí mať okná prehliadača ani posúvať zobrazenia recyklátora. Namiesto toho chceme namiesto toho ukázať plátno. V aplikácii Android Studio je plátno rovnaké ako v umení: je to médium, z ktorého môžeme čerpať.

Zmeňte tento riadok takto:

setContentView (nové GameView (toto))

Zistíte, že toto je opäť podčiarknuté červeno. ale teraz ak stlačíte Alt + Enter, nemáte možnosť importovať triedu. Namiesto toho máte možnosť vytvoriť trieda. Inými slovami, chystáme sa vytvoriť si vlastnú triedu, ktorá bude definovať, čo sa deje na plátne. To nám umožní priťahovať sa na obrazovku a nielen ukazovať hotové pohľady.

Kliknite pravým tlačidlom myši na názov balíka v hierarchii nad vľavo a vyberte položku Nový> Trieda, Teraz sa vám zobrazí okno na vytvorenie triedy a budete to nazývať GameView, V časti SuperClass napíšte: android.view.SurfaceView čo znamená, že trieda zdedí metódy - svoje schopnosti - od SurfaceView.

Do poľa Interface (s) napíšete android.view.SurfaceHolder.Callback, Rovnako ako u akejkoľvek triedy, aj teraz musíme vytvoriť nášho konštruktora. Použite tento kód:

súkromné ​​vlákno MainThread; verejné GameView (kontextový kontext) {super (kontext); . GetHolder () addCallback (to); }

Zakaždým, keď je naša trieda volaná, aby vytvorila nový objekt (v tomto prípade náš povrch), spustí konštruktor a vytvorí nový povrch. Riadok „super“ volá nadtriedu av našom prípade je to SurfaceView.

Pridaním spätného volania dokážeme zachytiť udalosti.

Teraz prepíšeme niektoré metódy:

@Override public void surfaceChanged (držiteľ SurfaceHolder, formát int, šírka int, výška int)) {} @Override public void surfaceCreated (držiteľ SurfaceHolder) {} @Override public void surfaceDestroyed (držiteľ SurfaceHolder) {}

V zásade nám umožňujú prepísať (odtiaľ názov) metódy v nadtriede (SurfaceView). Vo svojom kóde by ste už nemali mať žiadne červené podčiarknutia. Pekný.

Práve ste vytvorili novú triedu a zakaždým, keď sa na to odvolávame, vytvorí pre vašu hru plátno, na ktoré bude maľovaná. vyučovanie vytvoriť objekty a potrebujeme ešte jeden.

Vytváranie vlákien

Zavoláme novú triedu MainThread, Jeho úlohou bude vytvoriť vlákno. Vlákno je v podstate ako paralelná vidlica kódu, ktorá môže bežať súčasne s hlavné časť vášho kódu. Môžete mať naraz spustených veľa vlákien, čo umožňuje, aby sa veci vyskytovali súčasne, namiesto toho, aby sa držali prísnej postupnosti. Je to dôležité pre hru, pretože sa musíme ubezpečiť, že bude plynulo fungovať, aj keď sa veľa deje.

Vytvorte svoju novú triedu tak, ako ste to urobili predtým, a tentoraz sa bude rozširovať závit, V konštruktorovi len zavoláme Super(), Pamätajte, že to je super trieda, ktorá je Thread a ktorá pre nás môže urobiť všetko ťažké. Je to ako vytvoriť program na umývanie riadu, ktorý práve volá práčka().

Keď sa volá táto trieda, vytvorí samostatné vlákno, ktoré bude fungovať ako odnož hlavnej veci. A je to z tu že chceme vytvoriť náš GameView. To znamená, že musíme tiež odkázať na triedu GameView a používame tiež SurfaceHolder, ktorý obsahuje plátno. Takže ak je plátno povrch, stojan je SurfaceHolder. A GameView to všetko spája.

Celá vec by mala vyzerať takto:

public class MainThread rozširuje vlákno {private SurfaceHolder surfaceHolder; súkromné ​​GameView gameView; public MainThread (SurfaceHolder surfaceHolder, GameView gameView) {super (); this.surfaceHolder = povrchHolder; this.gameView = gameView; }}

Schweet. Teraz máme GameView a vlákno!

Vytvorenie hernej slučky

Teraz máme suroviny, ktoré potrebujeme na výrobu našej hry, ale nič sa nedeje. Tu prichádza herná slučka. V podstate ide o slučku kódu, ktorá obíde okolo a kontroluje vstupy a premenné pred nakreslením obrazovky. Naším cieľom je, aby to bolo čo najviac konzistentné, aby v snímke neboli žiadne koktania alebo škytavky, ktoré budem skúmať o niečo neskôr.

Zatiaľ sme stále v MainThread triedy a prepíšeme metódu z nadtriedy. Tento je beh.

A vyzerá to trochu takto:

@Override public void run () {while (running) {canvas = null; try {canvas = this.surfaceHolder.lockCanvas (); synchronizovaný (surfaceHolder) {this.gameView.update (); this.gameView.draw (plátno); }} catch (Výnimka e) {} nakoniec {if (canvas! = null) {try {povrchHolder.unlockCanvasAndPost (canvas); } catch (Výnimka e) {e.printStackTrace (); }}}}}

Uvidíte veľa podčiarknutia, preto musíme pridať ďalšie premenné a odkazy. Choďte späť na vrchol a pridajte:

súkromný povrchHlavný povrchHolder; súkromné ​​GameView gameView; súkromné ​​boolovské behanie; verejné statické plátno;

Nezabudnite importovať plátno. Plátno je to, na čo sa skutočne chystáme. Pokiaľ ide o „lockCanvas“, je to dôležité, pretože to je to, čo v podstate zmrazuje plátno, aby sme ho mohli čerpať. Je to dôležité, pretože inak by ste sa mohli pokúsiť o viac pokusov naraz. Stačí vedieť, že na úpravu plátna musíte najprv lock plátno.

Aktualizácia je metóda, ktorú sa chystáme vytvoriť, a tu sa budú zábavné veci objavovať neskôr.

vyskúšať a úlovok Medzitým sú jednoducho požiadavky Java, ktoré ukazujú, že sme ochotní vyskúšať výnimky (chyby), ktoré sa môžu vyskytnúť, ak plátno nie je pripravené atď.

Nakoniec chceme byť schopní založiť vlákno, keď ho potrebujeme. Na to potrebujeme ďalší spôsob, ktorý nám umožní uviesť veci do pohybu. To je to, čo tečúcou Premenná je pre (všimnite si, že logická hodnota je typ premennej, ktorá je vždy pravdivá alebo nepravdivá). Pridajte túto metódu do MainThread trieda:

public void setRunning (boolean isRunning) {running = isRunning; }

V tomto bode by sa však ešte mala zdôrazniť jedna vec, a to aktualizovať, Je to preto, že sme metódu aktualizácie ešte nevytvorili. Takže sa vráťte späť GameView a teraz pridajte metódu.

verejná neplatná aktualizácia () {}

Musíme tiež štart vlákno! Urobíme to v našom surfaceCreated metóda:

@Override public void surfaceCreated (Držitel SurfaceHolder) {thread.setRunning (true); thread.start (); }

Keď je povrch zničený, musíme tiež zastaviť vlákno. Ako ste asi uhádli, my to zvládneme v surfaceDestroyed metóda. Ale keďže vidíme, že to môže v skutočnosti vyžadovať viac pokusov zastaviť vlákno, vložíme to do slučky a použijeme ju vyskúšať a úlovok znova. Ako:

@Override public void surfaceDestroyed (držitel SurfaceHolder) {boolean retry = true; while (opakovať) {try {thread.setRunning (false); thread.join (); } catch (InterrupttedException e) {e.printStackTrace (); } opakovať = false; }}

A nakoniec, zamierte k konštruktorovi a uistite sa, že vytvoríte novú inštanciu svojho vlákna, inak získate obávanú výnimku nulového ukazovateľa! A potom urobíme GameView zameraním, čo znamená, že zvládne udalosti.

thread = new MainThread (getHolder (), this); setFocusable (true);

Teraz môžeš konečne skutočne túto vec otestujte! Je to tak, kliknite na príkaz Spustiť mali by v skutočnosti beží bez akýchkoľvek chýb. Pripravte sa na útek!

Je to ... je to ... prázdna obrazovka! Celý ten kód. Pre prázdnu obrazovku. Ale toto je prázdna obrazovka príležitosť, Máte povrch a beh s hernou slučkou na zvládanie udalostí. Teraz zostáva už len to, aby sa veci stali. Nezáleží na tom, či ste až doteraz nepostupovali v tutoriále podľa všetkého. Ide o to, že môžete jednoducho recyklovať tento kód a začať vyrábať skvelé hry!

Robíme grafiku

Teraz máme prázdnu obrazovku, aby sme mohli čerpať, všetko, čo musíme urobiť, je čerpať z nej. Našťastie je to jednoduchá časť. Všetko, čo musíte urobiť, je prepísať metódu remízy v našej GameView triedy a potom pridajte nejaké pekné obrázky:

@Override public void draw (Canvas canvas) {super.draw (canvas); if (canvas! = null) {canvas.drawColor (Color.WHITE); Farba: nová farba (); color.setColor (Color.rgb (250, 0, 0)); canvas.drawRect (100, 100, 200, 200, farba); }}

Spustite toto a teraz by ste mali mať pekne červený štvorec v ľavom hornom rohu inak bielej obrazovky. Toto je určite zlepšenie.

Teoreticky by ste si mohli celú svoju hru teoreticky vytvoriť tým, že ju vložíte do tejto metódy (a prevládate) onTouchEvent zvládnuť vstup), ale nebol by to strašne dobrý spôsob, ako robiť veci. Vloženie novej farby do našej slučky značne spomalí veci, a to aj vtedy, ak to umiestnime niekde inde, čím sa pridá príliš veľa kódu kresliť metóda by bola škaredá a ťažké ju sledovať.

Namiesto toho má oveľa väčší zmysel manipulovať s hernými objektmi pomocou ich vlastných tried. Začneme tým, ktorý ukazuje postavu a táto trieda sa bude volať CharacterSprite, Choďte do toho a urobte to.

Táto trieda pritiahne na plátno sprite a bude vyzerať takto

public class CharacterSprite {private bitmap image; public CharacterSprite (Bitmap bmp) {image = bmp; } verejné void draw (Canvas canvas) {canvas.drawBitmap (image, 100, 100, null); }}

Ak chcete použiť tento postup, musíte najskôr načítať bitmapu a potom zavolať triedu GameView, Pridajte odkaz na súkromný CharacterSprite characterSprite a potom v surfaceCreated metóda, pridajte riadok:

characterSprite = nový CharacterSprite (BitmapFactory.decodeResource (getResources (), R.drawable.avdgreen));

Ako vidíte, bitmapa, ktorú načítame, sa ukladá do zdrojov a nazýva sa avdgreen (bola z predchádzajúcej hry). Teraz všetko, čo musíte urobiť, je odovzdať túto bitmapu do novej triedy v kresliť metóda s:

characterSprite.draw (plátno);

Teraz kliknite na príkaz Spustiť a na obrazovke by sa mala zobraziť vaša grafika! Toto je BeeBoo. Kreslil som ho do svojich školských učebníc.

Čo keby sme chceli, aby sa tento malý chlapček pohol? Jednoduché: my len vytvoríme x a y premenné pre svoje pozície a potom tieto hodnoty zmeníme v aktualizovať metóda.

Takže pridajte odkazy na svoje CharacterSprite a potom nakreslite bitmapu na x, y, Vytvorte si tu metódu aktualizácie a zatiaľ len vyskúšame:

y ++;

Zakaždým, keď herná slučka beží, presunieme znak dolu po obrazovke. Majte na pamäti, y súradnice sa merajú zhora 0 je horná časť obrazovky. Samozrejme musíme zavolať aktualizovať metóda v CharacterSprite z aktualizovať metóda v GameView.

Stlačte tlačidlo Prehrať znova a teraz uvidíte, že váš obrázok sa pomaly sleduje po obrazovke. Zatiaľ nezískame žiadne ocenenia hry, ale je to začiatok!

Dobre, robiť veci trochu ešte zaujímavejšie je, že tu len upustím kód „skákacie lopty“. To spôsobí, že sa naše grafické odrazy okolo obrazovky od okrajov, ako napríklad tie staré šetriče obrazovky systému Windows. Viete, tie podivne hypnotické.

verejná aktualizácia neplatností () {x + = xVelocity; y + = yVelocity; if ((x> screenWidth - image.getWidth ()) || (x <0)) {xVelocity = xVelocity * -1; } if ((y> screenHeight - image.getHeight ()) || (y <0)) {yVelocity = yVelocity * -1; }}

Budete tiež musieť definovať tieto premenné:

súkromná int xVelocity = 10; súkromná int yVelocity = 5; private int screenWidth = Resources.getSystem (). getDisplayMetrics (). widthPixels; private int screenHeight = Resources.getSystem (). getDisplayMetrics (). heightPixels;

optimalizácia

Tam je kopa viac ponoriť sa sem, od manipulácie so vstupom hráča po zmenu mierky obrázkov, až po správu toho, že sa po obrazovke bude pohybovať veľa znakov naraz. Práve teraz sa postava odráža, ale ak sa pozriete veľmi pozorne, je to mierne koktanie. Nie je to hrozné, ale skutočnosť, že ju vidíte voľným okom, je niečo ako varovný signál. Rýchlosť sa tiež veľmi líši na emulátore v porovnaní s fyzickým zariadením. Teraz si predstavte, čo sa stane, keď budete mať ton ísť na obrazovku naraz!

Existuje niekoľko riešení tohto problému. Začnem tým, že v ňom vytvorím súkromné ​​celé číslo MainThread a zavolajte to targetFPS, Toto bude mať hodnotu 60.Pokúsim sa nechať svoju hru bežať takou rýchlosťou a medzitým sa skontrolujem, či je. Preto chcem tiež zavolať súkromné ​​dvojité video averageFPS.

Budem tiež aktualizovať beh metóda na meranie toho, ako dlho trvá každá herná slučka, a potom pauza túto hernú slučku dočasne, ak je pred cieľovým FPS. Potom si spočítame, ako dlho to trvá teraz vzal a potom vytlačiť, aby sme mohli vidieť v denníku.

@Override public void run () {long startTime; dlhá dobaMillis; dlho waitTime; long totalTime = 0; int frameCount = 0; long targetTime = 1000 / targetFPS; while (running) {startTime = System.nanoTime (); canvas = null; try {canvas = this.surfaceHolder.lockCanvas (); synchronizovaný (surfaceHolder) {this.gameView.update (); this.gameView.draw (plátno); }} catch (Výnimka e) {} nakoniec {if (canvas! = null) {try {povrchHolder.unlockCanvasAndPost (canvas); } catch (Výnimka e) {e.printStackTrace (); }}} timeMillis = (System.nanoTime () - startTime) / 1000000; waitTime = targetTime - timeMillis; vyskúšajte {this.sleep (waitTime); } catch (Výnimka e) {} totalTime + = System.nanoTime () - startTime; frameCount ++; if (frameCount == targetFPS) {averageFPS = 1000 / ((totalTime / frameCount) / 1000000); frameCount = 0; totalTime = 0; System.out.println (averageFPS); }}}

Teraz sa naša hra pokúša uzamknúť FPS na 60 a mali by ste zistiť, že vo všeobecnosti meria pomerne stabilný 58-62 FPS na modernom zariadení. Na emulátore však môžete získať iný výsledok.

Skúste to zmeniť na 60 a 30 a uvidíte, čo sa stane. Hra sa spomaľuje a to mali by teraz si prečítajte 30 vo svojom logcate.

Záverečné myšlienky

Na optimalizáciu výkonu môžeme urobiť aj niekoľko ďalších vecí. K tejto téme je skvelý blogový príspevok. Pokúste sa zdržať vytvárania nových inštancií programu Skicár alebo bitmapy vo vnútri slučky a všetko inicializujte zvonka pred začiatkom hry.

Ak plánujete vytvoriť ďalšiu hru so systémom Android, potom máte k dispozícii iste jednoduchšie a efektívnejšie spôsoby, ako to dosiahnuť v týchto dňoch. Určite však stále existujú scenáre použitia, ktoré umožňujú kreslenie na plátno, a je to veľmi užitočná zručnosť, ktorú môžete pridať do svojho repertoáru. Dúfam, že táto príručka trochu pomohla a želám vám veľa šťastia vo vašich pripravovaných programovacích činnostiach!

ĎalšieSprievodca pre začiatočníkov k jazyku Java

Ak hráte veľa videohier, v určitom okamihu te pravdepodobne mali nápad na hru. Jediná vec, ktorá by vám mohla brániť v tom, aby a táto hra tala kutočnoťou, je znaloť...

Koncom februára poločnoť Google rozpolala pozvánky na udaloť z 19. marca 2019 na konferencii Game Developer Conference (GDC). amotná pozvánka a kutočnoť, že a táto udaloť kon&...

Najnovšie Príspevky