Advertisement
  1. Code
  2. Games

Membangun Permainan Snake Klasik di AS3

Scroll to top
Read Time: 33 min

Indonesian (Bahasa Indonesia) translation by Ari Ana (you can also view the original English article)

Dalam tutorial ini saya ingin menunjukkan kepada Anda betapa mudahnya membuat permainan "Snake" klasik dalam Flash. Saya akan mencoba menjelaskan semuanya dengan mudah, selangkah demi selangkah, sehingga Anda dapat mengembangkan permainan lebih lanjut untuk kebutuhan Anda! Permainan ini akan dikembangkan di AS3 dan saya akan menggunakan IDE FlashDevelop.


Perkenalan

Permainannya tidak akan rumit. Setiap kali kita menabrak dinding, itu akan memulai kembali permainannya. Setelah memakan apel, ular akan tumbuh, dan Apple 'baru' akan muncul. (Sebenarnya, itu akan menjadi apel yang sama, tapi saya akan menjelaskannya nanti.)

Salah satu aspek terpenting dari permainan ini adalah reaksi kode terhadap peristiwa KEY_DOWN. Ular hanya akan mengubah arahnya setelah tanda tick berlalu, tidak segera setelah penekanan tombol. Ini berarti bahwa, jika ular itu berjalan dengan benar, dan Anda menekan ke bawah dan kiri dengan sangat cepat, ular itu akan turun, bukan ke bawah DAN kiri. Tanpa 'fitur' ini ular akan memungkinkan kita untuk pergi ke kiri ketika kita berjalan ke kanan, yang berarti itu menghantam dirinya sendiri.


Mari Lihat Permainan Ini!

Mari kita lihat hasil akhir yang akan kita jalani:


Langkah 1: Membuat Proyek

Di FlashDevelop, buat Project baru, dan di dalam folder 'src' buat folder 'com'. Di folder 'com' buat kelas baru, dan beri nama 'Element.as'.

Atur dimensi proyek menjadi 600x600px.

The FlashDevelop project structure

Langkah 2: Tunggu... Apa itu Elemen?

Ular itu membentuk kotak biru, yang saya sebut elemen. Kita akan membuat Kelas Element, yang menggambar elemen. Apel merah juga akan menjadi elemen, jadi kita akan memperpanjang kode dengan beberapa baris lagi.

Oleh karena itu kita tidak akan membuat kelas baru untuk apel. (Tetapi jika Anda benar-benar ingin, Anda bisa.)


Langkah 3: Menulis Kelas Element

Kelas Element menciptakan persegi. Itu tidak menggambarnya di atas panggung, itu hanya menciptakannya. Titik registrasi elemen - posisi yang dimaksud oleh koordinat x dan y - berada di kiri atas.

Setelah membuka Element.as Anda akan melihat sesuatu seperti ini:

1
2
package com 
3
{
4
  /**

5
	 * ...

6
	 * @author Fuszenecker Zsombor

7
	 */
8
	public class Element 
9
	{
10
		
11
		public function Element() 
12
		{
13
			
14
		}
15
		
16
	}
17
}

Pertama kita membutuhkan ini untuk memperluas kelas Shape, jadi kita bisa menggunakan obyek graphics untuk menggambar persegi. Setelah ini, buat dua variabel: satu untuk arah (jika itu bagian dari ular), dan satu untuk nilai skor (jika itu apel), dan kemudian ubah parameter fungsi constructor:

1
2
package com 
3
{
4
	import flash.display.Shape;
5
	
6
	public class Element extends Shape
7
	{
8
		protected var _direction:String;
9
		//IF IT IS AN APPLE ->

10
		protected var _catchValue:Number;
11
		
12
		//color,alpha,width,height

13
		public function Element(_c:uint,_a:Number,_w:Number,_h:Number) 
14
		{
15
16
		}
17
	}
18
}

Sekarang isi fungsi dengan beberapa kode:

1
2
package com 
3
{
4
	import flash.display.Shape;
5
	
6
	public class Element extends Shape
7
	{
8
		protected var _direction:String;
9
		//IF IT IS AN APPLE ->

10
		protected var _catchValue:Number;
11
		
12
		//color,alpha,width,height

13
		public function Element(_c:uint,_a:Number,_w:Number,_h:Number) 
14
		{
15
			graphics.lineStyle(0, _c, _a);
16
			graphics.beginFill(_c, _a);
17
			graphics.drawRect(0, 0, _w, _h);
18
			graphics.endFill();
19
			
20
			_catchValue = 0;
21
		}
22
	}
23
}

Sekarang, setiap kali kita membuat elemen, itu akan menggambar persegi panjang dan mengatur nilai skor dari elemen ke 0 secara default. (Ia tidak akan menempatkan persegi panjang di atas panggung, itu hanya menggambarnya di dalam dirinya sendiri. Perhatikan bahwa kita belum memanggil fungsi addChild().)

Mari selesaikan kelas ini dan akhirnya kita bisa menguji seberapa banyak yang sudah kita lakukan:

1
2
package com 
3
{
4
	import flash.display.Shape;
5
	
6
	public class Element extends Shape
7
	{
8
		protected var _direction:String;
9
		//IF IT IS AN APPLE ->

10
		protected var _catchValue:Number;
11
		
12
		//color,alpha,width,height

13
		public function Element(_c:uint,_a:Number,_w:Number,_h:Number) 
14
		{
15
			graphics.lineStyle(0, _c, _a);
16
			graphics.beginFill(_c, _a);
17
			graphics.drawRect(0, 0, _w, _h);
18
			graphics.endFill();
19
			
20
			_catchValue = 0;
21
		}
22
		
23
		//ONLY USED IN CASE OF A PART OF THE SNAKE

24
		public function set direction(value:String):void
25
		{
26
			_direction = value;
27
		}
28
		public function get direction():String
29
		{
30
			return _direction;
31
		}
32
		
33
		//ONLY USED IN CASE OF AN APPLE

34
		public function set catchValue(value:Number):void
35
		{
36
			_catchValue = value;
37
		}
38
		public function get catchValue():Number
39
		{
40
			return _catchValue;
41
		}
42
	}
43
44
}

Kita menciptakan empat fungsi untuk mengubah arah dan nilai dari apel. Kita mencapai ini dengan menggunakan setter dan getter. Lebih lanjut tentang Setter/Getter di artikel ini!


Langkah 4: Menguji Kelas Element

Buka Main.as sekarang.

Impor kelas com.Element dan buat Element dalam fungsi init():

1
2
package  
3
{
4
	import flash.display.Sprite;
5
	import flash.events.Event;
6
	import com.Element;
7
		
8
	public class Main extends Sprite
9
	{
10
		public function Main() 
11
		{
12
			if(stage)
13
				addEventListener(Event.ADDED_TO_STAGE, init);
14
			else
15
				init();
16
		}
17
		
18
		private function init(e:Event = null):void
19
		{
20
			var testElement:Element = new Element(0x00AAFF, 1, 10, 10);
21
			testElement.x = 50;
22
			testElement.y = 50;
23
			this.addChild(testElement);
24
			
25
		}
26
		
27
	}
28
}

