Cum se utilizează Bitmasking-ul pentru placi de tigla în Auto-Tile Layouts

Fabricarea unui tileset atractiv și variat este un proces consumator de timp, dar rezultatele merită adesea. Cu toate acestea, chiar și după crearea artei, tot trebuie să o combinați la nivelul dvs.! 

Puteți pune fiecare țiglă, una câte una, cu mâna - sau puteți automatiza procesul folosind bitmasking, așa că trebuie doar să desenați forma terenului.

Ce este Bitmasking de tigla?

Mărirea bitului de tigla este o metodă pentru selectarea automată a sprite-ului adecvat dintr-un tiletet definit. Acest lucru vă permite să plasați o placă generică de destinație oriunde doriți să apară un anumit tip de teren, în loc să introduceți o parte potențial enormă de diferite dale. 

Vedeți acest videoclip pentru o demonstrație:

(Puteți descărca demo-urile și fișierele sursă din repo-ul GitHub.)

Atunci când se ocupă cu mai multe tipuri de teren, numărul de variații diferite poate depăși 300 sau mai multe plăci. Desenarea acestui sprite mult mai diferit este cu siguranta un proces consumator de timp, dar bit mascarea tiglelor asigura ca actul de plasare a acestor placi este rapid si eficient.

Cu o implementare statică a masurării bitului, hărțile sunt generate în timpul execuției. Cu câteva trucuri mici, puteți extinde bitmasking-ul pentru a permite ca plăcile dinamice să se schimbe în timpul jocului. În acest tutorial, vom acoperi elementele de bază ale bitmasking-ului de tigla în timp ce ne deplasăm spre implementări mai complicate care folosesc plăci de colț și tipuri multiple de teren.

Cum functioneaza Bitmasking-ul de tigla

Prezentare generală

Mărirea bitului de țiglă se referă la calcularea unei valori numerice și la atribuirea unui anumit sprite bazat pe acea valoare. Fiecare țiglă se uită la plăcile vecine pentru a determina ce sprite din set să-și atribuie. 

Fiecare sprite dintr-un tileset este numerotat, iar procesul de mascare bitmaker returnează un număr corespunzător poziției unui sprite în tileset. În timpul execuției, se efectuează procedura de mascare a bitului, iar fiecare placă este actualizată cu sprite adecvat.

Foaia de sprite de mai sus este alcătuită din plăci de teren cu toate configurațiile de granițe posibile. Numerele de pe fiecare placă reprezintă valoarea de mascare bit, pe care o vom învăța cum să calculam în secțiunea următoare. Deocamdată, este important să înțelegeți modul în care valoarea de mascare a bitului se referă la tigla de teren. Spritele sunt ordonate secvențial, astfel încât o valoare a bitmaskingului 0 returnează primul sprite, până la o valoare de 15 care returnează numărul 16lea spiriduș. 

Calcularea valorii bitmasking

Calculul acestei valori este relativ simplu. În acest exemplu, presupunem un singur tip de teren fără piese de colț. 

Fiecare țiglă verifică existența plăcilor în nord, vest, est și sud, iar fiecare cec returnează un boolean, unde 0 reprezintă un spațiu gol și 1 semnifică prezența unei alte plăci de teren. 

Acest rezultat boolean este apoi înmulțit cu valoarea direcției binare și adăugat la totalul de execuție a valorii de mascare bitstream - este mai ușor de înțeles cu câteva exemple:

Valori direcționale pe 4 biți

  • Nord = 20 = 1
  • Vest = 21 = 2
  • Est = 22 = 4
  • Sud = 23 = 8

Pătratul verde din figura de mai sus reprezintă tigla de teren pe care o calculam. Începem prin a verifica o țiglă spre nord. Nu există nicio piesă la nord, așa că verificarea booleană returnează o valoare 0. Vom multiplica 0 cu valoarea direcțională pentru Nord, 20 = 1, oferindu-ne 1 * 0 = 0

