| Tutorial Flash - HTML5 - Javascript - DKV

Latest Blog



06.07.2022

MPI Component

Library untuk pengembangan multimedia interaktif dengan Flash/Animate

23.10.2020

Virtual Lab Flash

Library untuk pengembangan laboratorium virtual dengan Flash/Animate

06.10.2020

Game Among Us

Membuat gerakan karakter seperti pada game Among Us

05.10.2020

Multimedia Interaktif Tata Surya

Membuat Multimedia Pembelajaran Interaktif tentang tata surya

04.10.2020

Animasi Rotasi Bumi 3D

Membuat animasi bumi berotasi dengan grafik 3 Dimensi

01.10.2020

Membuat Kuis Essay

Mengecek jawaban kuis essay pada aplikasi pembelajaran interaktif

12.09.2020

Membuat Game Ular Tangga

Membuat game ular tangga dengan Adobe Flash/Animate AS3

10.09.2020

Membuat Pengacak Dadu

Membuat acak dadu untuk game ular tangga/monopoly

13.07.2020

Membuat Game Onet

Membuat game mencari gambar yang sama (onet) dengan JS/HTML5

11.06.2020

Membuat Kuis CBT

Membuat kuis CBT, menyimpan nilai ke server dengan PHP dan XML


ALL BLOG

Latest Games


;
Free Games

Indonesia Soccer League

Play Indonesian Soccer League on Flash 3D Games

Kecerdasan buatan - simulasi lalu lintas dengan Flash AS3

Pendahuluan

Dalam suatu game yang kompleks dimana melibatkan gerakan otomatis dari sebuah mobil NPC (Non Playable Character), membuat sistem pathfinding untuk gerakan tersebut merupakan tantangan yang rumit. Dalam game Sim Taxi dan Ace Gangster misalnya, terdapat beberapa kendaraan berupa mobil yang bergerak mengelilingi peta kota secara otomatis dengan sistem top-down view. Untuk kedua kasus tersebut (Sim Taxi dan Ace Gangster) membuat gerakan mobil tidak terlalu rumit karena peta kota dibuat dengan sistem Array mapping, sehingga deteksi jalan, tikungan, pertigaan dan perempatan jalan cukup ditentukan dengan nilai array dimana objek tersebut berada.

Namun demikian, lain halnya jika akan membuat kota yang tidak memiliki array mapping (art base), tentunya mendeteksi kondisi jalan merupakan tantangan tersendiri. Untuk itu melalui tutorial ini, saya memberikan satu alternatif solusi yang pernah saya pakai dalam membuat simulasi lalu lintas pada peta berbasis gambar (art base).



Proses Pembuatan Simulasi lalu lintas Art Base dengan AS3

  1. Pada file aplikasi Flash, buatlah sebuah file baru AS3

  2. Dengan menggunakan drawing tool, buatlah sebuah gambar peta kota pandangan atas (warna merah adalah area yang tidak dapat dilewati), kemudian convert menjadi MovieClip "road_hit". Pastikan registration point movieclip tersebut di pojok kiri atas (Lihat gambar)

  3. simulasi lalulintas dengan flash
  4. Buatlah layer baru, ubah namanya menjadi layer start(Lihat gambar). Kemudian buatlah sebuah movieclip panah (menghadap ke atas). Selanjutnya atur posisinya di atas movieclip road_hit. Hal ini dimaksudkan sebagai posisi awal keluarnya mobil. Selanjutnya seleksi semua panah dan convert menjadi movieclip "car_start". Edit movieclip tersebut untuk memastikan agar registration point movieclip car_start sama dengan posisi registration point movieclip road_hit

  5. simulasi lalulintas dengan flash
  6. Selanjutnya buatlah gambar mobil dengan pandangan atas, lalu convert menjadi movieclip car_ai. Edit movieclip tersebut, tambahkan sebuah layar dan buatlah sebuah movieclip berupa lingkaran kecil yang akan kita gunakan sebagai sensor. Duplikasi movieclip sensor tersebut sebanyak 4 kali, letakkan diposisi depan (1 buah), dan samping masing-masing 2 buah. (lihat gambar)

  7. Tambahkan instance name pada masing-masing sensor tersebut, yaitu sensor_f, sensor_r, sensor_r2, sensor_l dan sensor_l2

  8. simulasi lalulintas dengan flash
  9. Setelah itu anda dapat menset nilai alpha dari sensor-sensor tersebut menjadi 0% sehingga tidak terlihat di layar.

  10. Hapus movieclip car_ai dari layar. Karena penambahan mobil ke layar nantinya menggunakan kode

  11. Agar dapat diimport oleh kode, tambahkan linkage pada movieclip car_ai

  12. Setelah asset siap, buatlah layer baru (layer kode), klik frame 1 layer kode. Buka panel Action(F9), dan tuliskan kode berikut
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.MovieClip;