Pertama kita membuat variabel testElement yang memegang elemen kita. Kita membuat Element baru dan menetapkan itu ke variabel testElement kita. Perhatikan argumen yang kita kirimkan: pertama kita berikan warna, lalu alfa, lebar, dan tinggi. Jika Anda melihat pada fungsi Element di kelas Element, Anda dapat melihat bagaimana menggunakan data ini untuk menggambar persegi panjang.

Setelah membuat Element, kita memposisikannya dan meletakkannya di atas panggung!


Langkah 5: Mengatur Variabel

Lihatlah kode berikut. Saya menulis fungsi variabel di setelahnya (perhatikan bahwa kita mengimpor kelas yang diperlukan juga):

1
2
package  
3
{
4
	import flash.display.Sprite;
5
	import flash.text.TextField;
6
	import flash.utils.Timer;
7
	import flash.events.TimerEvent;
8
	import flash.ui.Keyboard;
9
	import flash.events.KeyboardEvent;
10
	import flash.events.MouseEvent;
11
	import flash.events.Event;
12
	
13
	import com.Element;
14
		
15
	public class Main extends Sprite
16
	{
17
		
18
		//DO NOT GIVE THESE VARS A VALUE HERE! 

19
		//Give them their values in the init() function.

20
		private var snake_vector:Vector.<Element>; //the snake's parts are held in here

21
		private var markers_vector:Vector.<Object>; //the markers are held in here

22
		private var timer:Timer;
23
		private var dead:Boolean;
24
		private var min_elements:int; //holds how many parts the snake should have at the beginning

25
		private var apple:Element; //Our apple

26
		private var space_value:Number; //space between the snake's parts

27
		private var last_button_down:uint; //the keyCode of the last button pressed

28
		private var flag:Boolean; //is it allowed to change direction?

29
		private var score:Number;
30
		private var score_tf:TextField; //the Textfield showing the score

31
		
32
		public function Main() 
33
		{
34
			if(stage)
35
				addEventListener(Event.ADDED_TO_STAGE, init);
36
			else
37
				init();
38
		}
39
		
40
		private function init(e:Event = null):void
41
		{
42
			snake_vector = new Vector.<Element>;
43
			markers_vector = new Vector.<Object>;
44
			space_value = 2; //There will be 2px space between every Element

45
			timer = new Timer(50); //Every 50th millisecond, the moveIt() function will be fired! This will set the SPEED of the snake

46
			dead = false;
47
			min_elements = 10; //We will begin with 10 elements.

48
			apple = new Element(0xFF0000, 1, 10, 10); //red, not transparent, width:10, height: 10;

49
			apple.catchValue = 0; //pretty obvious - the score of the apple

50
			last_button_down = Keyboard.RIGHT; //The first direction of the snake is set in this variable

51
			score = 0;
52
			score_tf = new TextField(); //this is the TextField which shows our score.

53
			this.addChild(score_tf);
54
		}	
55
	}
56
}

Variabel yang paling penting adalah snake_vector. Kita akan menempatkan setiap Element dari ular di Vector ini.

Lalu ada markers_vector. Kita akan menggunakan penanda untuk mengatur arah dari bagian-bagian ular. Setiap obyek dalam Vector ini akan memiliki posisi dan tipe. Tipe ini akan memberi tahu kita apakah ular harus pergi ke kanan, kiri, atas, atau ke bawah setelah 'memukul' obyek. (Mereka tidak akan bertabrakan, hanya posisi penanda dan bagian ular yang akan diperiksa.)

Sebagai contoh, jika kita menekan DOWN, sebuah obyek akan dibuat. X dan y dari obyek ini akan menjadi koordinat x dan y kepala ular, dan jenisnya akan "Down". Setiap kali posisi salah satu Element ular sama dengan objek ini, arah elemen ular akan diatur ke "Down".

Silakan baca komentar di sebelah variabel untuk memahami apa yang dilakukan variabel lain!


Langkah 6: Menulis Fungsi attachElement()

Fungsi attachElement() akan mengambil empat parameter: elemen ular baru, koordinat x dan y, dan arah bagian terakhir dari ular.

1
2
private function attachElement(who:Element,lastXPos:Number = 0,lastYPos:Number = 0,dirOfLast:String = "R"):void
3
{
4
5
}

Sebelum kita meletakkan elemen di atas panggung kita harus memposisikannya. Tetapi untuk ini kita memerlukan arah elemen terakhir ular, untuk mengetahui apakah elemen baru harus berada di atas, di bawah, atau di samping ini.

Setelah memeriksa arah dan mengatur posisi, kita bisa menambahkannya ke panggung.

1
2
private function attachElement(who:Element,lastXPos:Number = 0,lastYPos:Number = 0,dirOfLast:String = "R"):void
3
{
4
	if (dirOfLast == "R")
5
	{
6
		who.x = lastXPos - snake_vector[0].width - space_value;
7
		who.y = lastYPos;
8
	}
9
	else if(dirOfLast == "L")
10
	{
11
		who.x = lastXPos + snake_vector[0].width + space_value;
12
		who.y = lastYPos;
13
	}
14
	else if(dirOfLast == "U")
15
	{
16
		who.x = lastXPos;
17
		who.y = lastYPos + snake_vector[0].height + space_value;
18
	}
19
	else if(dirOfLast == "D")
20
	{
21
		who.x = lastXPos;
22
		who.y = lastYPos - snake_vector[0].height - space_value;
23
	}
24
	this.addChild(who);
25
}

Sekarang kita dapat menggunakan fungsi ini dalam fungsi init():

1
2
for(var i:int=0;i<min_elements;++i)
3
{
4
	snake_vector[i] = new Element(0x00AAFF,1,10,10);
5
	snake_vector[i].direction = "R"; //The starting direction of the snake

6
	if (i == 0)//first snake element

7
	{
8
		//you have to place the first element on a GRID. (now: 0,0) 

9
		//[possible x positions: (snake_vector[0].width+space_value)*<UINT> ]

10
		attachElement(snake_vector[i],0,0,snake_vector[i].direction) 
11
		snake_vector[0].alpha = 0.7;
12
	}
13
	else
14
	{
15
		attachElement(snake_vector[i], snake_vector[i - 1].x, snake_vector[i - 1].y, snake_vector[i - 1].direction);
16
	}
17
}

Kita membuat 10 Element pertama, dan mengatur arah mereka ke 'R' (kanan). Jika ini adalah elemen pertama, kita memanggil attachElement() dan kita mengubah alpha-nya sedikit (jadi "head" adalah warna yang sedikit lebih terang).

