Visaptveroša apmācība par liesmu (vai kā padarīt spēles ar plandīšanos)

Ievads

Sveiki visiem! Es esmu Luan, un laipni lūdzam šajā pirmajā visaptverošajā Flame apmācībā.

Flame ir minimālisma spēles Flutter spēles dzinējs, kas nodrošina dažus moduļus, lai izveidotu uz audekla balstītu spēli.

Šajā apmācībā mēs izveidosim ļoti vienkāršu spēli, kurā kastes kritīs un mērķis ir tās iznīcināt, pirms tās nonāks ekrāna apakšdaļā.

Šādi izskatīsies spēle

Jūs pats varat pārbaudīt spēli, lai uzzinātu, ko mēs gatavojamies instalēt šo APK vai instalēt to no Play veikala.

Tas ļaus mums aptvert visas iespējas, ko nodrošina ietvars, un parādīs, kā veikt visvienkāršākās darbības: atveidošanu, rakstus, audio, tekstu, animācijas un daudz ko citu.

Kāpēc mēs tomēr izvēlējāmies šo spēli? Papildus tam, ka ietvara izpēte ir ļoti vienkārša, taču pilnīga, ir arī labs faktors, ka mums ir resursi, lai to izdarītu!

Šai spēlei mēs izmantosim šādus resursus: viens crate sprite, viens sprādziena sprite (ar animāciju), sprādziena skaņa, 'miss' skaņa (ja lodziņš nav trāpīts), fona mūzika un arī skaists fonts rezultāta atveidošanai.

Ir grūti atrast internetā pieejamus labus resursus, taču šajā lieliskajā vietnē mēs atradām visu (izņemot fontu). Tie ir patiešām lieliski, absolūti ieteicams.

Pašlaik sprite lapas netiek atbalstītas, tāpēc, pirmkārt, mums visi resursi jāpārveido piemērotos formātos. Turklāt mums ir jāpārvērš viss audio MP3 (tiek atbalstīts arī OGG; WAV nav). Tā kā viss ir izdarīts, šeit varat lejupielādēt paketi ar visu nepieciešamo, kas jums būs vajadzīgs resursiem.

Tāpat vērts pieminēt, ka viss šeit aprakstītais ir pilnībā funkcionējoša versija GitHub. Jūs vienmēr varat ielūkoties, ja rodas šaubas. Arī piemērs tika izveidots, precīzi izpildot šīs darbības, un veicot biežas saistības kā momentuzņēmumus. Visā apmācībā es sasaistīšu īpašās saistības, kas veic krātuves izveidi ar attiecīgo posmu. Tas ļaus jums izveidot kontrolpunktus un pārlūkot veco kodu, lai redzētu visu, kas nebija skaidrs.

Pēdējā lieta; Jūs varat pārbaudīt pilnu Flame dokumentāciju šeit. Ja jums ir kādi jautājumi, ieteikumi, kļūdas, droši atveriet problēmu vai sazinieties ar mani.

Bez tam jums būs jāinstalē arī Flutter un Dart. Ja tas jums ir piemērots, jums var būt arī IntelliJ IDEA, kas ir ļoti laba vieta koda rakstīšanai. Lai instalētu šos materiālus, varat pārbaudīt, cik daudz mācību materiālu tur ir, piemēram, šo.

Pamati

Tāpēc pagaidām es pieņemu, ka jums viss ir gatavs. Tātad, vienkārši izpildiet šo un atveriet to!

Pirmais, kas jums jādara, ir pievienot atkarību no liesmas. Dodieties uz savu pubspec.yaml failu un pārliecinieties, ka atkarību atslēga norāda liesmu:

Šeit mēs izmantojam jaunāko versiju 0.5.0, taču varat arī izvēlēties jaunu, ja tāda ir pieejama.

Tagad jūsu main.dart failā jau ir daudz lietu: “galvenā” metode, kas ir jāsaglabā; un sekojošs izsaukums uz runApp metodi. Šajā metodē tiek izmantoti logrīki un citi plandīšanās komponenti, kas tiek izmantoti lietotņu ekrānu veidošanā. Tā kā mēs veidojam spēli, mēs uzzīmēsim visu uz audekla un neizmantojam šos komponentus; tāpēc izvelciet to visu ārā.

