Logica Pokopunk another part3

hallo balik lagi dengan meneruskan tulisan saya sebelumnya, dan saya mohon maaf atas keterlambatan tulisan ini. Pada part kali ini saya membuat :
– setiap blok bisa disentuh
– hanya boleh pindah setiap blok yang bersentuhan
– menghapus blok jika lebih dari 3 yang sudah disatukan/dipilih
– membuat blok baru yang telah hilang

Pertama, kita buka file Hexa.as dan kita masukan beberapa variable untuk mengubahnya

package actor
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import net.flashpunk.Entity;
	import net.flashpunk.Graphic;
	import net.flashpunk.graphics.Image;
	import net.flashpunk.Mask;
	import net.flashpunk.FP;
	import net.flashpunk.utils.*;

	public class Hexa extends Entity
	{
		private var img : Image = new Image(new BitmapData(32, 32, false, 0xFFFFFF));
		public var pForPoint : Point = new Point(0, 0);
		public var hasPointUp : Boolean = false;
		public function Hexa(numimg:int)
		{
			graphic = img;

			switch(numimg)
			{
				case 0:
					img.color = 0xFF0000;
					break;
				case 1:
					img.color = 0x00FF00;
					break;
				case 2:
					img.color = 0x0000FF;
					break;
				case 3:
					img.color = 0xFF00FF;
					break;
				default:
					img.color = 0xFFCC00;
					break;
			}
			type = "block";
			setHitbox(32, 32);
		}

	}

}

saya mengubah pada line 15 dengan menambahkan var point, yang akan digunakan untuk mengetahui var nilai var yang dibawa oleh setiap blok hexa. Dan pada line 16 saya menambahkan var bool yang saya gunakan untuk memudahkan mengetahui apakah blok ini sudah saya lewati. Dan terakhir saya menambahkan pada line 39 untuk membuat type dari class hexa ini, yang digunakan untuk mengetahui setiap blok yang disentuh.

Setelah mengubah class hexa, selanjutnya kita mengubah class GameStage yang banyak sekali perubahan. Sekarang buka file GameStage.as, dan kita bahas satu-persatu :

public function GameStage()
{
	for (var kolom:int = 0; kolom < 7; kolom++)
	{
		arHolder[kolom] = new Array();
		for (var baris:int = 0; baris < 7; baris++)
		{
			var newInt : int = FP.rand(5);
			arHolder[kolom][baris] = newInt;
		}
	}

	for (var thisX:int = 0; thisX < 7; thisX++)
	{
		for (var thisY:int = 0; thisY < 7; thisY++)
		{
			var ranInt :int = arHolder[thisX][thisY];
			var newHex : Hexa = new Hexa(ranInt);
			add(newHex);
			newHex.x = ((thisX + 3) * 40) + 40;
			newHex.pForPoint.x = thisX;
			newHex.pForPoint.y = thisY;
			newHex.name = thisX+" "+thisY;
			if (thisX % 2 != 1)
			{
				newHex.y = ((thisY+3) * 40)+10;
			}
			else
			{
				newHex.y = ((thisY+3) * 40)-10;
			}
		}
	}
}

pada line 8 saya mengubah dari random 6 menjadi 5, karena saya melakukan kesalahan bahwa hanya ada 5 warna yang ada didalam game tersebut. Setelah itu kita juga mengisi variable point pada hexa yang nanti akan kita gunakan untuk mengecek posisi array holder. Dan tentunya terkahir posisinya kita atur sesuai dengan pokopang, pada line 24, saya mengecek apakah posisi X tesebut jika dibagi 2 akan menyisakan angka 1? jika iya maka posisi Y akan ditambah 10, jika tidak posisinya akan di kurang 10.

Ok kalian bisa melakukan pengechekan code dengan mengcompilenya, atau lanjut ke bagian selanjutnya, dimana kita akan membuat hexa tersebut bisa di klik. Ubah fungsi update menjadi seperti dibawah ini :

override public function update():void
{
	super.update();
	var e : Hexa = Hexa(this.collidePoint("block", mouseX, mouseY));
	if (e != null && Input.mousePressed)
	{
		remove(e);
	}
}

kode diatas membuat setiap blok yang kita klik akan dihapus dari world. Untuk mencoba coba complie code yang sudah dibuat, dan klik blok hexa tersebut.

Jika kalian berhasil melakukannya kita bisa melanjutkan untuk memperbaiki code tersebut, yang kita inginkan adalah, setiap blok yang tersentuh akan kita akan memasukan kedalam array collect, dan dibandingkan dengan blok selanjutnya yang kita sentuh apakah nilainya sama dengan nilai yang selanjutnya. Jika iya maka masukan kedalam array collect. coba cek gambar di bawah ini :

contoh logika

