Advertisement
  1. Code
  2. Games

Membuat Game Tic-Tac-Toe yang Cerdas dengan AS3

Scroll to top
Read Time: 35 min

() translation by (you can also view the original English article)

"Tic-Tac-Toe, itu membosankan!" Anda mungkin berpikir. Dalam tutorial ini saya akan menunjukkan kepada Anda bahwa membangun game Tic-Tac-Toe sama sekali tidak membosankan. Ini adalah game yang ideal untuk dibuat ketika Anda ingin belajar ActionScript 3.0. Sementara membangunnya, Anda akan belajar banyak tentang fungsi dan event listener, Anda akan melihat betapa mudahnya untuk menyesuaikan grafik permainan dan Anda bahkan akan belajar cara memprogram Artificial Intelligence (AI)!

Pratinjau Hasil Akhir

Mari kita lihat hasil akhir yang akan kita kerjakan:


Langkah 1: Persiapan

Kami akan mulai dengan membuat file Flash baru (File > New > Flash File (ActionScript 3.0)). Atur dimensi stage ke 300x300 dan gunakan latar belakang hitam. Di properti (Window> Properties), isi "TicTacToe" sebagai definisi kelas. Sekarang simpan file di folder proyek Anda (mis. Desktop\MyFirstGame\) sebagai "TicTacToe.fla".

Selanjutnya, kita akan mengatur file AS3 yang akan kita gunakan. Kami mulai dengan tiga file .as, yang juga kami simpan di folder proyek kami. Tulis kode berikut dan simpan file dengan nama yang sama dengan nama kelas. Jadi kelas TicTacToe yang Anda simpan sebagai "TicTacToe.as", dll.

1
2
package
3
{
4
  import flash.display.MovieClip;
5
	
6
	public class TicTacToe extends MovieClip
7
	{
8
		public function TicTacToe():void
9
		{
10
			trace("TicTacToe");
11
		}
12
	}
13
}
1
2
package
3
{
4
	import flash.display.MovieClip;
5
6
	public class Game extends MovieClip
7
	{
8
		public function Game(num:uint):void
9
		{
10
			trace("Game");
11
		}
12
	}
13
}
1
2
package
3
{
4
	import flash.display.MovieClip;
5
	
6
	public class Tile extends MovieClip
7
	{
8
		public function Tile():void
9
		{
10
			trace("Tile");
11
		}
12
	}
13
}

Kelas pertama, TicTacToe.as, akan menjadi kelas dokumen kami. Tidak yakin apa maksudnya? Baca pengantar cepat ini untuk kelas dokumen.


Langkah 2: Latar Belakang Yang Sedikit Lebih Banyak

Kami sekarang memiliki empat file di folder proyek kami: satu file .fla dan tiga file .as. Ketika Anda menguji Flash movie Anda (Control > Test Movie), Anda akan melihat stage dengan latar belakang hitam dan "TicTacToe" di layar Output (Window > Output). Bagus, tapi apa yang akan kita lakukan dengannya?

File TicTacToe.as akan menangani fungsionalitas menu kami, yang akan kami tulis di akhir tutorial ini (lebih menyenangkan untuk mendapatkan game yang berfungsi secepat mungkin, kan?). Menu hanya akan memiliki dua tombol, satu pemain atau dua pemain.

File Game.as akan menangani game kami. Ini juga mengapa kami meminta argumen "num"; ini akan menentukan jumlah pemain manusia. kami akan mulai dengan 2, tetapi nanti kami juga ingin menulis fungsionalitas ketika hanya ada satu pemain. Dalam hal ini, komputer harus bermain sebagai pemain dua.

File terakhir, Tile.as, akan kami gunakan untuk membuat ubin (Anda dapat menebaknya). Maksud saya, ubin adalah salah satu dari sembilan tempat di mana Anda dapat menempatkan O atau X (atau gambar bunga, hewan peliharaan Anda, logo, sebut saja).


Langkah 3: Grafik Garis Grid

Kami akan mulai dengan membuat garis. Anda bisa menjadi sekreatif yang Anda inginkan, tetapi pastikan garis-garisnya membagi stage menjadi 9 blok yang sama. Inilah yang saya lakukan: Saya membuat MovieClip baru (Insert > New Symbol) dan menggambar 2 garis horizontal dan 2 garis vertikal dengan panjang 300px. Garis horizontal yang saya atur di x = 0 dan (y = 100 || y = 200). Garis vertikal saya atur di (x = 100 || x = 200) dan y = 0.

Di perpustakaan Anda (Window > Library), klik kanan MovieClip baru Anda, pergi ke Properties dan centang kotak yang mengatakan "Export for ActionScript". Isi dengan "Grrid" sebagai definisi kelas.


Langkah 4: Ubin Grafik

Selanjutnya kita akan membuat ubin O dan X. Anda dapat menggunakan gambar apa pun yang Anda inginkan, meskipun Anda harus mengingat satu hal: grid kami membagi stage kami menjadi 9 ubin persegi 100x100px, sehingga setiap ubin tidak boleh lebih besar dari 100x100. Inilah yang saya lakukan: Saya membuat MovieClip baru dan membuat bentuk dengan Rectangle Tool 100x100. Bentuk ini saya selaraskan sehingga bagian kiri atas adalah titik registrasi MovieClip. Warna isian bisa apa saja, tetapi atur ke alpha 0%. Dengan cara ini ubin MovieClip Anda selalu 100x100 dan Anda dapat menggambar gambar apa pun yang Anda inginkan di atas bentuk 100x100.

Anda dapat menghapus latar belakang 100x100 setelah Anda menggambar bentuk X dan O, tetapi itu tidak terlalu menjadi masalah. Ini adalah game kecil sehingga tidak perlu menghapus bentuk dengan mempertimbangkan kinerja. Saya merasa mudah untuk meninggalkannya sehingga saya dapat mengubah grafik di kemudian hari tanpa kehilangan orientasi di mana saya dapat meletakkan semuanya. Anda hanya perlu memilih kedua grafik (bentuk 100x100 dan grafik Anda sendiri) dan menyelaraskannya ke tengah (pastikan Align To Stage tidak aktif), dan Anda selesai.

Ini adalah dua MovieClips yang saya buat. Dua telur kecil di sebelah kanan adalah hasil akhir. Saya tidak akan masuk ke detail tentang cara membuat angka telur keren, tutorial ini adalah tentang membuat game. Percobaan dengan grafik Anda sendiri, dan coba hal-hal baru seperti menggunakan timeline MovieClip Anda.

