Kattava liekki-opetusohjelma (tai kuinka pelien tekeminen räpyttelemällä)

esittely

Hei kaikki! Olen Luan ja olen tervetullut tähän ensimmäiseen kattavaan Flame-opetusohjelmaan.

Flame on minimalistinen Flutter-pelimoottori, joka tarjoaa muutama moduuli Canvas-pohjaisen pelin tekemistä varten.

Tässä opetusohjelmassa aiomme luoda hyvin yksinkertaisen pelin, jossa laatikot putoavat ja tavoitteena on tuhota ne ennen kuin ne osuvat näytön alaosaan.

Näin peli näyttää

Voit tarkistaa pelin itse nähdäksesi, mitä olemme asentamassa tämän APK: n tai sen asentamiseen Play Kaupasta.

Tämän avulla voimme kattaa kaikki kehyksen tarjoamat ominaisuudet ja osoittaa kuinka suorittaa kaikkein perustoiminnot: renderointi, spritit, ääni, teksti, animaatiot ja paljon muuta.

Miksi valitsimme tämän pelin? Sen lisäksi, että se on erittäin yksinkertainen mutta täydellinen kehysten tutkimiseen, on hyvä asia myös se, että meillä on resursseja sen tekemiseen!

Tähän peliin aiomme käyttää seuraavia resursseja: yksi laatikko sprite, yksi räjähdys sprite (animaatiolla), räjähdysääni, 'miss' ääni (kun ruutuun ei löydy), taustamusiikki ja myös kaunis fontti tuloksen tekemiseen.

On vaikea löytää hyviä resursseja, jotka ovat kaupallisesti saatavissa Internetistä, mutta löysimme kaiken (paitsi kirjasimen) tästä mahtavasta sivustosta. Ne ovat todella hienoja, ehdottomasti suositeltavia.

Toistaiseksi sprite-arkkeja ei tueta, joten ensinnäkin meidän on muunnettava kaikki resurssit sopiviin muotoihin. Meidän on myös muunnettava kaikki ääni MP3: ksi (OGG on myös tuettu; WAV ei ole). Koska kaikki on tehty, voit ladata täältä paketin kaiken tarvitsemastasi resurssiviisaan.

Maininnan arvoinen myös, että kaikki tässä kuvattu on sitoutunut täysin toimivana kokonaisena versiona GitHubiin. Voit aina katsoa, ​​kun epäilet. Myös esimerkki luotiin seuraamalla tätä tarkkaa vaihetta ja ottamalla usein sitoumuksia tilannekuvina. Yhdistän koko opetusohjelman tietyt sitoumukset, jotka siirtävät arkistoa kyseiseen vaiheeseen. Tämän avulla voit tehdä tarkistuspisteitä ja selata vanhaa koodia nähdäksesi kaiken, mikä ei ollut selkeää.

Viimeinen asia; voit tarkistaa täydellisen dokumentoinnin Flamea varten täältä. Jos sinulla on kysyttävää, ehdotuksia, virheitä, avaa ongelma tai ota minuun yhteyttä.

Lisäksi tarvitset myös Flutter and Dart asennettuna. Jos se sopii sinulle, sinulla voi olla myös IntelliJ IDEA, joka on erittäin hyvä paikka kirjoittaa koodisi. Asentaaksesi nämä asiat, voit tutustua lukuisiin tutoriaaliin, kuten tämä.

Perusasiat

Joten nyt oletan, että sinulla on kaikki valmis. Joten suorita vain seuraava ja avaa se!

Ensimmäinen asia, joka sinun on tehtävä, on lisätä liekkiriippuvuus. Siirry pubspec.yaml-tiedostoosi ja varmista, että riippuvuusnäppäimessä näkyy liekki:

Käytämme tässä uusinta versiota 0.5.0, mutta voit myös valita uuden, jos se on saatavana.