merah = posisi hexa yang dipilih kuning = posisi hexa yang bisa dipilih selanjutnya hijau = adalah posisi hexa yang sudah dimasukan kedalam koleksi array

Saatnya kita ubah code dari fungsi update kita, tapi sebelumnya tambahkan dulu beberapa variable:

public class GameStage extends World
{
	private var arHolder : Array = new Array();
	private var cekInt : int = -1;
	private var arCollect : Array = new Array();
	private var oneShote : Boolean = false;

	... //fungsi yang lain tapi tidak saya tampilkan

	override public function update():void
	{
		super.update();
		var e : Hexa = Hexa(this.collidePoint("block", mouseX, mouseY));
		if (e != null && Input.mousePressed)
		{
			oneShote = false;
			if (cekInt == -1)
			{
				cekInt = arHolder[e.pForPoint.x][e.pForPoint.y];
				e.hasPointUp = true;
				arCollect.push(e.pForPoint.x + " " + e.pForPoint.y);
			}
		}
	}
}

cek line 16, disini saya membuat variable oneShote yang saya gunakan untuk mengetahui bahwa mouse sudah di clik, dan selanjutnya mengecheck apakah posisi cekInt di posisi kosong, jika iya maka masukan posisi x dan y dari hexa kedalam arCollect. Selanjutnya meneruskan code setelah if.

else if (e != null && Input.mouseDown )
{
	var s:String = arCollect[arCollect.length - 1];
	var cekX : int = int(s.substr(0, 1));
	var cekY : int = int(s.substr(2,1));
	var tempCekInt : int = arHolder[e.pForPoint.x][e.pForPoint.y];

	if (e.hasPointUp == false)
	{
		if (cekArray(cekX, cekY, e.pForPoint.x, e.pForPoint.y) && (cekInt == tempCekInt))
		{
			arCollect.push(e.pForPoint.x + " " + e.pForPoint.y);
			e.hasPointUp = true;
		}
	}
}
else if (Input.mouseReleased && oneShote==false)
{
	if (arCollect.length > 2)
	{
		for (var i : int = 0 ; i < arCollect.length; i++)
		{
			var a: String = arCollect[i];
			var cekforX : int = int(a.substr(0, 1));
			var cekforY : int = int(a.substr(2, 1));
			arHolder[cekforX][cekforY] = -1;
			var hex : Hexa = getInstance(cekforX+" "+cekforY)as Hexa;
			remove(hex);
		}
	}
	oneShote = true;
	arCollect.splice(0);
	cekInt = -1;
	GoDownArray();
	createAnotherHexa();
}

Saatnya membahas code diatas, dari line 3 ~ 5, saya mengambil data dari arCollect pada posisi terakhir, dan selanjutnya mengetahui dari posisi cekX dan cekY dari arCollect tersebut, dan membuat var int untuk mengetahui nilai dari hexa tersebut.

Lanjut ke line 8, disana dilakukan pengecheckan sekali lagi apakah hexa tersebut sudah masuk kedalam arCollect apa belum. Dan setelah pada line 10 saya melakukan cekarray dari posisi yang baru dengan posisi yang sebelumnya, apakah sesuai dengan rules yang kita inginkan (yang akan dibahas setelah ini), dan mengecek int dari nilai hexa yang baru dan nilai hexa yang sebelumnya. Pada line 12 jika kondisi diatasnya true, maka nilai hexa tersebut dimasukan kembali ke arcollect, dan menandakan hexa tersebut kalau sudah dimasukan kedalam arCollect.

Lanjut ke line 17, Dimana fungsi tersebut akan mengecheck mouseRelease dan oneshote dalam kondisi false. Dan melakukan pengechekan kembali apakah arCollect lebih dari 2. Pada line 21, saya membuat looping untuk menghapus setiap hexa yang ada di arCollect, dan menganti posisi arHolder yang akan dihapus menjadi -1. Pada line 31, saya mulai mengembalikan oneshote menjadi true, mengkosongkan arCollect, mengembalikan cekInt, melakukan fungsi GoDownArray, dan melakukan fungsi createAnotherHexa.

saatnya lanjut ke fungsi yang lain. Cek fungsi cekArray yang dibawah ini :

private function cekArray(xIni:int, yIni:int, xTujuan:int, yTujuan:int):Boolean
{
	if (xTujuan < 0 || xTujuan > 6|| yTujuan < 0 || yTujuan > 6) return false;
	if (xIni == xTujuan && (yIni == yTujuan + 1 || yIni == yTujuan - 1)) return true;
	else if (xIni == xTujuan + 1 || xIni == xTujuan -1)
	{
		if (xIni % 2 == 0)
		{
			if(yIni == yTujuan || yIni == yTujuan - 1) return true;
		}
		else
		{
			if(yIni == yTujuan || yIni == yTujuan + 1) return true;
		}
	}
	return false;
}

