Faceți un joc Match-3 în Construct 2 puncte, potrivire și gravitate

În tutorialul anterior, am integrat un sistem de detectare a potrivirii de bază în jocul nostru Match-3. În timp ce ne îndreptăm spre un joc jucabil, mai sunt câteva elemente importante de joc de care avem nevoie înainte de a putea numi cu adevărat ceea ce avem un "joc". Acest articol se va concentra pe completarea unor detalii care lipsesc și ne apropie mult de produsul nostru final.


Joc final Demo

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




1. Puncte de atribuire

Vom acoperi punctele înainte de a începe îmbunătățirea sistemului de potrivire, deoarece va fi mult mai ușor să vedem prima problemă în sistemul nostru actual de potrivire dacă avem un sistem de puncte implementat.

Sistemul de puncte din jocul nostru va fi foarte simplu, pentru fiecare bloc folosit pentru a forma un anumit grup, jucătorul va primi 10 puncte. Într-un tutorial mai târziu vom adăuga și un sistem care permite jucătorului să câștige mai multe puncte prin legarea mai multor grupuri, dar pentru moment ne vom concentra pe introducerea unui sistem simplu de puncte pentru jucător.

Înainte de a începe editarea evenimentelor, trebuie să adăugăm un afiș de puncte, așa că mai întâi mergeți la Aspectul 1 și faceți următoarele:

  1. Introduceți un nou spiriduș obiect.
    1. Deschideți imaginea Game Field Imagini / ScoreArea.png din pachetul grafic.
    2. Închideți editorul de animație.
    3. Setați poziția la 491, 383.
  2. Introduceți un nou Text obiect.
    1. Seteaza Font la Calibri, Bold, 22 utilizând meniul derulant.
    2. Seteaza Nume la ScoreText
    3. Seteaza Culoare la alb sau 255, 255, 255
    4. Seteaza Poziţie la 419, 398.
    5. Seteaza mărimea la 200, 50.
    6. Seteaza Text la 0.

Aspectul 1 ar trebui să arate astfel:

Acum, că avem ceva de spus jucătorului ce înseamnă textul de puncte și un obiect text pentru a afișa scorul jucătorului, putem trece la punerea efectivă a punctelor jucătorului. Mergi la Fișa evenimentului 1 și să creeze un nou Variabila globală.

Numele variabilei globale: "Scorul" Tip = Numărul Valoarea = 0

Variabila ar trebui să arate astfel:

Aceasta este variabila pe care o vom modifica ori de câte ori dăm jucătorilor puncte. Apoi, vom crea o nouă funcție care, atunci când va fi apelată, va detecta câte blocuri a jucat în grupuri și le va da numărul corespunzător de puncte.

Eveniment: Stare: Funcție> La funcția Nume = "GivePoints" Stare: Sistem> Pentru fiecare obiect = Stare bloc: Blocare> Setare variabilă instanță boolean Instance Variable = IsMatched Acțiune: System> Add to Variable = Score Value = 10 Action: ScoreText > Setați text Text = Scor

Codul dvs. ar trebui să arate astfel:

Deci, pentru a reitera, acest eveniment priveºte fiecare bloc. De fiecare dată când găsește un bloc care are IsMatched setat la Adevărat - ceea ce înseamnă că a fost confirmat că face parte dintr-un grup - îi dă jucătorului 10 puncte pentru acel bloc și actualizează textul scorului.

Dacă vă testați jocul în acest moment, se va părea că funcția nu funcționează. Motivul pentru acest lucru este că nu am numit funcția oriunde în cod, deci punctele nu sunt niciodată incrementate, iar textul nu se actualizează niciodată. Du-te la tine FindMatches și adăugați o nouă acțiune la începutul sub-evenimentului final pentru această funcție.

Acțiune: Funcție> Funcție apel Nume = "GivePoints"

Ta FindMatches funcția ar trebui să pară acum:

Notă: asigurați-vă că ați adăugat această nouă acțiune la începutul sub-evenimentului. Dacă adăugați această acțiune până la sfârșit, aceasta nu va funcționa, deoarece toate blocurile potrivite vor fi distruse înainte de GivePoints se numește funcția. Aceasta înseamnă că, atunci când caută Blocurile potrivite, nu va găsi niciunul și astfel jucătorul nu va primi niciun punct.

În acest moment vă puteți testa din nou jocul și ar trebui să vedeți actualizarea textului de puncte și că jucătorul primește numărul corect de puncte pentru fiecare meci pe care îl efectuează.


2. Îmbunătățirea detecției meciurilor

