Making a shooter game with flashpunk: making waves of enemies

Part 1: Memulai dengan flashpunk dan AS3

Part 2: Membuat pesawat menembakkan peluru

Part 3: Tambahkan musuh, tambahkan ketegangan

Part 4: Saatnya bullet pattern!

Part 5

Part 6: Improving our character

Part 7: Background

Part 8: Scrolling camera

Tak terasa kita sudah sampai di seri kesembilan dari serial tutorial membuat game dengan flashpunk. Sekarang kita akan menambahkan lebih banyak musuh ke dalam stage kita yang sudah scrolling secara otomatis. Tapi sebelum itu, kita akan memperbaiki satu bug dari tutorial kita sebelumnya. Coba dari hasil tutorial sebelumnya, ketika scrolling (belum sampai ujung atas) klik-tahan mouse untuk menembak. Peluru tidak keluar dari pesawat, ketika kita mendekat bagian atas, baru terlihat peluru kita. Ini karena posisi awal dan akhir peluru yang masih belum kita ubah.

Ada yang aneh

Bug peluru tutorial sebelumnya

Untuk memperbaikinya kita tinggal mengubah posisi awal dan akhir peluru kita sesuai dengan camera offset. Dalam class character, ubahlah code buat menembakkan peluru jadi seperti ini:

				if (timeToDeltaShot > deltaShot)
				{
					shoot(FP.camera. x + Input.mouseX, FP.camera.y + Input.mouseY);
					timeToDeltaShot -= deltaShot;
				}

dan ubahlah inisiasi peluru dalam fungsi shoot() menjadi seperti ini:

var peluru:Bullet = new Bullet(AssetsList.PELURU1, FP.camera.x + x, FP.camera.y + y, xTarget, yTarget);

dengan dua perbaikan ini sebenarnya kita sudah memperbaiki bug kita, tapi masih ada satu masalah lagi: yaitu peluru akan otomatis dihapus dari world kalau keluar dari koordinat tertentu. Coba lihat fungsi update() kelas Bullet, kita akan bisa melihat baris codenya. Bagaimana penyelesaiannya? tinggal comment saja baris yang menghapus peluru dan masalah selesai.

			if (x < 0 || x > 640 || y < 0 || y > 480)
			{
				// remove peluru ketika keluar dari game window
				// this.world.remove(this);
			}

Peluru sudah menembak dengan benar

Now that that’s done, mari kita bahas tentang tulisan kita kali ini. Kalau kamu memainkan game shmup (shoot ‘em up) para musuh berdatangan dalam beberapa kelompok,  tiap-tiap kelompok terdiri dari beberapa musuh. Kelompok-kelompok ini dinamakan wave (saya menamakannya begitu, mungkin orang lain punya istilah sendiri), dan bagaimana cara membuat wave inilah yang akan kita bahas dalam blog post kali ini. Sekali lagi saya tidak mengatakan bahwa cara saya adalah yang paling benar, cara ini juga bukanlah satu-satunya cara, tapi ini adalah cara yang akan saya share dalam kesempatan ini.

Contoh wave dari touhou

Wave adalah rentetan musuh seragam (setipe) yang muncul dengan jeda waktu tertentu. Dari definisi simple barusan, kita bisa membuat wave dengan mudah dengan menggunakan loop (perulangan). Kita akan membuat class wave yang mampu mengatur kapan dan dimana satu wave muncul, berapa banyak musuh dalam satu wave, dan AI apa yang digunakan para musuh dengan mudah. Buatlah class baru seperti di bawah ini:

package  
{
	import net.flashpunk.World;
	
	/**
	 * ...
	 * @author Aryadi Perwira Subagio
	 */
	public class Wave 
	{
		
		public function Wave() 
		{
			
		}
		
		/**
		 * Menambahkan satu wave ke permainan
		 * @param	x				Posisi x dari musuh pertama di wave ini
		 * @param	y				Posisi y dari musuh pertama di wave ini
		 * @param	deltaX			Selisih x antara tiap musuh di wave ini
		 * @param	deltaY			Selisih y antara tiap musuh di wave ini
		 * @param	enemy			Musuh yang dibuat wave ini
		 * @param	howMany			Jumlah musuh
		 * @param	dunia			World-nya wave ini
		 */
		public function addWave(x:int, y:int, deltaX:int, deltaY:int, player:Character, howMany:int, dunia:World):void 
		{
			for (var i:int = 0; i < howMany; i++) 
			{
				var AI:BasicAI = new BasicAI(player);
				var musuh:Enemy = new Enemy(AssetsList.ENEMY1, AI);
				musuh.x = x + i * deltaX;
				musuh.y = y + i * deltaY;
				
				musuh.layer = 2;
				dunia.add(musuh);
				
			}
		}
		
	}

}

