Trong trò chơi lật hình, sau khi người chơi lật hai hình (bấm vào một hình rồi bấm thêm một hình nữa), nếu hai hình không giống nhau, chúng bị “úp” trở lại. Nếu hai hình giống nhau, chúng giữ nguyên trạng thái.
Ta xem đó là hai hình đã “hoàn thành nhiệm vụ”. Người chơi tiếp tục lật các hình khác và cố gắng ghi nhớ vị trí của các hình để có thể lật liên tiếp hai hình giống nhau. Khi không còn hình nào bị “úp”, trò chơi kết thúc.
Hiện tại, trong chương trình của ta, hàm xử lý tình huống bấm chuột không kiểm tra gì cả, chỉ giữ nguyên trạng thái của hình được lật. Để có thể thực hiện việc kiểm tra như vừa nêu, mỗi hình cần có một biến cho biết nó là loại hình gì, có thể đặt tên là type. Hình cũng cần chứa biến gọi là solved chẳng hạn, có thể nhận trị true hoặc false để cho biết nó đã “hoàn thành nhiệm vụ” hay chưa. Ngoài ra, ta cũng cần một biến để ghi nhận lần bấm chuột đang xét là lần thứ mấy, có thể đặt tên là count. Phải có đủ thông tin như vậy, chương trình mới có thể “suy xét” và hành động thích hợp mỗi khi người dùng bấm chuột.
Biến type cần có trị ra sao? Nhìn lại phần đầu chương trình, bạn thấy rằng ta đã dùng biểu thức n % 8 để thu được các trị số từ 0 đến 7 (các nhân vật được đánh số từ 0 đến 7). Hai thể hiện giống nhau là hai thể hiện ứng với cùng số thứ tự, nghĩa là cùng được tạo ra từ một nhân vật. Ta gọi đó là hai thể hiện cùng loại. Bạn hiểu ngay: biến type cần có trị từ 0 đến 7. Ta cần lấy trị của biểu thức n % 8 để gán cho biến type của từng hình được xem xét trong vòng lặp ở phần đầu chương trình.
Bạn viết thêm vào phần đầu chương trình như sau:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
tiles = new Array();</p>backs = new Array();n = 0;type = 0;count = 0;for(i = 0; i < 4; i++) {tiles[i] = new Array();backs[i] = new Array();for(j = 0; j < 4; j++) {type = n%8;attachMovie("Tile" + type, "tile" + i + j, n);attachMovie("Back", "back" + i + j, n + 100);n++;tiles[i][j] = this["tile" + i + j];tiles[i][j]._x = 20 + 120 * j;tiles[i][j]._y = 20 + 120 * i;tiles[i][j].type = type;tiles[i][j].solved = false;backs[i][j] = this["back" + i + j];backs[i][j]._x = 20 + 120 * j;backs[i][j]._y = 20 + 120 * i;}}... |
Ta lưu trị số của biểu thức n % 8 vào biến type dùng chung và gán trị của biến type dùng chung ấy vào biến type bên trong mỗi hình bằng câu lệnh tiles[i][j].type = type. Câu lệnh tiles[i][j].solved = false; nhằm tạo ra biến solved bên trong mỗi hình và gán ngay cho nó trị ban đầu là false (chưa “hoàn thành nhiệm vụ”).
Nếu bạn từng có kinh nghiệm về ngôn ngữ lập trình khác, có thể bạn thấy “phong cách” của ngôn ngữ lập trình ActionScript trong Flash hơi lạ lùng: khi cần biến mới, ta chỉ đơn giản dùng biến đó, không cần khai báo trước. Khi dùng một biến chưa từng có, bạn đã tạo ra biến mới. Tuy nhiên, thói quen viết ra các biến cần dùng ở đầu chương trình và gán trị ban đầu cho nó (xem như một cách khai báo các biến sẽ dùng trong chương trình, giống như trong ngôn ngữ lập trình Pascal) là thói quen tốt, giúp chương trình rõ ràng, dễ hiểu hơn. Không hiếm trường hợp người lập trình đọc lại những đoạn mã từng do chính mình viết và… không hiểu lúc trước mình viết cái gì!
Nhờ lưu giữ thông tin quan trọng khi tạo ra các hình cho trò chơi, bạn có cơ sở để thực hiện những điều cần làm mỗi khi người dùng bấm chuột. Trong hàm xử lý tình huống bấm chuột, bạn viết thêm như sau:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
...this.onMouseUp = function() {for(i = 0; i < 4; i++) {for(j = 0; j < 4; j++) {if(tiles[i][j].hitTest(_root._xmouse, _root._ymouse, true)) {//backs[i][j]._visible = false;if(!tiles[i][j].solved) {}return;}}}} |
Bạn cần xóa đi câu lệnh backs[i][j]._visible = false; vì bây giờ ta không chỉ đơn giản phơi ra hình được bấm, mà phải cân nhắc cẩn thận. Khi xem xét hình được bấm, trước tiên bạn cần biết nó đã “hoàn thành nhiệm vụ” hay chưa bằng cách dùng câu lệnh if(!tiles[i][j].solved). Nếu biến solved bên trong hình đang xét có trị false (chưa “hoàn thành nhiệm vụ”), ta mới cần tiếp tục xem xét. Nếu biến solved bên trong hình đang xét có trị là true (hình đang xét đã “hoàn thành nhiệm vụ”) thì không cần làm gì hết. Câu lệnh return; thể hiện điều đó.
Khi hình được bấm chưa “hoàn thành nhiệm vụ”, ta cần nhận biết lần bấm chuột đang xét là lần thứ mấy, từ đó mới quyết định cần làm gì cho thích hợp. Trong cặp dấu gộp { } theo sau câu lệnh if(!tiles[i][j].solved), bạn diễn đạt suy nghĩ của mình như sau:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
...this.onMouseUp = function() {for(i = 0; i < 4; i++) {for(j = 0; j < 4; j++) {if(tiles[i][j].hitTest(_root._xmouse, _root._ymouse, true)) {//backs[i][j]._visible = false;if(!tiles[i][j].solved) {if(count == 0) {backs[i][j]._visible = false;count = 1;}else if(count == 1) {backs[i][j]._visible = false;}}return;}}}} |
Nếu lần bấm chuột đang xét là lần thứ nhất (trị của biến count là 0), ta gán trị 1 cho biến count. Nhờ vậy, khi xem xét một lần bấm chuột, nếu thấy biến count có trị là 1, ta biết rằng đó là lần bấm chuột thứ hai. Trong cả hai lần bấm chuột, điều đầu tiên cần làm là phơi ra hình được bấm bằng câu lệnh backs[i][j]._visible = false; (cho hình “mặt sau” biến đi).
Trong lần bấm chuột thứ hai, ta cần so sánh hình đang xét với hình được bấm của lần trước. Như vậy, cần phải có thêm hai biến để ghi nhớ chỉ số hàng và cột của lần bấm chuột thứ nhất. Bạn tiếp tục viết thêm:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
...this.onMouseUp = function() {for(i = 0; i < 4; i++) {for(j = 0; j < 4; j++) {if(tiles[i][j].hitTest(_root._xmouse, _root._ymouse, true)) {//backs[i][j]._visible = false;if(!tiles[i][j].solved) {if(count == 0) {backs[i][j]._visible = false;count = 1;r = i;c = j;}else if(count == 1) {backs[i][j]._visible = false;if(r == i && c == j)return;if(tiles[r][c].type == tiles[i][j].type) {tiles[i][j].solved = true;tiles[r][c].solved = true;count = 0;}else {backs[i][j]._visible = true;backs[r][c]._visible = true;count = 0;}}}return;}}}} |
Trong lần bấm chuột thứ nhất, ta dùng hai biến r và c để ghi nhớ chỉ số hàng và cột của hình được bấm. Trong lần bấm chuột thứ hai, nếu hình được bấm chính là hình trước thì không cần làm gì hết. Điều này thể hiện bằng câu lệnh điều kiện:
|
1
2
3
|
if(r == i && c == j)return; |
Nếu hình được bấm đang xét khác với hình được bấm lần trước, ta cần so sánh biến type bên trong hai hình, xem có giống nhau không. Nếu giống, ta gán trị true cho biến solved trong mỗi hình để “đánh dấu”, cho biết chúng đã “hoàn thành nhiệm vụ”. Nếu không giống, cả hai hình đang xét đều được “úp” trở lại. Dù giống hay không giống, ta cho biến count trở về trị 0, kết thúc một đợt kiểm tra.
Bạn chạy thử chương trình xem sao nhé.
Theo echip

Các ý kiến mới nhất