Jika Anda ingin mengatur posisi di tempat lain, maka ingatlah hal-hal berikut: ular harus diletakkan di atas grid, jika tidak maka akan terlihat buruk dan tidak akan berfungsi. Jika Anda ingin mengubah posisi x dan y Anda dapat melakukannya dengan cara berikut:

Mengatur posisi x: (snake_vector[0].width+space_value)*[UINT], di mana Anda harus mengganti [UINT] dengan bilangan bulat positif.

Mengatur posisi y: (snake_vector[0].height+space_value)*[UINT], di mana Anda harus mengganti [UINT] dengan bilangan bulat positif.

Mari kita ubah ke ini:

1
2
if (i == 0)//first snake element

3
{
4
	//you have to place the first element on a GRID. (now: 0,0) 

5
	//[possible x positions: (snake_vector[0].width+space_value)*<UINT>]

6
	attachElement(
7
		snake_vector[i],
8
		(snake_vector[0].width+space_value)*20,
9
		(snake_vector[0].height+space_value)*10,
10
		snake_vector[i].direction
11
	);
12
	snake_vector[0].alpha = 0.7;
13
}

Dan elemen pertama ular diatur ke ruang 20 di x-grid dan 10 ruang di y-grid.

Inilah yang telah kita dapat sejauh ini:

1
2
package  
3
{
4
	import flash.display.Sprite;
5
	import flash.text.TextField;
6
	import flash.utils.Timer;
7
	import flash.events.TimerEvent;
8
	import flash.ui.Keyboard;
9
	import flash.events.KeyboardEvent;
10
	import flash.events.MouseEvent;
11
	import flash.events.Event;
12
	
13
	import com.Element;
14
		
15
	public class Main extends Sprite
16
	{
17
		
18
		//DO NOT GIVE THEM A VALUE HERE! Give them a value in the init() function

19
		private var snake_vector:Vector.<Element>; //the snake's parts are held in here

20
		private var markers_vector:Vector.<Object>; //the markers are held in here

21
		private var timer:Timer; 
22
		private var dead:Boolean;
23
		private var min_elements:int; //holds how many parts should the snake have at the beginning

24
		private var apple:Element; //Our apple

25
		private var space_value:Number; //space between the snake parts

26
		private var last_button_down:uint; //the keyCode of the last button pressed

27
		private var flag:Boolean; //is it allowed to change direction?

28
		private var score:Number;
29
		private var score_tf:TextField; //the Textfield showing the score

30
		
31
		public function Main() 
32
		{
33
			if(stage)
34
				addEventListener(Event.ADDED_TO_STAGE, init);
35
			else
36
				init();
37
		}
38
		
39
		private function init(e:Event = null):void
40
		{
41
			snake_vector = new Vector.<Element>;
42
			markers_vector = new Vector.<Object>;
43
			space_value = 2;
44
			timer = new Timer(50); //Every 50th millisecond, the moveIt() function will be fired!

45
			dead = false;
46
			min_elements = 10; //We will begin with 10 elements.

47
			apple = new Element(0xFF0000, 1,10, 10); //red, not transparent, width:10, height: 10;

48
			apple.catchValue = 0; //pretty obvious

49
			last_button_down = Keyboard.RIGHT; //The first direction of the snake is set in this variable

50
			score = 0;
51
			score_tf = new TextField(); //this is the TextField which shows our score.

52
			this.addChild(score_tf);
53
			
54
			for(var i:int=0;i<min_elements;++i)
55
			{
56
				snake_vector[i] = new Element(0x00AAFF,1,10,10);
57
				snake_vector[i].direction = "R"; //The starting direction of the snake

58
				if (i == 0)//first snake element

59
				{
60
					//you have to place the first element on a GRID. (now: 0,0) [possible x positions: (snake_vector[0].width+space_value)*<UINT> ]

61
					attachElement(snake_vector[i], (snake_vector[0].width + space_value) * 20, (snake_vector[0].height + space_value) * 10, snake_vector[i].direction);
62
					snake_vector[0].alpha = 0.7;
63
				}
64
				else
65
				{
66
					attachElement(snake_vector[i], snake_vector[i - 1].x, snake_vector[i - 1].y, snake_vector[i - 1].direction);
67
				}
68
			}
69
		}	
70
		
71
		private function attachElement(who:Element,lastXPos:Number = 0,lastYPos:Number = 0,dirOfLast:String = "R"):void
72
		{
73
			if (dirOfLast == "R")
74
			{
75
				who.x = lastXPos - snake_vector[0].width - space_value;
76
				who.y = lastYPos;
77
			}
78
			else if(dirOfLast == "L")
79
			{
80
				who.x = lastXPos + snake_vector[0].width + space_value;
81
				who.y = lastYPos;
82
			}
83
			else if(dirOfLast == "U")
84
			{
85
				who.x = lastXPos;
86
				who.y = lastYPos + snake_vector[0].height + space_value;
87
			}
88
			else if(dirOfLast == "D")
89
			{
90
				who.x = lastXPos;
91
				who.y = lastYPos - snake_vector[0].height - space_value;
92
			}
93
			this.addChild(who);
94
		}
95
	}
96
}

Langkah 7: Menulis Fungsi placeApple()

Fungsi ini melakukan hal berikut:

  1. Ini memeriksa apakah apel itu tertangkap. Untuk ini kita akan menggunakan parameter caught, dan mengatur nilai defaultnya ke true, jika kita tidak melewatkan nilai apa pun sebagai parameter di masa depan. Jika tertangkap, itu menambah 10 nilai skor apel (jadi apel berikutnya bernilai lebih).
  2. Setelah ini apel harus direposisi (kita tidak membuat apel baru) pada posisi grid acak.
  3. Jika ditempatkan pada ular, kita harus menempatkannya di tempat lain.
  4. Jika belum di atas panggung, kita letakkan di sana.
1
2
private function placeApple(caught:Boolean = true):void
3
{
4
	if (caught)
5
		apple.catchValue += 10;
6
		
7
	var boundsX:int = (Math.floor(stage.stageWidth / (snake_vector[0].width + space_value)))-1;
8
	var randomX:Number = Math.floor(Math.random()*boundsX);
9
		
10
	var boundsY:int = (Math.floor(stage.stageHeight/(snake_vector[0].height + space_value)))-1;
11
	var randomY:Number = Math.floor(Math.random()*boundsY);
12
13
	apple.x = randomX * (apple.width + space_value);
14
	apple.y = randomY * (apple.height + space_value);
15
		
16
	for(var i:uint=0;i<snake_vector.length-1;i++)
17
	{
18
		if(snake_vector[i].x == apple.x && snake_vector[i].y == apple.y)
19
			placeApple(false);
20
	}
21
	if (!apple.stage)
22
		this.addChild(apple);
23
}

