Tambahkan musuh, tambahkan ketegangan

Di artikel pertama saya, kita membuat pesawat kita bergerak sesuai tombol yang ditekan. Di artikel kedua, pesawat kita sudah bisa menembakkan peluru di arah mouse. Sekarang kita akan menambahkan musuh untuk kita lawan. Langsung saja, tambahkan sprite berikut ke folder asset

 


sprite seperti ini disebt spritesheet, yaitu satu file gambar / image terdapat beberapa sprite yang nantinya bisa dianimasikan oleh engine, dalam hal ini flashpunk. Buatlah class enemy yang meng-inherit class Entity.

 

package
{
	import net.flashpunk.Entity;
	import net.flashpunk.graphics.Spritemap;
	import net.flashpunk.FP;

	/**
	 * ...
	 * @author Aryadi Perwira Subagio
	 */
	public class Enemy extends Entity
	{
		private var img:Spritemap;
		private var logic:EnemyAI;

		public function Enemy(sprite:*, AI:EnemyAI)
		{
			img = new Spritemap(sprite, 32, 32);
			img.add("fly", [0, 1, 2], 10);
			graphic = img;
			img.play("fly");

			logic = AI;
			logic.actor = this;
		}

		override public function update():void
		{
			logic.update(FP.elapsed);
		}

	}

}


class Enemy ini mirip dengan class Character, bedanya adalah bukannya memakai class Image, class Enemy memakai class Spritemap, ini karena Spritemap lebih berguna untuk animasi menggunakan spritesheet. Kode di baris 18 membuat frame-frame animasi berdasarkan spritesheet yang kita masukkan di parameter pertama, parameter kedua dan ketiga adalah lebar dan tinggi satu sprite di dalam spritesheet, dalam hal ini 32 x 32. Di baris 19 kita menambahkan animasi bernama “fly” dengan frame ke 0, ke 1, dan ke 2. Urutan frame dimulai dari frame ke 0, yaitu sprite pertama dalam jarak 32 x 32 dari titik 0, 0. Frame ke 1 adalah frame di sebelah kanannya, dan seterusnya hingga sampai ujung spritesheet. Jika tinggi spritesheet lebih dari 32, misalkan kita punya spritesheet 3 sprite mendatar dan 2 sprite menurun, maka frame ke 3 adalah sprite terkiri dari baris kedua, begitu seterusnya untuk baris ketiga. Parameter ketiga adalah frame per second, yang kita buat 10 FPS, tapi bisa diubah sesuai keinginan programmer.

 

Baris ke 21 membuat spritesheet menjalankan animasi sesuai dengan nama animasi yang kita panggil. Di sini kita menjalankan animasi “fly” tapi dalam class dengan spritesheet lebih besar dan lebih banyak animasi, kita bisa menentukan animasi mana yang ingin kita jalankan. Baris ke 23 mengatur logic alias AI musuh yang akan berjalan tiap update, dan baris ke 24 memberitahu class AI bahwa ia di-assign ke entity ini.

 

Dalam fungsi update kita memanggil fungsi update dari logic agar AI bisa menggerakkan Enemy. FP.Elapsed adalah berapa lama waktu telah berlalu semenjak frame sebelumnya, idealnya fungsi update mengetahui waktu ini agar pergerakan semua Entity dalam game sama cepat walaupun dimainkan di komputer dengan spesifikasi berbeda.

 

Berikutnya kita akan membuat class EnemyAI sebagai AI untuk musuh, buat kelas baru seperti ini:

 

package
{
	/**
	 * ...
	 * @author Aryadi Perwira Subagio
	 */
	public class EnemyAI
	{
		protected var player:Character;
		public var actor:Enemy;

		public function EnemyAI()
		{

		}

		public function update(elapsedTime:Number):void
		{

		}
	}

}

 

variabel player adalah supaya musuh mengetahui posisi pemain agar bisa menembakkan peluru dengan tepat, variabel actor menentukan Enemy mana yang menggunakan AI ini. Class kosong, atau disebut juga abstract class, ini sudah cukup untuk bisa kita gunakan karena pengimplementasiannya adalah di child class, mari kita buat contoh child class dari EnemyAI.

 

package
{
	/**
	 * ...
	 * @author Aryadi Perwira Subagio
	 */
	public class BasicAI extends EnemyAI
	{
		private var moveSpeed:int = 50;
		private var deltaShot:Number = 1;
		private var timeToDeltaShot:Number = 0;

		public function BasicAI(player:Character)
		{
			this.player = player;
		}

		override public function update(elapsedTime:Number):void
		{
			actor.y += moveSpeed * elapsedTime;

			timeToDeltaShot += elapsedTime;
			if (timeToDeltaShot >= deltaShot)
			{
				shoot(player);
				timeToDeltaShot -= deltaShot;
			}

			if (actor.y > 480)
			{
				actor.world.remove(actor);
			}
		}

		private function shoot(target:Character):void
		{
			var peluru:Bullet = new Bullet(actor.x, actor.y, target.x, target.y);
			actor.world.add(peluru);
		}
	}

}

 