Ekspor kedua MovieClips untuk ActionScript dengan cara yang sama seperti yang Anda lakukan dengan Grid. Pastikan Anda memberikan nama definisi kelas TileO dan TileX. Kami sekarang memiliki tiga item di perpustakaan kami: Grid, TileO dan TileX. Kita hanya perlu dua lagi sebelum kita bisa membuat skrip!


Langkah 5: Penyorot Grafis

Seperti yang saya katakan, kita hampir siap untuk melakukan beberapa scripting, tetapi kita perlu dua grafik lagi. Ketika seseorang memenangkan game, kami tidak ingin memulai game baru segera tetapi melihat garis game terlebih dahulu. Untuk ini kita memerlukan bentuk untuk posisi di atas ubin ketika ubin adalah bagian dari garis yang menang. Saya hanya ,membuat bentuk 100x100 putih dengan alpha diatur ke 50%, tapi saya tahu Anda bisa melakukan yang lebih baik. Anda dapat membuat tanda V hijau yang bagus, senyum bahagia, apa saja. Ekspor MovieClip untuk ActionScript dengan TileE definisi kelas (E untuk "END"; Saya memiliki sesuatu tentang nama pendek, dan dalam game sederhana seperti ini Anda akan ingat apa artinya).

Grafik terakhir yang perlu Anda buat adalah tombol ": ubin, tempat kami menerapkan semua event listener dalam ubin. Sekali lagi, buat bentuk 100x100 dengan alpha yang disetel ke 0%. Pastikan, seperti semua grafik ubin yang kami buat, bahwa titik pendaftaran diatur ke sudut kiri atas. Ekspor MovieClip untuk ActionScript dengan TileB definisi kelas (B untuk "BUTTON").

Kami sekarang memiliki lima MovieClips di perpustakaan kami yang akan kami gunakan untuk membangun game Tic-Tac-Toe.


Langkah 6: Game Baru

Kami akan mulai dengan lambat. Buka kelas dokumen Anda (TicTacToe.as) dan terapkan perubahan berikut:

1
2
package
3
{
4
	import flash.display.MovieClip;
5
	
6
	public class TicTacToe extends MovieClip
7
	{
8
		public function TicTacToe():void
9
		{
10
			var game:Game = new Game(2); // Add a new game

11
			addChild(game); // Add the game to the display list

12
		}
13
	}
14
}

Itu saja. Ketika kami sekarang menguji Flash Movie, jendela Output akan menampilkan Game. Kami menyediakan 2 sebagai argumen untuk konstruktor Game() karena kami ingin memulai dengan membangun game untuk dua pemain. Kami juga menambahkan game ke daftar tampilan, tetapi tidak akan melihat apa-apa karena kelas game hanya berisi pernyataan jejak saat ini.


Langkah 7: Ubin!

Akan menyenangkan jika ini adalah langkah 9, bukan?

...

Bagaimanapun! Kami akan menambahkan ubin ke game. Saya akan menambahkan banyak kode sekaligus, dan hasilnya adalah kita tidak akan melihat apa pun kecuali 9 jejak dengan kata "Tile", tapi itu sepadan. Saya akan menjelaskan semua kode, tetapi cobalah membaca dan memahaminya sendiri terlebih dahulu.

1
2
package
3
{
4
	import flash.display.MovieClip;
5
	import flash.events.Event;
6
7
	public class Game extends MovieClip
8
	{
9
		public var numPlayers:uint;
10
		public var turn:uint;
11
		private var _grid:Grid = new Grid();
12
		private var _tiles:Array = new Array();
13
		
14
		public function Game(num:uint):void
15
		{
16
			numPlayers = num;
17
			turn = 0;
18
			addVisuals();
19
			addTileListeners();
20
			nextTurn();
21
		}
22
		
23
		private function addVisuals():void
24
		{
25
			var tile1:Tile = new Tile();
26
			var tile2:Tile = new Tile();
27
			var tile3:Tile = new Tile();
28
			var tile4:Tile = new Tile();
29
			var tile5:Tile = new Tile();
30
			var tile6:Tile = new Tile();
31
			var tile7:Tile = new Tile();
32
			var tile8:Tile = new Tile();
33
			var tile9:Tile = new Tile();
34
			tile1.x = tile4.x = tile7.x = tile1.y = tile2.y = tile3.y = 0;
35
			tile2.x = tile5.x = tile8.x = tile4.y = tile5.y = tile6.y = 100;
36
			tile3.x = tile6.x = tile9.x = tile7.y = tile8.y = tile9.y = 200;
37
			addChild(tile1);
38
			addChild(tile2);
39
			addChild(tile3);
40
			addChild(tile4);
41
			addChild(tile5);
42
			addChild(tile6);
43
			addChild(tile7);
44
			addChild(tile8);
45
			addChild(tile9);
46
			addChild(_grid);
47
			_tiles.push(tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9);
48
		}
49
		
50
		private function addTileListeners():void
51
		{
52
			for (var i:int = 0; i < _tiles.length; i++) {
53
				_tiles[i].addEventListener("TILE_ACTIVE", nextTurn);
54
			}
55
		}
56
		
57
		public function nextTurn(e:Event = null):void
58
		{
59
			trace("Next turn!");
60
			turn += 1;
61
		}
62
	}
63
}

Seperti yang Anda lihat, pertama saya membuat beberapa variabel. Variabel numPlayers melacak berapa banyak pemain yang bermain. Kita membutuhkan ini nanti ketika kita menambahkan AI. Hal yang sama berlaku untuk variabel turn, yang mencatat giliran siapa. Kami juga membuat _grid, sebuah instance dari simbol Grid, yang ingin kami tampilkan. Akhirnya, array _tiles akan melacak semua ubin.

Fungsinya adalah teman Anda, jadi saya menulis fungsi baru untuk menambahkan ubin, addVisuals() (Anda dapat menulis semua kode di konstruktor, tetapi ini lebih rapi). Dalam fungsi ini, pertama-tama kita membuat sembilan ubin baru. Posisi x dan y ubin diatur sedemikian rupa sehingga ubin akan diposisikan sebagai keypad ponsel:

1
2
            x = 0    x = 100   x = 200
3
4
y = 0       tile1     tile2     tile3
5
y = 100     tile4     tile5     tile6
6
y = 200     tile7     tile8     tile9

Kami menambahkan setiap ubin ke daftar tampilan (yang tidak akan kami lihat, karena ubin belum memiliki visual), dan juga mendorongnya ke daftar _tiles (dalam urutan yang benar, ini sangat penting untuk pemeriksaan AI/menang) kemudian). Panggilan addChild() terakhir adalah untuk grid, yang ingin kami posisikan di atas semua ubin. Terakhir tapi bukan yang akhir, kami menambahkan event listener ke semua ubin dengan fungsi addTileListeners(). Event yang kami dengarkan belum ada, tetapi kami akan mengirimkannya dari kelas ubin nanti. Ketika event dipicu, ia menjalankan fungsi nextTurn yang akan menangani giliran dan memeriksa garis kemenangan. Tentu saja kita memanggil fungsi nextTurn() di dalam konstruktor sehingga kita dapat memulai game.


