Lag et Match-3-spill i Construct 2 Poeng, Match og Gravity

I den tidligere opplæringen integrerte vi et grunnleggende match-deteksjonssystem i vårt Match-3-spill. Mens vi er godt på vei til å ha et spillbart spill, er det fortsatt noen få viktige spillelementer vi trenger før vi virkelig kan ringe hva vi har et "spill". Denne artikkelen skal fokusere på å fylle ut noen av de manglende detaljene, og få oss mye nærmere til vårt endelige produkt.


Final Game Demo

Her er en demonstrasjon av spillet vi jobber med i denne serien:




1. Tildelende poeng

Vi skal dekke poeng før vi begynner å forbedre det matchende systemet, fordi det vil være mye lettere å se det første problemet i vårt nåværende matchende system hvis vi har et poengsystem implementert.

Poengsystemet i vårt spill skal være veldig enkelt, for hver blokk som brukes til å danne en gitt gruppe, vil spilleren motta 10 poeng. I en senere opplæring vil vi også legge til i et system som gjør at spilleren kan få flere poeng ved å koble sammen flere grupper, men for nå vil vi fokusere på å bare introdusere et enkelt poengsystem for spilleren.

Før vi begynner å redigere hendelsene, må vi legge til et poeng-display, så først gå til Layout 1 og gjør følgende:

  1. Sett inn en ny Sprite gjenstand.
    1. Åpne bildet Game Field Bilder / PartiturArea.png fra grafikkpakken.
    2. Lukk animasjonseditoren.
    3. Still posisjonen til 491, 383.
  2. Sett inn en ny Tekst gjenstand.
    1. Sett Font til Calibri, Fet, 22 bruker rullegardinmenyen.
    2. Sett Navn til ScoreText
    3. Sett Farge til Hvit eller 255, 255, 255
    4. Sett Stilling til 419, 398.
    5. Sett Størrelse til 200, 50.
    6. Sett Tekst til 0.

Layout 1 skal nå se slik ut:

Nå som vi har noe å fortelle spilleren hva poengteksten betyr, og et tekstobjekt for å vise spillerens poengsum med, kan vi fortsette å gi spilleren poeng. Gå til Event Sheet 1 og opprett en ny Global variabel.

Global Variable Name: "Score" Type = Nummerverdi = 0

Variabelen skal se slik ut:

Dette er variabelen vi vil endre når vi gir spilleren poeng. Deretter skal vi opprette en ny funksjon som, når den kalles, vil oppdage hvor mange blokker spilleren har passet inn i grupper, og gi dem riktig antall poeng.

Hendelse: Tilstand: Funksjon> På Funksjonsnavn = "GivePoints" Tilstand: System> For hvert objekt = Blokktilstand: Blokk> Er boolean instans variabel sett Instans Variable = IsMatched Action: System> Legg til Variabel = Poengverdi = 10 Handling: ScoreText > Angi tekst Tekst = Score

Koden din skal se slik ut:

Så, for å gjenta, ser dette arrangementet på hver enkelt blokk. Hver gang den finner en blokk som har IsMatched satt til ekte - som betyr at det er bekreftet å være en del av en gruppe - den gir spilleren 10 poeng for den Blokken, og oppdaterer poengteksten.

Hvis du tester spillet ditt på dette tidspunktet, vil det virke som om funksjonen ikke virker. Årsaken til dette er fordi vi ikke har faktisk kalt funksjonen hvor som helst i koden, slik at punktene aldri blir økt, og teksten blir aldri oppdatert. Gå til din FindMatches funksjon og legg til en ny handling til begynnelsen av den endelige underhendelsen for denne funksjonen.

Handling: Funksjon> Anropsfunksjon Navn = "GivePoints"

Din FindMatches funksjonen skal nå se slik ut:

Merk: Pass på at du har lagt til denne nye handlingen i begynnelsen av underarrangementet. Hvis du legger til denne handlingen til slutten, vil den ikke fungere siden alle de matchede blokkene vil bli ødelagt før GivePoints funksjon kalles. Dette betyr at når den søker etter de matchende blokkene, vil den ikke finne noen og så vil spilleren ikke motta noen poeng.

På dette tidspunktet kan du teste spillet ditt igjen, og du bør se oppdatering av poengteksten, og at spilleren mottar riktig antall poeng for hver kamp de lager.


