Pengantar Aksial Koordinat untuk Heksagonal Ubin Berbasis Permainan
() translation by (you can also view the original English article)



Dasar heksagonal ubin berbasis pendekatan yang dijelaskan dalam tutorial heksagonal minesweeper mendapat pekerjaan dilakukan tetapi sangat tidak efisien. Menggunakan konversi langsung dari data tingkat berbasis array dua dimensi dan koordinat layar, yang membuatnya tidak perlu rumit untuk menentukan disadap ubin.
Juga, perlu menggunakan logika yang berbeda tergantung pada ganjil atau genap baris/kolom ubin ini tidak nyaman. Seri tutorial ini mengeksplorasi sistem koordinat alternatif layar yang dapat digunakan untuk meringankan logika dan membuat hal-hal yang lebih nyaman. Saya sangat menyarankan Anda membaca tutorial heksagonal minesweeper sebelum bergerak maju dengan tutorial ini sebagai salah satu menjelaskan render grid yang didasarkan pada array dua dimensi.
1. aksial Koordinat
Pendekatan standar yang digunakan untuk layar koordinat dalam tutorial heksagonal minesweeper disebut pendekatan koordinat offset. Hal ini karena alternatif baris atau kolom diimbangi dengan nilai sementara menyelaraskan grid heksagonal.
Untuk menyegarkan ingatan Anda, silakan merujuk ke gambar di bawah, yang menunjukkan perataan horizontal dengan koordinat nilai offset ditampilkan.



Pada gambar diatas, berturut-turut dengan sama i
saya nilai disorot dalam warna merah, dan kolom dengan nilai j
sama disorot dalam warna hijau. Untuk membuat segala sesuatu yang sederhana, kita tidak akan membahas varian yang aneh dan bahkan offset karena keduanya hanya cara untuk mendapatkan hasil yang sama.
Mari saya memperkenalkan alternatif koordinat layar yang lebih baik, koordinat aksial. Mengkonversi koordinat offset aksial varian ini sangat sederhana. I
menghargai tetap sama, tetapi nilai j
dikonversi menggunakan formula axialJ =-floor(j/2)
. Sebuah metode sederhana dapat digunakan untuk mengkonversi offset Phaser.Point
untuk varian aksial, seperti yang ditunjukkan di bawah ini.
1 |
function offsetToAxial(offsetPoint){ |
2 |
offsetPoint.y=(offsetPoint.y-(Math.floor(offsetPoint.x/2))); |
3 |
return offsetPoint; |
4 |
}
|
Konversi sebaliknya akan seperti ditunjukkan di bawah.
1 |
function axialToOffset(axialPoint){ |
2 |
axialPoint.y=(axialPoint.y+(Math.floor(axialPoint.x/2))); |
3 |
return axialPoint; |
4 |
}
|
Berikut adalah nilai x
saya nilai i
, dan nilai y
adalah nilai j
untuk dua-dimensi array. Setelah konversi, nilai-nilai yang baru akan terlihat seperti gambar di bawah.



Perhatikan bahwa garis hijau yang mana nilai j
tetap sama tidak berzig-zag lagi, tapi agak sekarang diagonal untuk grid heksagonal kami.
Untuk grid heksagonal vertikal selaras, koordinat offset yang ditampilkan dalam gambar di bawah.



Konversi ke koordinat aksial mengikuti persamaan sama, dengan perbedaan bahwa kita menjaga nilai j
yang sama dan mengubah i
nilai. Metode di bawah ini menunjukkan konversi.
1 |
function offsetToAxial(offsetPoint){ |
2 |
offsetPoint.x=(offsetPoint.x-(Math.floor(offsetPoint.y/2))); |
3 |
return offsetPoint; |
4 |
}
|
Hasilnya adalah seperti yang ditunjukkan di bawah ini.