Langkah 8: AI Permulaan

Dimungkinkan untuk membuat sistem AI yang sangat kompleks, tetapi karena Tic-Tac-Toe adalah game yang agak kecil dengan opsi terbatas, lebih baik mengambil jalan keluar yang mudah. Kami menambahkan semua ubin ke Array _tiles. Ubin pertama (tile1) ditambahkan pertama, sehingga memiliki index = 0. Ubin kedua memiliki index = 1, dll. Jika kita memvisualisasikan ini di layar, akan terlihat seperti ini:

1
2
0 1 2
3
3 4 5
4
6 7 8

Inilah cara kami akan memeriksa apakah seseorang memiliki tiga berturut-turut: kami membuat array dari semua kombinasi yang memungkinkan Anda dapat menang. Sebagai contoh, 0 1 2 adalah kombinasi pemenang, dan begitu juga 1 4 7 dan 2 4 6(diagonal). Tambahkan variabel berikut ke skrip Game.as Anda:

1
2
private var _combos:Array = new Array(new Array(0, 1, 2), new Array(3, 4, 5), new Array(6, 7, 8),
3
                                      new Array(0, 3, 6), new Array(1, 4, 7), new Array(2, 5, 8),
4
                                      new Array(0, 4, 8), new Array(2, 4, 6));

Kemudian, kami akan memeriksa index semua ubin O dan X di dalam array _tiles. Ketika index, misalnya, empat ubin X adalah 0 4 5 dan 8, kita dapat memeriksa apakah kombinasi yang menang cocok dengan index ini. Misalnya, ada 0, tetapi tidak 1 dan 2, jadi ubin X tidak cocok dengan kombinasi pemenang 0 1 2. Kami akan melakukan ini untuk setiap kombinasi, dan pada akhirnya akan melihat bahwa kombinasi 0 4 8 telah dibuat. Script untuk ini akan diberikan beberapa langkah kemudian.


Langkah 9: .. Ubin di Layar!

Lagipula harus membuat lelucon. Saya mungkin membuat Anda takut dengan kode berikut untuk Tile.as, tetapi saya akan bertanya sekali lagi: coba cari tahu sendiri dan setelah membaca komentar saya pada kode. Ini mungkin tampak banyak, tetapi jika Anda membacanya dan membaca komentar Anda akan memahami cara kerjanya.

1
2
package
3
{
4
	import flash.display.MovieClip;
5
	import flash.events.Event;
6
	import flash.events.EventDispatcher;
7
	import flash.events.MouseEvent;
8
	
9
	public class Tile extends MovieClip
10
	{
11
		public var isSet:String; // Variable to hold which player clicked this tile

12
		
13
		private var tileB:TileB = new TileB();
14
		private var tileE:TileE = new TileE();
15
		private var tileO:TileO = new TileO();
16
		private var tileX:TileX = new TileX();
17
		
18
		public function Tile():void
19
		{
20
			isSet = "not set"; // The tile is still free for players to use

21
			tileO.visible = false; // Set the tile visibility to false

22
			tileX.visible = false;
23
			tileE.visible = false;
24
			addChild(tileO); // Add the graphics in this order!

25
			addChild(tileX);
26
			addChild(tileE);
27
			addChild(tileB); // Button needs to be on top

28
			addButtonListeners(); // Function to add the listeners

29
		}
30
		
31
		public function addButtonListeners():void // Public, as we want to use it from the game class later on

32
		{
33
			this.buttonMode = true;
34
			tileB.addEventListener(MouseEvent.MOUSE_OVER, showGraphic);
35
			tileB.addEventListener(MouseEvent.MOUSE_OUT, hideGraphic);
36
			tileB.addEventListener(MouseEvent.CLICK, chooseGraphic);
37
		}
38
		
39
		public function removeButtonListeners():void // Public, as we want to use it from the game class later on

40
		{
41
			this.buttonMode = false;
42
			tileB.removeEventListener(MouseEvent.MOUSE_OVER, showGraphic);
43
			tileB.removeEventListener(MouseEvent.MOUSE_OUT, hideGraphic);
44
			tileB.removeEventListener(MouseEvent.CLICK, chooseGraphic);
45
		}
46
		
47
		private function showGraphic(e:MouseEvent):void
48
		{
49
			if (Game(this.parent).turn % 2 == 0) { // turn % 2 is always either 0 or 1: 0%2 = 0, 1%2 = 1, 2%2 = 0, 3%2 = 1, etc.

50
				tileO.visible = true; // It's O's turn, show the O graphic

51
			} else {
52
				tileX.visible = true; // It's X's turn, show the X graphic

53
			}
54
		}
55
		
56
		private function hideGraphic(e:MouseEvent):void
57
		{
58
			tileO.visible = false; // Hide the graphics

59
			tileX.visible = false; // For both O and X

60
		}
61
		
62
		private function chooseGraphic(e:MouseEvent):void
63
		{
64
			removeButtonListeners(); // Remove the listeners (this tile is now disabled)

65
			isSet = (Game(this.parent).turn % 2 == 0) ? "O" : "X"; // Set the isSet variable to O or X

66
			trace(isSet);
67
			dispatchEvent(new Event("TILE_ACTIVE")); // Dispatch the event

68
		}
69
	}
70
}

Apakah Anda sudah mengujinya? Karena jika semuanya berjalan dengan baik, Anda akan melihat game yang berfungsi sekarang! Mari kita bahas skripnya sebentar.

Kami mulai dengan membuat semua gambar. Masing-masing dari sembilan ubin memiliki grafis TileB, TileE, TileX dan TileO. Di konstruktor (fungsi publik Tile()) kami menambahkan grafik ini ke daftar tampilan dan mengatur visibilitas ke false. Hanya grafik TileB yang tetap pada visible = true, karena kami ingin menambahkan event listener kami ke grafik ini. Tidak masalah; itu sebabnya kami mengatur alpha ke 0%.

Baik fungsi addButtonListeners() dan removeButtonListeners() berbicara sendiri. Saat kami menempatkan mouse di atas ubin, kami ingin grafik yang benar ditampilkan. Saat kami memindahkan mouse dari ubin, kami ingin menyembunyikan gambar. Ketika kami mengklik, kami ingin itu menunjukkan grafik dan membuatnya tetap terlihat sehingga pemain berikutnya dapat bermain. Kami melakukan ini dengan operator modulo.