Akan ada beberapa matematika di sini, tetapi jika Anda memikirkannya, Anda harus memahami mengapa demikian. Hanya menggambar di beberapa kertas jika perlu.

  • boundsX akan menampung berapa banyak elemen yang dapat digambar dalam satu baris.
  • randomX mengambil boundsX ini, mengalikannya dengan Angka antara nol dan satu, dan membulatkan kebawah. Jika boundsX adalah 12 dan Angka acak adalah 0,356, maka floor(12*0,356) adalah 4, sehingga apel akan ditempatkan pada tempat ke-4 pada x-grid.
  • boundsY akan menampung berapa banyak elemen yang dapat digambar dalam satu kolom.
  • randomY mengambil boundsY ini, mengalikannya dengan Angka antara nol dan satu, dan membulatkan kebawah.
  • Kemudian kita menetapkan posisi x dan y ke angka-angka ini.

Dalam perulangan for, kita memeriksa apakah posisi x dan y apel yang baru identik dengan salah satu elemen snake_vectors. Jika demikian, kita memanggil fungsi placeApple() lagi (fungsi rekursif), dan mengatur parameter ke false. (Artinya apel itu tidak tertangkap, kita hanya perlu memposisikan ulang)

(apple.stage) mengembalikan nilai true jika apel ada di panggung. kita menggunakan operator '!' untuk membalikkan nilai itu, jadi jika TIDAK di atas panggung, kita letakkan di sana.

Hal terakhir yang perlu kita lakukan adalah memanggil fungsi placeApple() di akhir fungsi init().

1
2
private function init(e:Event = null):void
3
{
4
    /*   

5
	.

6
	.

7
	.

8
	*/
9
	
10
	placeApple(false);
11
}

Perhatikan bahwa kita melewatkan false sebagai parameter. Ini logis, karena kita tidak menangkap apel dalam fungsi init(). Kita hanya akan menangkapnya dalam fungsi moveIt().

Sekarang hanya ada tiga fungsi untuk menulis: fungsi directionChanged(), moveIt() dan gameOver().


Langkah 8: Memulai Fungsi moveIt()

Fungsi moveIt() bertanggung jawab untuk semua pergerakan. Fungsi ini akan memeriksa batas dan memeriksa apakah ada obyek pada posisi x dan y dari kepala ular. Itu juga akan mencari apel di posisi ini.

Untuk semua ini, kita akan menggunakan variabel timer kita.

Tambahkan dua baris lagi di akhir fungsi init():

1
2
timer.addEventListener(TimerEvent.TIMER,moveIt);
3
timer.start();

Lihatlah komentar-komentar di source code, untuk melihat blok kode mana yang melakukan apa.

1
2
		private function moveIt(e:TimerEvent):void
3
		{
4
			if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)
5
			{
6
				//This code runs if the snakes heads position and the apples position are the same

7
			}
8
			
9
			if (snake_vector[0].x > stage.stageWidth-snake_vector[0].width || snake_vector[0].x < 0 || snake_vector[0].y > stage.stageHeight-snake_vector[0].height || snake_vector[0].y < 0)
10
			{
11
				//This block runs if the snakes head is out of the stage (hitting the walls)

12
			}
13
			
14
			
15
			for (var i:int = 0; i < snake_vector.length; i++)
16
			{
17
				/*

18
					START OF FOR BLOCK

19
					This whole 'for' block will run as many times, as many elements the snake has.

20
					If there are four snake parts, this whole for cycle will run four times. 

21
				*/
22
				
23
				if (snake_vector[i] != snake_vector[0] && (snake_vector[0].x == snake_vector[i].x && snake_vector[0].y == snake_vector[i].y))
24
				{
25
					//If the snakes heads position is the same as any of the snake parts, this block will run (Checking the collision with itself).

26
				}
27
			
28
				if (markers_vector.length > 0)
29
				{
30
					//if there are direction markers, this code runs

31
				}
32
			
33
				
34
				var DIRECTION:String = snake_vector[i].direction; //getting the direction of the current snake element.

35
				switch (DIRECTION)
36
				{
37
					//Sets the new position of the snakes part

38
				}
39
				
40
				/*

41
					END OF FOR BLOCK

42
				*/
43
			}
44
			
45
		}

Sekarang kita perlu mengkodekan pergerakannya. Untuk ini kita melompat ke blok switch, yang akan berjalan pada setiap bagian ular, karena perulangan for.

Pertama kita perlu memeriksa arah elemen saat ini.

1
2
				switch (DIRECTION)
3
				{
4
					case "R" :
5
						//Here we need to set the new x position for the current part

6
						break;
7
					case "L" :
8
						//Here we need to set the new x position for the current part

9
						break;
10
					case "D" :
11
						//Here we need to set the new y position for the current part

12
						break;
13
					case "U" :
14
						//Here we need to set the new y position for the current part

15
						break;
16
				}

Ketika arah bagian diatur ke "R", misalnya, kita perlu menambahkan sesuatu ke posisi X saat ini (nilai space_value plus lebar bagian ular).

Dengan pemikiran ini, kita bisa mengisinya:

1
2
				switch (DIRECTION)
3
				{
4
					case "R" :
5
						snake_vector[i].x += snake_vector[i].width + space_value;
6
						break;
7
					case "L" :
8
						snake_vector[i].x -= snake_vector[i].width + space_value;
9
						break;
10
					case "D" :
11
						snake_vector[i].y += snake_vector[i].height + space_value;
12
						break;
13
					case "U" :
14
						snake_vector[i].y -= snake_vector[i].width + space_value;
15
						break;
16
				}

Setelah menguji kode, Anda harus melihat bahwa ular bergerak, dan pergi keluar dari panggung dan tidak pernah berhenti. (Anda mungkin perlu menyegarkan halaman - atau klik saja di sini untuk memuatnya di jendela baru.)

Jadi kita harus menghentikan ular itu


Langkah 9: Menulis Fungsi gameOver()

Fungsi ini akan menjadi yang terpendek. Kita hanya membersihkan panggung dan memulai kembali:

1
2
private function gameOver():void 
3
{
4
	dead = true;
5
	timer.stop();
6
	while (this.numChildren)
7
		this.removeChildAt(0);
8
	timer.removeEventListener(TimerEvent.TIMER,moveIt);
9
	init();
10
}

Itu saja. Kita mengatur variabel dead menjadi true, menghentikan pergerakan dengan timer, menghapus setiap anak dari kelas dan memanggil fungsi init(), seperti kita baru saja memulai permainan.

Sekarang, mari kita kembali ke fungsi moveIt().


Langkah 10: Melanjutkan Fungsi moveIt()

Kita akan menggunakan fungsi gameOver() di dua tempat. Yang pertama adalah ketika kita memeriksa apakah kepala berada di luar batas, dan yang kedua adalah ketika ular menyerang dirinya sendiri:

1
2
		private function moveIt(e:TimerEvent):void