Nyt main.dart-tiedostossasi on jo paljon tavaraa: 'tärkein' menetelmä, joka on pidettävä yllä; ja seuraava kutsu runApp-menetelmään. Tämä menetelmä vie widgetit ja muut Flutter-komponentit, joita käytetään sovellusnäyttöjen luomiseen. Koska teemme peliä, piirrämme kaiken kankaalle emmekä käytä näitä komponentteja; joten poista kaikki tämä.

Päämenetelmämme on nyt tyhjä, ja aiomme lisätä kaksi asiaa; ensinnäkin jokin kokoonpano:

Flame.dart -tuonti antaa pääsyn staattiseen Flame-luokkaan, joka on vain haltija useille muille hyödyllisille luokille. Käytämme enemmän tästä myöhemmin. Toistaiseksi me kutsumme kahta menetelmää tähän liekki luokkaan.

Viimeinen on itsestään selvä, se poistaa osan kirjaamisesta äänentoistolaitteiden laajennuksesta. Nyt pian lisäämme ääniä peliin, ja jos se ei toimi, sinun on kommentoitava sitä vianetsinnän vuoksi. Mutta pääsemme sinne lopulta.

Ensimmäinen rivi on monimutkaisempi. Periaatteessa jotkut Flutterin tärkeät toiminnot puuttuvat, koska emme käytä runApp-menetelmää. Tämä enableEvents-puhelu tekee jonkin verran ratkaisua saadaksesi jokaisen sovelluksen kannalta välttämättömän ilman widgettejä.

Viimeinkin meidän on aloitettava peli. Tätä varten lisäämme vielä yhden luokan tuontiluetteloon, Game-luokan. Tämä luokka tarjoaa minkä tahansa pelin luomiseen tarvittavan abstraktion: pelisilmukan. Se on alaluokiteltu siten, että joudut toteuttamaan minkä tahansa pelin perustan: päivitysmenetelmän, jota kutsutaan aina sopivaksi ja joka vie viimeisen päivityksen jälkeen kuluneen ajan, sekä renderöintimenetelmän, jonka on tiedettävä kuinka piirtää pelin nykytila. Silmukan sisäiset toiminnot jätetään Game-luokan ratkaistavaksi (voit katsoa tietysti, se on hyvin yksinkertaista), ja sinun täytyy vain soittaa aloittaaksesi, no, aloita.

Tarkastuspiste: 599f809

Tällä hetkellä renderöinti ei tee mitään, joten jos käynnistät sen, sen pitäisi suorittaa, mutta antaa sinulle mustan näytön. Makea! Joten saimme toiminnallisen sovelluksen, jossa ei ole widgettejä ja ampuma-ainesta, ja tyhjän kankaan, jotta voimme piirtää sovelluksemme.

Muotoilu

Ja miten piirustus tehdään? Piirrämme yksinkertainen suorakulmio nähdäksesi sen toiminnassa. Lisää seuraava renderöintimenetelmääsi:

Kuten näette, määrittelemme tässä suorakulmion näytön sijainnin perusteella. Seuraava kuva osoittaa, kuinka säännöt on suunnattu. Periaatteessa alkuperä on vasemmassa yläkulmassa ja akseli nousee oikealle ja alaspäin.

Huomaa myös, että useimmat piirtomenetelmät vievät maalin. Maali ei ole vain yksi väri, vaan se voi olla Degradè tai jokin muu kuvio. Normaalisti haluat joko yksivärisen tai siirtyä suoraan Sprite-malliin. Joten asetimme värin maalin sisällä värin esiintymäksi.

Väri edustaa yhtä ARGB-väriä; luot sen kokonaisluvulla, jonka voit kirjoittaa heksadesimaalilla lukemisen helpottamiseksi; se on muodossa A (alfa, läpinäkyvyys, yleensä 0xFF) ja sitten kaksi numeroa R: lle, G: lle ja B: lle samassa järjestyksessä.

Siellä on myös kokoelma nimettyjä värejä; se on kuitenkin materiaalipaketin sisällä. Varo vain tuodaan Värit-moduuli, jotta et vahingossa käytä jotain muuta materiaalipaketista.

Joten hienoa, nyt meillä on neliö!

Tarkastuspiste: 4eff3bf