2. Forbedre Match Detection

Nå som vi har poengsystemet i, vil jeg at du skal kjøre spillet, og opprett scenariet som vises nedenfor.


Bytt nå blokkene jeg har markert her, og se poengene dine for å se hvor mange poeng du får.


Når du dannet denne kampen, burde du ha sett at du fikk 50 poeng. Dette skyldes at poengsystemet for tiden gir spilleren 10 poeng for hver blokk som er merket som IsMatched, i motsetning til å gi spilleren 10 poeng for hver blokk Brukt i hver kamp, ​​som systemet jeg beskrev ovenfor.

Hvis punktsystemet fungerte riktig, ville det gi spilleren 60 poeng: 30 for den vertikale gruppen på tre blokker og 30 for den horisontale gruppen av tre blokker. Dette problemet stammer fra det faktum at kampsystemet ikke har noen måte å markere når en blokk er kombinert både horisontalt og vertikalt; det vet bare om blokken er i likhet med alt.

For å løse dette problemet skal vi først legge til to nye Instansvariabler til vårt Blokkobjekt, MatchedX og MatchedY.

Instansvariabel: Navn = MatchedX Type = Boolean Initial Value = Feil Instansvariabel: Navn = MatchedY Type = Boolean Initial Value = Falsk

Dine variabler skal se slik ut:


Disse variablene skal brukes sammen med IsMatched å fortelle systemet når Blokken er en del av horisontal eller X, grupper, og når Blokken er en del av vertikale, eller Y, grupper. Nå som vi har variablene, skal vi endre CheckMatches fungere slik at når den merker en blokk IsMatched fordi den fant en stor nok gruppe, vil den også merke den blokken som en del av en X- eller Y-gruppe, avhengig av om parameter 3 eller parameter 4 er 1.

Gå til CheckMatches funksjonen og erstatt originalen NumMatchesFound sjekk med disse to nye underhendelsene:

Sub-Event: Tilstand: System> Sammenlign to verdier Første verdi = Funksjon.Param (3) Sammenligning = Lige til andre verdi = 1 Tilstand: System> Sammenlign variabel variabel = NumMatchesFound Comparison = Større eller lik verdi = 3 Handling: Blokk> Sett Boolsk instansvariabel = IsMatched Value = True Action: Block> Angi boolsk instansvariabel = MatchedX Value = True sub-Event: Tilstand: System> Sammenligne to verdier Første verdi = Funksjon.Param (4) Sammenligning = Like til andre verdi = 1 Tilstand : System> Sammenlign variabel variabel = NumMatchesFound Comparison = Større eller lik verdi = 3 Handling: Blokk> Angi boolsk instans variabel = IsMatched Value = True Action: Block> Angi boolsk instans variabel = MatchedY Value = True

Din CheckMatches funksjonen skal nå se slik ut:


Så den nye versjonen av CheckMatches Fungerer på samme måte som den forrige, bortsett fra at den nå også sjekker for å se om Blokken ble funnet å være en kamp i en vertikal gruppe eller en horisontal gruppe, og merker Blokken tilsvarende med de nye variablene MatchedX og MatchedY.

Tildele ekstra poeng til blokker som passer to ganger

Nå som vi har en måte å bestemme når en blokk er matchet vertikalt, matches det horisontalt og matches i begge retninger, i motsetning til bare å vite at det er blitt matchet i en gruppe, må vi legge til en underhendelse til GivePoints funksjon som vil distribuere ytterligere 10 poeng for en blokk som har begge MatchedX og MatchedY satt til ekte.

Gå til GivePoints funksjon og legg til denne underhendelsen:

Sub-Event: Tilstand: Blokk> Er Boolean instans variabel sett Instans variabel = MatchedX Tilstand: Blokk> Er Boolean instans variabel sett Instans variabel = MatchedY Action: System> Legg til Variabel = Score Verdi = 10 Handling: Tekst> Angi tekst Verdi = Score

Din GivePoints funksjonen skal nå se slik ut:


Hvis du kjører spillet ditt og igjen lager scenariet jeg illustrert ovenfor, skal poenget ditt nå øke med 60 poeng.


3. legge til tyngdekraften