var game_active:Boolean = true;
var ai_car_handler:MovieClip = new MovieClip();

function on_mouseup(e:MouseEvent){
	game_active = !game_active;	
}
stage.addEventListener(MouseEvent.MOUSE_UP, on_mouseup);
function find_point(ob:Object):Object
{
	var dist:Number = Math.sqrt(ob.x * ob.x + ob.y * ob.y);
	var rad:Number = Math.atan(ob.y / ob.x);
	var rot:Number = 0;
	if (ob.x > 0)
	{
		rot = rad * 180 / Math.PI;
	}
	else
	{
		rot = rad * 180 / Math.PI + 180;
	}
	return {a:dist, b:rot};
}
function setup_ai_car(px:Number, py:Number, rot:Number, id:Number):void
{
	var ob = new car_ai();
	ob.name = "ai_" + id;
	ob.c_id = id;
	//ob.c_id_txt.text = String(id);
	ob.x = px;
	ob.y = py;
	ob.start_x = ob.x;
	ob.start_y = ob.y;
	ob.start_rot = rot;
	ob.rotation = rot;
	ob.d_f = find_point(ob.sensor_f).a;
	ob.r_f = find_point(ob.sensor_f).b;
	ob.d_l = find_point(ob.sensor_l).a;
	ob.r_l = find_point(ob.sensor_l).b;
	ob.d_l2 = find_point(ob.sensor_l2).a;
	ob.r_l2 = find_point(ob.sensor_l2).b;
	ob.d_r = find_point(ob.sensor_r).a;
	ob.r_r = find_point(ob.sensor_r).b;
	ob.d_r2 = find_point(ob.sensor_r2).a;
	ob.r_r2 = find_point(ob.sensor_r2).b;
	ob.dist = 0;
	ob.normal_speed = 2;
	ob.t_rot = rot;
	ob.ai_type = 1;
	ob.turn = 0;
	ob.wait = 0;
	ob.old_speed = 0;
	ob.old_ai = 1;
	ob.addEventListener(Event.ENTER_FRAME, move_ai_car);
	ai_car_handler.addChild(ob);
}
function move_ai_car(e:Event)
{
	if (game_active){
	var ob = e.currentTarget;
	//lurus
	if (ob.ai_type == 1)
	{
		ob.speed = ob.normal_speed;
		//find empty area
		find_road(ob, road_hit);
		if (ob.turn != 0)
		{
			ob.ai_type = ob.turn + 1;
			//left
			if (ob.turn == 1)
			{
				ob.t_rot = ob.rotation - 90;
			}
			if (ob.turn == 2)
			{
				ob.t_rot = ob.rotation + 90;
			}
		}
	}
	if (ob.ai_type == 2)
	{
		//left
		ob.speed = ob.normal_speed / 1.5;
		ob.rotation -=  4;
		if (c_rot(ob.rotation, ob.t_rot)<=2){
			ob.rotation = ob.t_rot;
			ob.ai_type = 1;
		}
	}
	if (ob.ai_type == 3)
	{
		//right
		ob.speed = ob.normal_speed / 1.5;
		ob.rotation +=  4;
		if (c_rot(ob.rotation, ob.t_rot)<=2){
			ob.rotation = ob.t_rot;
			ob.ai_type = 1;			
		}
	}
	if (ob.ai_type == 4)
	{
		//lurus
		ob.dist+=ob.speed;
		// > road width
		if (ob.dist>20){
			ob.ai_type = 1;	
		}
	}
	if (ob.ai_type == 5)
	{
		//lost
		ob.x = ob.start_x;
		ob.y = ob.start_y;
		ob.rotation = ob.start_rot;
		ob.ai_type = 1;
	}
	//ai_hit
	if (hit_other_car(ob) && ob.ai_type<5){		
		ob.old_ai = ob.ai_type;
		ob.ai_type = 6;
		trace(ob.c_id + "wait");
		ob.old_speed = ob.speed;
		ob.wait = 30;
	}
	if (ob.ai_type == 6)
	{
		ob.speed = 0;
		ob.wait--;
		if (ob.wait<=0){
			ob.speed = ob.old_speed;
			ob.wait = 0;			
			trace(ob.c_id + "go");
			ob.ai_type = ob.old_ai;
		}
		
	}
	ob.x +=  ob.speed * Math.sin(ob.rotation * Math.PI / 180);
	ob.y -=  ob.speed * Math.cos(ob.rotation * Math.PI / 180);
	
	}
}