Tiedämme myös kuinka hallitsijat toimivat, mutta emme tiedä ruudun mittoja! Kuinka piirtämme jotain muihin kolmeen kulmaan ilman näitä tietoja? Älä pelkää, koska liekillä on menetelmä hakea näytön todellinen ulottuvuus (johtuu siitä, että sen ympärillä on dokumentoitu ongelma).

Pohjimmiltaan async-menetelmä

Huomaa, että odotettavissa olevaa avainsanaa, kuten JavaScriptiä, voidaan käyttää vain async-toiminnossa, joten muista tehdä pääasynkki (Flutter ei välitä).

Seuraava tarkistuspiste hakee mitat kerran päämenetelmässä ja tallentaa ne Game-luokan sisälle, koska tarvitsemme niitä toistuvasti.

Tarkastuspiste: a1f9df3

Levittäminen sprites

Lopuksi tiedämme kuinka piirtää mikä tahansa muoto missä tahansa näytön näytössä. Mutta me haluamme spritejä! Seuraava tarkistuspiste lisää joitain hyödykkeitä, joita aiomme käyttää, sopivaan omaisuuskansioon:

Tarkastuspiste: 92ebfd9

Ja seuraava tekee yhden tärkeän asian, jota et voi unohtaa: lisää kaikki pubsepc.yaml-tiedostoosi. Kun koodiasi rakennetaan, Dart niputtaa vain sinä määrittelemäsi resurssit.

Tarkastuspiste cf5975f

Viimeinkin olemme valmiita piirtämään spriteemme. Perus tapa, jolla liekki antaa sinulle mahdollisuuden, on paljastaa Flame.images.load ('polku kuvat-kansiosta') -menetelmä, joka palauttaa ladatun kuvan lupauksen, joka voidaan sitten piirtää canvas.drawImage-menetelmällä.

Laatikon piirtäminen on kuitenkin erittäin yksinkertaista tehdä, koska voimme käyttää SpriteComponent-luokkaa, kuten näin:

Abstrakti komponenttiluokka on käyttöliittymä, jossa on kaksi menetelmää, renderöinti ja päivitys, aivan kuten pelimme. Ajatuksena on, että peli voi koostua komponenteista, joiden renderöinti- ja päivitysmenetelmiä kutsutaan pelin menetelmiin. SpriteComponent on toteutus, joka tuottaa spriteen, ottaen huomioon sen nimen ja koon (neliö tai suorakulmainen), (x, y) -asennon ja pyörimiskulman. Se kutistuu tai laajentaa kuvaa sopivasti halutun koon mukaiseksi.

Tässä tapauksessa lataamme crate.png-tiedoston, jonka on oltava omaisuus / kuvat -kansiossa, ja siinä on laatikkoluokka, joka piirtää 128x128 pikselin laatikot, kiertokulman 0.

Sitten lisäämme Crate-ominaisuuden peliin, pikaistamme sen näytön yläreunaan, keskitämme vaakasuoraan ja teemme sen pelisilmukassamme:

Tämä tekee laatikostamme! Mahtava! Koodi on melko lyhyt ja myös helppo lukea.

Tarkastuspiste 7603ca4

Päivitetään tila pelisilmukassa

Laatkamme on kaikki, mutta pysähtynyt ilmaan. Haluamme siirtää sitä! Jokainen laatikko putoaa vakionopeudella alaspäin. Meidän on tehtävä se päivitysmenetelmässämme; muuta vain ykköspalautetta, joka meillä on:

Tämä menetelmä vie viimeisestä päivityksestä kuluneen ajan (sekunteina). Yleensä tämä tulee olemaan hyvin pieni (10 ms: n luokka). Joten NOPEUS on vakio näissä yksiköissä; tässä tapauksessa nopeus = 100 pikseliä sekunnissa.

Tarkastuspiste: 452dc40

Tulojen käsittely