Dalam komputasi, operasi modulo menemukan sisa pembagian satu angka dengan yang lain - Wikipedia.

Saat kami mengeklik ubin, fungsi chooseGraphic(e:MouseEvent) menjadi pemicu. Dalam fungsi ini kami menghapus semua lisener, mengatur variabel isSet (melacaknya) dan menjalankan event TILE_ACTIVE. Langkah selanjutnya: periksa siapa yang menang!


Langkah 10: Game Bagus!

Mari kita mulai dengan mudah: tambahkan skrip berikut ke file Tile.as untuk menangani situasi kemenangan:

1
2
public function showEnd():void { // Added to show the tileE

3
		tileE.visible = true;
4
}

Mudah bukan? Ini adalah fungsi publik sehingga kami dapat memanggilnya dari kelas Game, dan yang dilakukannya hanyalah mengatur visibilitas tileE menjadi true. Sekarang buka Game.as lagi dan bersiaplah untuk beberapa skrip serius. Kami akan menambahkan satu variabel, mengedit fungsi nextTurn() dan menambahkan dua fungsi baru:

1
2
package
3
{
4
	import flash.display.MovieClip;
5
	import flash.events.Event;
6
7
	public class Game extends MovieClip
8
	{
9
		public var numPlayers:uint;
10
		public var turn:uint;
11
		public var left:uint = 10; // Added to keep track of free tiles; 10 because we do -1 once without marking a tile

12
		private var _grid:Grid = new Grid();
13
		private var _tiles:Array = new Array();
14
		private var _combos:Array = new Array(new Array(0, 1, 2), new Array(3, 4, 5), new Array(6, 7, 8),
15
											  new Array(0, 3, 6), new Array(1, 4, 7), new Array(2, 5, 8),
16
											  new Array(0, 4, 8), new Array(2, 4, 6));
17
		
18
		public function Game(num:uint):void
19
		{
20
			numPlayers = num;
21
			turn = 0;
22
			addVisuals();
23
			addTileListeners();
24
			nextTurn();
25
		}
26
		
27
		private function addVisuals():void
28
		{
29
			var tile1:Tile = new Tile();
30
			var tile2:Tile = new Tile();
31
			var tile3:Tile = new Tile();
32
			var tile4:Tile = new Tile();
33
			var tile5:Tile = new Tile();
34
			var tile6:Tile = new Tile();
35
			var tile7:Tile = new Tile();
36
			var tile8:Tile = new Tile();
37
			var tile9:Tile = new Tile();
38
			tile1.x = tile4.x = tile7.x = tile1.y = tile2.y = tile3.y = 0;
39
			tile2.x = tile5.x = tile8.x = tile4.y = tile5.y = tile6.y = 100;
40
			tile3.x = tile6.x = tile9.x = tile7.y = tile8.y = tile9.y = 200;
41
			addChild(tile1);
42
			addChild(tile2);
43
			addChild(tile3);
44
			addChild(tile4);
45
			addChild(tile5);
46
			addChild(tile6);
47
			addChild(tile7);
48
			addChild(tile8);
49
			addChild(tile9);
50
			addChild(_grid);
51
			_tiles.push(tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9);
52
		}
53
		
54
		private function addTileListeners():void
55
		{
56
			for (var i:int = 0; i < _tiles.length; i++) {
57
				_tiles[i].addEventListener("TILE_ACTIVE", nextTurn);
58
			}
59
		}
60
		
61
		public function nextTurn(e:Event = null):void
62
		{
63
			if (!checkWin()) {      // Only if the checkWin function returns false, continue

64
				left -= 1;          // Someone chose a tile so there's one less left to choose from

65
				if (left > 0) {     // While there are tiles left...

66
					turn += 1;      // Add one to the turn (next player is up)

67
				} else {
68
					endGame();      // Else end the game (it's a draw)

69
				}
70
			}
71
		}
72
		
73
		private function checkWin():Boolean
74
		{
75
			var won:Boolean = false;                            // First set a boolean to false

76
			for each (var combi:Array in _combos) {             // For each combi (array) in our _combos array

77
				var xwin = true;                                // Assume x won

78
				var owin = true;                                // Assume o won

79
				for each (var tile:int in combi) {              // For each tile index (number) in our combi array

80
					xwin = xwin && _tiles[tile].isSet == "X";   // Set xwin and owin to true, but only when there is an X or O

81
					owin = owin && _tiles[tile].isSet == "O";   // with the same index as the number in the combi array

82
				}
83
				if (xwin || owin) {                             // If either xwin or owin is true

84
					endGame(combi);                             // End the game (supply the combi)

85
					won = true;                                 // Set won to true

86
					break;                                      // Break out of the loop (important! there is a winning combination so no more checking needed)

87
				} else {
88
					won = false;                                // Else set won to false (no combination yet)

89
				}
90
			}
91
			return won;                                         // Return won

92
		}
93
		
94
		private function endGame(combi:Array = null):void
95
		{
96
			for (var i:int = 0; i < _tiles.length; i++) {       // For each tile in the tiles Array

97
				_tiles[i].removeButtonListeners();              // Remove the listeners

98
				if (combi) {                                    // If there is a combi supplied (someone won)

99
					for each (var j:int in combi) {             // Check each number in that combi...

100
						if (i == j) _tiles[i].showEnd();        // And highlight the corresponding tile with showEnd()

101
					}
102
				}
103
			}
104
		}
105
	}
106
}

Kita mulai dengan variabel left. Ketika ini mencapai nol, itu berarti tidak ada ubin lagi yang tersisa dan game berakhir. Biasanya ini berarti seri.

Selanjutnya adalah fungsi nextTurn(e: Event = null), yang pertama hanya turn += 1 di dalamnya. Seperti yang Anda lihat, sekarang memiliki lebih banyak kondisi. Setiap kali fungsi dipanggil, kami memeriksa apakah seseorang menang. Jika tidak, kami tahu ada satu petak yang lebih sedikit untuk dipilih, jadi kami lakukan left  -= 1. Selama ada ubin yang tersisa, kami dapat membiarkan pemain lain melakukan langkahnya. Tidak ada ubin yang tersisa berarti akhir game (seri, karena kami hanya mencapai bagian skrip ini jika belum ada situasi kemenangan).

Fungsi checkWin() paling baik dijelaskan dengan sebuah contoh. Mari kita ambil situasi berikut:

1
2
tile1 = X     tile 4 = O
3
tile2 = X     tile 5 = O
4
tile3 = X

Tile1 memiliki index 0 di dalam array _tiles. Yang pertama untuk pernyataan for each memeriksa semua Array yang bersarang di dalam array _combos. Yang pertama berisi "0 1 2". Yang pernyataan each kedua menangani angka-angka ini (yang mewakili index ubin). Inilah yang terjadi pada pernyataan for each kedua:

1
2
first combo  = 0 1 2
3
4
- FIRST PASS                   _tiles[0].isSet = X
5
var tile     = 0
6
xwin (true)  = xwin (true)  && _tiles[0].isSet == X (true)
7
owin (flase) = owin (true)  && _tiles[0].isSet == O (false)
8
9
- SECOND PASS                  _tiles[1].isSet = X
10
var tile     = 1
11
xwin (true)  = xwin (true)  && _tiles[1].isSet == X (true)
12
owin (flase) = owin (false) && _tiles[1].isSet == O (false)
13
14
- THIRD PASS                   _tiles[2].isSet = X
15
var tile     = 2
16
xwin (true)  = xwin (true)  && _tiles[2].isSet == X (true)
17
owin (flase) = owin (false) && _tiles[2].isSet == O (false)

Seperti yang Anda lihat, ketika pernyataan for each kedua selesai, xwin akan true dan owin akan false. Ini memicu pernyataan if dan panggilan untuk fungsi endGame(combi: Array = null). Dengan itu, ia memasukan kombinasi pemenang yang akan kami gunakan dalam fungsi. Fungsi checkWin() mengembalikan true atau false, yang saya jelaskan sebelumnya.

Fungsi endGame() mudah dimengerti. Pertama, untuk setiap ubin di Array _tiles, kami menonaktifkan event listener. Kami juga memeriksa apakah ada kombinasi yang disediakan (artinya seseorang menang bukannya seri). Jika demikian, kami memeriksa ubin mana yang merupakan bagian dari kombinasi dan memanggil fungsi showEnd() pada ubin tersebut. Ini akan menampilkan grafik 'TileE'.


Milestone 1

Kami sekarang memiliki game yang berfungsi. Untuk sumber dari semua yang kami lakukan sejauh ini, periksa _milestone1.zip. Hasil!


Langkah 11: Fungsi AI

Saya harap Anda tidak bingung dengan semua skrip yang kami lakukan sejauh ini. kami akan melanjutkan dengan bagian AI dari game, yang membutuhkan beberapa fungsi. Pertama, mari kita buat beberapa perubahan dan tambahkan fungsi untuk menambahkan AI. Di TicTacToe.as, ubah baris berikut:

1
2
var game:Game = new Game(1); // Changed number of human players to 1

Selanjutnya, di Game.as, tambahkan variabel berikut:

1
2
private var _xlist:Array = new Array(); // keep track of all x tiles

3
private var _olist:Array = new Array(); // keep track of all o tiles

4
private var _flist:Array = new Array(); // keep track of all free tiles

Dalam fungsi addVisuals(), tambahkan baris berikut (setelah Anda mendorong ubon ke Array _tiles):

1
2
_flist.push(tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9); // added all tiles to the free list

Kemudian ubah fungsi nextTurn(e: Event = null) menjadi yang berikut:

1
2
public function nextTurn(e:Event = null):void
3
{
4
    if (!checkWin()) {
5
        if (e) { // added check for an event (we call the function once without marking a tile)

6
            if (e.currentTarget.isSet == "X") { // if the tile is set to X

7
                _xlist.push(e.currentTarget); // add it to the X list

8
            }
9
            if (e.currentTarget.isSet == "O") { // if the tile is set to O

10
                _olist.push(e.currentTarget); // add it to the O list

11
            }
12
            _flist.splice(_flist.indexOf(e.currentTarget), 1); // remove the tile from the free list

13
        }
14
        left -= 1;
15
        if (left > 0) {
16
            turn += 1;
17
            if (turn % 2 == 0 && numPlayers == 1) handleAI(); // check if the PC should choose a tile

18
        } else {
19
            endGame();
20
        }
21
    }
22
}

Tentu saja, tambahkan juga fungsi handleAI() ke kelas Game.as:

1
2
private function handleAI():void
3
{
4
    trace(_xlist);
5
    trace(_olist);
6
    trace(_flist);
7
}

Saat kami sekarang menguji Flash movie, setelah giliran pertama kami, kami melihat tiga daftar di Jendela Output kami. Panjang _xlist akan menjadi satu elemen (Anda memilih ubin untuk ditandai). _olist kosong (pemain dua belum mengambil ubin) dan _flist panjangnya delapan elemen (masih ada delapan ubin yang bisa dipilih). Kami akan menggunakan daftar ini di langkah berikutnya untuk membiarkan AI memilih ubin.


Langkah 12: AI Seberapa Cerdas?

Ada banyak cara untuk skrip perilaku komputer. Seperti yang mungkin Anda ketahui, jika kedua pemain memperhatikan dan mengetahui aturannya, permainan Tic-Tac-Toe selalu berakhir imbang. Kami hanya dapat membuat skrip semua situasi sehingga hasilnya selalu imbang atau menang untuk komputer. Tapi apa yang menyenangkan dari itu? Saya memilih untuk membuat AI yang tidak pintar, tetapi juga tidak bodoh. Ini adalah aturan yang akan kami tulis:

  • untuk setiap ubin bebas, pilih jika ubin ini ditambah semua ubin yang sudah dipilih memenangkan permainan
  • untuk setiap ubin bebas, pilih jika ubin ini ditambah semua ubin yang sudah dipilih memenangkan game
  • jika tidak, pilih ubin bebas acak

Jadi komputer pertama-tama harus memeriksa apakah ia dapat memenangkan game. Jika komputer tidak bisa menang dengan ubin bebas ini, itu harus memeriksa apakah pemain manusia bisa menang dengan ubin ini. Ketika komputer maupun pemain manusia tidak bisa menang, itu harus memilih ubin acak. Kita bisa membuatnya berpikir di depan, dan alih-alih memilih ubin acak, biarkan ubin itu memilih dari ubin yang memungkinkan untuk memenangkan ronde berikutnya. Tetapi sekali lagi, kami tidak akan melakukan itu karena itu akan membuat game cukup membosankan.


Langkah 13: AI Mengaktifkan Ubin

Tidak ada yang lebih mudah dari langkah ini. Kita harus mengaktifkan ubin agar komputer dapat menandainya. Biasanya, ketika kami bermain dengan dua pemain, mouse digunakan untuk memicu pertukaran grafik dan mengirimkan event yang mengatur pergantian ke plus satu. Karena komputer tidak menggunakan MouseEvents, kita perlu mengubah dua fungsi di Tile.as sehingga mereka dapat digunakan dari file Game.as. Ini adalah fungsi-fungsi tersebut:

1
2
public function showGraphic(e:MouseEvent = null):void // Changed to public and set MouseEvent to null
1
2
public function chooseGraphic(e:MouseEvent = null):void // Changed to public and set MouseEvent to null

Dengan cara ini, kita dapat memanggil fungsi showGraphic() dan selectGraphic() (karena bersifat publik) tanpa pasokan MouseEvent (karena jika tidak dimasukan, kami menyediakan nul).


Langkah 14: Skrip AI

Mari kita menulis skrip untuk AI sekarang. Ini adalah tampilan file Game.as Anda. Saya sudah menulis komentar di samping setiap baris yang saya ubah.

1
2
package
3
{
4
	import flash.display.MovieClip;
5
	import flash.events.Event;
6
	import flash.events.TimerEvent; // We now use a timer event

7
	import flash.utils.Timer; // And also a timer

8
9
	public class Game extends MovieClip
10
	{
11
		public var numPlayers:uint;
12
		public var turn:uint;
13
		public var left:uint = 10;
14
		private var _grid:Grid = new Grid();
15
		private var _tiles:Array = new Array();
16
		private var _combos:Array = new Array(new Array(0, 1, 2), new Array(3, 4, 5), new Array(6, 7, 8),
17
											  new Array(0, 3, 6), new Array(1, 4, 7), new Array(2, 5, 8),
18
											  new Array(0, 4, 8), new Array(2, 4, 6));
19
		private var _xlist:Array = new Array();
20
		private var _olist:Array = new Array();
21
		private var _flist:Array = new Array();
22
		private var _choose:Boolean = false; // Added variable to check if the computer made a choice

23
		
24
		public function Game(num:uint):void
25
		{
26
			numPlayers = num;
27
			turn = 0;
28
			addVisuals();
29
			addTileListeners();
30
			nextTurn();
31
		}
32
		
33
		private function addVisuals():void
34
		{
35
			var tile1:Tile = new Tile();
36
			var tile2:Tile = new Tile();
37
			var tile3:Tile = new Tile();
38
			var tile4:Tile = new Tile();
39
			var tile5:Tile = new Tile();
40
			var tile6:Tile = new Tile();
41
			var tile7:Tile = new Tile();
42
			var tile8:Tile = new Tile();
43
			var tile9:Tile = new Tile();
44
			tile1.x = tile4.x = tile7.x = tile1.y = tile2.y = tile3.y = 0;
45
			tile2.x = tile5.x = tile8.x = tile4.y = tile5.y = tile6.y = 100;
46
			tile3.x = tile6.x = tile9.x = tile7.y = tile8.y = tile9.y = 200;
47
			addChild(tile1);
48
			addChild(tile2);
49
			addChild(tile3);
50
			addChild(tile4);
51
			addChild(tile5);
52
			addChild(tile6);
53
			addChild(tile7);
54
			addChild(tile8);
55
			addChild(tile9);
56
			addChild(_grid);
57
			_tiles.push(tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9);
58
			_flist.push(tile1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9);
59
		}
60
		
61
		private function addTileListeners():void
62
		{
63
			for (var i:int = 0; i < _tiles.length; i++) {
64
				_tiles[i].addEventListener("TILE_ACTIVE", nextTurn);
65
			}
66
		}
67
		
68
		public function nextTurn(e:Event = null):void
69
		{
70
			if (!checkWin()) {
71
				if (e) {
72
					if (e.currentTarget.isSet == "X") {
73
						_xlist.push(e.currentTarget);
74
					}
75
					if (e.currentTarget.isSet == "O") {
76
						_olist.push(e.currentTarget);
77
					}
78
					_flist.splice(_flist.indexOf(e.currentTarget), 1);
79
				}
80
				left -= 1;
81
				if (left > 0) {
82
					turn += 1;
83
					if (turn % 2 == 0 && numPlayers == 1) handleAI();
84
				} else {
85
					endGame();
86
				}
87
			}
88
		}
89
		
90
		private function handleAI():void
91
		{
92
			_choose = false; // The computer didn't choose a tile yet

93
			for (var i:int = 0; i < _flist.length; i++) {
94
				_flist[i].removeButtonListeners(); // Remove all listeners on the free tiles so the human can't play

95
			}
96
			var timer:Timer = new Timer(500, 1); // Set a timer (make it look like the computer 'thinks' for half a second)

97
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, handleAIChoice); // Add a listener to the timer

98
			timer.start(); // Start the timer

99
		}
100
		
101
		private function handleAIChoice(e:TimerEvent):void
102
		{
103
			var i:int;
104
			for (i = 0; i < _flist.length; i++) {
105
				if (!_choose) { // If the computer didn't make a choice yet

106
					var ocheck:Array = _olist.concat(); // Make a copy of the _olist

107
					var xcheck:Array = _xlist.concat(); // Make a copy of the _xlist

108
					ocheck.push(_flist[i]); // Add a free tile to the ocheck array

109
					xcheck.push(_flist[i]); // Add a free tile to the xcheck array

110
					if (checkAIWin(ocheck)) break; // Check if with the free tile, o wins (this function also places the tile, if so)

111
					if (checkAIWin(xcheck)) break; // Check if with the free tile, x wins

112
				}
113
			}
114
			if (!_choose) {
115
				// If the computer didn't pick a tile yet (no win possible for x or o)

116
				trace("Pick random spot");
117
				var tile:int = Math.floor(Math.random() * _flist.length); // Pick a random index

118
				_flist[tile].showGraphic(); // Set the tile with the random index to show the graphic

119
				_flist[tile].chooseGraphic(); // Set the tile with the random index to choose the graphic

120
			}
121
			for (i = 0; i < _flist.length; i++) {
122
				if (!checkWin()) _flist[i].addButtonListeners(); // Add all listeners on the free tiles again so the human can play

123
			}
124
		}
125
		
126
		private function checkAIWin(check:Array):Boolean
127
		{
128
			for each (var combi in _combos) {
129
				var win = true;
130
				for each (var tile in combi) {
131
					if (check.indexOf(_tiles[tile]) == -1) { // Same function, but now we supply a check array

132
						win = false // If the check array doesnt include the tile of the combination, it's not a winning situation

133
					}
134
				}
135
				if (win) {
136
					// If there is a winning situation, choose the tile

137
					trace("Block or check winning tile");
138
					check[check.length - 1].showGraphic(); // We added the free tile at the end of the check array

139
					check[check.length - 1].chooseGraphic(); // So set the tile with index check.length - 1 to show/choose

140
					_choose = true; // Make sure we set _choose to true (all other checks in handleAIChoice will be skipped)

141
					break;
142
				}
143
			}
144
			return _choose;
145
		}
146
		
147
		private function checkWin():Boolean
148
		{
149
			var won:Boolean = false;
150
			for each (var combi in _combos) {
151
				var xwin = true;
152
				var owin = true;
153
				for each (var tile in combi) {
154
					xwin = xwin && _tiles[tile].isSet == "X";
155
					owin = owin && _tiles[tile].isSet == "O";
156
				}
157
				if (xwin || owin) {
158
					endGame(combi);
159
					won = true;
160
					break;
161
				} else {
162
					won = false;
163
				}
164
			}
165
			return won;
166
		}
167
		
168
		private function endGame(combi:Array = null):void
169
		{
170
			for (var i:int = 0; i < _tiles.length; i++) {
171
				_tiles[i].removeButtonListeners();
172
				if (combi) {
173
					for each (var j in combi) {
174
						if (i == j) _tiles[i].showEnd();
175
					}
176
				}
177
			}
178
		}
179
	}