function c_rot(ob1:Number,ob2:Number):Number
{
	var dis_angle:Number = Math.abs(ob1 - ob2) % 360;
	if (dis_angle > 180)
	{
		dis_angle = 360 - dis_angle;
	}
	return dis_angle;
}
function find_road(ob, hit)
{
	var px_l:Number = ob.x + ob.d_l * Math.cos((ob.r_l + ob.rotation) * Math.PI / 180);
	var py_l:Number = ob.y + ob.d_l * Math.sin((ob.r_l + ob.rotation) * Math.PI / 180);
	var px_l2:Number = ob.x + ob.d_l2 * Math.cos((ob.r_l2 + ob.rotation) * Math.PI / 180);
	var py_l2:Number = ob.y + ob.d_l2 * Math.sin((ob.r_l2 + ob.rotation) * Math.PI / 180);
	var px_r:Number = ob.x + ob.d_r * Math.cos((ob.r_r + ob.rotation) * Math.PI / 180);
	var py_r:Number = ob.y + ob.d_r * Math.sin((ob.r_r + ob.rotation) * Math.PI / 180);
	var px_r2:Number = ob.x + ob.d_r2 * Math.cos((ob.r_r2 + ob.rotation) * Math.PI / 180);
	var py_r2:Number = ob.y + ob.d_r2 * Math.sin((ob.r_r2 + ob.rotation) * Math.PI / 180);
	var px_f:Number = ob.x + ob.d_f * Math.cos((ob.r_f + ob.rotation) * Math.PI / 180);
	var py_f:Number = ob.y + ob.d_f * Math.sin((ob.r_f + ob.rotation) * Math.PI / 180);
	var px_f2:Number = ob.x + 1.5*ob.d_f * Math.cos((ob.r_f + ob.rotation) * Math.PI / 180);
	var py_f2:Number = ob.y + 1.5*ob.d_f * Math.sin((ob.r_f + ob.rotation) * Math.PI / 180);
	ob.turn = 0;
	//left
	if (!hit.hitTestPoint(px_l,py_l,true) && hit.hitTestPoint(px_l2,py_l2,true))
	{
		//lurus atau belok?
		if (!hit.hitTestPoint(px_f2,py_f2,true) && Math.random()*10<7){
			ob.turn = 3;
			ob.dist = 0;
		}else{
			ob.turn = 1;
		}		
	}
	//right
	if (!hit.hitTestPoint(px_r,py_r,true) && hit.hitTestPoint(px_r2,py_r2,true))
	{
		//lurus atau belok?
		if (!hit.hitTestPoint(px_f2,py_f2,true) && Math.random()*10<7){
			ob.turn = 3;
			ob.dist = 0;
		}else{
			ob.turn = 2;
		}		
	}
	//front left
	if (hit.hitTestPoint(px_f,py_f,true))
	{
		if (! hit.hitTestPoint(px_l,py_l,true) && ! hit.hitTestPoint(px_l2,py_l2,true))
		{
			ob.turn = 1;
		}else if (! hit.hitTestPoint(px_r,py_r,true) && ! hit.hitTestPoint(px_r2,py_r2,true))
		{
			ob.turn = 2;
		}
	}
	//out of area
	if (hit.hitTestPoint(px_l,py_l,true) && hit.hitTestPoint(px_l2,py_l2,true) && hit.hitTestPoint(px_r,py_r,true) && hit.hitTestPoint(px_r2,py_r2,true)){
		ob.ai_type = 5;
	}
}
function hit_other_car(ob:Object):Boolean{
	var px_f:Number = ob.x + 0.5*ob.d_f * Math.cos((ob.r_f + ob.rotation) * Math.PI / 180);
	var py_f:Number = ob.y + 0.5*ob.d_f * Math.sin((ob.r_f + ob.rotation) * Math.PI / 180);
	if (ai_car_handler.hitTestPoint(px_f,py_f,true)){		
		return true;
	}else{
		return false;
	}
}