Baris 9 sampai 11 adalah variabel-variabel yang kita butuhkan untuk class ini. Variabel moveSpeed adalah kecepatan gerak musuh, di sini kita buat sama dengan player, dan dua variabel sisanya adalah untuk memberikan jeda tembakan musuh, di sini kita buat jeda tembakan satu detik. Di constructor kita berikan player sebagai parameter agar musuh bisa mengetahui posisi player. Fungsi update memiliki parameter elapsedTime untuk mengetahui berapa lama waktu telah berlalu sejak frame sebelumnya.

 

Baris ke 20 menggerakkan Enemy ke bawah sesuai dengan kecepatan gerak. Baris ke 22 menambahkan waktu ke jeda waktu antar tembakan sesuai dengan waktu yang telah berlalu sejak frame sebelumnya, jika jeda waktu sudah melewati jeda antar tembakan yang sudah kita tentukan, Enemy akan menembak target yang dalam hal ini adalah player, setelah itu jeda waktu antar tembakan akan direset untuk perhitungan jeda tembakan berikutnya. Untuk mereset, timeToDeltaShot tidak kita kembalikan ke 0 tapi kita kurangi dengan deltaShot. Ini karena ketika menembak, besar kemungkinannya bahwa timeToDeltaShot lebih dari deltaShot, kalau kita kembalikan ke 0 maka akan ada perbedaan waktu antara tembakan sekarang dengan tembakan berikut. Untuk waktu tembakan yang sempurna, kita kurangi timeToDeltaShot dengan deltaShot.

 

Conditional if di baris 29 mencek apakah Enemy sudah keluar dari layar, jika sudah maka Enemy akan dikeluarkan dari world agar tidak di-update lagi. Kalau masih di-update setelah keluar dari layar akan ada tembakan dari luar layar. Fungsi shoot di AI ini kurang lebih sama dengan fungsi Shoot milih class Character, bedanya adalah fungsi ini menarget pemain.

 

Itu adalah class-class baru yang kita buat di tulisan ini, sekarang sebelum men-test hasil akhir game kita kita akan memperbarui dua class lama, yang pertama adalah class Character. Ubahlah fungsi update agar pesawat pemain menembak bukan ketika mouse ditekan, tapi ditahan, dengan kode berikut:

 

			if (Input.mouseDown)
			{
				timeToDeltaShot += FP.elapsed;

				if (timeToDeltaShot > deltaShot)
				{
					shoot(Input.mouseX, Input.mouseY);
					timeToDeltaShot -= deltaShot;
				}
			}

 

logika kode ini sama dengan logika kode BasicAI, karena itu tambahkan variabel ini di class Character:

 

		private var deltaShot:Number = 0.5;
		private var timeToDeltaShot:Number = 0;

 

Berikutnya kita akan mengubah class MapOne, pertama-tama embed sprite musuh

 

		[Embed(source = "../assets/enemy-1.png")]
		private const ENEMY1:Class;

 

lalu tambahkan variabel untuk membuat musuh dan juga Ainya

 

		private var AI1:BasicAI = new BasicAI(airship);
		private var enemy:Enemy = new Enemy(ENEMY1, AI1);

 

kemudian ubahlah constructor untuk mengubah posisi awal pemain dan musuh, dan juga menambahkan musuh

 

		public function MapOne()
		{
			airship.x = 300;
			airship.y = 400;

			enemy.x = 200;
			enemy.y = 10;

			add(airship);
			add(enemy);
		}

 

kalau sudah, tekan F5 dan lihatlah game kita sudah memiliki musuh.

 

 

Di bawah ini adalah hasil jadinya.

Blogproject

Aryadi Perwira

Self-proclaimed AS3 blackbelt.

More Posts

Notice: This work is licensed under a BY-NC-SA. Permalink: Tambahkan musuh, tambahkan ketegangan
  • http://noahzer.blogspot.com/ noahzer

    gw tes dari gamenya.. kok reloadnya lama ya.. maksudnya setelah ditembakkan (udah lewat layar yg kelihatan).. di klik lagi gk mau.. musuhnya bisa nembak juga?
    kyaknya besok bakalan main hitArea?!?
    *mungkin*

    • http://twitter.com/AryadiPS Aryadi Subagio

      sekarang event-na sudah jadi mousedown, jadi tinggal klik-tahan bukan klik-lepas, dan pesawat akan menembak otomatis dengan jeda setengah detik. kalau mau lebih cepat tinggal ganti variabel aja

      besok? tunggu tanggal mainna ya, hahahaha

  • http://www.facebook.com/giripp Giri Prahasta Iruma

    Kok rasanya ada yang terlewat ya? misalnya Bullet itu didapat darimana? Player dapat fungsi bullet juga dari mana ya? AI1 itu apa?

    • http://www.facebook.com/giripp Giri Prahasta Iruma

      Aha! No problemo, ternyata kelewatan satu artikel :D

  • vivi

    mas yadi,,kok saya ada error disini yah,,kenapa tuh ya?padahal uda ikutin instruksinya

    private var AI1:BasicAI = new BasicAI(airship);

    error di airshipnya

    • vivi

      C:Documents and SettingsVicklynneDesktopAI testtest AIsrcMapOne.as(20): col: 42 Error: Incorrect number of arguments. Expected no more than 0.

Stop SOPA