180
}

Ambil napas dalam-dalam. Perubahan pertama yang harus saya jelaskan adalah pada fungsi handleAI, yang memicu ketika komputer harus memilih ubin. Kami menggunakan variabel _choose di sini dan mengaturnya ke false (komputer belum memilih ubin). Kami kemudian menghapus semua listener dari ubin bebas. Dengan cara ini, pemain manusia tidak dapat mengklik kapan saja untuk bergerak ke komputer. Terakhir namun tidak kalah pentingnya, kami mengatur timer. Saya melakukan ini karena terlihat sedikit lebih keren jika komputer benar-benar "berpikir" tentang kepindahannya. Script untuk membuat pilihan akan dijalankan dalam beberapa milidetik, tetapi dengan cara ini Anda dapat membuatnya terlihat benar-benar membutuhkan sesuatu untuk dipikirkan.

Perubahan besar kedua adalah fungsi handleAIChoice. Saya menambahkan komentar yang harus menjelaskan semuanya di sini. Kami menggunakan trik concat() untuk membuat salinan _olist dan _xlist (var copy = original tidak menyalin array original! Jika Anda memodifikasi copy, Anda juga akan memodifikasi yang original). Bagian yang paling penting adalah panggilan ke fungsi checkWin(), yang kami berikan semua ubin X atau O yang sudah dipilih dengan ubin bebas (kami melakukan ini untuk setiap ubin bebas).

checkAIWin() terlihat seperti fungsi checkWin() yang kami buat sebelumnya, tapi kali ini kami menyediakan array. Kami tidak akan memeriksa semua ubin X atau O, tetapi untuk array ubin yang kami berikan (yang berarti: semua ubin X ditambah satu ubin bebas, atau semua ubin O ditambah satu ubin bebas). Jika array yang disediakan berisi semua ubin yang diperlukan untuk kombinasi yang menang, variabel win akan tetap true. Jika tidak, ini akan disetel ke false.

Dalam kasus win == true, ini artinya ubin bebas akan menciptakan situasi kemenangan. Komputer selalu ingin memilih ubin ini, karena jika itu membuat komputer menang, itu bagus. Dan jika ubin bebas memungkinkan pemain manusia menang, itu harus memblokir ubin bebas sehingga pemain manusia tidak bisa menang.


Milestone 2

Kami sekarang memiliki game yang berfungsi dengan AI. Untuk semua yang kami lakukan sejauh ini, periksa _milestone2.zip. Hasil!


Langkah 15: Menu Grafik

Buat dua Tombol untuk tombol "One Player" dan tombol "Two Players". Ekspor mereka untuk ActionScript dengan nama kelas B1 dan B2 (B untuk "Button"). Ini milik saya:


Langkah 16: Menambahkan fungsionalitas menu

Tentu saja, menu Anda harus ditambahkan ke stage dan bekerja. Ini cukup mudah (ya, Anda bisa santai, bagian yang sulit sudah selesai). Lihatlah file TicTacToe.as Anda dan tulis kode berikut:

1
2
package
3
{
4
	import flash.display.MovieClip;
5
	import flash.events.Event;
6
	import flash.events.MouseEvent;
7
	
8
	public class TicTacToe extends MovieClip
9
	{
10
		private var b1:B1 = new B1();
11
		private var b2:B2 = new B2();
12
		private var game:Game;
13
		
14
		public function TicTacToe():void
15
		{
16
			b1.x = 120;
17
			b1.y = 60;
18
			b2.x = 180;
19
			b2.y = 240;
20
			addChild(b1);
21
			addChild(b2);
22
			b1.addEventListener(MouseEvent.CLICK, startGame);
23
			b2.addEventListener(MouseEvent.CLICK, startGame);
24
			addMenu();
25
		}
26
		
27
		private function startGame(e:MouseEvent):void
28
		{
29
			b1.visible = false;
30
			b2.visible = false;
31
			game = (e.currentTarget == b1) ? new Game(1) : new Game(2);
32
			game.addEventListener("restart", addMenu);
33
			addChild(game);
34
		}
35
		
36
		private function addMenu(e:Event = null):void
37
		{
38
			if (game != null) {
39
				removeChild(game);
40
				game = null;
41
			}
42
			b1.visible = true;
43
			b2.visible = true;
44
		}
45
	}
46
}

Karena semua skrip di atas adalah baru, saya tidak menulis baris komentar apa pun. Pertama, kami membuat tiga variabel. Kami membuat tombol dan variabel game. Dalam konstruktor (TicTacToe()) kami mengatur posisi x dan y dari tombol kami. Pastikan Anda memposisikan tombol Anda sendiri pada koordinat yang benar. Kemudian kami menambahkan tombol ke daftar tampilan dan menambahkan listener MouseEvent. Terakhir, kami memanggil fungsi addMenu().

Di startGame(e: MouseEvent) kami mengatur kedua tombol menjadi visible = false. Dengan cara ini, kita tidak akan melihatnya lagi. Jika Anda ingin melewati bagian ini, Anda harus memastikan Grid MovieClip memiliki latar belakang yang solid. Anda tidak akan dapat melihat tombol itu, karena Anda menempatkan game di atasnya. Saya lebih suka memastikan (Anda mungkin ingin memposisikan game Anda di tempat lain) dan mengatur visibility ke false. Kami kemudian memeriksa tombol mana yang telah ditekan. Jika b1, kami ingin memanggil new Game(1) (1 pemain, vs komputer). Jika tidak, kami membutuhkan new Game(2) (2 pemain manusia). Lalu kami menambahkan event listener RESTART ke game, sehingga kami dapat memeriksa kapan game selesai. Terakhir tapi bukan yang akhir: tambahkan game ke daftar tampilan sehingga kita benar-benar bisa bermain.