Sebelum kita menggunakan koordinat baru untuk memecahkan masalah, biarkan aku cepat memperkenalkan Anda ke layar koordinat alternatif lain: kubus koordinat.
2. Kubus atau Kubik Koordinat
Penertiban zigzag sendiri berpotensi telah memecahkan sebagian besar ketidaknyamanan kami memiliki dengan sistem koordinat offset. Kubus atau kubik koordinat lebih lanjut akan membantu kami dalam menyederhanakan rumit logika seperti heuristik atau berputar di sekitar sel heksagonal.
Seperti yang Anda mungkin bisa menebak dari nama, sistem kubik memiliki tiga nilai. Nilai k
atau z
ketiga berasal dari persamaan x y + z = 0
, dimana x
dan y
adalah koordinat aksial. Ini membawa kita ke metode ini sederhana untuk menghitung nilai z
.
1 |
function calculateCubicZ(axialPoint){ |
2 |
return -axialPoint.x-axialPoint.y; |
3 |
}
|
Persamaan x y + z = 0
adalah benar-benar 3D pesawat yang melewati diagonal dari sebuah grid kubus tiga dimensi. Menampilkan semua tiga nilai untuk grid akan menghasilkan gambar berikut untuk keberpihakan heksagonal berbeda.






Garis biru menunjukkan ubin mana nilai z
tetap sama.
3. Keuntungan dari Sistem Koordinat Baru
Anda mungkin bertanya-tanya bagaimana sistem koordinat baru ini membantu kita dengan logika heksagonal. Saya akan menjelaskan beberapa manfaat sebelum kita melanjutkan untuk membuat Tetris heksagonal dengan menggunakan pengetahuan baru.
Gerakan
Mari kita mempertimbangkan ubin tengah pada gambar diatas, yang memiliki nilai-nilai koordinat kubik 3,6, -9
. Kami menyadari bahwa satu koordinat nilai tetap sama untuk ubin di garis berwarna. Selanjutnya, kita bisa melihat bahwa koordinat sisa baik menambah atau mengurangi oleh 1 saat menjejaki salah satu garis berwarna. Misalnya, jika nilai x
tetap sama dan meningkatkan nilai y
1 sepanjang arah, nilai z
berkurang sebesar 1 untuk memenuhi persamaan kami mengatur x y + z = 0
. Fitur ini menjadikan mengontrol gerakan lebih mudah. Kami akan menempatkan ini untuk digunakan dalam bagian kedua dari seri.
Tetangga
Oleh logika yang sama, sangat mudah untuk menemukan tetangga untuk ubin x, y, z
. Dengan menjaga x
yang sama, kita mendapatkan dua tetangga diagonal, x, y-1, z + 1
dan x, y + 1, z-1.
Dengan menjaga y yang sama, kita mendapatkan dua tetangga vertikal, x-1, y, z + 1
dan x + 1, y, z-1.
Dengan menjaga z yang sama, kita mendapatkan sisa dua tetangga diagonal, x + 1, y-1, z
dan x-1, y + 1, z
. Gambar di bawah menggambarkan hal ini untuk ubin di asal.