Mūsu galvenā metode tagad ir tukša, un mēs pievienosim divas lietas; Pirmkārt, daži konfigurācija:

Imports flame.dart ļauj piekļūt statiskās Flame klasei, kas ir tikai turētājs vairākām citām noderīgām klasēm. Vēl vairāk mēs to izmantosim vēlāk. Pagaidām šajā Flame klasē mēs saucam divas metodes.

Pēdējais ir pašsaprotams, tas atspējo daļu reģistrēšanas no audio atskaņotāju spraudņa. Tagad drīz pievienosim spēlei audio, un, ja tā nedarbosies, tas jums ir jā komentē, lai novērstu traucējumus. Bet mēs tur nonāksim galu galā.

Pirmā rinda ir sarežģītāka. Būtībā dažas svarīgas Flutter funkcionalitātes nav, jo mēs neizmantojam runApp metodi. Šis enableEvents zvans nedaudz novērš risinājumu, lai iegūtu visu, kas ir nepieciešams katrai lietojumprogrammai, neizmantojot logrīkus.

Visbeidzot, mums jāsāk sava spēle. Lai to izdarītu, mēs importēšanas sarakstam pievienosim vēl vienu klasi - Game klasi. Šī klase nodrošina abstrakciju, kas nepieciešama, lai izveidotu jebkuru spēli: spēles cilpu. Tam jābūt apakšklasificētam, lai jums būtu jāievieš jebkuras spēles pamats: atjaunināšanas metode, kas tiek izsaukta vienmēr, kad tā ir ērta, un kas prasa laiku, kas pagājis kopš pēdējās atjaunināšanas, un renderēšanas metode, kurai jāzina, kā uzzīmēt pašreizējais spēles stāvoklis. Cilpas iekšējā darbība ir atstāta spēles klasei, lai tā varētu to atrisināt (jūs varat to apskatīt, protams, tas ir ļoti vienkārši), un jums vienkārši jāzvana sākumam, lai sāktu.

Kontrolpunkts: 599f809

Pašlaik apmetums neko nedara, tāpēc, ja to palaižat, tam vajadzētu darboties, bet jums vajadzētu dot melnu ekrānu. Saldi! Tātad, lai sāktu zīmēt mūsu lietotni, mēs saņēmām funkcionālu lietotni bez logrīkiem un plauktiņa, kā arī tukšu audeklu.

Formu atveidošana

Un kā notiek zīmēšana? Uzzīmēsim vienkāršu taisnstūri, lai to redzētu darbībā. Pievienojiet šo savai atveidošanas metodei:

Kā redzat, šeit mēs definējam taisnstūri, pamatojoties uz ekrāna pozīcijām. Šis attēls parāda, kā ir orientēti noteikumi. Būtībā izcelsme ir augšējā kreisajā stūrī, un ass palielinās pa labi un uz leju.

Turklāt ņemiet vērā, ka lielākajai daļai zīmēšanas metožu ir nepieciešama krāsa. Paint nav tikai viena krāsa, bet tā var būt arī Degradè vai kāda cita faktūra. Parasti jūs vēlaties vai nu vienkrāsainu krāsu, vai arī dodieties tieši uz Sprite. Tātad mēs krāsu krāsā iestatījām tikai uz krāsu.

Krāsa apzīmē vienu ARGB krāsu; jūs to izveidojat ar veselu skaitli, kuru varat pierakstīt ar sešpadsmit zīmēm, lai būtu vieglāk lasīt; tas ir formātā A (alfa, caurspīdīgums, parasti 0xFF) un pēc tam divi cipari R, G un B šādā secībā.

Ir arī nosaukto krāsu kolekcija; tas tomēr ir materiāla iesaiņojuma iekšpusē. Tikai jāuzmanās importēt tikai moduli Krāsas, lai nejauši neizmantotu kaut ko citu no materiāla paketes.

Tātad, lieliski, tagad mums ir kvadrāts!

Kontrolpunkts: 4eff3bf