Fungsi addMenu(e: Event = null) tidak banyak membantu. Ini dipanggil pertama kali kami membuka Flash Movie kami, dan setiap kali game berakhir. Pertama-tama memeriksa apakah ada game, dan jika demikian itu menghapusnya dari daftar tampilan dan mengatur game ke null. Selanjutnya mengatur visibilitas tombol menjadi true sehingga kita dapat mengkliknya lagi.


Langkah 17: Ini Tidak bekerja!

Saat Anda menguji game, itu berfungsi dengan baik. Tetapi ketika Anda menyelesaikan game pertama Anda, itu tidak menampilkan menu. Ini karena kami belum menambahkan dispatcher event RESTART ke file Game.as. Ayo lakukan itu. Dalam fungsi endGame(combi: Array = null), tambahkan baris berikut:

1
2
var timer:Timer = new Timer(1500, 1);
3
timer.addEventListener(TimerEvent.TIMER_COMPLETE, restart);
4
timer.start();

Ini memulai penghitung waktu 1,5 detik (sehingga Anda akan memiliki waktu untuk melihat siapa yang benar-benar menang). Selanjutnya, buat fungsi yang dipanggil oleh timer:

1
2
private function restart(e:TimerEvent):void
3
{
4
    dispatchEvent(new Event("restart"));
5
}

Semua fungsi ini adalah mengirimkan event RESTART, yang kami tunggu di kelas TicTacToe. Game selesai!


Milestone 3

Kami sekarang memiliki game yang berfungsi dengan AI dan menu. Untuk semua yang kami lakukan sejauh ini, periksa _milestone3.zip. Hasil!


Langkah 18: Bisakah Anda Menemukan Bugnya?

Saya harap Anda masih bersama kami. Kami memang memiliki game yang berfungsi sekarang, tetapi jika Anda menguji game tersebut secara berlebihan, Anda mungkin telah menemukan bug. Komputer AI memeriksa setiap ubin bebas jika itu bisa menang dengan ubin itu. Jika tidak, ia memeriksa apakah bisa hilang oleh ubin itu. Jadi pikirkan: komputer dapat memilih ubin, dan bisa menang dengan ubin 4. Ini juga bisa kalah dengan ubin 2. Jadi ketika memeriksa ubin 2, itu akan memilih ubin itu karena akan kehilangan putaran berikutnya jika tidak , jangan pernah mencapai centang pada ubin 4 yang dengannya memenangkan putaran ini. Solusi: periksa dulu semua ubin bebas untuk situasi menang. Kemudian periksa situasi yang hilang. Ini akan menjadi fungsi handleAIChoice(e: TimerEvent) Anda yang baru (bagi yang pernyataan for pertama menjadi dua):

1
2
private function handleAIChoice(e:TimerEvent):void
3
{
4
    var i:int;
5
    for (i = 0; i < _flist.length; i++) {
6
        if (!_choose) {
7
            var ocheck:Array = _olist.concat();
8
            ocheck.push(_flist[i]);
9
            if (checkAIWin(ocheck)) break;
10
        }
11
    }
12
    for (i = 0; i < _flist.length; i++) {
13
        if (!_choose) {
14
            var xcheck:Array = _xlist.concat();
15
            xcheck.push(_flist[i]);
16
            if (checkAIWin(xcheck)) break;
17
        }
18
    }
19
    if (!_choose) {
20
        var tile:int = Math.floor(Math.random() * _flist.length);
21
        _flist[tile].showGraphic();
22
        _flist[tile].chooseGraphic();
23
    }
24
    for (i = 0; i < _flist.length; i++) {
25
        if (!checkWin()) _flist[i].addButtonListeners();
26
    }
27
}

Langkah 19: Saran Grafik

Meskipun ini tutorial, saya suka melihat orang-orang mempelajari sesuatu dan membangunnya. Untuk membantu Anda dalam perjalanan, saya akan menulis beberapa saran tentang hal-hal yang dapat Anda ubah dan/atau tambahkan.

Secara visual, Anda memiliki sedikit keterbatasan. Perhatikan bahwa Anda dapat mengedit MovieClips dari Grid, Ubin, dan Tombol. Jangan membatasi diri Anda pada satu frame: aset ini adalah MovieClips karena suatu alasan. Misalnya, Anda dapat membuat animasi burung terbang dan menggunakannya sebagai Ubin. Anda dapat membuat warna Grid berubah, biarkan Tombol Anda terpental, namai itu. Anda dapat membuat Loading MovieClip yang bagus dan menambahkannya ke game. Atur visibilitasnya ke false, dan menjadi true saat komputer "berpikir". Daripada mengakhiri permainan dengan jeda, perlihatkan gambar siapa yang menang dengan kembang api dan orang-orang bersorak. Jadilah kreatif.


Langkah 20: Saran Skrip

Meskipun Anda sudah memiliki game Tic-Tac-Toe yang berfungsi, Anda selalu dapat menambahkan lebih banyak fungsi dan mengubah fungsi yang sudah dimilikinya. Misalnya, alih-alih aturan yang saya berikan kepada Anda, Anda bisa membuat aturan baru untuk AI. Selalu pilih sudut pertama. Mulailah dengan ubin tengah jika tersedia. Atau biarkan komputer berpikir selangkah lebih maju - Anda setengah jalan di sana!

Saran lain yang bisa saya buat, adalah secara acak memutuskan siapa yang akan mulai ketika Anda bermain versus komputer. Ini mungkin terlihat cukup mudah, tetapi pastikan Anda memikirkannya. Itu dimulai dengan mengubah baris berikut di Game.as:


if (turn % 2 == 0 && numPlayers == 1) handleAI(); // Change turn % 2 == 0 to turn % 2 == randomBegin

Di konstruktor Game(num: uint), atur randomBegin menjadi 0 atau 1. Ini semua yang perlu Anda lakukan, tetapi lihat fungsi handleAIChoice kami. Dalam fungsi ini pertama-tama kita memeriksa situasi menang untuk O, kemudian untuk X. Ini benar ketika komputer bermain dengan ubin O, tetapi ketika Anda membuat bagian ini acak ... Jadi, mungkin mengubah dua pernyataan for menjadi fungsi dan memanggil mereka dalam urutan yang benar, tergantung pada randomBegin.


Kesimpulan

Saya sangat berharap Anda menyukai tutorial ini. Ini adalah pertama saya, saya mencoba untuk tetap sederhana tetapi menyenangkan dan saya harap saya berhasil. Jika Anda memiliki pertanyaan tentang tutorial ini, silakan tinggalkan komentar di sini. Saya juga ingin melihat apa yang Anda buat dengan bantuan tutorial ini, jadi jangan ragu untuk mengirim URL ke proyek Anda.

Terima kasih telah membaca dan menikmati Flash dan ActionScript!

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.