Izčrpna vadnica o plamenu (ali kako narediti igre s tresenjem)

Uvod

Pozdravljeni vsi skupaj! Jaz sem Luan in dobrodošli na tej prvi celoviti vadnici o plamenu.

Flame je minimalistični igralec igre Flutter, ki ponuja nekaj modulov za izdelavo igre na platnu.

V tej vadnici bomo ustvarili zelo preprosto igro, kjer bodo škatle padle in cilj je, da jih uničite, preden bodo zadele dno zaslona.

Tako bo izgledala igra

Lahko sami preverite igro, da vidite, kaj nameravamo namestiti ta APK ali pa ga namestite iz Trgovine Play.

To nam bo omogočilo, da pokrijemo vse funkcije, ki jih nudi ogrodje, in pokažemo, kako izvajati najosnovnejše operacije: upodabljanje, pisma, zvok, besedilo, animacije in drugo.

Zakaj smo izbrali to igro? Poleg tega, da je za raziskovanje ogrodja zelo preprost, vendar popoln, je en dober dejavnik tudi to, da imamo za to tudi vire!

Za to igro bomo uporabili naslednje vire: en zaboj sprite, en eksploziv v obliki eksplozije (z animacijo), zvok eksplozije, zvok 'miss' (kajti če škatlice ni zadeto), glasba v ozadju in tudi precej pisave za upodabljanje partiture.

Na internetu je težko najti dobre vire, ki so komercialno dostopni, vendar smo na tem super spletnem mestu našli vse (razen pisave). Res so odlični, vsekakor priporočljivo.

Zaenkrat sprite liste niso podprte, zato moramo najprej vse vire pretvoriti v ustrezne formate. Prav tako moramo pretvoriti ves zvok za MP3 (podpira se tudi OGG; WAV ni). Ko je vse končano, lahko tukaj naložite sveženj z vsem, kar boste potrebovali.

Omeniti velja tudi, da je vse, kar je opisano tukaj, kot popolnoma funkcionalna popolna različica zavezana na GitHubu. Vedno lahko pogledate, ko ste v dvomih. Primer je bil ustvarjen po teh natančnih korakih in ob snemanju pogostih zavez. Skozi celotno vadnico bom povezal posebne zaveze, ki shranijo shrambo v zadevno fazo. Tako boste lahko naredili kontrolne točke in brskali po stari kodi, če želite videti vse, kar ni bilo jasno.

Še zadnja stvar; si lahko ogledate celotno dokumentacijo za Plamen tukaj. Če imate kakršna koli vprašanja, predloge, napake, odprite težavo ali me kontaktirajte.

Poleg tega boste potrebovali tudi Flutter in Dart. Če vam ustreza, lahko imate tudi IntelliJ IDEA, ki je zelo dober kraj za pisanje kode. Če želite namestiti te stvari, si lahko ogledate številne vaje, kot je ta.

Osnove

Zaenkrat bom predvideval, da imate vse pripravljeno. Torej, samo zaženite naslednje in ga odprite!

Prvo, kar morate storiti, je dodati odvisnost od plamena. Pojdite v svojo datoteko pubspec.yaml in se prepričajte, da ključ odvisnosti vsebuje plamen:

Tukaj uporabljamo najnovejšo različico, 0.5.0, lahko pa izberete tudi novo, če je na voljo.

Zdaj ima vaša datoteka main.dart že ogromno stvari: "glavna" metoda, ki jo je treba ohraniti; in poznejši klic metode runApp. Ta metoda jemlje pripomočke in druge komponente Flutter, ki se uporabljajo za izdelavo zaslonov aplikacij. Ker bomo igrali igro, bomo na platnu narisali vse in teh komponent ne bomo uporabljali; zato odstrani vse to.

Naša glavna metoda je zdaj prazna in dodali bomo dve stvari; najprej nekaj konfiguracije:

Uvoz flame.dart omogoča dostop do statičnega razreda Flame, ki je samo imetnik več uporabnih drugih razredov. Več tega bomo uporabili kasneje. Za zdaj v tem razredu Flame imenujemo dve metodi.

Zadnji je sam po sebi razumljiv, saj onemogoči del beleženja iz vtičnika za avdioplayer. Zdaj bomo v igro kmalu dodali zvok, in če ne deluje, morate to komentirati, če želite odpraviti težave. Ampak sčasoma bomo prišli tja.

