Kuinka kirjoittaa ensimmäinen Android-peli Java-sovellukseen

Kirjoittaja: John Stephens
Luomispäivä: 1 Tammikuu 2021
Päivityspäivä: 19 Saattaa 2024
Anonim
Kuinka kirjoittaa ensimmäinen Android-peli Java-sovellukseen - Sovellukset
Kuinka kirjoittaa ensimmäinen Android-peli Java-sovellukseen - Sovellukset

Sisältö


Android-pelin luomiseen on paljon tapoja, ja yksi tärkeä tapa on tehdä se tyhjästä Android Studio Java -sovelluksella. Tämä antaa sinulle parhaan mahdollisuuden hallita, kuinka haluat pelisi näyttää ja käyttäytyä, ja prosessi opettaa sinulle taitoja, joita voit käyttää myös monissa muissa skenaarioissa - luodaan sitten splash-näyttö sovellukselle vai haluatko vain lisää animaatioita. Tässä mielessä tämä opetusohjelma näyttää sinulle, kuinka luoda yksinkertainen 2D-peli Android Studion ja Java-sovelluksen avulla. Löydät kaikki koodit ja resurssit Githubista, jos haluat seurata niitä.

Asettaa

Pelin luomiseksi meidän on käsiteltävä muutamia erityisiä käsitteitä: pelisilmukat, langat ja kankaat. Aluksi käynnistämällä Android Studio. Jos sinulla ei ole sitä asennettuna, tutustu Android Studio -esittelyyn, joka menee asennusprosessin läpi. Aloita nyt uusi projekti ja muista valita Tyhjä aktiviteetti -malli. Tämä on peli, joten et tietenkään tarvitse sellaisia ​​elementtejä kuin FAB-painike, joka monimutkaistaa asioita.


Ensimmäinen asia, jonka haluat tehdä, on muuttaa AppCompatActivity että aktiviteetti. Tämä tarkoittaa, että emme käytä toimintapalkin ominaisuuksia.

Samoin haluamme tehdä pelistämme koko näytön. Lisää seuraava koodi onCreate (): seen ennen setContentView () -puhelua:

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

Huomaa, että jos kirjoitat koodin ja se alleviivattu punaisella, se tarkoittaa todennäköisesti, että sinun on tuotava luokka. Toisin sanoen sinun on kerrottava Android Studiolle, että haluat käyttää tiettyjä lauseita ja asettaa ne saataville. Jos napsautat vain alleviivattua sanaa mihin tahansa ja painat sitten Alt + Enter, se tehdään sinulle automaattisesti!


Pelinäkymän luominen

Voit olla tottunut sovelluksiin, jotka käyttävät XML-skriptiä määrittelemään näkymien asettelun, kuten painikkeet, kuvat ja tarrat. Tämä on mitä linja setContentView tekee meille.

Mutta jälleen kerran, tämä on peli, joka tarkoittaa, että sillä ei tarvitse olla selainikkunoita tai vierittäviä kierrätysnäkymiä. Sen sijaan haluamme näyttää kankaan. Android Studiossa kangas on aivan sama kuin taiteessa: se on väline, jota voimme käyttää.

Joten muuta tämä rivi lukea niin:

setContentView (uusi GameView (tämä))

Huomaat, että tämä on jälleen alleviivattu punaisella. Mutta nyt Jos painat Alt + Enter, sinulla ei ole mahdollisuutta tuoda luokkaa. Sen sijaan sinulla on mahdollisuus luoda Luokka. Toisin sanoen olemme tekemässä omaa luokkaa, joka määrittelee mitä kankaalle aiotaan jatkaa. Tämän avulla voimme vetää näytölle sen sijaan, että näyttäisimme vain valmis näkymiä.

Joten napsauta hiiren oikealla painikkeella paketin nimeä vasemmalla olevassa hierarkiasasi ja valitse Uusi> luokka. Sinulle esitetään nyt ikkuna luokan luomiseen ja aiot soittaa siihen GameView. Kirjoita SuperClass-kenttään: android.view.SurfaceView mikä tarkoittaa, että luokka perii menetelmät - sen ominaisuudet - SurfaceView: lta.

Kirjoita Interface (s) -ruutuun android.view.SurfaceHolder.Callback. Kuten minkä tahansa luokan kanssa, meidän on nyt luotava rakentajamme. Käytä tätä koodia:

yksityinen MainThread-säie; julkinen GameView (kontekstiyhteys) {super (konteksti); getHolder (). addCallback (tämä); }

Joka kerta, kun luokkamme kutsutaan tekemään uusi esine (tässä tapauksessa pintamme), se ajaa rakentajaa ja luo uuden pinnan. Rivi 'super' kutsuu superluokkaa ja tässä tapauksessa SurfaceView.

Lisäämällä takaisinsoitto pystymme sieppaamaan tapahtumia.

Ohita nyt jotkin menetelmät:

@Peräytä julkinen tyhjä pintamuutos (SurfaceHolder-haltija, int-muoto, int-leveys, int-korkeus) {} @On ohittaa julkinen tyhjä pintaCreated (SurfaceHolder-haltija) {} @On ohittaa julkinen tyhjä pintaDestroyed (SurfaceHolder-haltija) {}

Nämä antavat meille periaatteessa mahdollisuuden ohittaa (tästä johtuen nimi) menetelmät superluokassa (SurfaceView). Sinulla ei nyt pitäisi olla enää punaisia ​​alleviivauksia koodissasi. Kiva.

Olet juuri luonut uuden luokan, ja joka kerta kun viitaamme siihen, se rakentaa kangaspelissäsi pelillesi maalaamiseksi. Luokat luoda esineitä ja tarvitsemme vielä yhden.

Lankojen luominen

Uutta luokkaamme kutsutaan MainThread. Ja sen tehtävänä on luoda säie. Lanka on olennaisesti kuin rinnakkaiskoodin haarukka, joka voi kulkea samanaikaisesti tärkein osa koodistasi. Sinulla voi olla paljon säikeitä käynnissä kerralla, jolloin asiat voivat tapahtua samanaikaisesti sen sijaan, että noudattaisit tiukkaa järjestystä. Tämä on tärkeätä pelille, koska meidän on varmistettava, että sen toiminta jatkuu sujuvasti, vaikka paljon tapahtuu.

Luo uusi luokka samalla tavalla kuin aiemmin, ja tällä kertaa se jatkuu Lanka. Suunnittelijaan me vain soitamme Super (). Muista, että se on superluokka, joka on Thread ja joka voi tehdä kaiken raskaan nostamisen meille. Tämä on kuin ohjelman luominen pyydettävien astioiden pesemiseksi pesukone().

Kun tätä luokkaa kutsutaan, se aikoo luoda erillisen säikeen, joka kulkee pääosan sivukuvana. Ja se on kotoisin tässä että haluamme luoda GameView-sovelluksemme. Tämä tarkoittaa, että meidän on myös viitattava GameView-luokkaan ja käytämme myös SurfaceHolderia, joka sisältää kankaan. Joten jos kangas on pinta, SurfaceHolder on maalausteline. Ja GameView yhdistää sen kaiken.

Koko asian pitäisi näyttää seuraavalta:

julkisen luokan MainThread laajentaa ketjua {yksityinen SurfaceHolder surfaceHolder; yksityinen GameView gameView; julkinen MainThread (SurfaceHolder surfaceHolder, GameView gameView) {super (); this.surfaceHolder = surfaceHolder; this.gameView = gameView; }}

Schweetin. Meillä on nyt GameView ja säie!

Pelisilmukan luominen

Meillä on nyt raaka-aineet, jotka tarvitsemme pelin tekemiseen, mutta mitään ei tapahdu. Pelin silmukka tulee tänne. Pohjimmiltaan tämä on koodisilmukka, joka menee ympäri ja tarkistaa tulot ja muuttujat ennen näytön piirtämistä. Tavoitteenamme on tehdä siitä mahdollisimman johdonmukainen, jotta kehysnopeudessa ei ole kokkuja tai hikoituksia, joita tutkin vähän myöhemmin.

Toistaiseksi olemme edelleen MainThread luokan ja ohitamme menetelmän superluokasta. Tämä on juosta.

Ja se menee hiukan tähän:

@On ohita julkinen tyhjä suoritus () {samalla (käynnissä) {kangas = nolla; kokeile {canvas = this.surfaceHolder.lockCanvas (); synkronoitu (surfaceHolder) {this.gameView.update (); this.gameView.draw (kangas); }} kiinni (poikkeus e) {} lopuksi {if (kangas! = nolla) {kokeile {surfaceHolder.unlockCanvasAndPost (kangas); } saalis (poikkeus e) {e.printStackTrace (); }}}}}