Pentru o țiglă de teren înconjurată în întregime de spațiu gol, fiecare verificare booleană revine 0, rezultând în numărul binar pe 4 biți 0000 sau 1 * 0 + 2 * 0 + 4 * 0 + 8 * 0 = 0. Există 16 combinații posibile totale, de la 0 la 15, deci 1Sf sprite în tileset va fi folosit pentru a reprezenta acest tip de țiglă de teren cu o valoare de 0.

O placă de teren mărginită de o singură țiglă spre nord întoarce o valoare binară de 0001, sau 1 * 1 + 2 * 0 + 4 * 0 + 8 * 0 = 1. 2nd sprite în tileset va fi folosit pentru a reprezenta acest tip de teren cu o valoare de 1.

O țiglă de teren mărginită de o țiglă spre nord și o țiglă spre Est întoarce o valoare binară de 0101, sau 1 * 1 + 2 * 0 + 4 * 1 + 8 * 0 = 5. A șasea sprite din tileset va fi utilizată pentru a reprezenta acest tip de teren cu o valoare de 5.

O țiglă de teren mărginită de o țiglă spre est și o țiglă spre vest întoarce o valoare binară 0110, sau 1 * 0 + 2 * 1 + 4 * 1 + 8 * 0 = 6. Al șaptelea sprite din tileset va fi folosit pentru a reprezenta acest tip de teren cu o valoare de 6.

Atribuirea Sprites la Placi

După calcularea valorii bitmasking a unei plăci, atribuim sprite-ul corespunzător din tileset. Acest pas final poate fi efectuat în timp real pe măsură ce harta se încarcă, sau rezultatul poate fi salvat și încărcat în editorul tău de țigle ales pentru o editare ulterioară.

Cifra din stânga reprezintă un tileset de 4 biți, cu un singur teren, așa cum ar apărea secvențial pe o foaie de țiglă. Cifra din dreapta descrie modul în care țiglele se uită în joc după ce sunt plasate utilizând procedura de mascare bitmaps. Fiecare țiglă este marcată cu valoarea sa de mascare a bitului pentru a arăta relația dintre ordinea unei plăci pe foaia de țiglă și poziția sa în joc. 

De exemplu, să examinăm țigla din colțul din dreapta sus al figurii din dreapta. Această țiglă este mărginită de țigle către Vest și Souh. Verificarea booleană returnează o valoare binară de 1010, sau 1 * 0 + 2 * 1 + 4 * 0 + 8 * 1 = 10. Această valoare corespunde cu 11lea sprite în foaia de țiglă.

Complexitatea Tileset

Numărul de controale boleale direcționate necesare depinde de complexitatea dorită a setului dvs. de tile. Prin ignorarea pieselor de colț, puteți utiliza această soluție simplificată pe 4 biți, care necesită doar patru verificări binare direcționate. 

Dar ce se întâmplă atunci când doriți să creați un teren mai atractiv vizual? Veți avea nevoie să vă ocupați de existența plăcilor de colț, ceea ce crește cantitatea de sprite de la 16 la 48. Următorul exemplu de mascare bit-bit pe 8 biți necesită opt controale direcționale Boolean pentru fiecare placă.

Bitmasking pe 8 biți cu plăci de colț

Pentru acest exemplu, creăm un tileset de sus în jos care descrie terenul ieros din apropierea oceanului. În acest caz, oceanul nostru există pe un strat sub plăcile de teren. Acest lucru ne permite să folosim o soluție cu un singur teren, menținând în același timp iluzia că două tipuri de teren se ciocnesc. 

Odată ce jocul se execută și procedura de mascare bitstream este completă, spritele nu se vor schimba niciodată. Aceasta este o implementare statică, solidă a masurării bitului în care totul are loc înainte ca jucătorul să vadă vreodată plăcile.

Introducerea plăcilor de colț