Prva vrstica je bolj zapletena. V bistvu manjka nekaj ključnih funkcij Flutterja, ker ne uporabljamo metode runApp. Ta klic enableEvents nekoliko reši, da dobite tisto, kar je nujno za vsako aplikacijo, ne da bi pri tem potrebovali uporabo pripomočkov.

Končno moramo začeti svojo igro. Da bi to naredili, bomo na seznam uvozov dodali še en razred, razred Igre. Ta razred ponuja abstrakcijo, potrebno za ustvarjanje katere koli igre: igro zanke. Podklasirati mora biti tako, da boste morali izvajati osnovo katere koli igre: način posodobitve, ki se imenuje, kadar je to primerno, in traja čas, ki je minil od zadnje posodobitve, ter način upodabljanja, ki mora znati narisati trenutno stanje igre. Notranje delovanje zanke je za razrešitev razreda za igre ostalo (lahko pogledate, seveda je zelo preprosto), in preprosto morate poklicati za začetek, no, začeti.

Kontrolna točka: 599f809

Trenutno upodabljalec ne naredi ničesar, tako da, če ga zaženete, se mora zagnati, vendar vam daje črni zaslon. Sladko! Tako smo dobili funkcionalno aplikacijo brez pripomočkov in kaj podobnega ter prazno platno za začetek risanja naše aplikacije.

Oblika upodabljanja

In kako poteka risanje? Narišite preprost pravokotnik in si oglejte akcijo. V način upodabljanja dodajte naslednje:

Tu, kot vidite, določimo pravokotnik, ki temelji na položajih zaslona. Naslednja slika prikazuje usmerjanje pravil. V osnovi je izvor v zgornjem levem kotu, os pa se poveča v desno in navzdol.

Upoštevajte tudi, da večina načinov risanja vzame barvanje. Barva ni samo ena barva, ampak je lahko Degradè ali kakšna druga tekstura. Običajno bi si želeli trdno barvo ali šli naravnost na Sprite. Torej samo barvo znotraj barve nastavimo na primerek Color.

Barva predstavlja eno barvo ARGB; ustvarite ga s celim številom, ki ga lahko zapišete v šestnajsti za lažje branje; je v obliki A (alfa, preglednost, običajno 0xFF) in nato dve števki za R, G in B v tem vrstnem redu.

Obstaja tudi zbirka poimenovanih barv; vendar je znotraj materialnega paketa. Pazite le, da uvozite samo modul Colors, da ne bi slučajno uporabili česa drugega iz materialnega paketa.

Torej, super, zdaj imamo kvadrat!

Kontrolna točka: 4eff3bf