Näet paljon alleviivausta, joten meidän on lisättävä lisää muuttujia ja viitteitä. Siirry takaisin alkuun ja lisää:

yksityinen SurfaceHolder; yksityinen GameView gameView; yksityinen boolean-juoksu; julkinen staattinen kangaskangas;

Muista tuoda kangas. Kangas on asia, johon oikeasti vedomme. Mitä lockCanvasiin tulee, se on tärkeätä, koska juuri se, mikä jäädyttää kankaan, antaa meille mahdollisuuden vedota siihen. Se on tärkeää, koska muuten sinulla voi olla useita ketjuja, jotka yrittävät piirtää sitä kerralla. Vain tiedä, että kankaan muokkaamiseksi sinun on ensin tehtävä Lukko kangas.

Päivitys on menetelmä, jonka aiomme luoda, ja tässä hauskoja juttuja tapahtuu myöhemmin.

yrittää ja ottaa kiinni sillä välin ovat vain Java-vaatimuksia, jotka osoittavat, että olemme valmiita yrittämään käsitellä poikkeuksia (virheitä), joita saattaa tapahtua, jos kangas ei ole valmis jne.

Viimeinkin haluamme pystyä aloittamaan säieemme tarvittaessa. Tätä varten tarvitsemme täällä toisen menetelmän, jonka avulla voimme asettaa asiat liikkeelle. Se mitä käynnissä muuttuja on varten (Huomaa, että Boolen tyyppi on muuttuja, joka on aina tosi tai epätosi). Lisää tämä menetelmä MainThread luokka:

public void setRunning (boolean isRunning) {käynnissä = isRunning; }

Mutta tässä vaiheessa yksi asia olisi silti korostettava, ja se on päivittää. Tämä johtuu siitä, että emme ole vielä luoneet päivitysmenetelmää. Joten pop takaisin GameView ja lisää nyt menetelmä.

julkinen tyhjä päivitys () {}

Meidän on myös tehtävä alkaa lanka! Aiomme tehdä tämän meidän surfaceCreated menetelmä:

@Paina julkinen tyhjä pintaCreated (SurfaceHolder-haltija) {thread.setRunning (true); thread.start (); }

Lanka on myös pysäytettävä, kun pinta tuhoutuu. Kuten olet ehkä arvata, käsittelemme asiaa surfaceDestroyed menetelmä. Mutta koska se voi tosiasiallisesti kestää useita yrityksiä pysäyttää säiettä, asetamme tämän silmukkaan ja käytämme yrittää ja ottaa kiinni uudelleen. Niin kuin:

@Peräytä julkinen tyhjä pintaDestroyed (SurfaceHolder-haltija) {boolean retry = true; while (yritä uudelleen) {kokeile {thread.setRunning (false); thread.join (); } saalis (InterruptedException e) {e.printStackTrace (); } yritä uudelleen = väärä; }}

Ja lopuksi, siirry rakentajan kanssa ja varmista, että luot uuden säikeen esiintymän, muuten saat pelätyn nollaosoittimen poikkeuksen! Ja sitten aiomme tehdä GameView-ohjelmasta tarkennettavissa, eli se pystyy käsittelemään tapahtumia.

säie = uusi MainThread (getHolder (), tämä); setFocusable (tosi);

Nyt voit vihdoin todella testata tämä asia! Se on oikein, napsauta suorita ja se pitäisi oikeasti ajaa ilman virheitä. Valmistaudu puhallettavaksi!

Se on… se on… tyhjä näyttö! Kaikki tuo koodi. Tyhjä näyttö. Mutta tämä on tyhjä näyttö tilaisuus. Sinulla on pinta ylöspäin ja juoksut pelisilmukalla tapahtumien käsittelemiseen. Nyt kaikki, mitä jäljellä on, saa asiat tapahtumaan. Sillä ei ole edes merkitystä, jos et ole seurannut kaikkea opetusohjelmassa tähän saakka. Asia on, että voit kierrättää tämän koodin aloittaaksesi loistavien pelien tuottamisen!

Grafiikan tekeminen

Aivan, nyt meillä on tyhjä näyttö, johon piirtää, meidän tarvitsee vain piirtää siihen. Onneksi se on yksinkertainen osa. Sinun tarvitsee vain ohittaa piirtomenetelmämme GameView luokan ja lisää sitten hienoja kuvia:

@Paina julkisen tyhjän piirtäminen (Canvas-kangas) {super.draw (canvas); if (kangas! = nolla) {canvas.drawColor (Color.WHITE); Maalimaali = uusi maali (); paint.setColor (Color.rgb (250, 0, 0)); canvas.drawRect (100, 100, 200, 200, maali); }}

Suorita tämä ja nyt pitäisi olla melko punainen neliö muuten valkoisen näytön vasemmassa yläkulmassa. Tämä on varmasti parannus.

Voit teoriassa luoda melko paljon koko pelisi pitämällä sitä tämän menetelmän sisällä (ja ohittamalla) onTouchEvent käsitellä syötettä), mutta se ei olisi kovin hyvä tapa edetä asioissa. Uuden maalin sijoittaminen silmukkaansa hidastaa asioita huomattavasti, ja vaikka laitamme tämän muualle, lisäämällä liikaa koodia piirtää menetelmästä tulisi ruma ja vaikea seurata.

Sen sijaan on paljon järkevämpää käsitellä peliobjekteja omilla luokillaan. Aloitamme sellaisella, joka näyttää merkin, ja tätä luokkaa kutsutaan CharacterSprite. Mene eteenpäin ja tee se.

Tämä luokka piirtää sprite kankaalle ja näyttää siltä

julkinen luokka CharacterSprite {yksityinen bittikarttakuva; julkinen CharacterSprite (bittikartta bmp) {image = bmp; } julkinen mitätön piirtäminen (kankaalle piirtoalusta) {canvas.drawBitmap (kuva, 100, 100, nolla); }}

Nyt käyttääksesi tätä sinun on ensin ladattava bittikartta ja soitettava sitten luokalle GameView. Lisää viittaus yksityinen CharacterSprite characterSprite ja sitten surfaceCreated menetelmä, lisää rivi:

characterSprite = uusi CharacterSprite (BitmapFactory.decodeResource (getResources (), R.dravable.avdgreen));

Kuten näette, lataamamme bittikartta tallennetaan resursseihin ja sitä kutsutaan avdgreen (se oli edellisestä pelistä). Nyt sinun tarvitsee vain siirtää kyseinen bittikartta uudelle luokalle piirtää menetelmä:

characterSprite.draw (kangas);

Napsauta nyt suorita ja sinun pitäisi nähdä grafiikka näkyvän näytöllä! Tämä on BeeBoo. Piirrän hänet koulun oppikirjoihini.

Entä jos halusimme saada tämän pienen kaverin liikkumaan? Yksinkertainen: Luomme vain x- ja y-muuttujat hänen sijainneilleen ja sitten muutamme näitä arvoja päivittää menetelmä.

Joten lisää viitteet omaan CharacterSprite ja piirrä sitten bittikartta osoitteeseen x, y. Luo päivitysmenetelmä täällä, ja nyt yritämme vain:

y ++;

Joka kerta kun pelisilmukka käy, siirrämme merkkiä näytöllä alas. Muistaa, y koordinaatit mitataan ylhäältä niin 0 on näytön yläreuna. Tietenkin meidän on soitettava päivittää menetelmä sisään CharacterSprite alkaen päivittää menetelmä sisään GameView.

Paina toista uudelleen ja nyt näet, että kuvasi hidastuu näytön alaosaan. Emme ole vielä voittaneet yhtään pelipalkintoa, mutta se on alku!

Okei, tehdä asioita hieman mielenkiintoisempaa, aion vain pudottaa tänne pomppipallon koodin. Tämä saa graafisesta näytöstämme poistumaan näytön reunoista, kuten vanhat Windows-näytönsäästäjät. Tiedätkö omituiset hypnoottiset.

public void update () {x + = xVelocity; y + = yVelocity; if ((x> näytön leveys - image.getWidth ()) || (x <0)) {xVelocity = xVelocity * -1; } if ((y> screenHeight - image.getHeight ()) || (y <0)) {yVelocity = yVelocity * -1; }}

Sinun on myös määriteltävä nämä muuttujat:

yksityinen int xVelocity = 10; yksityinen int yelocity = 5; yksityinen int-näyttöleveys = Resurssit.getSystem (). getDisplayMetrics (). leveysPixelit; yksityinen int screenHeight = Resurssit.getSystem (). getDisplayMetrics (). korkeuspikselit;

optimointi