Hal ini jauh lebih mudah sekarang bahwa kita tidak perlu menggunakan logika yang berbeda berdasarkan genap atau ganjil baris/kolom.
Bergerak di Sekitar Genteng
Satu hal yang menarik untuk melihat gambar di atas adalah semacam siklik simetri untuk semua ubin sekitar merah ubin. Jika kita mengambil koordinat setiap ubin tetangga, koordinat ubin tetangga segera dapat diperoleh dengan Bersepeda nilai koordinat baik kiri atau kanan dan kemudian membahagi dengan -1.
Sebagai contoh, tetangga atas memiliki nilai - 1,0,1
, yang dulu kanan berputar di menjadi 1, - 1,0
dan setelah berlipat -1 menjadi - 1,1,0
, yang merupakan koordinat tetangga tepat. Berputar kiri dan membahagi dengan -1 menghasilkan 0,-1,1
, yang merupakan koordinat tetangga kiri. Dengan mengulangi ini, kita dapat melompat antara semua ubin tetangga sekitar ubin pusat. Ini adalah fitur yang sangat menarik yang dapat membantu dalam logika dan algoritma.
Perhatikan bahwa hal ini terjadi hanya karena fakta bahwa ubin tengah dianggap berada di asal. Kita bisa dengan mudah membuat setiap ubin x, y, z
untuk berada di asal dengan mengurangi nilai x
, y
dan z
dari itu dan semua ubin lain.
Heuristik
Menghitung heuristik efisien adalah kunci ketika datang ke pathfinding atau serupa algoritma. Kubik koordinat membuatnya lebih mudah untuk menemukan heuristik sederhana untuk grid heksagonal karena aspek-aspek yang disebutkan di atas. Kita akan membahas hal ini secara rinci dalam bagian kedua dari seri ini.
Berikut adalah beberapa keuntungan dari sistem koordinat baru. Kita bisa menggunakan perpaduan sistem koordinat yang berbeda dalam implementasi praktis kami. Misalnya, array dua dimensi masih merupakan cara terbaik untuk menyimpan data tingkat, koordinat yang adalah koordinat offset.
Mari kita mencoba untuk membuat versi heksagonal permainan Tetris terkenal dengan menggunakan pengetahuan baru ini.
4. Membuat Heksagonal Tetris
Kita semua telah bermain Tetris, dan jika Anda adalah pengembang game, Anda mungkin telah membuat versi Anda sendiri juga. Tetris adalah salah satu permainan ubin berbasis yang paling mudah yang dapat menerapkan, selain tic tac toe atau Checker, menggunakan array dua dimensi sederhana. Mari kita pertama daftar fitur dari Tetris.
- Dimulai dengan dua dimensi kotak kosong.
- Blok yang berbeda muncul di bagian atas dan pindahkan ke bawah satu ubin pada waktu sampai mereka mencapai bagian bawah.
- Setelah mereka mencapai bagian bawah, mereka mendapatkan disemen ada atau menjadi tidak interaktif. Pada dasarnya, mereka menjadi bagian dari grid.
- Sementara menjatuhkan, blok bisa dipindahkan ke samping, berputar searah jarum jam/ikut, dan jatuh.
- Tujuannya adalah untuk mengisi semua ubin di baris mana pun, yang seluruh baris menghilang, runtuh sisa grid diisi ke atasnya.
- Permainan berakhir ketika ada ubin bebas lagi di atas untuk blok baru untuk memasukkan grid.
Mewakili blok yang berbeda
Sebagai permainan memiliki blok menjatuhkan vertikal, kami akan menggunakan grid heksagonal vertikal selaras. Ini berarti bahwa memindahkan mereka ke samping akan membuat mereka bergerak secara zig-zag. Baris penuh dalam grid terdiri dari serangkaian ubin dalam rangka zig-zag. Dari titik ini, Anda mungkin mulai mengacu pada kode sumber yang disediakan dengan tutorial ini.
Tingkat data disimpan dalam sebuah array dua dimensi yang bernama levelData
, dan terjemahan dilakukan menggunakan offset koordinat, seperti yang dijelaskan dalam tutorial minesweeper heksagonal. Silakan merujuk ke itu jika Anda mengalami kesulitan mengikuti kode.
Unsur interaktif dibagian berikut menunjukkan blok yang berbeda yang kita akan menggunakan. Ada satu blok tambahan, yang terdiri dari tiga ubin diisi selaras vertikal seperti pilar. BlockData
digunakan untuk membuat blok yang berbeda.
1 |
function BlockData(topB,topRightB,bottomRightB,bottomB,bottomLeftB,topLeftB){ |
2 |
this.tBlock=topB; |
3 |
this.trBlock=topRightB; |
4 |
this.brBlock=bottomRightB; |
5 |
this.bBlock=bottomB; |
6 |
this.blBlock=bottomLeftB; |
7 |
this.tlBlock=topLeftB; |
8 |
this.mBlock=1; |
9 |
}
|
Kosong blok template adalah serangkaian tujuh ubin yang terdiri dari ubin tengah yang dikelilingi oleh tetangganya enam. Untuk setiap Blok Tetris, ubin tengah selalu diisi dilambangkan oleh nilai 1
, sedangkan ubin kosong akan dilambangkan oleh nilai 0
. Blok yang berbeda diciptakan oleh mempopulasikan ubin BlockData
sebagai di bawah ini.
1 |
var block1= new BlockData(1,1,0,0,0,1); |
2 |
var block2= new BlockData(0,1,0,0,0,1); |
3 |
var block3= new BlockData(1,1,0,0,0,0); |
4 |
var block4= new BlockData(1,1,0,1,0,0); |
5 |
var block5= new BlockData(1,0,0,1,0,1); |
6 |
var block6= new BlockData(0,1,1,0,1,1); |
7 |
var block7= new BlockData(1,0,0,1,0,0); |
Kami memiliki total tujuh blok yang berbeda.
Memutar blok
Mari saya tunjukkan bagaimana blok memutar menggunakan elemen interaktif di bawah ini. Tekan dan tahan untuk memutar blok, dan tekan x
untuk mengubah arah rotasi.
Untuk memutar blok, kita perlu untuk menemukan semua ubin yang memiliki nilai 1
, set nilai ke 0
, memutar sekali di sekitar ubin tengah untuk menemukan ubin tetangga, dan set nilainya ke 1
. Untuk memutar ubin di sekitar ubin lain, kita dapat menggunakan logika yang dijelaskan dalam bergerak di sekitar ubin bagian di atas. Kami tiba di bawah metode untuk tujuan ini.
1 |
function rotateTileAroundTile(tileToRotate, anchorTile){ |
2 |
tileToRotate=offsetToAxial(tileToRotate);//convert to axial |
3 |
var tileToRotateZ=calculateCubicZ(tileToRotate);//find z value |
4 |
anchorTile=offsetToAxial(anchorTile);//convert to axial |
5 |
var anchorTileZ=calculateCubicZ(anchorTile);//find z value |
6 |
tileToRotate.x=tileToRotate.x-anchorTile.x;//find x difference |
7 |
tileToRotate.y=tileToRotate.y-anchorTile.y;//find y difference |
8 |
tileToRotateZ=tileToRotateZ-anchorTileZ;//find z difference |
9 |
var pointArr=[tileToRotate.x,tileToRotate.y,tileToRotateZ];//populate array to rotate |
10 |
pointArr=arrayRotate(pointArr,clockWise);//rotate array, true for clockwise |
11 |
tileToRotate.x=(-1*pointArr[0])+anchorTile.x;//multiply by -1 & remove the x difference |
12 |
tileToRotate.y=(-1*pointArr[1])+anchorTile.y;//multiply by -1 & remove the y difference |
13 |
tileToRotate=axialToOffset(tileToRotate);//convert to offset |
14 |
return tileToRotate; |
15 |
}
|
16 |
//...
|
17 |
function arrayRotate(arr, reverse){//nifty method to rotate array elements |
18 |
if(reverse) |
19 |
arr.unshift(arr.pop()) |
20 |
else
|
21 |
arr.push(arr.shift()) |
22 |
return arr |
23 |
}
|
Variabel searah jarum jam
digunakan untuk berputar searah jarum jam atau anticlockwise, yang dicapai dengan bergerak nilai array dalam arah yang berlawanan di arrayRotate.
Bergerak blok
Kami menjaga melacak yang i
dan j
mengimbangi koordinat untuk ubin tengah blok menggunakan variabel blockMidRowValue
dan blockMidColumnValue
masing-masing. Untuk memindahkan blok, kami kenaikan atau pengurangan nilai-nilai ini. Kami memperbarui nilai yang sesuai di levelData
dengan nilai-nilai blok yang menggunakan metode paintBlock
. LevelData
diperbarui digunakan untuk membuat adegan setelah setiap perubahan negara.
1 |
var blockMidRowValue; |
2 |
var blockMidColumnValue; |
3 |
//...
|
4 |
function moveLeft(){ |
5 |
blockMidColumnValue--; |
6 |
}
|
7 |
function moveRight(){ |
8 |
blockMidColumnValue++; |
9 |
}
|
10 |
function dropDown(){ |
11 |
paintBlock(true); |
12 |
blockMidRowValue++; |
13 |
}
|
14 |
function paintBlock(){ |
15 |
clockWise=true; |
16 |
var val=1; |
17 |
changeLevelData(blockMidRowValue,blockMidColumnValue,val); |
18 |
var rotatingTile=new Phaser.Point(blockMidRowValue-1,blockMidColumnValue); |
19 |
if(currentBlock.tBlock==1){ |
20 |
changeLevelData(rotatingTile.x,rotatingTile.y,val*currentBlock.tBlock); |
21 |
}
|
22 |
var midPoint=new Phaser.Point(blockMidRowValue,blockMidColumnValue); |
23 |
rotatingTile=rotateTileAroundTile(rotatingTile,midPoint); |
24 |
if(currentBlock.trBlock==1){ |
25 |
changeLevelData(rotatingTile.x,rotatingTile.y,val*currentBlock.trBlock); |
26 |
}
|
27 |
midPoint.x=blockMidRowValue; |
28 |
midPoint.y=blockMidColumnValue; |
29 |
rotatingTile=rotateTileAroundTile(rotatingTile,midPoint); |
30 |
if(currentBlock.brBlock==1){ |
31 |
changeLevelData(rotatingTile.x,rotatingTile.y,val*currentBlock.brBlock); |
32 |
}
|
33 |
midPoint.x=blockMidRowValue; |
34 |
midPoint.y=blockMidColumnValue; |
35 |
rotatingTile=rotateTileAroundTile(rotatingTile,midPoint); |
36 |
if(currentBlock.bBlock==1){ |
37 |
changeLevelData(rotatingTile.x,rotatingTile.y,val*currentBlock.bBlock); |
38 |
}
|
39 |
midPoint.x=blockMidRowValue; |
40 |
midPoint.y=blockMidColumnValue; |
41 |
rotatingTile=rotateTileAroundTile(rotatingTile,midPoint); |
42 |
if(currentBlock.blBlock==1){ |
43 |
changeLevelData(rotatingTile.x,rotatingTile.y,val*currentBlock.blBlock); |
44 |
}
|
45 |
midPoint.x=blockMidRowValue; |
46 |
midPoint.y=blockMidColumnValue; |
47 |
rotatingTile=rotateTileAroundTile(rotatingTile,midPoint); |
48 |
if(currentBlock.tlBlock==1){ |
49 |
changeLevelData(rotatingTile.x,rotatingTile.y,val*currentBlock.tlBlock); |
50 |
}
|
51 |
}
|
52 |
function changeLevelData(iVal,jVal,newValue,erase){ |
53 |
if(!validIndexes(iVal,jVal))return; |
54 |
if(erase){ |
55 |
if(levelData[iVal][jVal]==1){ |
56 |
levelData[iVal][jVal]=0; |
57 |
}
|
58 |
}else{ |
59 |
levelData[iVal][jVal]=newValue; |
60 |
}
|
61 |
}
|
62 |
function validIndexes(iVal,jVal){ |
63 |
if(iVal<0 || jVal<0 || iVal>=levelData.length || jVal>=levelData[0].length){ |
64 |
return false; |
65 |
}
|
66 |
return true; |
67 |
}
|
Di sini, currentBlock
poin untuk blockData
dalam adegan. Dalam paintBlock
, pertama kami menetapkan nilai levelData
untuk ubin tengah blok 1
seperti yang selalu 1
untuk semua blok. Indeks dari titik tengah adalah blockMidRowValue
, blockMidColumnValue.
Kemudian kami pindah ke indeks levelData
ubin di atas tengah ubin blockMidRowValue-1
, blockMidColumnValue
, dan diatur ke 1
jika blok ini ubin sebagai 1
. Kemudian kita berputar searah jarum jam sekali di sekitar tengah ubin untuk mendapatkan ubin berikutnya dan ulangi proses yang sama. Hal ini dilakukan untuk semua ubin sekitar ubin tengah untuk blok.
Memeriksa operasi yang sah
Sementara bergerak atau memutar blok, kita perlu memeriksa apakah itu adalah operasi yang sah. Misalnya, kami tidak dapat memindahkan atau memutar blok jika ubin yang dibutuhkan untuk menduduki sudah diduduki. Juga, kita tidak bisa memindahkan blok di luar grid kami dua dimensi. Kita juga perlu untuk memeriksa jika blok dapat turun lebih lanjut, yang akan menentukan jika kita perlu semen blok atau tidak.
Untuk semua ini, saya menggunakan canMove(i,j)
metode, yang mengembalikan boolean yang mengindikasikan jika menempatkan blok di i, j
adalah langkah yang berlaku. Untuk setiap operasi, sebelum benar-benar mengubah nilai levelData
, kami memeriksa apakah posisi baru untuk blok posisi yang sah yang menggunakan metode ini.
1 |
function canMove(iVal,jVal){ |
2 |
var validMove=true; |
3 |
|
4 |
var store=clockWise; |
5 |
var newBlockMidPoint=new Phaser.Point(blockMidRowValue+iVal,blockMidColumnValue+jVal); |
6 |
clockWise=true; |
7 |
if(!validAndEmpty(newBlockMidPoint.x,newBlockMidPoint.y)){//check mid, always 1 |
8 |
validMove=false; |
9 |
}
|
10 |
var rotatingTile=new Phaser.Point(newBlockMidPoint.x-1,newBlockMidPoint.y); |
11 |
if(currentBlock.tBlock==1){ |
12 |
if(!validAndEmpty(rotatingTile.x,rotatingTile.y)){//check top |
13 |
validMove=false; |
14 |
}
|
15 |
}
|
16 |
newBlockMidPoint.x=blockMidRowValue+iVal; |
17 |
newBlockMidPoint.y=blockMidColumnValue+jVal; |
18 |
rotatingTile=rotateTileAroundTile(rotatingTile,newBlockMidPoint); |
19 |
if(currentBlock.trBlock==1){ |
20 |
if(!validAndEmpty(rotatingTile.x,rotatingTile.y)){ |
21 |
validMove=false; |
22 |
}
|
23 |
}
|
24 |
newBlockMidPoint.x=blockMidRowValue+iVal; |
25 |
newBlockMidPoint.y=blockMidColumnValue+jVal; |
26 |
rotatingTile=rotateTileAroundTile(rotatingTile,newBlockMidPoint); |
27 |
if(currentBlock.brBlock==1){ |
28 |
if(!validAndEmpty(rotatingTile.x,rotatingTile.y)){ |
29 |
validMove=false; |
30 |
}
|
31 |
}
|
32 |
newBlockMidPoint.x=blockMidRowValue+iVal; |
33 |
newBlockMidPoint.y=blockMidColumnValue+jVal; |
34 |
rotatingTile=rotateTileAroundTile(rotatingTile,newBlockMidPoint); |
35 |
if(currentBlock.bBlock==1){ |
36 |
if(!validAndEmpty(rotatingTile.x,rotatingTile.y)){ |
37 |
validMove=false; |
38 |
}
|
39 |
}
|
40 |
newBlockMidPoint.x=blockMidRowValue+iVal; |
41 |
newBlockMidPoint.y=blockMidColumnValue+jVal; |
42 |
rotatingTile=rotateTileAroundTile(rotatingTile,newBlockMidPoint); |
43 |
if(currentBlock.blBlock==1){ |
44 |
if(!validAndEmpty(rotatingTile.x,rotatingTile.y)){ |
45 |
validMove=false; |
46 |
}
|
47 |
}
|
48 |
newBlockMidPoint.x=blockMidRowValue+iVal; |
49 |
newBlockMidPoint.y=blockMidColumnValue+jVal; |
50 |
rotatingTile=rotateTileAroundTile(rotatingTile,newBlockMidPoint); |
51 |
if(currentBlock.tlBlock==1){ |
52 |
if(!validAndEmpty(rotatingTile.x,rotatingTile.y)){ |
53 |
validMove=false; |
54 |
}
|
55 |
}
|
56 |
clockWise=store; |
57 |
return validMove; |
58 |
}
|
59 |
function validAndEmpty(iVal,jVal){ |
60 |
if(!validIndexes(iVal,jVal)){ |
61 |
return false; |
62 |
}else if(levelData[iVal][jVal]>1){//occuppied |
63 |
return false; |
64 |
}
|
65 |
return true; |
66 |
}
|
Proses berikut adalah sama dengan paintBlock
, tapi bukan mengubah nilai-nilai apapun, ini hanya mengembalikan boolean menunjukkan langkah yang berlaku. Meskipun saya menggunakan rotasi mengelilingi logika tengah ubin untuk menemukan tetangga, alternatif yang lebih mudah dan cukup efisien adalah menggunakan nilai-nilai koordinat langsung para tetangga, yang dapat dengan mudah ditentukan dari koordinat tengah ubin.
Render permainan
Tingkat permainan visual diwakili oleh RenderTexture
yang bernama gameScene
. Dalam array levelData
, ubin kosong akan memiliki nilai 0
, dan ubin diduduki akan memiliki nilai 2
atau lebih tinggi.
Blok semen dilambangkan dengan nilai 2
, dan bernilai 5
menunjukkan ubin yang perlu dihapus karena itu adalah bagian dari deretan selesai. Nilai 1
berarti bahwa ubin adalah bagian dari blok. Setelah setiap perubahan negara permainan, kami memberikan tingkat menggunakan informasi di levelData
, seperti yang ditunjukkan di bawah ini.
1 |
//..
|
2 |
hexSprite.tint='0xffffff'; |
3 |
if(levelData[i][j]>-1){ |
4 |
axialPoint=offsetToAxial(axialPoint); |
5 |
cubicZ=calculateCubicZ(axialPoint); |
6 |
if(levelData[i][j]==1){ |
7 |
hexSprite.tint='0xff0000'; |
8 |
}else if(levelData[i][j]==2){ |
9 |
hexSprite.tint='0x0000ff'; |
10 |
}else if(levelData[i][j]>2){ |
11 |
hexSprite.tint='0x00ff00'; |
12 |
}
|
13 |
gameScene.renderXY(hexSprite,startX, startY, false); |
14 |
}
|
15 |
//...
|
Maka nilai 0
dituliskan tanpa warna apapun, nilai 1
dituliskan dengan warna merah, nilai 2
dituliskan dengan warna biru, dan bernilai 5
dituliskan dengan warna hijau.
5. para permainan selesai
Menempatkan semuanya bersama-sama, kita mendapatkan selesai permainan Tetris heksagonal. Silakan pergi melalui kode sumber untuk memahami implementasi lengkap. Anda akan melihat bahwa kita menggunakan offset koordinat dan kubik koordinat untuk tujuan yang berbeda. Misalnya, untuk menemukan jika baris selesai, kami memanfaatkan offset koordinat dan memeriksa baris levelData
.
Kesimpulan
Ini menyimpulkan bagian pertama dari seri. Kami telah berhasil membuat permainan Tetris heksagonal yang menggunakan kombinasi offset koordinat, aksial koordinat dan koordinat kubus.
Di bagian penutup dari seri, kita akan mempelajari tentang gerakan karakter menggunakan koordinat baru di grid heksagonal horizontal selaras.