Acum, când avem sistemul de puncte, vreau să rulați jocul și să creați scenariul prezentat mai jos.


Acum schimbați blocurile pe care le-am evidențiat aici și urmăriți scorul dvs. pentru a vedea câte puncte câștigați.


Când ați format acest meci, ar fi trebuit să văd că ați câștigat 50 de puncte. Acest lucru se datorează faptului că, în prezent, sistemul de puncte dă jucătorului 10 puncte pentru fiecare bloc care este marcat ca IsMatched, spre deosebire de a da jucătorului 10 puncte pentru fiecare bloc folosit în fiecare meci, precum sistemul pe care l-am descris mai sus.

Dacă sistemul de puncte funcționează corect, acesta ar da jucătorului 60 de puncte: 30 pentru grupul vertical de trei blocuri și 30 pentru grupul orizontal de trei blocuri. Această problemă rezultă din faptul că sistemul de potrivire nu are nici un fel de marcare atunci când un bloc este egal atât orizontal și vertical; știe doar dacă blocul este într-adevăr asociat.

Pentru a rezolva această problemă, vom adăuga mai întâi două noi Variabile de instanta la obiectul nostru Block, MatchedX și MatchedY.

Variabila instanței: Name = MatchedX Type = Valoarea inițială booleană = Variabila falsă a instanței: Name = MatchedY Type = Valoarea inițială booleană = false

Variabilele dvs. ar trebui să arate astfel:


Aceste variabile vor fi utilizate împreună cu IsMatched pentru a comunica sistemului atunci când Blocul face parte din grupurile orizontale sau X și atunci când Blocul face parte din grupurile verticale sau Y. Acum, când avem variabilele, vom modifica CheckMatches astfel încât atunci când etichetează un bloc IsMatched deoarece a găsit un grup suficient de mare, va eticheta, de asemenea, că blocul face parte dintr-un grup X sau Y, în funcție de parametrul 3 sau de parametrul 4 care este 1.

Mergeți la CheckMatches funcția și înlocuiți originalul NumMatchesFound verificați cu aceste două sub-evenimente noi:

Sub-Event: Stare: Sistem> Comparați două valori Prima valoare = Function.Param (3) Comparație = Egal cu a doua valoare = 1 Stare: Sistem> Comparație variabilă Variable = NumMatchesFound Comparison = Valoare mai mare sau egală = Boolean Instance variabila = IsMatched Value = Adevarata actiune: Block> Set Boolean Instance variabila = MatchedX Value = True Sub-Event: Stare: System> Compara doua valori Prima valoare = Function.Param (4) : Sistem> Comparați variabila Variable = NumMatchesFound Comparison = Valoare egală sau mai mare = 3 Acțiune: Bloc> Setare Boolean Instance instance = Valoare IsMatched = Adevărată acțiune: Blocare> Set variabil instanță booleană = Valoare matchedY =

Ta CheckMatches funcția ar trebui să pară acum:


Deci, noua versiune de CheckMatches funcționează în același mod ca și cel precedent, cu excepția faptului că acum verifică dacă blocul a fost găsit într-un grup vertical sau într-un grup orizontal și etichetează blocul în consecință cu noile variabile MatchedX și MatchedY.

Acordarea de puncte suplimentare blocurilor care se potrivesc de două ori

Acum, că avem o modalitate de a determina când o blocare este potrivită vertical, potrivită orizontal și potrivită în ambele direcții, spre deosebire de a ști că a fost potrivită într-un grup, trebuie să adăugăm un sub-eveniment la GivePoints care va distribui un plus de 10 puncte pentru un bloc care are ambele MatchedX și MatchedY setați la true.

Mergeți la GivePoints și adăugați acest sub-eveniment:

Sub-Event: Condiție: Bloc> Este setată variabila de instanță booleană Variabila instanță = MatchedX Stare: Bloc> Este setată variabila de instanță Boolean Variație instanță = MatchedY Acțiune: Sistem> Adăugare la Variabila = Scor

Ta GivePoints funcția ar trebui să pară acum:


Dacă rulați jocul și creați din nou scenariul pe care l-am ilustrat mai sus, scorul dvs. ar trebui acum să crească corect cu 60 de puncte.


3. Adăugarea gravității

Acum, că avem un sistem Puncte implementat și am actualizat sistemul de potrivire, vom începe să îmbunătățim un alt aspect important al gameplay-ului. Dacă ați petrecut tot timpul joc cu acest joc până în acest punct, veți ști că una dintre cele mai mari probleme este că, atunci când blocurile sunt distruse, nimic nu se întâmplă la blocurile de deasupra lor. În mod specific, blocurile deasupra spațiilor goale nu cad pentru a completa spațiile respective.