Vemo tudi, kako delujejo ravnila, vendar ne poznamo dimenzij zaslona! Kako bomo v teh treh kotih narisali nekaj brez teh podatkov? Ne bojte se, saj ima Flame način, kako ugotoviti dejansko dimenzijo zaslona (to je zato, ker je okoli tega dokumentirana težava.

V bistvu metoda asinhronizacije

Upoštevajte, da je mogoče ključno besedo čakati, tako kot v JavaScriptu, uporabiti samo v funkciji asinhronizacije, zato se prepričajte, da je vaša glavna async (Flutter ne bo vseeno)

Naslednja kontrolna točka bo v glavni metodi enkrat prejela dimenzije in jih shranila znotraj našega razreda igre, ker jih bomo potrebovali večkrat.

Kontrolna točka: a1f9df3

Kalivanje Sprites

Končno vemo, kako narisati poljubno obliko, kjer koli na zaslonu. Želimo pa sprites! Naslednja kontrolna točka doda nekaj sredstev, ki jih bomo uporabili, v ustrezno mapo sredstev:

Kontrolna točka: 92ebfd9

Naslednja pa naredi eno ključno stvar, ki je ne morete pozabiti: dodajte vse v svojo datoteko pubsepc.yaml. Ko bo vaša koda izdelana, bo Dart združeval le vire, ki ste jih tam določili.

Checkpoint cf5975f

Končno smo pripravljeni potegniti svoj sprite. Osnovni način, kako vam Flame omogoča, je, da izpostavite metodo Flame.images.load ("pot iz mape slik"), ki vrne obljubo za naloženo sliko, ki jo lahko nato narišete z metodo canvas.drawImage.

V primeru risanja gajbja je to zelo enostavno, saj lahko uporabimo razred SpriteComponent, kot je:

Razred abstraktnih komponent je vmesnik z dvema načinoma: upodabljanje in posodabljanje, tako kot naša igra. Ideja je ta, da je igra lahko sestavljena iz komponent, ki imajo metode prikazovanja in posodabljanja, imenovane znotraj igre. SpriteComponent je izvedba, s katero je sprite prikazan glede na njegovo ime in velikost (kvadratno ali pravokotno), položaj (x, y) in kot vrtenja. Sliko bo primerno skrčil ali razširil, da bo ustrezala želeni velikosti.

V tem primeru naložimo datoteko 'crate.png', ki mora biti v mapi sredstev / slik, in v razredu zabojnikov, ki nariše polja 128x128 slikovnih pik, z kotom vrtenja 0.

Nato v igro dodamo lastnost zaboj, jo postavimo na vrh zaslona, ​​centrirano vodoravno in jo prestavimo v našo igro:

Tako bo naš zaboj! Super! Koda je precej jedrnato in tudi enostavno berljiva.

Kontrolna točka 7603ca4

Stanje posodobitve v zanki igre

Naš zaboj je vse prej kot ustavljen v zraku. Želimo ga premakniti! Vsak zaboj bo padel s konstantno hitrostjo navzdol. To moramo storiti v naši metodi posodabljanja; samo spremenite položaj Y na enem zaboju, ki ga imamo:

Ta metoda potrebuje čas (v sekundah), ki je trajal od zadnje posodobitve. Običajno bo to zelo malo (vrstni red 10 ms). Torej je HITROST konstanta v teh enotah; v našem primeru SPEED = 100 slikovnih pik / sekundo.

Kontrolna točka: 452dc40

Ravnanje z vnosom

Ura! Zaboji padejo navzdol in izginejo, vendar z njimi ne morete komunicirati. Dodajmo metodo za uničenje zabojev, ki se jih dotaknemo. Za to bomo uporabili dogodek okna. Predmet okna je na voljo v vsakem projektu Flutter po vsem svetu in ima nekaj uporabnih lastnosti. Registrirali bomo v glavni metodi dogodek onPointerDataPacket, torej ko uporabnik dotakne zaslona:

Izvlečemo (x, y) koordinate klika in ga posredujemo naravnost naši igri; tako igra lahko prenese klik, ne da bi skrbela za podrobnosti o dogodkih.

Da bi stvari postale bolj zanimive, si privoščimo tudi novo kategorijo iger, da bi namesto enega napisali seznam zabojev. Če želimo, to je tisto, kar si želimo. Metode upodabljanja in posodabljanja nadomestimo z forEach nad zaboji in nov način vnosa postane:

Kontrolna točka: 364a6c2

Upodabljanje več duhov

Tu je treba omeniti eno ključno točko in to glede načina upodabljanja. Ko damo zaboj, stanje platna prevedemo in zasučemo poljubno, da omogočimo risanje. Ker bomo risali več gajb, moramo ponastaviti platno med vsakim narisanim. To je narejeno z metodami save, ki shrani trenutno stanje in obnovi, ki obnovi predhodno shranjeno stanje in ga izbriše.

To je pomembna pripomba, saj je vir številnih čudnih napak. Mogoče bi morali to storiti samodejno v vsakem upodabljanju? Ne vem, kaj misliš?

Zdaj želimo več zabojev! Kako to storiti? No, način posodobitve je lahko naš čas. Zato želimo, da se na seznam doda vsaka zaboj (sproži) vsako sekundo. Tako smo ustvarili še eno spremenljivko v razredu Game, da zberemo delta-krat (t) iz vsakega klica za posodobitev. Ko je več kot 1, se ponastavi in ​​zažene nov zaboj:

Ne pozabite obdržati prejšnje posodobitve, tako da zaboji ne bodo prenehali padati. Prav tako spremenimo hitrost na 250 slikovnih pik / sekundo, da postanejo stvari nekoliko bolj zanimive.

Kontrolna točka: 3932372

Upodabljanje animacij

To bi moral biti GIF, kajne? Za to vadbo delamo pri nastavitvi boljših posnetkov zaslona in GIF-jev!

Zdaj poznamo osnove ravnanja s sprite in upodabljanja. Pojdimo na naslednji korak: Eksplozije! Katera igra je dobra brez njih? Eksplozija je zver drugačne vrste, saj ima animacijo. Animacije v Plamenu se izvedejo preprosto tako, da se različne upodabljajo na upodabljanju glede na trenutno oznako. Na enak način, kot smo ročnim merilnikom dodali škatle za drstenje, bomo za vsako eksplozijo dodali lastnost lifeTime. Prav tako eksplozija ne bo podedovala od SpriteComponent, saj ima slednji lahko le en Sprite. Razširili bomo nadrazred, PositionComponent in izvedli upodabljanje z Flame.image.load.

Ker ima vsaka eksplozija veliko okvirjev in jih je treba pripraviti odzivno, bomo vsak okvir predhodno naložili enkrat in ga shranili v statično spremenljivko znotraj razreda eksplozije; tako:

Upoštevajte, da naložimo vsak svoj 7 okvirjev za animacijo, po vrstnem redu. Nato v načinu upodabljanja naredimo preprosto logiko, da se odločimo, kateri okvir bomo narisali:

Upoštevajte, da rišemo "ročno" z uporabo drawImageRect, kot je razloženo prej. Ta koda je podobna kot SpriteComponent pod pokrovom. Upoštevajte tudi, da če slike ni v matriki, se nič ne nariše - torej po TIME sekundah (nastavimo jo na 0,75 ali 750 ms), se nič ne upodobi.

To je dobro in dobro, vendar ne želimo še naprej onesnaževati svojega razpona eksplozij z eksplodiranimi eksplozijami, zato dodamo tudi metodo uničevanja (), ki vrne, na podlagi lifeTime, ali naj uničimo eksplozivni objekt.

Končno posodobimo našo igro, dodamo seznam eksplozij, jih upodobimo po načinu upodabljanja in posodobimo na način posodabljanja. Za povečanje življenjske dobe jih je treba posodobiti. Ta čas si vzamemo tudi za ponovno prilagajanje tega, kar je bilo prej v Game.update metodi, to pomeni, da polja padajo, da so znotraj metode Crate.update, ker je to odgovornost zaboja. Zdaj igra posodablja samo delegate drugim. Končno moramo v posodobitvi s seznama odstraniti, kar je bilo uničeno. Za to ponuja seznam zelo uporaben način, removeWhere:

To smo že uporabili pri načinu vnosa, da odstranimo polja, ki so se jih dotaknili iz matrike. Tam je tudi, kjer bomo ustvarili eksplozijo.

Za več podrobnosti si oglejte kontrolno točko.

Kontrolna točka: d8c30ad

Predvajanje zvoka

V naslednji zavezi bomo končno predvajali nekaj zvoka! Če želite to narediti, morate datoteko dodati v mapo sredstev, znotraj sredstev / zvoka /. To mora biti MP3 ali OGG datoteka. Nato kjer koli v kodi zaženite:

Kjer je ime datoteke.mp3 ime datoteke znotraj. V našem primeru bomo predvajali zvok eksplozije.mp3, ko kliknemo v polje.

Poleg tega začnimo podeljevati ločila. Dodamo spremenljivko točk, da zadrži trenutno število točk. Začne se z ničlo; dobimo 10 točk na klik, in izgubimo 20, ko je škatla udarila ob tla.

Zdaj imamo obveznost, da se ukvarjamo s pobegnimi škatlami. Glede na to, kar smo storili v razredu Explosion, dodamo metodo za uničenje zaboja, ki se bo vrnila, ali so zunaj zaslona. To začenja postajati vzorec! Če ga uničimo, odstranimo iz matrike in prilagodimo točke.

Za zdaj točkovanje deluje, vendar se ne prikazuje nikjer; to bo kmalu prišlo.

Zvok na tej naslednji kontrolni točki ne bo deloval, ker sem datoteke pozabil dodati in jih vstaviti v pubspec.yaml; to se stori v naslednjem dokumentu.

Kontrolna točka: 43a7570

Zdaj želimo še več zvokov! Zvočni predvajalniki (ne pozabite) lib, ki jih uporablja Plamen, vam omogočajo predvajanje več zvokov naenkrat, kot ste morda že opazili, če ste klikali blazno, zdaj pa to uporabimo v svojo korist, tako da predvajamo zgrešeni zvok, ko polje udari ob tla (uniči metodo zaboja) in glasbo v ozadju.

Za predvajanje glasbe v ozadju v zanki uporabite metodo zanke, ki deluje tako kot prej:

V tej zavezi popravimo tudi uničenje pogojev za zaboje, ki smo jih zamudili v prejšnji zavezi (ker ni bilo mogoče vedeti, zdaj je zvok).

Kontrolna točka: f575150

Besedilo upodabljanja

Zdaj, ko imamo vse zvoke, ki jih želimo (ozadje, glasba, zvočni efekti, MP3, OGG, zanka hkrati), pojdimo v upodabljanje besedila. Konec koncev moramo videti ta rezultat. Način, kako to storite "ročno", je ustvariti objekt odstavek in uporabiti risalni paragraf platna. Potrebna je veliko konfiguracije in precej zmedenega API-ja, vendar se lahko doseže tako:

Kontrolna točka: e09221e

Ta je narisan v privzeti pisavi in ​​lahko uporabite lastnost fontFamily, da določite drugačno skupno sistemsko pisavo; čeprav boste verjetno v svoji igri želeli dodati po meri.

Zato sem se napotil na 1001fonts.com in dobil to lepo komercialno brezplačno pisavo Halo kot TTF. Ponovno spustite datoteko v sredstva / pisave, zdaj pa jo morate v datoteko pubspec.yaml uvoziti drugače. Namesto dodajanja še enega sredstva obstaja posebna oznaka pisave, ki jo privzeto komentira s popolnimi navodili, kako dodati pisave. Torej, dodelite mu ime in naredite nekaj takega:

Ta dodatna abstrakcijska plast je iz samega Flutterja in vam omogoča, da dodate več datotek isti pisavi (za določitev krepkih, večjih velikosti itd.) Zdaj pa nazaj k našemu odstavku, le gradniku TextStyle konstruktor dodamo lastnost pisaveFamily: 'Halo'.

Zaženite in videli boste lepo pisavo Halo!

Kontrolna točka: 3155bda

Ta opisana metoda vam bo dala več nadzora, če želite na primer več stilov v istem odstavku. Če pa želite, tako kot v tem primeru, en sam oblikovan preprost odstavek, za njegovo ustvarjanje uporabite pomočnik Flame.util.text:

Ta ena vrstica nadomešča prejšnje 4 in izpostavi najpomembnejše lastnosti. Besedilo (prvi argument) je obvezno, vse ostalo pa je poljubno, z razumnimi privzetki.

Za barvo znova uporabljamo pomočnik Colors.white, lahko pa uporabimo tudi novo Color (0xFFFFFFFF), če želite določeno barvo.

Kontrolna točka: 952a9df

In tam ga imate! Popolna igra s sprite upodabljanjem, upodabljanjem besedila, zvokom, zanko igre, dogodki in upravljanjem države.

Izpustite

Ali je vaša igra pripravljena na izdajo?

Samo sledite tem nekaj preprostim korakom iz vaje Flutter.

Vsi so precej preprosti, kot lahko vidite na tej končni kontrolni točki, razen dela Icons, ki bi lahko povzročil nekoliko glavobola. Moje priporočilo je, da naredite veliko (512 ali 1024 px) različico svoje ikone in uporabite spletno mesto Make App Icon, da ustvarite zadrgo z vsem, kar potrebujete (iOS in Android).

Kontrolna točka: 2974f29

Kaj drugega?

Ste uživali v Plamenu? Če imate kakršne koli predloge, napake, vprašanja, zahteve po funkcijah ali kar koli drugega, me kontaktirajte!

Želite izboljšati svojo igro in izvedeti več? Kaj pa dodajanje strežnika s Firebase in Google Sign-om? Kaj pa dajanje oglasov? Kako je z nastavitvijo glavnega menija in več zaslonov?

Seveda je treba še veliko izboljšati - to je samo primer igre. Morala pa bi dati osnovno predstavo o temeljnih konceptih razvoja iger s Flutterjem (z ali brez Plamena).

Upam, da so vsi uživali!

Prvotno objavljeno na GitHubu.