Faceți un joc Match-3 în Construct 2 Detectarea meciurilor

Până în prezent, această serie a acoperit elementele de bază ale înființării unui joc Match-3 și implementarea elementelor inițiale de joc, cum ar fi schimbarea blocurilor. În acest tutorial, vom construi pe toate acestea și vom începe să detectăm când jucătorul a făcut un meci.


Joc final Demo

Iată o demonstrație a jocului pe care lucrăm în această serie:




1. Detectarea unei potriviri

Pentru moment, vom aplica doar o versiune de bază a sistemului de potrivire, concentrându-ne pe găsirea atunci când meciurile există și distrugând blocurile potrivite. În articolele ulterioare vom continua dezvoltarea și avansarea sistemului.

Bacsis: Trebuie să citiți cum funcționează o funcție recursivă, dacă nu știți deja; în esență, este o funcție care se numește ea însăși. Funcțiile recursive pot funcționa în mod similar cu buclele, dar deoarece ele pot lua și variabilele returnate, ele au mult mai multe utilizări decât buclele.

Ca și în tutorialul anterior, mai întâi vreau să discut despre cum va funcționa sistemul și apoi să încerce să-l construiască.

  • Sistemul de potrivire va itera prin fiecare instanță a bloc obiect.
  • Pentru fiecare bloc, va trece culoarea și poziția blocului pe care îl privește într-o funcție recursivă care va privi vecinul orizontal sau vertical și va determina dacă aceștia sunt de aceeași culoare.
  • Dacă se găsește o potrivire, se va apela funcția din nou cu poziția și culoarea noului bloc, mai degrabă decât cu cel original.
  • Aceasta va continua până când nu se va găsi o potrivire. În acel moment, va verifica câte meciuri a găsit.
  • Dacă a găsit trei sau mai multe meciuri, acesta marchează toate blocurile la care tocmai sa uitat Potrivite cu IsMatched variabilă de exemplu pe care am făcut-o într-unul din tutoriile anterioare; altfel, nu face nimic.
  • În sfârșit, odată ce toate blocurile au fost verificate, funcția va distruge fiecare bloc care este marcat ca o potrivire.

În primul rând, avem nevoie de un eveniment care să poată fi repetat prin fiecare bloc. Modul în care am construit sistemul, se repetă de fapt prin blocuri de două ori: o dată pentru a verifica potrivirile verticale și o dată pentru a verifica potrivirile orizontale. În funcție de ce verificare se face, va folosi o funcție diferită pentru a căuta efectiv meciul.

Primul lucru pe care trebuie să-l facem este să faci a Variabila globală pentru a urmări câte blocuri de potrivire am găsit în orice iterație dată:

Nume variabilă globală: "NumMatchesFound" Type = Number Value = 0

Acum, hai să facem Eveniment care va itera prin blocuri:

Eveniment: Functia> Functia> Functia> Functia> Functie> Functia> CallMatches "Parametru 0: Block.X Parametrul 1 : Block.Y Parametrul 2: Block.Color Sub-Event: Sistem> Comparați NumMatchesFound variabilă> = 3 Acțiune: Bloc> Setare Boolean IsMatched = Sub-Event True: Sistem> 1 Acțiune: Funcție> Funcție> Funcția de apelare Nume: "CheckMatchesY" Parametrul 0: Block.X Parametrul 1: Block.Y Parametrul 2: Block.Color Sub-Event: System> Compare NumMatchesFound> = 3 Acțiune: Block> Set Boolean IsMatched = Sub-eveniment adevărat: Bloc> Este setată variabila instanță booleană Sistem> Așteptați a doua = 0.1 Bloc> Distrugeți

Codul dvs. ar trebui să arate astfel:


În acest caz, repetăm ​​fiecare bloc și îi trimitem CheckMatchesX sau CheckMatchesY, funcțiile care vor verifica dacă blocul învecinat este o potrivire.