Acest lucru este bine în teste, dar în versiunea finală ar fi în detrimentul gameplay-ului să lase lucrurile așa cum sunt, așa că următorul lucru pe care îl vom adăuga este "gravitatea" care va cauza Blocurile să cadă și să completeze spații goale atunci când alte blocuri sunt distruse.

Modul în care vom implementa acest sistem este de fapt destul de simplu. Vom efectua o verificare folosind Bloc> Se suprapune la offset eveniment pentru a vedea dacă există un bloc sub blocul la care ne uităm. Dacă găsim că nu există nici un bloc, vom muta blocul pe care îl căutăm în jos pentru a umple spațiul gol; altfel, nu vom face nimic.

Pentru a face acest lucru, vom crea un eveniment nou:

Eveniment: Stare: INVERT> Bloc> Se suprapune la offset Obiect = Blocare Offset X = 0 Offset Y = 8 Acțiune: Bloc> Deplasare la unghi Unghi = 90 Distanța = (Block.Width + 2) / 2

Codul dvs. ar trebui să arate astfel:


Dacă executați jocul în acest moment, veți vedea că în momentul în care jocul începe, toate blocurile cad din ecran! Motivul pentru aceasta este că nu am pus nimic în cod pentru a spune unde ar fi "podeaua" câmpului de joc.

Deci, în mod esențial, blocurile de pe rândul de jos realizează că nu există blocuri sub ele și căderile corespunzătoare. Apoi, odată ce cel mai mic rând de blocuri a căzut, următoarea linie inferioară vede că acum nu mai există blocuri de sub ele, iar acestea cad. Acest proces continuă până când toate blocurile au căzut și părăsesc ecranul complet gol.

Puteți vedea o versiune ușor încetinită a acestei acțiuni în GIF de mai jos:


Pentru a rezolva acest lucru, vom adăuga oa doua condiție la eveniment.

Eveniment: Stare: Bloc> Comparare Y Comparație = Mai puțin sau egal Y = SPAWNY - 1

Codul dvs. ar trebui să arate astfel:


Adăugând această nouă condiție, asigurăm că numai "Blocurile" care sunt situate deasupra poziției Y a rândului cel mai de jos sunt afectate de "gravitatea" noastră. În ciuda acestei soluții, avem încă câteva probleme.

Confruntarea cu tragerea

Problema principală este că evenimentul care pare să vadă dacă există un spațiu gol sub un bloc nu are nimic de spus că este inactivă atunci când playerul trage un bloc. Aceasta înseamnă că, dacă trageți un bloc prea departe, fără a lăsa să-l lăsați, Blocurile în poziția de deasupra locului în care l-ați târât vor cădea în spațiul lăsat de blocul pe care l-ați târât. În plus, blocul pe care îl trageți va avea de asemenea o problemă dacă îl scoateți din câmpul de joc și acesta va începe să dispară de cursorul mouse-ului, deoarece nu există blocuri sub el.

Pentru a rezolva această problemă, trebuie să adăugăm o nouă variabilă globală pentru a spune sistemului atunci când ne mișcăm o blocare, o nouă acțiune la evenimentele de tragere și coborâre bloc pentru a seta această variabilă globală și oa treia condiție pentru evenimentul gravitator, această variabilă trebuie luată în considerare înainte de activare.

În primul rând, să facem variabila globală:

Variabila globală: Name = BlockBeingMoved Type = Număr Initial Value = 0

Variabila dvs. ar trebui să arate astfel:


Acum, du-te la În DragDrop trageți începutul eveniment și adăugați o nouă acțiune:

Acțiune: Sistem> Set Variable Value = BlockBeingMoved Value = 1

De asemenea, mergeți la Pe drop DragDrop eveniment și adăugați o nouă acțiune la evenimentul principal:

Acțiune: Sistem> Set Variable Value = BlockBeingMoved Value = 0

Cu liniile adăugate, evenimentele DragDrop ar trebui să arate astfel:


În cele din urmă, mergeți la Evenimentul de gravitate și adăugați o nouă condiție:

Stare: Sistem> Comparați Variabila variabilă = Comparație Comparată Comparată Comparată = Egal Valoare = 0

Codul dvs. de gravitate ar trebui să arate astfel:


Noua variabilă pe care am creat-o, BlockBeingMoved, este folosit pentru a indica sistemului când un bloc este mutat de către Player. Dacă variabila este egală 0 înseamnă că nici un bloc nu este mutat și poate rula scripturile de gravitate ca normal. Dacă variabila este egală 1, înseamnă un bloc este fiind mutat, iar scripturile de gravitate nu ar trebui să fie difuzate.

Dacă executați jocul în acest moment, veți vedea că, indiferent de locul în care mutați blocul în timp ce îl trageți, nu apar probleme.

Verificarea pentru meciurile noi

Acum avem doar o ultimă problemă cu privire la sistemul gravitațional. Rulați jocul și creați un scenariu similar cu acesta:


Acum, faceți schimbul pe care l-am subliniat în următoarea imagine.


Ar trebui să observați că atunci când grupul Green / Star Blocks este distrus, un bloc de portocaliu / hexagon cade și formează un grup de trei blocuri, dar nu se distruge.

Motivul pentru care aceste blocuri nu se distrug este că nu am sunat niciodată FindMatches funcționează a doua oară pentru a vedea dacă s-au format noi potriviri când blocurile au căzut pentru a umple spațiile goale. Pentru a rezolva acest lucru, mergeți la evenimentul care verifică spațiile goale de sub Blocuri și adăugați acest Eveniment Else:

Eveniment: Stare: Sistem> Altă acțiune: Funcție> Funcție apel Nume = "FindMatches"

Codul dvs. ar trebui să arate astfel:


Această declarație altceva înseamnă că, ori de câte ori constată că nu există spații goale, va efectua un control pentru a vedea dacă există grupuri de distrugere. Acest eveniment se va executa automat ori de câte ori Blocurile se încadrează în noi poziții, deoarece acestea sunt activate de o instrucțiune Else care este legată de acea verificare și se va declanșa numai după ce este sigur că toate Blocurile au căzut.

Dacă executați jocul în acest moment, veți găsi că acum puteți crea lanțuri de blocuri prin distrugerea blocurilor astfel încât să se formeze grupuri atunci când rămân blocurile rămase. În plus, veți observa, de asemenea, că atunci când porniți jocul inițial, vor fi distruse, de asemenea, toate grupurile care s-au născut inițial. După cum am spus în tutorialul anterior, vom elimina în cele din urmă meciurile pre-făcute, astfel încât această problemă nu va avea importanță în cele din urmă.

Eliminarea blocurilor din layout-ul inițial

În cele din urmă, trebuie să facem un alt lucru înainte de a putea lua în considerare sistemul nostru de gravitate complet. În funcție de locul în care ați plasat sprite bloc inițial când ați terminat primul tutorial, este posibil să observați că atunci când începeți jocul, acesta cade și devine vizibil.

Dacă nu știi ce vreau să spun, du-te la Aspectul 1, setați poziția blocului dvs. Sprite 521, -32, și conduceți jocul. Când joci jocul, ar trebui să vezi terenul original Block în poziția pe care am evidențiat-o în imaginea de mai jos:


După cum puteți vedea în imaginea de mai sus, blocul inițial cade din poziția sa off-screen și devine vizibil. Nu vrem acest lucru, pentru că ne va cauza probleme mai târziu. Pentru a rezolva această mică problemă, vom adăuga o acțiune la La începutul aspectului eveniment care va distruge orice blocuri care se află în Layout când se încarcă inițial.

Acțiune: Bloc> Distrugeți

Evenimentul dvs. ar trebui să arate astfel:


Acum când conduceți jocul, nu mai trebuie să vedeți Blocul. S-ar putea să vă întrebați de ce nu am șters doar blocul din Layout, așa că nu trebuie să ne temem de această problemă deloc. Motivul pentru care nu am făcut acest lucru este că Construct 2 nu poate crea copii ale oricărui tip de obiect cu Evenimente, cu excepția cazului în care există deja o instanță a acelui tip de obiect în joc când acesta este încărcat pentru prima dată. Prin ștergerea ei în cadrul unui eveniment, îl eliminăm astfel încât să nu devină o problemă mai târziu și vom face posibilă reproducerea cât mai multor Blocuri de care avem nevoie prin cod.


Concluzie

Am abordat o mulțime de subiecte în acest tutorial și în timp ce putem face mai mult, cred că este important să faceți o pauză și să lăsați această informație să se scufunde. În următoarea tranșă, vom rezolva câteva probleme mici, textul fantastic de puncte plutitoare pe care ați observat-o este în demo-ul final și configurați sistemul de înlănțuire.

Sper că ai multe din această parte a seriei și te voi vedea aici săptămâna viitoare.