Dari code diatas saya akan melakukukan pengecekan setiap hexa yang kita click, hanya boleh memilih posisi hexa yang saling bersentuhan, buat lebih jelasnya coba cek gambar dibawah.

logic sample

merah = hexa yang kita pilih kuning = hexa yang boleh dipilih selanjutnya

Lanjut ke fungsi untuk menurunkan hexa dimana jika ada posisi hexa yang kosong atau telah dihapus, maka posisi hexa yang diatasnya akan diturunkan. cek code dibawah ini :

private function GoDownArray():void
{
	for (var kolom:int = 0 ; kolom < 7; kolom++)
	{
		for (var baris: int = 6; baris > 0; baris--)
		{
			if (arHolder[kolom][baris] == -1)
			{
				for (var cekBarisAtas : int = baris - 1; cekBarisAtas > 0; cekBarisAtas--)
				{
					if (arHolder[kolom][cekBarisAtas] != -1) { break;}
				}
				arHolder[kolom][baris] = arHolder[kolom][cekBarisAtas];
				arHolder[kolom][cekBarisAtas] = -1;

				var hex : Hexa = getInstance(kolom + " " + cekBarisAtas) as Hexa;
				if (hex == null) continue;
				hex.pForPoint.y = baris;

				if (kolom % 2 != 1)
				{
					hex.y = ((baris+3) * 40)+10;
				}
				else
				{
					hex.y = ((baris+3) * 40)-10;
				}
				hex.name = kolom +" " + baris;

			}

		}
	}
}

Jadi saya melakukan looping untuk mengeecheck adakah arHolder yang nilai arraynya -1, jika ada akan dilakukan looping kembali. Cek kode diatas pada line 9 ~ 11, dimana kode tersebut jika akan dilakukan pengecekan pada array yang diatasnya. Jika bertemu dengan posisi arHolder yang tidak sama dengan -1 maka looping akan dihentikan, dan menukarnya nilai tersebut dengan nilai aray yang kosong, dan memanggil hexa pada posisi tersebut untuk turun ke posisi yang kosong. Setelah menurunkan posisi hexa, selanjutnya kita akan membuat hexa baru yang telah ditinggalkan oleh hexa yang lama karena sudah diturunkan, untuk itu cek kode yang bawah ini :

private function createAnotherHexa():void
{
	for (var kolom:int = 0 ; kolom < 7; kolom++)
	{
		for (var baris: int = 6; baris > -1; baris--)
		{
			if (arHolder[kolom][baris] == -1)
			{
				var newInt : int = FP.rand(5);
				arHolder[kolom][baris] = newInt;
				var newHexa : Hexa = new Hexa(newInt);
				add(newHexa);
				newHexa.x = ((kolom + 3) * 40) + 40;
				newHexa.pForPoint.x = kolom;
				newHexa.pForPoint.y = baris;
				newHexa.name = kolom+" "+baris;
				if (kolom % 2 != 1)
				{
					newHexa.y = ((baris+3) * 40)+10;
				}
				else
				{
					newHexa.y = ((baris+3) * 40)-10;
				}
			}
		}
	}
}

Dikode diatas saya melakukan looping jika ada arHolder yang nilainya -1, maka akan di isi dengan nilai array yang baru dan dibuat hexa baru pada posisi hexa yang kosong. Untuk kode lengkap dari GameStage.as bisa dicek dibawah ini :