Pentru a trimite blocul în funcție, trecem prin funcții trei parametri diferiți:

  • Parametrul 0 este poziția X a blocului
  • Parametrul 1 este poziția Y a blocului
  • Parametrul 2 este culoarea.

După ce fiecare bloc este trimis într-una din funcții și funcția termină să fie difuzată, aceasta verifică NumMatchesFound pentru a vedea dacă a găsit trei sau mai multe blocuri de potrivire și apoi etichetează blocurile ca fiind Potrivite dacă a fost așa.

În cele din urmă, fiecare bloc care este marcat ca fiind Potrivite este distrus după trecerea unui secund. Acest aștepta declarația este acolo pentru a permite jocului să comute imaginile pentru Blocuri la imaginea care indică faptul că sunt potrivite și să dea jucătorului un moment pentru a observa această schimbare.

(În timp ce ați putea să eliminați aștepta fără a afecta negativ jocul, face ca potrivirea să fie mai ușoară pentru jucător și să încetinească jocul suficient pentru ca jucătorul să poată urmări cu ușurință ceea ce se întâmplă.)


2. Cele două funcții de verificare

Înainte trebuie să facem CheckMatchesX și CheckMatchesY funcții. Aceste funcții vor funcționa în mod similar cu iteratorii de mai sus, deoarece va exista o versiune pentru verificarea potrivirilor orizontale, CheckMatchesX, și una pentru meciurile verticale, CheckMatchesY.

Verificări orizontale

Mai întâi, să construim funcția de verificare orizontală:

Eveniment: Funcție> Funcția On: Denumire: Submodul "CheckMatchesX": Stare: Bloc> Comparare XX = Function.Param (0) + (Block.Width + 2) Condiție: Block> Compare YY = Function.Param : Bloc> Comparați variabila de instanță Color = Function.Param (2) Acțiune: Sistem> Add to Variable = NumBlocks Valoare = 1 Acțiune: Function> Call function Nume: "CheckMatchesX" Parameter 0: Function.Param (0) + Block. Lățime + 2) Parametru 1: Funcție.Param (1) Parametru 2: Funcție.Param (2) Sub-eveniment: Sistem> Comparați variabila NumMatchesFound> = 3 Acțiune: Block> Set Boolean IsMatched =

Codul dvs. ar trebui să arate astfel:


Deci, ce face această funcție?

  • În primul rând, testează dacă un bloc vecin există chiar în stânga blocului în care am trecut.
  • Odată ce funcția confirmă existența unui bloc în locația învecinată, verifică dacă este aceeași culoare ca blocul în care am trecut.
  • Dacă este, crește NumMatchesFound de unul, și trece blocul nou găsit în funcție, la fel ca pentru original.
  • Aceasta continuă până când se găsește un bloc care nu are aceeași culoare ca originalul. În acel moment, verifică dacă a găsit suficiente blocuri de potrivire pentru a crea un grup și etichetează blocurile ca potriviri dacă a făcut-o.

Verificări verticale

Acum, să facem o altă versiune a acestei funcții, care va face același lucru și pentru meciurile verticale. Asta va fi al nostru CheckMatchesY funcţie. Puteți să copiați funcția originală și să efectuați toate modificările necesare sau să o construiți din nou de la zero; în fiecare caz, iată cum ar trebui să arate funcția atunci când este terminată:

Eveniment: Funcție> Funcție activată: Sub-eveniment "CheckMatchesY": Stare: Bloc> Comparare XX = Function.Param (0) Stare: Blocare> Comparație YY = Function.Param (1) + (Block.Width + : Bloc> Comparați variabila de exemplu Color = Function.Param (2) Acțiune: Sistem> Adăugare la Variable = NumBlocks Valoare = 1 Acțiune: Funcție> Funcție Call Name: Parametru 0: .Param (1) + (Block.Width + 2) Parametrul 2: Function.Param (2) Sub-Event: System> Compare NumMatchesFound> = 3 Acțiune: Block> Set Boolean IsMatched =

Codul dvs. ar trebui să arate astfel:



3. De fapt, cautam cecuri

În cele din urmă, trebuie să sunăm de fapt FindMatches funcţie. Mergeți la SwapBlocks și adăugați un nou sub-eveniment la sfârșitul funcției:

Eveniment: Funcție> Sub-eveniment: Acțiune: Funcție> Funcție apel Nume: "FindMatches"

Veți observa că acest sub-eveniment nu are de fapt condiții. Dacă nu ați făcut niciodată un sub-eveniment ca acesta, faceți doar un sub-eveniment cu orice condiție, deoarece vă cere să faceți o condiție atunci când faceți un sub-eveniment și apoi ștergeți condiția, dar lăsați sub-eveniment. În acest fel, asigurați-vă că sub-evenimentul se execută întotdeauna.

Ta SwapBlocks evenimentul ar trebui să arate astfel:

Dacă executați jocul în acest moment, veți vedea că blocurile sunt distruse atunci când apar meciuri. De asemenea, veți observa că toate meciurile care există atunci când începe jocul nu dispar până când nu faceți o schimbare de tip. Asta pentru că nu sunăm niciodată FindMatches funcție după ce am creat grila de blocuri.

Motivul pentru care nu am adăugat acest cod este că, în versiunea finală, va exista o altă funcție care împiedică generarea automată de astfel de rezultate, astfel că nu există niciun motiv să vă faceți griji în legătură cu această problemă. (Dar nu ezitați să sunați FindMatches mai devreme, dacă doriți.)


4. Consolidarea controalelor

În acest moment, avem un sistem destul de puternic de potrivire, dar problema este că codul nostru este redundant. În prezent, avem două funcții diferite care verifică dacă există un vecin care se potrivește, iar singura diferență dintre ele este aceea că se verifică pe verticală, iar celelalte verificări pe orizontală.

Deoarece versiunea gratuită a lui Construct 2 limitează câte evenimente putem avea, aceasta este cu siguranță o pierdere. Pentru a rezolva acest lucru, vom face o nouă versiune a funcției care poate face ambele verificări.

Dacă te uiți la funcție, vei vedea că singura diferență dintre cele două versiuni este aceea pe care o adaugi Block.Width + 2 la poziția x a blocului, iar cealaltă îl adaugă la poziția y a lui Bock. Deci, obstacolul pe care trebuie să-l depășim pentru a face această funcție unică, dă funcției o modalitate de a adăuga Block.Width + 2 numai la X, sau numai Y, fără folosind un Dacă declarație sau mai multe funcții, deoarece acestea necesită mai multe evenimente care trebuie executate.

Soluția mea pentru acest lucru nu este foarte complexă, dar va fi mai ușor să înțelegem dacă o putem vedea împreună, așa că o vom implementa și voi explica cum funcționează odată ce putem vedea totul în acțiune.

  1. Ștergeți CheckMatchesY eveniment.
  2. Redenumiți CheckMatchesX eveniment, pur și simplu, CheckMatches.
  3. În apelul pentru funcție CheckMatchesX sub FindMatches eveniment:
    1. Modificați apelul pentru funcții pentru CheckMatches in loc de CheckMatchesX.
    2. Adăuga Parametrul 3.
      1. Valoare = 1.
    3. Adăuga Parametrul 4.
      1. Valoare = 0.
  4. În apelul pentru funcție CheckMatchesY sub FindMatches eveniment:
    1. Modificați apelul pentru funcții pentru CheckMatches in loc de CheckMatchesY.
    2. Adăuga Parametrul 3.
      1. Valoare = 0.
    3. Adăuga Parametrul 4.
      1. Valoare = 1.

Așa cum voi explica în curând, acești parametri adăugați vor spune CheckMatches indiferent dacă efectuează o verificare orizontală sau o verificare verticală. Când trimitem 1 pentru Parametrul 3, și 0 pentru Parametrul 4, este o verificare orizontală și când trimitem 0 pentru Parametrul 3, și 1 pentru Parametrul 4, este o verificare verticala.

Acum, du-te înapoi la CheckMatches funcția și modificați condițiile și acțiunile care arată astfel:

Eveniment: Funcție> Funcția On: Denumire: CheckMatches Sub-Event: Stare: Bloc> Comparați XX = Function.Param (0) + (Block.Width + 2) YY = Function.Param (1) + (Block.Width + 2) * Function.Param (4)) Stare: Bloc> Comparati variabila de exemplu Color = Function.Param (2) Action: Block> Set Boolean IsMatched = : Funcția> Funcția de apelare Nume: "CheckMatches" Parametrul 0: Function.Param (0) + ((Block.Width + 2) * Function.Param (3)) Parametrul 1: Function.Param (1) + (Block. (2) Parametru 3: Parametru 3: Parametru 3: Parametru 4: Parametru 4: Funcție Parametru (4) Sub-eveniment: Sistem> Compara NumMatchesFound> 3 Acțiune: Bloc> Setare Boolean IsMatched = Adevărat

Asta e ceea ce ai FindMatches și CheckMatches codul ar trebui să arate acum:


Cum funcționează asta?

Deci, ce este de fapt această nouă versiune a funcției?

Ei bine, ori de câte ori sunați CheckMatches acum trimiți doi parametri, mai degrabă decât adăugați Block.Width + 2 la poziția x sau y, se adaugă (Block.Width + 2) * Funcție.Param (3) la poziția x și (Block.Width + 2) * Funcție.Param (4) la poziția y.

Deoarece unul dintre acești doi parametri va fi întotdeauna 1, iar celălalt va fi întotdeauna 0, aceasta înseamnă că fie poziția x, fie poziția y vor fi modificate - niciodată ambele!

De exemplu, dacă intrăm 1 pentru Parametrul 3, și 0 pentru Parametrul 4, apoi adaugă (Bloc. Lățime + 2) * 1, care este pur și simplu Block.Width + 2, la poziția x și (Bloc. Lățime + 2) * 0, care este 0, la poziția y.

Iată un exemplu rapid pentru a arăta ce vreau să spun și cum calculează poziția blocului în care va verifica meciul. Să spunem că în acest exemplu, blocul original este la (200, 200), iar blocurile au o lățime de 40. Deci, dacă vrem să obținem poziția blocului vertical învecinat, formulele se vor desfășura astfel:

  • X = 200 + ((Lățimea blocului + 2) * 0) = 200 + (40 + 2) * 0 = 200 + 0 = 200
  • Y = 200 + ((Lățimea blocului + 2) * 1) = 200 + (40 + 2) * 1 = 200 + 42 = 242

Dacă vrem să obținem poziția Blocului orizontal din vecinătate, formulele ar funcționa astfel:

  • X = 200 + ((Lățimea blocului + 2) * 1) = 200 + (40 + 2) * 1 = 200 + 42 = 242
  • Y = 200 + ((bloc. Lățime + 2) * 0) = 200 + (40 + 2) * 0 = 200 + 0 = 200

Dacă executați jocul acum, ar trebui să vedeți că sistemul de potrivire funcționează în continuare așa cum a procedat inițial, dar din perspectiva noastră, este de fapt un sistem mai bun.


Concluzie

În acest moment, funcția de detectare a potrivirii este încă incompletă, dar deja am făcut multe în acest tutorial și cred că este important să lăsăm toate aceste chiuvete înainte să adăugăm altceva. Având în vedere acest lucru, voi încheia acest articol aici. Check out demo-ul în forma sa actuală.

În următorul articol vom adăuga un sistem de puncte, vom îmbunătăți sistemul de potrivire și vom adăuga "gravitatea", astfel încât blocurile vor cădea atunci când Blocurile de dedesubt sunt eliminate.

Dacă doriți să obțineți un start cap la articolul următor, luați-vă ceva timp pentru a lua în considerare modul în care veți detecta atunci când există un spațiu gol sub un bloc. Încearcă să te uiți la Bloc> se suprapune la offset funcție de inspirație!