Vrem ca terenul să fie mai vizibil interesant decât soluția anterioară de 4 biți, așa că sunt necesare bucăți de colț. Acest bit suplimentar al complexității vizuale necesită o cantitate exponențială de lucrări suplimentare pentru artist, programator și jocul propriu-zis. Extinzându-ne pe ceea ce am învățat din soluția pe 4 biți, putem înțelege rapid modul de abordare a soluției pe 8 biți.

Aici este foaia completă de sprite pentru țiglele noastre de teren. Ai observat ceva ciudat cu privire la numărul de plăci? Exemplul de 4 biți de la mai devreme a avut ca rezultat 24 = 16 plăci, deci acest exemplu pe 8 biți ar trebui să aibă în mod sigur 28 = 256 de dale, dar sunt cu siguranță mai puține decât acolo. 

Deși este adevărat că această procedură de mascare a bitului pe 8 biți are drept rezultat 256 valori binare posibile, nu fiecare combinație necesită o piesă complet unică. Următorul exemplu va explica modul în care 256 de combinații pot fi reprezentate de doar 48 de piese.

Valori Direcționale pe 8 biți

  • Nord Vest = 20 = 1
  • Nord = 21 = 2
  • Nord Est = 22 = 4
  • Vest = 23 = 8
  • Est = 24 = 16
  • Sud Vest = 25 = 32
  • Sud = 26 = 64
  • Sud Est = 27 = 128

Acum facem opt Controale directionale booleene. Tigla centrală de deasupra este mărginită de plăci la nord, nord-est și est, astfel că acest control boolean returnează o valoare binară de 00010110 sau 1 * 0 + 2 * 1 + 4 * 1 + 8 * 0 + 16 * 1 + 32 * 0 + 64 * 0 + 128 * 0 = 22.

Tigla din stânga de deasupra este similară cu cea a plăcilor anterioare, dar acum este de asemenea mărginită de țigle către sud-vest și sud-est. Acest control directional boolean ar trebui să returnați o valoare binară de 10110110, sau 1 * 0 + 2 * 1 + 4 * 1 + 8 * 0 + 16 * 1 + 32 * 1 + 64 * 0 + 128 * 1 = 182

Această valoare este diferită de țigla anterioară, dar ambele plăci ar fi de fapt identice din punct de vedere vizual, astfel încât acestea devin redundante. 

Pentru a elimina concedierile, adăugăm o condiție suplimentară controlului nostru directional boolean: când verificăm prezența unei frontiere colţ trebuie să verificăm și țiglele vecine în cele patru direcții cardinale (directe Nord, Est, Sud sau Vest). 

De exemplu, țiglele spre nord-est sunt înconjurate de plăci existente, în timp ce plăcile din sud-vest și sud-est nu sunt. Aceasta înseamnă că plăcile de sud-vest și de sud-est nu sunt incluse în calcularea bitmash. 

Cu această nouă condiție, acest control boolean returnează o valoare binară de 00010110 sau 1 * 0 + 2 * 1 + 4 * 1 + 8 * 0 + 16 * 1 + 32 * 0 + 64 * 0 + 128 * 0 = 22 la fel ca înainte. Acum puteți vedea cum cele 256 de combinații pot fi reprezentate de doar 48 de piese.

Ordinul Placilor

O altă problemă pe care o puteți observa este că valorile calculate de procedura de mascare bit-bit pe 8 biți nu se mai corelează cu ordinea secvențială a plăcilor din foaia de sprite. Există doar 48 de dale, dar valorile noastre posibile calculate se situează între 0 și 255, astfel încât nu mai putem folosi valoarea calculată ca referință directă atunci când apucăm sprite adecvat. 

De aceea, avem nevoie de o structură de date care să conțină lista valorilor calculate și valorile corespunzătoare ale acestora. Modul în care doriți să implementați acest lucru depinde de dvs., dar rețineți că ordinea în care verificați dacă există plăci înconjurătoare dictează ordinea în care plăcile dvs. trebuie plasate în foaia de sprite. 