3
		{
4
			if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)
5
			{
6
				//This code runs if the snakes heads position and the apples position are the same

7
			}
8
			
9
			if (snake_vector[0].x > stage.stageWidth-snake_vector[0].width || snake_vector[0].x < 0 || snake_vector[0].y > stage.stageHeight-snake_vector[0].height || snake_vector[0].y < 0)
10
			{
11
				gameOver();
12
			}
13
			
14
			
15
			for (var i:int = 0; i < snake_vector.length; i++)
16
			{
17
				/*

18
					START OF FOR BLOCK

19
					This whole 'for' block will run as many times, as many elements the snake has.

20
					If there are four snake parts, this whole for cycle will run four times. 

21
				*/
22
				
23
				if (snake_vector[i] != snake_vector[0] && (snake_vector[0].x == snake_vector[i].x && snake_vector[0].y == snake_vector[i].y))
24
				{
25
					//If the snakes heads position is the same as any of the snake parts, this block will run

26
					gameOver();
27
				}
28
			
29
				if (markers_vector.length > 0)
30
				{
31
					//if there are direction markers, this code runs

32
				}
33
			
34
				
35
				var DIRECTION:String = snake_vector[i].direction; //getting the direction of the current snake element.

36
				switch (DIRECTION)
37
				{
38
					case "R" :
39
						snake_vector[i].x += snake_vector[i].width + space_value;
40
						break;
41
					case "L" :
42
						snake_vector[i].x -= snake_vector[i].width + space_value;
43
						break;
44
					case "D" :
45
						snake_vector[i].y += snake_vector[i].height + space_value;
46
						break;
47
					case "U" :
48
						snake_vector[i].y -= snake_vector[i].width + space_value;
49
						break;
50
				}
51
				
52
				/*

53
					END OF FOR BLOCK

54
				*/
55
			}
56
			
57
		}

Ini adalah kode yang kita miliki sekarang:

1
2
package  
3
{
4
	import flash.display.Sprite;
5
	import flash.text.TextField;
6
	import flash.utils.Timer;
7
	import flash.events.TimerEvent;
8
	import flash.ui.Keyboard;
9
	import flash.events.KeyboardEvent;
10
	import flash.events.MouseEvent;
11
	import flash.events.Event;
12
	
13
	import com.Element;
14
		
15
	public class Main extends Sprite
16
	{
17
		
18
		//DO NOT GIVE THEM A VALUE HERE! Give them a value in the init() function

19
		private var snake_vector:Vector.<Element>; //the snake's parts are held in here

20
		private var markers_vector:Vector.<Object>; //the markers are held in here

21
		private var timer:Timer; 
22
		private var dead:Boolean;
23
		private var min_elements:int; //holds how many parts should the snake have at the beginning

24
		private var apple:Element; //Our apple

25
		private var space_value:Number; //space between the snake parts

26
		private var last_button_down:uint; //the keyCode of the last button pressed

27
		private var flag:Boolean; //is it allowed to change direction?

28
		private var score:Number;
29
		private var score_tf:TextField; //the Textfield showing the score

30
		
31
		public function Main() 
32
		{
33
			if(stage)
34
				addEventListener(Event.ADDED_TO_STAGE, init);
35
			else
36
				init();
37
		}
38
		
39
		private function init(e:Event = null):void
40
		{
41
			snake_vector = new Vector.<Element>;
42
			markers_vector = new Vector.<Object>;
43
			space_value = 2;
44
			timer = new Timer(50); //Every 50th millisecond, the moveIt() function will be fired!

45
			dead = false;
46
			min_elements = 10; //We will begin with 10 elements.

47
			apple = new Element(0xFF0000, 1,10, 10); //red, not transparent, width:10, height: 10;

48
			apple.catchValue = 0; //pretty obvious

49
			last_button_down = Keyboard.RIGHT; //The first direction of the snake is set in this variable

50
			score = 0;
51
			score_tf = new TextField(); //this is the TextField which shows our score.

52
			this.addChild(score_tf);
53
			
54
			for(var i:int=0;i<min_elements;++i)
55
			{
56
				snake_vector[i] = new Element(0x00AAFF,1,10,10);
57
				snake_vector[i].direction = "R"; //The starting direction of the snake

58
				if (i == 0)//first snake element

59
				{
60
					//you have to place the first element on a GRID. (now: 0,0) [possible x positions: (snake_vector[0].width+space_value)*<UINT> ]

61
					attachElement(snake_vector[i], (snake_vector[0].width + space_value) * 20, (snake_vector[0].height + space_value) * 10, snake_vector[i].direction);
62
					snake_vector[0].alpha = 0.7;
63
				}
64
				else
65
				{
66
					attachElement(snake_vector[i], snake_vector[i - 1].x, snake_vector[i - 1].y, snake_vector[i - 1].direction);
67
				}
68
			}
69
			
70
			placeApple(false);
71
			timer.addEventListener(TimerEvent.TIMER, moveIt);
72
			timer.start();
73
		}	
74
		
75
		private function attachElement(who:Element,lastXPos:Number = 0,lastYPos:Number = 0,dirOfLast:String = "R"):void
76
		{
77
			if (dirOfLast == "R")
78
			{
79
				who.x = lastXPos - snake_vector[0].width - space_value;
80
				who.y = lastYPos;
81
			}
82
			else if(dirOfLast == "L")
83
			{
84
				who.x = lastXPos + snake_vector[0].width + space_value;
85
				who.y = lastYPos;
86
			}
87
			else if(dirOfLast == "U")
88
			{
89
				who.x = lastXPos;
90
				who.y = lastYPos + snake_vector[0].height + space_value;
91
			}
92
			else if(dirOfLast == "D")
93
			{
94
				who.x = lastXPos;
95
				who.y = lastYPos - snake_vector[0].height - space_value;
96
			}
97
			this.addChild(who);
98
		}
99
		
100
		private function placeApple(caught:Boolean = true):void
101
		{
102
			if (caught)
103
				apple.catchValue += 10;
104
			
105
			var boundsX:int = (Math.floor(stage.stageWidth / (snake_vector[0].width + space_value)))-1;
106
			var randomX:Number = Math.floor(Math.random()*boundsX);
107
			
108
			var boundsY:int = (Math.floor(stage.stageHeight/(snake_vector[0].height + space_value)))-1;
109
			var randomY:Number = Math.floor(Math.random()*boundsY);
110
111
			apple.x = randomX * (apple.width + space_value);
112
			apple.y = randomY * (apple.height + space_value);
113
			
114
			for(var i:uint=0;i<snake_vector.length-1;i++)
115
			{
116
				if(snake_vector[i].x == apple.x && snake_vector[i].y == apple.y)
117
					placeApple(false);
118
			}
119
			if (!apple.stage)
120
				this.addChild(apple);
121
		}		
122
		
123
		private function moveIt(e:TimerEvent):void
124
		{
125
			if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)
126
			{
127
				//This code runs if the snakes heads position and the apples position are the same

128
			}
129
			
130
			if (snake_vector[0].x > stage.stageWidth-snake_vector[0].width || snake_vector[0].x < 0 || snake_vector[0].y > stage.stageHeight-snake_vector[0].height || snake_vector[0].y < 0)
131
			{
132
				gameOver();
133
			}
134
			
135
			
136
			for (var i:int = 0; i < snake_vector.length; i++)
137
			{
138
				/*

139
					START OF FOR BLOCK

140
					This whole 'for' block will run as many times, as many elements the snake has.

141
					If there are four snake parts, this whole for cycle will run four times. 

142
				*/
143
				
144
				if (snake_vector[i] != snake_vector[0] && (snake_vector[0].x == snake_vector[i].x && snake_vector[0].y == snake_vector[i].y))
145
				{
146
					//If the snakes heads position is the same as any of the snake parts, this block will run

147
					gameOver();
148
				}
149
			
150
				if (markers_vector.length > 0)
151
				{
152
					//if there are direction markers, this code runs

153
				}
154
			
155
				
156
				var DIRECTION:String = snake_vector[i].direction; //getting the direction of the current snake element.

157
				switch (DIRECTION)
158
				{
159
					case "R" :
160
						snake_vector[i].x += snake_vector[i].width + space_value;
161
						break;
162
					case "L" :
163
						snake_vector[i].x -= snake_vector[i].width + space_value;
164
						break;
165
					case "D" :
166
						snake_vector[i].y += snake_vector[i].height + space_value;
167
						break;
168
					case "U" :
169
						snake_vector[i].y -= snake_vector[i].width + space_value;
170
						break;
171
				}
172
				
173
				/*

174
					END OF FOR BLOCK

175
				*/
176
			}
177
			
178
		}
179
		
180
		private function gameOver():void 
181
		{
182
			dead = true;
183
			timer.stop();
184
			while (this.numChildren)
185
				this.removeChildAt(0);
186
			timer.removeEventListener(TimerEvent.TIMER,moveIt);
187
			//stage.removeEventListener(KeyboardEvent.KEY_DOWN,directionChanged);

188
			init();
189
		}
190
		
191
	}