Hurraa! Laatikot putoavat alas ja katoavat, mutta et voi olla vuorovaikutuksessa niiden kanssa. Lisäämme tapa hävittää koskettavat laatikot. Sitä varten aiomme käyttää ikkunatapahtumaa. Ikkunaobjekti on saatavana jokaisessa Flutter-projektissa maailmanlaajuisesti, ja sillä on muutama hyödyllinen ominaisuus. Aiomme rekisteröidä päämenetelmällä onPointerDataPacket-tapahtuman, eli kun käyttäjä napauttaa näyttöä:

Otamme vain napsautuksen (x, y) -koordinaatin ja välitämme sen suoraan pelillemme. tällä tavalla peli pystyy käsittelemään napsautusta huolehtimatta tapahtumien yksityiskohdista.

Jotta asiat olisivat mielenkiintoisempia, tarkistakaamme myös Peli-luokan luettelo laatikoista yhden luettelon sijasta. Jälkeenpäin, sitä me haluamme. Korvaamme renderointi- ja päivitysmenetelmät forEach -laatikoilla, ja uudesta syöttötavasta tulee:

Tarkastuspiste: 364a6c2

Monien spritien renderointi

Tässä on mainittava yksi tärkeä kohta, ja se koskee renderöintimenetelmää. Kun tarjoamme laatikon, kankaan tila käännetään ja pyörii mielivaltaisesti piirtämisen mahdollistamiseksi. Koska aiomme piirtää useita laatikoita, meidän täytyy nollata kangas kunkin piirtämän välillä. Se tehdään tallennusmenetelmillä, jotka tallentavat nykyisen tilan ja palauttavat, joka palauttaa aiemmin tallennetun tilan poistamalla sen.

Tämä on tärkeä huomautus, koska se on lähde monille outoille virheille. Ehkä meidän pitäisi tehdä se automaattisesti jokaisessa renderöinnissä? En tiedä, mitä luulet?

Nyt haluamme lisää laatikoita! Kuinka se tehdään? No, päivitysmenetelmä voi olla ajastin. Joten haluamme uuden laatikon lisäämisen luetteloon (kuteutunut) joka sekunti. Joten loimme toisen muuttujan peliluokkaan kerätäksesi delta-ajat (t) jokaisesta päivityspuhelusta. Kun se ylittää yhden, se nollataan ja uusi laatikko kutee:

Älä unohda pitää edellistä päivitystä, joten laatikot eivät lopeta putoamista. Muutamme myös nopeuden 250 pikseliin sekunnissa tehdäksemme asioista hieman mielenkiintoisempia.

Tarkastuspiste: 3932372

Animaatioiden tuottaminen

Tämän pitäisi olla GIF, eikö niin? Pyrimme parantamaan tämän opetusohjelman näyttökuvien ja GIF-asetusten määritystä!

Nyt tiedämme Spriten käsittelyn ja renderoinnin perusteet. Siirrymme seuraavaan vaiheeseen: Räjähdykset! Mikä peli on hyvä ilman heitä? Räjähdys on erilainen peto, koska siinä on animaatio. Animaatiot liekissä tehdään yksinkertaisesti renderoimalla erilaisia ​​asioita nykyisen rastiin mukaan. Samoin kuin lisäsimme käsintehdyn ajastimen kuteviin laatikoihin, lisäämme elinajan ominaisuuden jokaiseen räjähdykseen. Räjähdystä ei myöskään peritä SpriteComponentilta, sillä viimeksi mainitussa voi olla vain yksi Sprite. Aiomme jatkaa superluokkaa, PositionComponent, ja toteuttaa renderointi Flame.image.load-sovelluksella.

Koska jokaisessa räjähdyksessä on paljon kehyksiä ja ne on piirrettävä reagoivasti, aiomme ladata jokaisen kehyksen esikatselulle kerran ja tallentaa staattiseen muuttujaan räjähdysluokassa; niin kuin:

Huomaa, että lataamme jokaisen seitsemästä animaatiokehyksestä järjestyksessä. Sitten teemme renderöintimenetelmässä yksinkertaisen logiikan päättääksesi mitä kehyksen piirtää:

Huomaa, että piirrämme 'käsin', käyttämällä drawImageRect-tapaa, kuten aiemmin selitettiin. Tämä koodi on samanlainen kuin mitä SpriteComponent tekee konepellin alla. Huomaa myös, että jos kuvaa ei ole taulukossa, mitään ei piirretä - joten TIME sekunnin kuluttua (asetamme sen arvoksi 0,75 tai 750 ms) mitään ei anneta.

Se on hyvä ja hyvä, mutta emme halua pilata räjähdysjoukkoamme räjähtäneillä räjähdyksillä, joten lisäämme myös tuhoamismenetelmän (), joka palauttaa käyttöiän perusteella, olisiko meidän tuhottava räjähdyskohde.

Lopuksi päivitämme pelimme, lisäämällä räjähdysluettelon, renderoimalla ne renderöintimenetelmällä ja päivittämällä sitten päivitysmenetelmällä. Ne on päivitettävä eliniän lisäämiseksi. Käytämme myös tätä aikaa reagoidakseen siihen, mikä oli aiemmin Game.update-menetelmässä, ts. Saa laatikot putoamaan, olemaan Crate.update-menetelmän sisällä, koska se on laatikon vastuulla. Nyt pelin päivitys vain delegoi toisille. Lopuksi, päivityksessä meidän on poistettava luettelosta se, mikä on tuhottu. Tätä varten Lista tarjoaa erittäin hyödyllisen menetelmän, poista missä:

Käytimme sitä jo syöttömenetelmässä ruutujen poistamiseksi, joita kosketettiin taulukosta. Siellä myös syntyy räjähdys.

Katso lisätietoja tarkistuspisteestä.

Tarkastuspiste: d8c30ad

Äänen toistaminen

Seuraavassa sitoutumisessa toistamme vihdoin ääntä! Tätä varten sinun on lisättävä tiedosto omaisuuskansioon, omaisuuden / äänen /. Sen on oltava MP3- tai OGG-tiedosto. Suorita sitten missä tahansa koodissasi:

Missä tiedostonimi.mp3 on sisällä olevan tiedoston nimi. Meidän tapauksessamme soitamme räjähdys.mp3-äänen napsauttamalla ruutua.

Aloitetaan lisäksi välimerkkien myöntäminen. Lisäämme pistemuuttujan pitääksesi nykyisen pistemäärän. Se alkaa nollalla; saamme 10 pistettä laatikkoa napsautettaessa ja häviämme 20, kun laatikko osui maahan.

Meillä on nyt velvollisuus käsitellä pakenevia laatikoita. Perustuu siihen, mitä teimme räjähdysluokalle, lisäämme hävitysmenetelmän laatikkoon, joka palauttaa, ovatko ne näytön ulkopuolella. Tästä on tulossa malli! Jos tuhotaan, poistamme ryhmästä ja säädämme pisteitä.

Toistaiseksi pisteytys toimii, mutta sitä ei näytetä missään; se tulee pian.

Ääni ei toimi tässä seuraavassa tarkistuspisteessä, koska unohdin lisätä tiedostot ja laittaa ne pubspec.yaml-tiedostoon; se on tehty seuraavassa sitoutumisessa.

Tarkastuspiste: 43a7570

Nyt haluamme lisää ääniä! Äänipelaajien (huom. S. Lib), jonka liekki käyttää, avulla voit soittaa useita ääniä kerralla, kuten olet jo huomannut, jos menit napsauttamalla vimmaa, mutta käytämme sitä nyt etumme, soittamalla missääni, kun ruutu osuu maahan (tuhota laatikon menetelmä) ja taustamusiikki.

Soitaksesi taustamusiikkia silmukalla, käytä silmukkamenetelmää, joka toimii kuten ennenkin:

Tässä sitoumuksessa korjaamme myös laatikoiden tuhoamisolosuhteet, jotka jäimme huomiotta edellisessä sitoumuksessa (koska ei ollut mitään tietävää, nyt on ääni).

Tarkastuspiste: f575150

Tekstin renderointi