Mēs arī zinām, kā darbojas lineāli, bet mēs nezinām ekrāna izmērus! Kā bez šīs informācijas mēs kaut ko uzzīmēsim pārējos trīs stūros? Nebaidieties, jo Flame ir metode, kā iegūt ekrāna faktisko izmēru (tas ir tāpēc, ka ap to ir dokumentēta problēma.

Būtībā async metode

Ņemiet vērā, ka gaidāmo atslēgvārdu, tāpat kā JavaScript, var izmantot tikai async funkcijā, tāpēc pārliecinieties, ka esat izveidojis galveno async (Flutter nebūs vienalga).

Nākamais kontrolpunkts vienreiz nolasīs izmērus galvenajā metodē un glabās tos mūsu spēles klasē, jo mums tie būs nepieciešami atkārtoti.

Kontrolpunkts: a1f9df3

Izciršanas sprites

Visbeidzot, mēs zinām, kā uzzīmēt jebkuru formu jebkur ekrānā. Bet mēs vēlamies sprites! Nākamais kontrolpunkts pievieno dažus aktīvus, kurus mēs izmantosim, atbilstošajā mapē:

Kontrolpunkts: 92ebfd9

Nākamais izdara vienu būtisku lietu, kuru nevar aizmirst: pievienojiet visu savam pubsepc.yaml failam. Kad jūsu kods tiek veidots, Dart tikai apkopos tur norādītos resursus.

Kontrolpunkts cf5975f

Visbeidzot, mēs esam gatavi uzzīmēt savu sprite. Pamata veids, kā Flame to ļauj, ir pakļaut Flame.images.load ('ceļš no attēlu mapes') metodei, kas atdod solījumu par ielādēto attēlu, kuru pēc tam var uzzīmēt ar metodi canvas.drawImage.

Tomēr kastes zīmēšanas gadījumā to ir ļoti vienkārši izdarīt, jo mēs varam izmantot SpriteComponent klasi, piemēram:

Abstraktā komponentu klase ir saskarne ar divām metodēm, renderēšanu un atjaunināšanu, tāpat kā mūsu spēle. Ideja ir tāda, ka spēli var veidot komponenti, kuru renderēšanas un atjaunināšanas metodes tiek izmantotas, izmantojot spēles metodes. SpriteComponent ir ieviešana, kas piešķir spritei, ņemot vērā tā vārdu un lielumu (kvadrāts vai taisnstūris), pozīciju (x, y) un griešanās leņķi. Tas attiecīgi sašaurinās vai paplašinās attēlu, lai tas atbilstu vēlamajam izmēram.

Šajā gadījumā mēs ielādējam failu “crate.png”, kam jābūt aktīvu / attēlu mapē, un tam ir Crate klase, kas ievelk kastes ar izmēru 128x128 pikseļi ar pagrieziena leņķi 0.

Pēc tam mēs pievienojam Crate īpašību spēlei, ievietojam to ekrāna augšdaļā, horizontāli centrēti un atveidojam tās spēles cilpā:

Tas padarīs mūsu Crate! Satriecošs! Kods ir diezgan kodolīgs un viegli lasāms.

Kontrolpunkts 7603ca4

Stāvokļa atjaunināšana spēles cilpā

Mūsu crate ir viss, bet apturēta gaisā. Mēs vēlamies to pārvietot! Katra kaste kritīsies ar nemainīgu ātrumu uz leju. Tas jādara mūsu atjaunināšanas metodē; vienkārši mainiet mūsu rīcībā esošā vienīgā kastes Y pozīciju:

Šī metode prasa laiku (sekundēs), kas pagāja no pēdējā atjauninājuma. Parasti tas būs ļoti mazs (10 ms). Tātad ĀTRUMS ir konstante tajās vienībās; mūsu gadījumā ĀTRUMS = 100 pikseļi sekundē.

Kontrolpunkts: 452dc40

Apstrādes ievade

Urā! Kastes nokrīt un pazūd, bet jūs nevarat ar tām mijiedarboties. Pievienosim metodi, kā iznīcināt mums pieskartās kastes. Šim nolūkam mēs izmantosim loga notikumu. Loga objekts ir pieejams visos Flutter projektos visā pasaulē, un tam ir dažas noderīgas īpašības. Mēs reģistrēsimies galvenajā metodē onPointerDataPacket notikumu, tas ir, kad lietotājs piesit ekrānam:

Mēs vienkārši iegūstam (x, y) klikšķa koordinātu un nododam to tieši mūsu spēlei; tādā veidā spēle var apstrādāt klikšķi, neuztraucoties par notikumu detaļām.

Lai padarītu lietas interesantākas, pārdomājiet arī Game klasi, lai tā vietā būtu viena piedāvājuma saraksts. Pēc tam to mēs vēlamies. Mēs aizstājam renderēšanas un atjaunināšanas metodes ar forEach over Crates, un jaunā ievades metode kļūst:

Kontrolpunkts: 364a6c2

Vairāku spritu atveidošana

Šeit ir jāpiemin viens būtisks punkts, un tas attiecas uz apmetuma metodi. Kad mēs veidojam crate, audekla stāvoklis tiek tulkots un patvaļīgi pagriezts, lai iespējotu zīmēšanu. Tā kā mēs gatavojamies uzzīmēt vairākas kastes, audekls ir jāiestata no jauna starp katru izvilkto. Tas tiek veikts ar saglabāšanas metodēm, kas saglabā pašreizējo stāvokli un atjaunošanu, kas atjauno iepriekš saglabāto stāvokli, izdzēšot to.

Šī ir svarīga piezīme, jo tā ir daudzu dīvainu kļūdu avots. Varbūt mums tas jādara automātiski katrā apmetumā? Es nezinu, ko tu domā?

Tagad mēs vēlamies vairāk kastu! Kā to izdarīt? Nu, atjaunināšanas metode var būt mūsu taimeris. Tāpēc mēs vēlamies, lai katru sekundi sarakstam tiktu pievienots jauns crate. Tātad Game klasē mēs izveidojām citu mainīgo, lai uzkrātu delta laikus (t) no katra atjaunināšanas zvana. Kad tas kļūst vairāk par 1, tas tiek atiestatīts un radās jauns crate:

Neaizmirstiet saglabāt iepriekšējo atjauninājumu, tāpēc kastes nepārstāj krist. Mēs arī mainām ātrumu uz 250 pikseļiem sekundē, lai padarītu lietas nedaudz interesantākas.

Kontrolpunkts: 3932372

Animāciju atveidošana

Tam vajadzētu būt GIF, vai ne? Mēs strādājam pie šīs apmācības labāku ekrānuzņēmumu un GIF iestatīšanas!

Tagad mēs zinām Sprite apstrādes un atveidošanas pamatus. Pāriesim pie nākamā soļa: sprādzieni! Kāda spēle ir laba bez viņiem? Sprādziens ir cita veida zvērs, jo tajā ir animācija. Animācijas Liesmā tiek veiktas, vienkārši padarot renderēšanu dažādas lietas atbilstoši pašreizējai ķeksītei. Tādā pašā veidā mēs pievienojām rokām darinātu taimeri nārsta kārbām, un mēs katrai eksplozijai pievienosim dzīves laiku. Arī Explosion netiks mantots no SpriteComponent, jo pēdējam var būt tikai viens Sprite. Mēs paplašināsim superklases, PositionComponent, un ieviesīsim renderēšanu ar Flame.image.load.

Tā kā katram sprādzienam ir daudz rāmju un tie ir jāiepūš atsaucīgi, mēs katru rāmi iepriekš ielādēsim un saglabāsim statiskajā mainīgajā lielumā Eksplozijas klase; piemēram, tā:

Ņemiet vērā, ka katrs no 7 animācijas kadriem tiek ielādēts secībā. Pēc tam renderēšanas metodē mēs izmantojam vienkāršu loģiku, lai izlemtu, kuru rāmi uzzīmēt:

Ņemiet vērā, ka mēs zīmējam “ar rokām”, izmantojot drawImageRect, kā paskaidrots iepriekš. Šis kods ir līdzīgs tam, ko SpriteComponent dara zem pārsega. Ņemiet vērā arī to, ka, ja attēls neatrodas masīvā, nekas netiek uzzīmēts - pēc TIME sekundēm (mēs to iestatījām uz 0.75 vai 750 ms) nekas netiks parādīts.

Tas ir labi un labi, bet mēs nevēlamies turpināt piesārņot mūsu sprādzienu masīvu ar eksplodētiem sprādzieniem, tāpēc mēs pievienojam arī iznīcināšanas () metodi, kas, pamatojoties uz dzīves laiku, atgriež, vai mums vajadzētu iznīcināt sprādziena priekšmetu.

Visbeidzot, mēs atjauninām mūsu spēli, pievienojot eksplozijas sarakstu, atveidojot tos renderēšanas metodē un pēc tam atjauninot atjaunināšanas metodi. Tie ir jāatjaunina, lai palielinātu to darbības laiku. Mēs arī šo laiku izmantojam, lai reaģētu uz to, kas iepriekš tika izmantots metodē Game.update, t.i., liek lodziņiem nokrist, lai būtu Crate.update metodes iekšpusē, jo par to ir atbildīgs kaste. Tagad spēles atjauninājumu deleģē tikai citiem. Visbeidzot, atjauninājumā mums no saraksta jāsvītro tas, kas ir iznīcināts. Šim nolūkam saraksts nodrošina ļoti noderīgu metodi.

Mēs to jau izmantojām ievades metodē, lai no masīva noņemtu rūtiņas, kurām pieskārās. Ir arī tas, kur mēs izveidosim sprādzienu.

Apskatiet kontrolpunktu, lai iegūtu sīkāku informāciju.

Kontrolpunkts: d8c30ad

Audio atskaņošana

Nākamajā solī mēs beidzot gatavojamies atskaņot audio! Lai to izdarītu, fails jāpievieno aktīvu mapei aktīvu / audio / iekšpusē. Tam jābūt MP3 vai OGG failam. Pēc tam visur, kur atrodams kods, palaidiet:

Kur filename.mp3 ir tajā esošā faila nosaukums. Mūsu gadījumā mēs atskaņosim sprādzienu.mp3 skaņu, kad noklikšķināsim lodziņā.

Turklāt sāksim piešķirt pieturzīmes. Mēs pievienojam punktu mainīgo, lai noturētu pašreizējo punktu skaitu. Tas sākas ar nulli; mēs iegūstam 10 punktus par katru lodziņu, kurā noklikšķināsim, un zaudēsim 20, kad kaste atsitās pret zemi.

Mums tagad ir pienākums rīkoties ar bēgošajām kastēm. Balstoties uz to, ko mēs izdarījām Explosion klasē, mēs pievienojam iznīcināšanas metodi Crate, kas atgriezīsies neatkarīgi no tā, vai tie ir ārpus ekrāna. Tas sāk kļūt par modeli! Ja iznīcina, mēs noņemam no masīva un pielāgojam punktus.

Pagaidām vērtēšana darbojas, taču tā nekur netiek rādīta; kas drīz notiks.

Šajā nākamajā kontrolpunktā audio nedarbosies, jo aizmirsu pievienot failus un ievietot tos pubspec.yaml; tas tiek darīts šādā saistībā.

Kontrolpunkts: 43a7570

Tagad mēs vēlamies vairāk skaņu! Audio atskaņotāji (atcerieties tos), ko izmanto Liesma, ļauj atskaņot vairākas skaņas vienlaikus, kā jūs jau varējāt pamanīt, ja noklikšķinājāt uz neprātu, bet tagad izmantosim to mūsu labā, atskaņojot garām skaņu, kad lodziņš nonāk zemē (iznīcina kastes metodi) un fona mūzika.

Lai atskaņotu fona mūziku ar cilpu, izmantojiet cilpas metodi, kas darbojas tāpat kā iepriekš:

Šajā apņemšanās mēs arī labojam krātuvju iznīcināšanas nosacījumu, kuru mēs nepadevām iepriekšējā apņemšanās laikā (jo nebija iespējas uzzināt, tagad ir pamatoti).

Kontrolpunkts: f575150

Teksta atveidošana

Tagad, kad mums ir viss nepieciešamais audio (fons, mūzika, skaņas efekti, MP3, OGG, cilpa, vienlaicīgi), ļaujieties teksta atveidošanai. Galu galā mums ir jāredz šis rādītājs. Veids, kā to var izdarīt “ar rokām”, ir izveidot rindkopas objektu un izmantot audekla drawParagraph. Tas prasa daudz konfigurācijas, un tas ir diezgan neskaidrs API, taču to var izpildīt šādi:

Kontrolpunkts: e09221e

Tas tiek novilkts noklusējuma fontā, un jūs varat izmantot īpašību fontFamily, lai norādītu citu parasto sistēmas fontu; lai gan, iespējams, savā spēlē vēlēsities pievienot pielāgotu.

Tāpēc es devos uz 1001fonts.com un ieguvu šo diezgan komerciālo bezmaksas Halo fontu kā TTF. Atkal vienkārši nometiet failu aktīvos / fontos, bet tagad tas ir jāimportē atšķirīgi failā pubspec.yaml. Tā vietā, lai pievienotu vēl vienu aktīvu, ir paredzēts fontu tags, kas pēc noklusējuma tiek komentēts ar pilnām instrukcijām par fontu pievienošanu. Piešķiriet tam vārdu un rīkojieties šādi:

Šis papildu abstrakcijas slānis ir izveidots pašā Flutter, un tas ļauj pievienot vairākus failus vienam fontam (lai definētu treknrakstu, lielākus izmērus utt.). Tagad, atgriežoties pie mūsu rindkopas, mēs vienkārši pievienojam īpašumam fontFamily: 'Halo' TextStyle konstruktoram.

Palaist, un jūs redzēsit diezgan Halo fontu!

Kontrolpunkts: 3155bda

Šī aprakstītā metode dos jums lielāku kontroli, ja, piemēram, vienā un tajā pašā rindkopā vēlaties izmantot vairākus stilus. Bet, ja vēlaties, piemēram, šajā gadījumā, vienkāršu rindkopu, izveidojiet to ar palīgu Flame.util.text:

Šī vienotā līnija aizstāj iepriekšējās 4 un atklāj vissvarīgākās funkcijas. Nepieciešams teksts (pirmais arguments), un visi pārējie nav obligāti, ar saprātīgām noklusējumiem.

Krāsai atkal tiek izmantots palīgs Colors.white, bet, ja vēlaties arī noteiktu krāsu, mēs varam izmantot arī jaunu Krāsa (0xFFFFFFFF).

Kontrolpunkts: 952a9df

Un tur jums tas ir! Pilnīga spēle ar sprite atveidošanu, teksta atveidošanu, audio, spēles cilpu, notikumiem un stāvokļa pārvaldību.

Atlaidiet

Vai jūsu spēle ir gatava izlaišanai?

Vienkārši izpildiet šos dažus vienkāršos soļus no Flutter apmācības.

Tie visi ir diezgan vienkārši, kā jūs varat redzēt šajā pēdējā kontrolpunktā, izņemot ikonu daļu, kas var radīt nedaudz galvassāpes. Mans ieteikums ir izveidot lielu (512 vai 1024 px) jūsu ikonas versiju un izmantot vietni Make App Icon, lai ģenerētu zip ar visu nepieciešamo (iOS un Android).

Kontrolpunkts: 2974f29

Kas vēl?

Vai jums patika Flame? Ja jums ir kādi ieteikumi, kļūdas, jautājumi, funkciju pieprasījumi vai kas cits, lūdzu, sazinieties ar mani!

Vai vēlaties uzlabot savu spēli un uzzināt vairāk? Kā būtu ar servera pievienošanu ar Firebase un Google pierakstīšanos? Kā būtu ar reklāmu ievietošanu? Kā būtu ar galvenās izvēlnes un vairāku ekrānu iestatīšanu?

Protams, ir daudz kas uzlabojams - tā ir tikai spēles spēle. Bet tam vajadzēja dot pamatideju par spēles attīstības pamatkoncepcijām ar Flutter (ar vai bez Flame).

Ceru, ka visiem patika!

Sākotnēji publicēts vietnē GitHub.