192
}

Langkah 11: Fungsi directionChanged()

Kita ingin listen ke keyboard, jadi kita benar-benar dapat mengendalikan ular. Untuk ini kita perlu memasukkan beberapa kode ke fungsi init() dan fungsi gameOver().

Taruh ini di akhir fungsi init() (mengatur fungsi listener):

1
2
stage.addEventListener(KeyboardEvent.KEY_DOWN,directionChanged);

Dan ini di akhir fungsi gameOver():

1
2
stage.removeEventListener(KeyboardEvent.KEY_DOWN,directionChanged);

Sekarang buat fungsi baru:

1
2
private function directionChanged(e:KeyboardEvent):void 
3
{
4
	var m:Object = new Object(); //MARKER OBJECT 

5
	//this will be added to the markers_vector, and have the properties x,y, and type 

6
	//the type property will show us the direction. if it is set to right, whenever a snake's part hits it, 

7
	//the direction of that snake's part will be set to right also

8
	
9
	if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT)
10
	{
11
		//If we pressed the LEFT arrow, 

12
		//and it was not the last key we pressed, 

13
		//and the last key pressed was not the RIGHT arrow either...

14
		//Then this block of code will run

15
	}
16
	markers_vector.push(m); //we push the object into a vector, so we can acces to it later (in the moveIt() function)

17
}

Apa yang masuk ke blok if?

  • Arah kepala harus ditulis ulang.
  • Obyek penanda harus diatur dengan benar.
  • Variabel last_button harus disetel ke tombol terakhir yang ditekan.
1
2
if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT && flag)
3
{
4
	snake_vector[0].direction = "L";
5
	m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"L"};
6
	last_button_down = Keyboard.LEFT;
7
}

Ulangi ini tiga kali lagi, dan kita akan memiliki ini:

1
2
private function directionChanged(e:KeyboardEvent):void 
3
		{
4
			var m:Object = new Object(); //MARKER OBJECT

5
6
			if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT)
7
			{
8
				snake_vector[0].direction = "L";
9
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"L"};
10
				last_button_down = Keyboard.LEFT;
11
			}
12
			else if (e.keyCode == Keyboard.RIGHT && last_button_down != e.keyCode && last_button_down != Keyboard.LEFT)
13
			{
14
				snake_vector[0].direction = "R";
15
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"R"};
16
				last_button_down = Keyboard.RIGHT;
17
			}
18
			else if (e.keyCode == Keyboard.UP && last_button_down != e.keyCode && last_button_down != Keyboard.DOWN)
19
			{
20
				snake_vector[0].direction = "U";
21
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"U"};
22
				last_button_down = Keyboard.UP;
23
			}
24
			else if (e.keyCode == Keyboard.DOWN && last_button_down != e.keyCode && last_button_down != Keyboard.UP)
25
			{
26
				snake_vector[0].direction = "D";
27
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"D"};
28
				last_button_down = Keyboard.DOWN;
29
			}
30
			markers_vector.push(m);
31
		}

Kita membutuhkan satu hal lagi untuk mengujinya. Dalam fungsi moveIt() kita memiliki sesuatu seperti ini:

1
2
				if (markers_vector.length > 0)
3
				{
4
					//if there are direction markers, this code runs

5
				}

Di sini kita perlu perulangan lagi, untuk memeriksa setiap bagian ular terhadap setiap penanda di atas panggung, dan memeriksa apakah mereka bertabrakan. Jika iya, kita perlu mengatur arah bagian ular ke jenis penanda. Jika ini adalah bagian ular terakhir yang bertabrakan dengan penanda, kita perlu menghapus penanda dari markers_vector, juga, sehingga bagian ular tidak bertabrakan dengannya lagi.

1
2
				if (markers_vector.length > 0)
3
				{
4
					for(var j:uint=0;j < markers_vector.length;j++)
5
					{
6
						if(snake_vector[i].x == markers_vector[j].x && snake_vector[i].y == markers_vector[j].y)
7
						{
8
							//setting the direction

9
							snake_vector[i].direction = markers_vector[j].type;
10
							if(i == snake_vector.length-1)
11
							{
12
								//if its the last snake_part

13
								markers_vector.splice(j, 1);
14
							}
15
						}
16
					}
17
				}

Sekarang jika Anda bermain dengannya itu terlihat baik-baik saja, tetapi ada bug di sana. Ingat apa yang saya katakan di awal tutorial?

Sebagai contoh, jika ular bergerak ke kanan dan Anda menekan kombo turun-kiri dengan sangat cepat, ia akan memukul dirinya sendiri dan memulai kembali permainan.