Nå som vi har et Points-system implementert, og vi har oppdatert det matchende systemet, skal vi begynne å forbedre et annet viktig aspekt av spillingen. Hvis du har brukt tid til å spille med spillet opp til dette punktet, vet du at et av de største problemene er at når Blokker ødelegges, skjer ingenting med blokkene over dem. Spesielt faller blokkene over tomme rom ikke for å fylle ut disse mellomrom.

Dette er fint i testene, men i den endelige versjonen ville det være skadelig for spillingen å forlate ting som de er, så det neste vi skal legge til er "tyngdekraften" som vil få blokkene til å falle og fylle ut tomme mellomrom når andre blokker ødelegges.

Måten vi skal implementere dette systemet på er faktisk ganske enkelt. Vi vil utføre en sjekk ved hjelp av Blokk> Overlapper ved forskyvning arrangement for å se om det er en blokk under blokken vi ser på. Hvis vi finner det ingen blokk, vil vi flytte blokken vi ser ned for å fylle ut det tomme rommet; ellers vil vi ikke gjøre noe.

For å gjøre dette arbeidet vil vi opprette en ny hendelse:

Hendelse: Tilstand: INVERT> Blokk> Overlapper mot offset Objekt = Blokk Offset X = 0 Offset Y = 8 Handling: Blokk> Flytt i vinkel Angle = 90 Avstand = (Blokk. Bredde + 2) / 2

Koden din skal se slik ut:


Hvis du kjører spillet på dette tidspunktet, vil du se at i det øyeblikket spillet begynner, faller alle blokkene av skjermen! Årsaken til dette er fordi vi ikke satte noe i koden for å fortelle det hvor "gulvet" av spillfeltet ville være.

Så i hovedsak ser blokkene på den nederste raden at det ikke er noen blokker under dem og faller tilsvarende. Så, når den laveste raden av Blokker har falt, ser den neste laveste raden at det nå ikke er noen blokker under dem, og de faller også. Denne prosessen fortsetter, til alle blokkene har falt, og etterlater skjermen helt tom.

Du kan se en litt redusert versjon av dette i handlingen i GIF nedenfor:


For å fikse dette, legger vi til en annen betingelse for arrangementet.

Hendelse: Tilstand: Blokk> Sammenlign Y Sammenligning = Mindre eller lik Y = SPAWNY - 1

Koden din skal nå se slik ut:


Ved å legge til denne nye tilstanden sikrer vi at bare blokker som er over Y-posisjonen til den laveste raden, påvirkes av vår "tyngdekraft". Til tross for denne løsningen har vi fortsatt noen problemer.

Å håndtere dra

Det primære problemet er at hendelsen som ser ut til å se om det er tomt plass under en blokk, har ingenting å fortelle at den er inaktiv når spilleren drar en blokk. Dette betyr at hvis du drar en blokk for langt uten å slippe av det, vil blokkene i stillingen over hvor du drog den fra, falle inn i plassen som er igjen av blokken du drog. Dessuten vil Blokken du drar, også ha et problem hvis du tar det ut av spillfeltet, og det vil begynne å falle bort fra musemarkøren siden det ikke er noen blokker under det.

For å fikse dette problemet må vi legge til en ny global variabel for å fortelle systemet når vi flytter en blokk, en ny handling til blokken dra og slippe hendelser for å angi denne globale variabelen, og en tredje betingelse for gravitasjonshendelsen så det tar Denne variabelen er i betraktning før du aktiverer.

La oss først gjøre den globale variabelen:

Global Variabel: Navn = BlockBeingMoved Type = Antall Initial Value = 0

Din variabel skal se slik ut:


Nå, gå til På DragDrop, dra start arrangement og legg til en ny handling:

Handling: System> Angi verdivariabel = BlockBeingMoved Value = 1

Også, gå til På DragDrop slipp hendelse og legg til en ny handling til den primære hendelsen:

Handling: System> Angi verdivariabel = BlockBeingMoved Value = 0

Med linjene lagt til, bør DragDrop-hendelsene nå se slik ut:


Til slutt, gå til gravitasjonsarrangementet og legg til en ny betingelse:

Tilstand: System> Sammenlign Variabel Variabel = BlockBeingMoved Comparison = Likeverdig = 0

Gravitasjonskoden din skal nå se slik ut:


Den nye variabelen vi opprettet, BlockBeingMoved, brukes til å fortelle systemet når en blokk blir flyttet av spilleren. Hvis variabelen er lik 0 det betyr at ingen blokk blir flyttet, og den kan kjøre gravitasjonsskriptene som normalt. Hvis variabelen er lik 1, det betyr en blokk er blir flyttet, og tyngdekraften skal ikke kjøres.

Hvis du kjører spillet på dette punktet, vil du se at uansett hvor du beveger Blokken mens du drar det, oppstår det ingen problemer.

Sjekker for nye kamper

Nå har vi bare ett siste problem å håndtere med hensyn til tyngdekraften. Kjør spillet og opprett et scenario som ligner dette:


Nå gjør du byttet som jeg har markert i dette neste bildet.


Du bør legge merke til at når gruppen Green / Star Blocks ødelegges, faller en Orange / Hexagon Block og danner en gruppe på tre blokker, men blir ikke ødelagt.

Grunnen til at disse blokkene ikke blir ødelagt er fordi vi aldri ringte FindMatches Fungerer en gang for å se om noen nye kamper ble dannet da blokkene falt for å fylle ut de tomme mellomrom. For å fikse dette, gå til arrangementet som sjekker om tomme mellomrom under Blokker og legg til denne andre hendelsen:

Hendelse: Tilstand: System> Øvrig handling: Funksjon> Anropsfunksjon Navn = "FindMatches"

Koden din skal se slik ut:


Denne andre setningen betyr at når det finner det ingen tomme mellomrom, vil det utføre en sjekk for å se om det er noen grupper å ødelegge. Denne hendelsen vil automatisk kjøre når Blokker faller inn i nye stillinger siden den er aktivert av en Else-setning som er knyttet til den sjekken, og vil bare brenne når det er sikkert at alle Blokkene har falt på plass.

Hvis du kjører spillet på dette punktet, vil du oppdage at du nå kan lage kjeder av blokker ved å ødelegge blokker på en måte som grupper blir dannet når de gjenværende blokkene faller. På toppen av det vil du også oppdage at når du først starter spillet, vil alle grupper som er oppstått i utgangspunktet bli ødelagt også. Som jeg sa i den forrige opplæringen, vil vi til slutt eliminere forhåndsdefinerte kamper, så dette problemet kommer ikke noe i slutten.

Fjerne blokker fra den første oppsettet

Til slutt må vi gjøre en annen ting før vi kan vurdere vårt tyngdekraftsystem fullført. Avhengig av hvor du plasserte den første Block sprite når du fullførte den første opplæringen, kan du merke at når du starter spillet faller det og blir synlig.

Hvis du ikke vet hva jeg mener, gå til Layout 1, sett posisjonen til blokksprite til 521, -32, og kjøre spillet. Når du spiller spillet, bør du se den opprinnelige Block land i stillingen jeg har markert i bildet nedenfor:


Som du kan se på bildet ovenfor, faller den opprinnelige blokken fra sin posisjon utenfor skjermen og blir synlig. Vi vil ikke ha dette fordi det bare kommer til å forårsake at vi utsteder problemer senere. For å løse dette lille problemet skal vi legge til en handling til På begynnelsen av oppsettet arrangement som vil ødelegge blokker som er i oppsettet når det først lastes.

Handling: Blokker> Ødelegg

Ditt arrangement skal nå se slik ut:


Nå når du kjører spillet, bør du ikke lenger se Blokken. Du kan spørre deg selv hvorfor vi ikke bare slette blokken fra Layout, slik at vi ikke trenger å bekymre deg for dette problemet i det hele tatt. Årsaken til at vi ikke gjorde dette, er at Konstruksjon 2 ikke kan lage kopier av en gjenstandstype med hendelser, med mindre det allerede er en forekomst av objekttype i spillet når den først lastes. Ved å slette den innen en hendelse, fjerner vi den så det blir ikke et problem senere, og vi gjør det mulig å gyte så mange blokker som vi trenger gjennom kode.


Konklusjon

Vi dekket mange emner i denne opplæringen, og mens det er mer vi kunne gjøre, synes jeg det er viktig å ta en pause og la denne informasjonen synke inn. I neste avtale vil vi fikse et par små problemer, lage Den fancy flytende poengteksten du kanskje har lagt merke til er i den endelige demoen, og sett opp kjedingssystemet.

Jeg håper du har fått mye ut av denne delen av serien, og jeg vil se deg tilbake her neste uke.