On paljon enemmän syvällään tänne, soittimen syöttämisen käsittelemisestä, kuvien koon muuttamiseen ja hallitsemiseen, jossa on paljon merkkejä, jotka kaikki liikkuvat näytön ympäri kerralla. Tällä hetkellä hahmo on pomppiva, mutta jos tarkastellaan tarkkaan, siellä tapahtuu lievää kokkoa. Se ei ole kauheaa, mutta se, että voit nähdä sen paljaalla silmällä, on varoitusmerkki. Nopeus vaihtelee myös paljon emulaattorissa fyysiseen laitteeseen verrattuna. Kuvittele nyt, mitä tapahtuu, kun sinulla on tonnia jatkuu näytöllä kerralla!

Tähän ongelmaan on olemassa muutamia ratkaisuja. Aluksi haluan tehdä yksityisen kokonaisluvun MainThread ja soita siihen targetFPS. Tämän arvo on 60.Aion yrittää saada minun pelini toimimaan tällä nopeudella, ja tarkastan sillä välin, että se on. Tätä varten haluan myös yksityisen kaksoissoiton averageFPS.

Aion päivittää myös juosta menetelmä mitata kuinka kauan jokainen pelisilmukka vie ja sitten tauko kyseinen pelisilmukka väliaikaisesti, jos se on targetFPS: n edellä. Laskemme sitten kuinka kauan se kestää nyt otti ja tulosta sitten sen, jotta voimme nähdä sen lokissa.

@Ovat ohittaa julkisen tyhjän suorituksen () {long startTime; pitkä aikaMillis; pitkä odotusaika; pitkä yhteensäTime = 0; int frameCount = 0; pitkä targetTime = 1000 / targetFPS; kun taas (käynnissä) {startTime = System.nanoTime (); kangas = nolla; kokeile {canvas = this.surfaceHolder.lockCanvas (); synkronoitu (surfaceHolder) {this.gameView.update (); this.gameView.draw (kangas); }} kiinni (poikkeus e) {} lopuksi {if (kangas! = nolla) {kokeile {surfaceHolder.unlockCanvasAndPost (kangas); } saalis (poikkeus e) {e.printStackTrace (); }}} timeMillis = (System.nanoTime () - startTime) / 1000000; waitTime = targetTime - timeMillis; kokeile {this.sleep (waitTime); } catch (poikkeus e) {} totalTime + = System.nanoTime () - startTime; ruutulaskuri ++; if (frameCount == targetFPS) {averageFPS = 1000 / ((totalTime / frameCount) / 1000000); frameCount = 0; totalTime = 0; System.out.println (averageFPS); }}}

Nyt pelimme yrittää lukita sen FPS-arvoon 60 ja sinun pitäisi huomata, että se yleensä mittaa melko tasaisen 58–62 FPS: n nykyaikaisella laitteella. Emulaattorissa saatat kuitenkin saada erilaisen tuloksen.

Yritä muuttaa 60–30 ja katso mitä tapahtuu. Peli hidastuu ja se pitäisi lue nyt 30 logcatissasi.

Ajatusten päättäminen

Voimme myös optimoida suorituskyvyn joitain muita asioita. Täältä löytyy hieno blogin viesti aiheesta. Yritä olla luomatta koskaan uusia Paint-esiintymiä tai bittikarttoja silmukan sisälle ja alusta kaikki ulkopuolella ennen pelin alkamista.

Jos aiot luoda seuraavan osuman Android-pelin, niin siellä on varmasti helpompia ja tehokkaampia tapoja hoitaa se nykyään. Mutta kankaalle piirtämiseen on ehdottomasti vielä käyttötapauksia, ja se on erittäin hyödyllinen taito lisätä ohjelmistoasi. Toivon, että tämä opas on auttanut jonkin verran, ja toivotan teille onnea tulevissa koodausyrityksissä!

SeuraavaAloittelijan opas Jaavaan

Jo kuva on tuhannen anan arvoinen, kuvittele, kuinka monta ana elinikäinen lieni copioa on arvoinen. copio on arkitovalokuvaukirjato, ja e tarjoaa inulle elinikäien lienin vain 29 dollarilla...

Lähe kaikki, mitä teemme nykyään, tapahtuu kannettavan tekniikkamme kautta. Työtä töihin ohjeiiin muiikkiin, akun loppuminen on käytännöä mahdoto...

Uudet Viestit