function add_ai_cars():void{
	car_ai_start.visible = false;
	for (var i=0;i<12; i++){
		var ob = car_ai_start.getChildAt(i);
		setup_ai_car(ob.x,ob.y,ob.rotation,i);
	}
}

addChild(ai_car_handler);
add_ai_cars();

Jalankan aplikasi dengan menekan tombol Ctrl+Enter, maka hasil dari tutorial ini adalah sebagai berikut:


Get Adobe Flash player

Penjelasan Kode

Penjelasan kode diatas adalah sebagai berikut :

    function find_road(ob, hit)
    {
    	...
    	//left
    	if (!hit.hitTestPoint(px_l,py_l,true) && hit.hitTestPoint(px_l2,py_l2,true))
    	{
    		...
    	}
    	//right
    	if (!hit.hitTestPoint(px_r,py_r,true) && hit.hitTestPoint(px_r2,py_r2,true))
    	{
    		...
    	}
    	//front left
    	if (hit.hitTestPoint(px_f,py_f,true))
    	{
    		...
    	}
    
  1. Untuk mendeteksi kondisi jalan, Movieclip car_ai menggunakan ke 5 sensornya. Dengan kode sederhana hitTestPoint, dapat ditentukan apakah sensor menyentuh jalan atau tidak, sehingga dapat ditentukan apakah sedang berada di jalan lurus, belokan, pertigaan maupun perempatan.
    Dengan logika sederhana dibuat peraturan sebagai berikut :
    • Mobil bergerak menggunakan jalur kanan (US / Eropa)
    • Mobil memiliki kecenderungan belok ke arah kanan
    • Jika ada belokan ke kanan, maka mobil akan mengecek kondisi jalan apakah belokan atau pertigaan
    • Jika belokan maka mobil akan belok
    • Jika pertigaan atau perempatan, maka akan diacak untuk menentukan mobil belok atau lurus

  2. function move_ai_car(e:Event)
    {
    ...
    
  3. Fungsi ini digunakan untuk menggerakkan car_ai. Variabel ob.ai_type digunakan untuk menentukan jenis gerakannya, apakah lurus, berhenti atau belok.

  4. function hit_other_car(ob:Object):Boolean{
    	var px_f:Number = ob.x + 0.5*ob.d_f * Math.cos((ob.r_f + ob.rotation) * Math.PI / 180);
    	var py_f:Number = ob.y + 0.5*ob.d_f * Math.sin((ob.r_f + ob.rotation) * Math.PI / 180);
    	if (ai_car_handler.hitTestPoint(px_f,py_f,true)){		
    		return true;
    	}else{
    		return false;
    	}
    }
    
  5. Sensor depan dari masing-masing mobil digunakan untuk menentukan deteksi tumbukan dengan mobil lain. Dengan menggunakan kode hitTestPoint, akan menghasilkan nilai true jika titik sensor depan menyentuh mobil lain, dan gerakan mobil akan dihentikan sementara sampai mobil yang berada di depannya lewat.

Kesimpulan

Sistem deteksi untuk simulasi lalulintas top down bisa dibuat dengan beberapa cara seperti dengan tile system (array mapping), maupun dengan menggunakan metode art base (dengan menggunakan sensor). Dengan cara tersebut kita dapat membuat kecerdasan buatan berupa simulasi gerakan mobil yang bergerak di dalam kota secara terus menerus dengan sedikit peluang untuk crash / macet.


File Sumber


File sumber Simulasi Mobil (CS5)




Share ( Ayo Berbagi )

Leave me a comment

untuk pertanyaan lebih baik di email langsung ke wandah [at] wandah [dot] com agar cepat direspon