bagian yang penting di sini adalah fungsi addWave() yang berguna untuk menambahkan wave yang kita mau ke dalam permainan. Di sini kita membuat perulangan yang akan membuat musuh sebanyak variabel howMany. Dalam perulangan ini kita membuat AI dan musuh seperti yang kita lakukan dalam class MapOne, menentukan target serangan (alias player) dan juga sprite musuh (di sini: AssetsList.ENEMY1). Selanjutnya kita mengatur posisi musuh dalam wave ini. Normalnya kita cukup memberi nilai ke dalam musuh.x dan musuh.y, tapi bisa saja dalam sebuah wave posisi musuh berbeda sedikit untuk membentuk formasi tertentu, karena itu kita memberikan i * deltaX dan deltaY. Kenapa harus dikalikan dengan i? karena nilai awal i adalah 0 sehingga posisi musuh pertama dalam wave ini adalah posisi seperti yang kita tentukan dalam parameter, untuk musuh berikutnya, posisinya akan berbeda sesuai jeda yang kita berikan.

Sepertinya saya belum pernah menjelaskan tentang perulangan (looping) dan kaitannya dengan permrograman, karena itu kali ini akan saya bahas sedikit. Perulangan (atau looping) dalam pemrograman adalah sebuah cara untuk mengulang baris kode kita sehingga kita tidak perlu melakukan tugas yang repetitif. Coba bayangkan kalau kita ingin membuat 50 pesawat dalam satu wave misalnya (iseng banget), maka akan lebih mudah bagi kita dengan membuat looping. Ada 3 macam looping dalam pemrograman: for loop, while loop, dan do while. Sekarang saya hanya akan membahas for loop, sisanya akan saya bahas di blog post saya yang lain kalau sempat.

For loop digunakan ketika kita tahu berapa kali kita akan mengulang baris kode kita. Dalam kasus di atas kita akan mengulang kode kita sebanyak nilai variabel howMany. Syntax penulisan for loop adalah for(inisiasi; kondisi; increment). Inisiasi adalah pendeklarasian variabel yang kita gunakan dalam for loop (dalam hal ini: i). Kondisi (sebenarnya saya lupa istilahnya, mungkin ada yang tahu?) adalah kondisi yang dimana jika kondisi ini bernilai true, maka perulangan akan terus berjalan (dalam hal ini: selama i bernilai kurang dari howMany). Increment adalah seberapa banyak penambahan terhadap variabel di inisiasi terjadi, i++ berarti nilai i bertambah satu setiap perulangannya (kita bisa menulis i = i + 2 atau i = i + 3 atau nilai lainnya kalau itu yang kita inginkan).

Sekarang mari kita implementasikan class baru kita ini. Bukalah class MapOne dan tambahkan variabel ini di awal class:

private var level1Wave:Wave = new Wave();

lalu tambahkan satu baris berikut di  dalam constructor:

level1Wave.addWave(100, 200, 10, 50, airship, 4, this);

silahkan ubah-ubah nilai parameter kalau anda mau. Kita bisa saja tekan F5 sekarang dan melihat hasilnya, tapi sebelum itu ada dua class yang harus kita ubah sedikit. Buka BasicAI lalu ubahlah fungsi shoot() menjadi seperti ini:

		private function shoot(target:Character):void 
		{
			if (!actor.world) 
			{
				// buat ngatasi bug
				return;
			}
			
			var peluru:Bullet = new Bullet(AssetsList.PELURU1, actor.x, actor.y, FP.camera.x + target.x, FP.camera.y + target.y, 500, "player");
			peluru.attackPower = actor.power;
			actor.world.add(peluru);
		}

yang paling mencolok adalah comment “// buat ngatasi bug” yang saya tulis di situ. Terkadang memang ada bug musuh mencoba nembak padahal sudah dihapus dari world sehingga menyebabkan crash, di sini kalau musuh sudah keluar dari world maka akan langsung keluar dari fungsi (tidak nembak). Kedua, dalam inisiasi peluru adalah posisi target kini memperhitungkan posisi camera (FP.camera.x dan FP.camera.y) kalau posisi target tidak memperhitungkan orientasi camera, maka tembakan musuh akan meleset (jauh).

Sesudah itu bukalah EnemyAI, dalam fungsi update() ada code yang berperan untuk menghapus musuh ketika sudah keluar dari window. Karena sekarang kita sudah menggunakan camera scrolling, maka code-nya pun harus diubah agar sesuai dengan orientasi camera.

public function update(elapsedTime:Number):void 
		{
			if (actor.y > FP.camera.y + FP.bounds.height) 
			{
				actor.world.remove(actor);
			}
		}

silahkan tekan F5 dan lihatlah hasilnya.

Dan seperti yang pernah saya janjikan, saya akan memberikan file project kita selama ini: Blog project

Aryadi Perwira

Self-proclaimed AS3 blackbelt.

More Posts

Notice: This work is licensed under a BY-NC-SA. Permalink: Making a shooter game with flashpunk: making waves of enemies
  • Ganteng00

    [ask] kalau ingin musuhnya muncul dari berbagai arah dengan jumlah misalnya 50 buah,,,bagaimana scriptnya???

Stop SOPA