Nyt kun meillä on kaikki haluamamme ääni (tausta, musiikki, ääniefektit, MP3, OGG, silmukka, samanaikaisesti), siirrytään tekstin renderointiin. Meidän täytyy nähdä se pistemäärä lopulta. Tapa, jolla tämä tehdään 'käsin', on luoda kappale-esine ja käyttää piirtoalustan drawParagraph-kuvaa. Se vaatii paljon määrityksiä ja on melko hämmentävä sovellusliittymä, mutta voidaan suorittaa näin:

Tarkastuspiste: e09221e

Tämä on piirretty oletusfonttiin, ja voit käyttää fontFamily-ominaisuutta määrittämään toisen yhteisen järjestelmäfontin; vaikka luultavasti peliin haluat lisätä mukautetun.

Joten menin sivulle 1001fonts.com ja sain tämän melko kaupallisen ilmaisen Halo-fontin TTF-muodossa. Pudota tiedosto vain omaisuuteen / fontteihin, mutta nyt se on tuotava eri tavalla pubspec.yaml-tiedostossa. Yhden lisälaitteen lisäämisen sijasta on oma fonttitunniste, jota kommentoidaan oletuksena täydellisin ohjein kirjasinten lisäämisestä. Joten anna sille nimi ja tee jotain kuten:

Tämä ylimääräinen abstraktiokerros on itse Flutterista ja antaa sinun lisätä useita tiedostoja samaan kirjasimeen (lihavoitujen, suurempien kokojen määrittelemiseksi jne.). Nyt, takaisin kappaleeseemme, lisäämme vain ominaisuuden fontFamily: 'Halo' TextStyle-rakentajaan.

Suorita ja näet melko Halo-kirjasimen!

Tarkastuspiste: 3155bda

Tämä kuvattu menetelmä antaa sinulle enemmän hallintaa, jos haluat esimerkiksi useita tyylejä samassa kappaleessa. Mutta jos haluat, kuten tässä tapauksessa, yhden tyylisen yksinkertaisen kappaleen, käytä sitä vain Flame.util.text-apulaitteella:

Tämä yksi rivi korvaa edelliset 4 ja paljastaa tärkeimmät ominaisuudet. Teksti (ensimmäinen argumentti) vaaditaan, ja kaikki muut ovat valinnaisia, järkevillä oletusarvoilla.

Värien suhteen käytämme taas Colors.white-apulaitetta, mutta voimme käyttää myös uutta väriä (0xFFFFFFFF), jos haluat tietyn värin.

Tarkastuspiste: 952a9df

Ja siinä se on! Täydellinen peli sprite-renderoinnilla, tekstin renderoinnilla, äänellä, pelisilmukalla, tapahtumilla ja valtionhallinnalla.

julkaisu

Onko pelisi valmis julkaisuun?

Seuraa vain näitä muutamia yksinkertaisia ​​vaiheita Flutter-opetusohjelmasta.

Ne ovat kaikki melko yksinkertaisia, kuten näet viimeisessä tarkistuspisteessä, lukuun ottamatta Kuvakkeet-osaa, joka saattaa aiheuttaa päänsärkyä. Suositukseni on luoda iso (512 tai 1024 px) versio kuvakkeestasi ja luoda Make App Icon -verkkosivustolla zip, jossa on kaikki tarvitsemasi (iOS ja Android).

Tarkastuspiste: 2974f29

Mitä muuta?

Nautitko liekistä? Jos sinulla on ehdotuksia, virheitä, kysymyksiä, ominaisuuspyyntöjä tai jotain, ota rohkeasti yhteyttä minuun!

Haluatko parantaa peliäsi ja oppia lisää? Entä palvelimen lisääminen Firebase- ja Google Sign In -sovelluksilla? Entä mainosten sijoittaminen? Entä päävalikon ja useiden näyttöjen asettaminen?

Tietenkin on paljon parannettavaa - tämä on vain esimerkkipeli. Mutta sen olisi pitänyt antaa perusidea pelien kehityksen ydinkonsepteista Flutterilla (liekin kanssa tai ilman).

Toivottavasti kaikki nauttivat siitä!

Alun perin julkaistu GitHubissa.