Pentru acest exemplu, verificăm dacă țiglele se învecinează în ordinea următoare: Nord-Vest, Nord, Nord-Est, Vest, Est, Sud-Vest, Sud, Sud-Est. 

Mai jos este setul complet de valori de mascare bitmaking, deoarece se referă la pozițiile plăcilor din foaia de sprite (nu ezitați să utilizați aceste valori în proiectul dvs. pentru a economisi timp):

2 = 1, 8 = 2, 10 = 3, 11 = 4,16 = 5,18 = 6,22 = 7,24 = 8,26 = 9,27 = 10,30 = 11,31 = = 13, 66 = 14, 72 = 15, 74 = 16, 75 = 17, 80 = 18,82 = 19,86 = 20,88 = 21,90 = 22,91 = 23,94 = , 104 = 26, 106 = 27, 107 = 28, 120 = 29, 122 = 30, 123 = 31, 126 = 32,127 = 33,208 = 34,210 = = 38, 219 = 39, 222 = 40, 223 = 41,248 = 42,250 = 43,251 = 44,254 = 45,255 = 46,0 = 47

Tipuri multiple de teren

Toate exemplele noastre anterioare presupun un singur tip de teren, dar ce se întâmplă dacă introducem un al doilea teren la ecuație? Avem nevoie de 5-biți bitmasking soluție, și avem nevoie pentru a defini noastre două tipuri de teren. De asemenea, trebuie să atribuiți o valoare plăcii centrale care este calculată numai în condiții specifice. Amintiți-vă că nu mai contabilizăm "spațiul gol" ca în exemplele anterioare; țiglele trebuie acum să fie înconjurate de o altă placă din toate părțile.

Figura de mai sus prezintă un exemplu cu două tipuri de teren și fără plăci de colț. Tipul 1 mereureturnează o valoare de 0 ori de câte ori este detectat în timpul verificării direcționării; se calculează și se utilizează valoarea plăcii centrale numai dacă acesta este tipul de teren 2. 

Tigla centrală din exemplul de mai sus este înconjurată de teren de tip 2 spre nord, vest și est, și pe teren de tip 1 la sud. Placa centrală este teren 1, deci nu este luată în calcul. Acest control boolean returnează o valoare binară de  00111, sau  1 * 1 + 2 * 1 + 4 * 1 + 8 * 0 + 16 * 0 = 7.

În acest exemplu, țigla noastră centrală este teren de tip 2, deci va fi luată în calcul. Placa centrală este înconjurată de teren de tip 2 spre nord și vest. Este, de asemenea, înconjurat de teren de tip 1 la est și sud. Acest control boolean returnează o valoare binară de  10011, sau  1 * 1 + 2 * 1 + 4 * 0 + 8 * 0 + 16 * 1 = 19 .

Implementarea dinamică

Calculul bitmashing poate fi, de asemenea, efectuat în timpul jocului, permițând schimbări în timp real în plasarea și aspectul plăcilor. Acest lucru este util pentru terenul destructibil, precum și pentru jocurile care permit construirea și construirea. Procedura inițială de mascare bit este obligatorie pentru toate plăcile, dar orice calcule dinamice suplimentare ar trebui să fie efectuate numai atunci când este absolut necesar. De exemplu, o placă de teren distrus ar declanșa calcularea bitmăcii doar pentru plăcile din jur.

Concluzie

Tamplarea bitului este un exemplu perfect de construire a unui sistem de lucru care să vă ajute în dezvoltarea jocurilor. Nu este ceva care influențează direct experiența jucătorului; în schimb, această metodă de automatizare a unei porțiuni consumatoare de timp a designului de nivel oferă un avantaj valoros dezvoltatorului. Pentru a pune pur și simplu: bitmasking tile este o modalitate rapidă de a face jocul să vă facă munca murdară, permițându-vă să vă concentrați pe sarcini mai importante.