Bagaimana kita memperbaikinya? Itu mudah. Kita memiliki variabel flag kita, dan kita akan menggunakannya untuk ini. Kita hanya akan dapat mengubah arah ular ketika ini diatur ke true (Default adalah false, periksa fungsi init() untuk itu).

Jadi kita perlu mengubah fungsi directionChanged() sedikit. Kepala blok if harus diubah: tambahkan sebuah klausa && flag di akhir setiap 'if'.

1
2
		private function directionChanged(e:KeyboardEvent):void 
3
		{
4
			var m:Object = new Object(); //MARKER OBJECT

5
6
			if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT && flag)
7
			{
8
				snake_vector[0].direction = "L";
9
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"L"};
10
				last_button_down = Keyboard.LEFT;
11
				flag = false;
12
			}
13
			else if (e.keyCode == Keyboard.RIGHT && last_button_down != e.keyCode && last_button_down != Keyboard.LEFT && flag)
14
			{
15
				snake_vector[0].direction = "R";
16
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"R"};
17
				last_button_down = Keyboard.RIGHT;
18
				flag = false;
19
			}
20
			else if (e.keyCode == Keyboard.UP && last_button_down != e.keyCode && last_button_down != Keyboard.DOWN && flag)
21
			{
22
				snake_vector[0].direction = "U";
23
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"U"};
24
				last_button_down = Keyboard.UP;
25
				flag = false;
26
			}
27
			else if (e.keyCode == Keyboard.DOWN && last_button_down != e.keyCode && last_button_down != Keyboard.UP && flag)
28
			{
29
				snake_vector[0].direction = "D";
30
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"D"};
31
				last_button_down = Keyboard.DOWN;
32
				flag = false;
33
			}
34
			markers_vector.push(m);
35
		}

Jika Anda mengujinya sekarang, itu tidak akan berhasil karena penandanya selalu false.

Kapan kita perlu mengaturnya menjadi true?

Setelah pindah/tick kita dapat mengizinkan pengguna untuk mengubah arah, kita hanya tidak ingin mengubahnya dua kali dalam satu tick. Jadi letakkan ini di akhir fungsi moveIt():

1
2
flag = true;

Sekarang uji, dan tidak ada bug lagi.


Langkah 12: Menyelesaikan Permainan

Sekarang satu-satunya hal yang perlu kita lakukan adalah 'apple-check'

Ingat ini di awal fungsi moveIt()?

1
2
			if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)
3
			{
4
				//This code runs if the snake's head's position and the apple's position are the same

5
			}

Inilah yang perlu kita lakukan di sana:

  • Memanggil fungsi placeApple(). (Kita tidak menetapkan parameter ke false; kita membiarkannya seperti itu. Default adalah true.)
  • Menampilkan skor saat ini
  • Lampirkan elemen baru ke bagian terakhir ular.
1
2
			if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)
3
			{
4
				//calling the placeApple() function

5
				placeApple();
6
				//show the current Score

7
				score += apple.catchValue;
8
				score_tf.text = "Score:" + String(score);
9
				//Attach a new snake Element

10
				snake_vector.push(new Element(0x00AAFF,1,10,10));
11
				snake_vector[snake_vector.length-1].direction = snake_vector[snake_vector.length-2].direction; //lastOneRichtung

12
				//attachElement(who,lastXPos,lastYPos,lastDirection)

13
				attachElement(snake_vector[snake_vector.length-1],
14
									  (snake_vector[snake_vector.length-2].x),
15
									  snake_vector[snake_vector.length-2].y,
16
									  snake_vector[snake_vector.length-2].direction);
17
			}

Sekarang semuanya harus berfungsi dengan baik. Cobalah:

Di sini adalah seluruh kelas Main lagi:

1
2
			package  