package room
{
	import actor.Hexa;
	import flash.geom.Point;
	import flash.net.NetStreamMulticastInfo;
	import net.flashpunk.Entity;
	import net.flashpunk.World;
	import net.flashpunk.FP;
	import net.flashpunk.utils.*;

	public class GameStage extends World
	{
		private var arHolder : Array = new Array();
		private var cekInt : int = -1;
		private var arCollect : Array = new Array();
		private var oneShote : Boolean = false;
		public function GameStage()
		{

			for (var kolom:int = 0; kolom < 7; kolom++)
			{
				arHolder[kolom] = new Array();

				for (var baris:int = 0; baris < 7; baris++)
				{
					var newInt : int = FP.rand(5);
					arHolder[kolom][baris] = newInt;

				}
			}

			for (var thisX:int = 0; thisX < 7; thisX++)
			{
				for (var thisY:int = 0; thisY < 7; thisY++)
				{
					var ranInt :int = arHolder[thisX][thisY];
					var newHex : Hexa = new Hexa(ranInt);
					add(newHex);
					newHex.x = ((thisX + 3) * 40) + 40;
					newHex.pForPoint.x = thisX;
					newHex.pForPoint.y = thisY;
					newHex.name = thisX+" "+thisY;
					if (thisX % 2 != 1)
					{
						newHex.y = ((thisY+3) * 40)+10;
					}
					else
					{
						newHex.y = ((thisY+3) * 40)-10;
					}
				}
			}
		}

		override public function update():void
		{
			super.update();
			var e : Hexa = Hexa(this.collidePoint("block", mouseX, mouseY));
			if (e != null && Input.mousePressed)
			{
				oneShote = false;
				if (cekInt == -1)
				{
					cekInt = arHolder[e.pForPoint.x][e.pForPoint.y];
					e.hasPointUp = true;
					arCollect.push(e.pForPoint.x + " " + e.pForPoint.y);
				}
			}
			else if (e != null && Input.mouseDown )
			{
				var s:String = arCollect[arCollect.length - 1];
				var cekX : int = int(s.substr(0, 1));
				var cekY : int = int(s.substr(2,1));
				var tempCekInt : int = arHolder[e.pForPoint.x][e.pForPoint.y];

				if (e.hasPointUp == false)
				{
					if (cekArray(cekX, cekY, e.pForPoint.x, e.pForPoint.y) && (cekInt == tempCekInt))
					{
						arCollect.push(e.pForPoint.x + " " + e.pForPoint.y);
						e.hasPointUp = true;
					}
				}
			}
			else if (Input.mouseReleased && oneShote==false)
			{
				if (arCollect.length > 2)
				{
					for (var i : int = 0 ; i < arCollect.length; i++)
					{
						var a: String = arCollect[i];
						var cekforX : int = int(a.substr(0, 1));
						var cekforY : int = int(a.substr(2, 1));
						arHolder[cekforX][cekforY] = -1;
						var hex : Hexa = getInstance(cekforX+" "+cekforY)as Hexa;
						remove(hex);
					}
				}
				oneShote = true;
				arCollect.splice(0);
				cekInt = -1;
				GoDownArray();
				createAnotherHexa();
			}
		}

		private function cekArray(xIni:int, yIni:int, xTujuan:int, yTujuan:int):Boolean
		{
			if (xTujuan < 0 || xTujuan > 6|| yTujuan < 0 || yTujuan > 6) return false;
			if (xIni == xTujuan && (yIni == yTujuan + 1 || yIni == yTujuan - 1)) return true;
			else if (xIni == xTujuan + 1 || xIni == xTujuan -1)
			{
				if (xIni % 2 == 0)
				{
					if(yIni == yTujuan || yIni == yTujuan - 1) return true;
				}
				else
				{
					if(yIni == yTujuan || yIni == yTujuan + 1) return true;
				}
			}
			return false;
		}

		private function GoDownArray():void
		{
			for (var kolom:int = 0 ; kolom < 7; kolom++)\
			{
				for (var baris: int = 6; baris > 0; baris--)
				{
					if (arHolder[kolom][baris] == -1)
					{
						for (var cekBarisAtas : int = baris - 1; cekBarisAtas > 0; cekBarisAtas--)
						{
							if (arHolder[kolom][cekBarisAtas] != -1) { break;}
						}

						arHolder[kolom][baris] = arHolder[kolom][cekBarisAtas];
						arHolder[kolom][cekBarisAtas] = -1;

						var hex : Hexa = getInstance(kolom + " " + cekBarisAtas) as Hexa;
						if (hex == null) continue;
						hex.pForPoint.y = baris;

						if (kolom % 2 != 1)
						{
							hex.y = ((baris+3) * 40)+10;
						}
						else
						{
							hex.y = ((baris+3) * 40)-10;
						}
						hex.name = kolom +" " + baris;

					}

				}
			}
		}

		private function createAnotherHexa():void
		{
			for (var kolom:int = 0 ; kolom < 7; kolom++)
			{
				for (var baris: int = 6; baris > -1; baris--)
				{
					if (arHolder[kolom][baris] == -1)
					{
						var newInt : int = FP.rand(5);
						arHolder[kolom][baris] = newInt;
						var newHexa : Hexa = new Hexa(newInt);
						add(newHexa);
						newHexa.x = ((kolom + 3) * 40) + 40;
						newHexa.pForPoint.x = kolom;
						newHexa.pForPoint.y = baris;
						newHexa.name = kolom+" "+baris;
						if (kolom % 2 != 1)
						{
							newHexa.y = ((baris+3) * 40)+10;
						}
						else
						{
							newHexa.y = ((baris+3) * 40)-10;
						}
					}
				}
			}
		}

		private function CekAllArray() :void
		{
			for (var i : int = 0 ; i < 7; i++)
			{
				FP.log(arHolder[i]);
			}
		}
	}
}

Fiuh… akhirnya kita selesai juga membahas semuanya. Untuk mencopy kode yang sudah saya buat kalian bisa download disini. Jika ingin mencoba bisa kesini

bagian lain dari tutorial ini :
1. Membuat game seperti pokopang
2. Memasukan hexa dan mengatur posisi seperti pokopang
3. Mengatur logika pokopang

Leave a Reply

Your email address will not be published. Required fields are marked *