3
{
4
	import flash.display.Sprite;
5
	import flash.text.TextField;
6
	import flash.utils.Timer;
7
	import flash.events.TimerEvent;
8
	import flash.ui.Keyboard;
9
	import flash.events.KeyboardEvent;
10
	import flash.events.MouseEvent;
11
	import flash.events.Event;
12
	
13
	import com.Element;
14
		
15
	public class Main extends Sprite
16
	{
17
		//DO NOT GIVE THEM A VALUE HERE! Give them a value in the init() function

18
		private var snake_vector:Vector.<Element>; //the snake's parts are held in here

19
		private var markers_vector:Vector.<Object>; //the markers are held in here

20
		private var timer:Timer; 
21
		private var dead:Boolean;
22
		private var min_elements:int; //holds how many parts should the snake have at the beginning

23
		private var apple:Element; //Our apple

24
		private var space_value:Number; //space between the snake parts

25
		private var last_button_down:uint; //the keyCode of the last button pressed

26
		private var flag:Boolean; //is it allowed to change direction?

27
		private var score:Number;
28
		private var score_tf:TextField; //the Textfield showing the score

29
		
30
		public function Main() 
31
		{
32
			if(stage)
33
				addEventListener(Event.ADDED_TO_STAGE, init);
34
			else
35
				init();
36
		}
37
		
38
		private function init(e:Event = null):void
39
		{
40
			snake_vector = new Vector.<Element>;
41
			markers_vector = new Vector.<Object>;
42
			space_value = 2;
43
			timer = new Timer(50); //Every 50th millisecond, the moveIt() function will be fired!

44
			dead = false;
45
			min_elements = 1;
46
			apple = new Element(0xFF0000, 1,10, 10); //red, not transparent, width:10, height: 10;

47
			apple.catchValue = 0; //pretty obvious

48
			last_button_down = Keyboard.RIGHT; //The starting direction of the snake (only change it if you change the 'for cycle' too.)

49
			score = 0;
50
			score_tf = new TextField();
51
			this.addChild(score_tf);
52
53
			//Create the first <min_elements> Snake parts

54
			for(var i:int=0;i<min_elements;++i)
55
			{
56
				snake_vector[i] = new Element(0x00AAFF,1,10,10);
57
				snake_vector[i].direction = "R"; //The starting direction of the snake

58
				if (i == 0)
59
				{
60
					//you have to place the first element on a GRID. (now: 0,0) [possible x positions: (snake_vector[0].width+space_value)*<UINT> ]

61
					attachElement(snake_vector[i],0,0,snake_vector[i].direction) 
62
					snake_vector[0].alpha = 0.7;
63
				}
64
				else
65
				{
66
					attachElement(snake_vector[i], snake_vector[i - 1].x, snake_vector[i - 1].y, snake_vector[i - 1].direction);
67
				}
68
			}
69
			
70
			placeApple(false);
71
			timer.addEventListener(TimerEvent.TIMER,moveIt);
72
			stage.addEventListener(KeyboardEvent.KEY_DOWN,directionChanged);
73
			timer.start();
74
		}
75
		
76
		private function attachElement(who:Element,lastXPos:Number = 0,lastYPos:Number = 0,dirOfLast:String = "R"):void
77
		{
78
			if (dirOfLast == "R")
79
			{
80
				who.x = lastXPos - snake_vector[0].width - space_value;
81
				who.y = lastYPos;
82
			}
83
			else if(dirOfLast == "L")
84
			{
85
				who.x = lastXPos + snake_vector[0].width + space_value;
86
				who.y = lastYPos;
87
			}
88
			else if(dirOfLast == "U")
89
			{
90
				who.x = lastXPos;
91
				who.y = lastYPos + snake_vector[0].height + space_value;
92
			}
93
			else if(dirOfLast == "D")
94
			{
95
				who.x = lastXPos;
96
				who.y = lastYPos - snake_vector[0].height - space_value;
97
			}
98
			this.addChild(who);
99
		}
100
		
101
		private function placeApple(caught:Boolean = true):void
102
		{
103
			if (caught)
104
				apple.catchValue += 10;
105
			
106
			var boundsX:int = (Math.floor(stage.stageWidth / (snake_vector[0].width + space_value)))-1;
107
			var randomX:Number = Math.floor(Math.random()*boundsX);
108
			
109
			var boundsY:int = (Math.floor(stage.stageHeight/(snake_vector[0].height + space_value)))-1;
110
			var randomY:Number = Math.floor(Math.random()*boundsY);
111
112
			apple.x = randomX * (apple.width + space_value);
113
			apple.y = randomY * (apple.height + space_value);
114
			
115
			for(var i:uint=0;i<snake_vector.length-1;i++)
116
			{
117
				if(snake_vector[i].x == apple.x && snake_vector[i].y == apple.y)
118
					placeApple(false);
119
			}
120
			if (!apple.stage)
121
				this.addChild(apple);
122
		}
123
		
124
		private function moveIt(e:TimerEvent):void
125
		{
126
			if (snake_vector[0].x == apple.x && snake_vector[0].y == apple.y)
127
			{
128
				placeApple();
129
				//show the current Score

130
				score += apple.catchValue;
131
				score_tf.text = "Score:" + String(score);
132
				//Attach a new snake Element

133
				snake_vector.push(new Element(0x00AAFF,1,10,10));
134
				snake_vector[snake_vector.length-1].direction = snake_vector[snake_vector.length-2].direction; //lastOneRichtung

135
				attachElement(snake_vector[snake_vector.length-1],
136
									  (snake_vector[snake_vector.length-2].x),
137
									  snake_vector[snake_vector.length-2].y,
138
									  snake_vector[snake_vector.length-2].direction);
139
			}
140
			if (snake_vector[0].x > stage.stageWidth-snake_vector[0].width || snake_vector[0].x < 0 || snake_vector[0].y > stage.stageHeight-snake_vector[0].height || snake_vector[0].y < 0)
141
			{
142
				gameOver();
143
			}
144
			
145
			for (var i:int = 0; i < snake_vector.length; i++)
146
			{
147
				if (markers_vector.length > 0)
148
				{
149
					for(var j:uint=0;j < markers_vector.length;j++)
150
					{
151
						if(snake_vector[i].x == markers_vector[j].x && snake_vector[i].y == markers_vector[j].y)
152
						{
153
							snake_vector[i].direction = markers_vector[j].type;
154
							if(i == snake_vector.length-1)
155
							{
156
								markers_vector.splice(j, 1);
157
							}
158
						}
159
					}
160
				}
161
				if (snake_vector[i] != snake_vector[0] && (snake_vector[0].x == snake_vector[i].x && snake_vector[0].y == snake_vector[i].y))
162
				{
163
					gameOver();
164
				}
165
			
166
				//Move the boy

167
				var DIRECTION:String = snake_vector[i].direction;
168
				switch (DIRECTION)
169
				{
170
					case "R" :
171
						snake_vector[i].x += snake_vector[i].width + space_value;
172
						break;
173
					case "L" :
174
						snake_vector[i].x -= snake_vector[i].width + space_value;
175
						break;
176
					case "D" :
177
						snake_vector[i].y += snake_vector[i].height + space_value;
178
						break;
179
					case "U" :
180
						snake_vector[i].y -= snake_vector[i].width + space_value;
181
						break;
182
				}
183
				
184
			}
185
						
186
			flag = true;
187
		}
188
		
189
		private function gameOver():void 
190
		{
191
			dead = true;
192
			timer.stop();
193
			while (this.numChildren)
194
				this.removeChildAt(0);
195
			timer.removeEventListener(TimerEvent.TIMER,moveIt);
196
			stage.removeEventListener(KeyboardEvent.KEY_DOWN,directionChanged);
197
			init();
198
		}
199
	
200
		private function directionChanged(e:KeyboardEvent):void 
201
		{
202
			var m:Object = new Object(); //MARKER OBJECT

203
204
			if (e.keyCode == Keyboard.LEFT && last_button_down != e.keyCode && last_button_down != Keyboard.RIGHT && flag)
205
			{
206
				snake_vector[0].direction = "L";
207
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"L"};
208
				last_button_down = Keyboard.LEFT;
209
				flag = false;
210
			}
211
			else if (e.keyCode == Keyboard.RIGHT && last_button_down != e.keyCode && last_button_down != Keyboard.LEFT && flag)
212
			{
213
				snake_vector[0].direction = "R";
214
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"R"};
215
				last_button_down = Keyboard.RIGHT;
216
				flag = false;
217
			}
218
			else if (e.keyCode == Keyboard.UP && last_button_down != e.keyCode && last_button_down != Keyboard.DOWN && flag)
219
			{
220
				snake_vector[0].direction = "U";
221
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"U"};
222
				last_button_down = Keyboard.UP;
223
				flag = false;
224
			}
225
			else if (e.keyCode == Keyboard.DOWN && last_button_down != e.keyCode && last_button_down != Keyboard.UP && flag)
226
			{
227
				snake_vector[0].direction = "D";
228
				m = {x:snake_vector[0].x, y:snake_vector[0].y, type:"D"};
229
				last_button_down = Keyboard.DOWN;
230
				flag = false;
231
			}
232
			markers_vector.push(m);
233
		}
234
		
235
	}
236
237
}

Langkah 13: Menyimpulkan Semuanya

Selamat! Anda baru saja membuat permainan yang bagus. Sekarang Anda bisa mengembangkannya lebih jauh, dan membuat apel super atau sesuatu. Untuk itu saya sarankan menggunakan fungsi lain yang bernama placeSuperApple() dan kelas baru bernama SuperApple. Setiap kali Anda menangkap apel super, bagian ular bisa diperpanjang oleh tiga elemen, mungkin. Ini bisa diatur dengan setter/getter di kelas SuperApple.

Jika Anda ingin melakukan ini, dan Anda terjebak di suatu tempat, tinggalkan saja saya komentar di sini.

Terima kasih atas waktu Anda!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.