Xem Demo.

Tạo Control Panel
Bảng điều khiển là một thành phần không thể thiếu trong hầu hết các thể loại game từ nhập vai, chiến thuật, mô phỏng đến các game giải đố,… Trong game này, nhiệm vụ của bảng điều khiển là cho phép người xem thông tin và và quản lý các thành phần mà họ tạo ra. Một phần không thể thiếu là liệt kê các loại tower mà người chơi được phép sử dụng.

Trước tiên, ta cần có những đối tượng làm button với một vài thuộc tính cơ bản. Các button sẽ giúp người chơi chọn lựa loại tower, thực hiện các tác vụ như nâng cấp, bán, điều khiển thời gian enemy xuất hiện,…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| function Button() { this .isSelected = false ; this .x = 0; this .y = 0; this .width = 1; this .height = 1; this .onclick; this .text; this .color; } Button.prototype.contain = function (x,y){ var right = this .x + this .width; var bottom = this .y + this .height; return x > this .x && x < right && y > this .y && y < bottom; } |
Tôi sử dụng hai mảng để lưu hai loại button cho từng mục đích: towerButtons và actionButtons. Chỉ có loại actionButton mới được gắn sự kiện onclick. Bạn có thể dễ dàng phân biệt hai loại button dựa vào màu sắc của chúng: actionButton chỉ có duy nhất một màu xám. Dựa vào tham số onclick , ta sẽ xác định được một button sẽ nằm trong mảng nào khi được tạo ra với phương thức addItem():
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| ControlPanel.prototype.addItem = function (x, y, width, height, color, text, onclick){ var button = new Button; button.x = x + this .left; button.y = y + this .top; button.width = width; button.height = height; button.color = color; button.text = text; button.onclick = onclick; if (onclick) this .actionButtons.push(button); else this .towerButtons.push(button); } |
Trong sự kiện onmousedown, ta sẽ kiểm tra tại vị trí chuột hiện tại có thuộc button nào không và thực hiện một hành động tương ứng với loại button đó. Với actionButton, ta chỉ cần kích hoạt sự kiện onclick của nó. Với towerButton, ta sẽ tạo ra một tower mới cùng với các thuộc tính của nó và gán vào map.selectedTower để sẵn sàng được đặt lên bản đồ. Mỗi towerButton sẽ cho ra một tower mới với các thuộc tính khác nhau về sức mạnh và giá tiền:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // select by index ControlPanel.prototype.select = function (i){ this .selectedItem = this .towerButtons[i]; this .towerButtons[i].isSelected = true ; var tower = new Tower(); tower.price = 200 * (i + 1); tower.color = this .towerButtons[i].color; tower.damage = 100 * (i + 1); tower.shootingRange = 100 + (i + 1) * 20; tower.fireDelay = 300 * (i + 1); tower.rotationSpeed = tower.rotationSpeed * ( this .towerButtons.length - i); tower.upgradePrice = 10 * (i + 1); this .map.selectedTower = tower; } |
Ngoài ra, trong phương thức draw() của lớp này, ta sẽ viết ra các thông tin của tower để người chơi lựa chọn như: damage, range, price,…
Quản lý các tower trên bản đồ
Với các tower đã được đặt trên bản đồ, người chơi có thể click chuột chọn nó để xem thông tin và thực hiện hai thao tác chính: nâng cấp và bán.
Để chọn được tower trên bản đồ dựa vào vị trí, ta sẽ lặp tuyến tính và kiểm tra như thông thường. Khi đã xác định được một tower chứa vị trí chuột, ta sẽ gán giá trị cho map.selectedTower để nó được vẽ một vòng tròn focus.
Để chọn được tower trên bản đồ dựa vào vị trí, ta sẽ lặp tuyến tính và kiểm tra như thông thường. Khi đã xác định được một tower chứa vị trí chuột, ta sẽ gán giá trị cho map.selectedTower để nó được vẽ một vòng tròn focus.
1
2
3
4
5
6
7
8
9
10
11
| Map.prototype.containTower = function (x, y){ for ( var i in this .towers) { if ( this .towers[i].contain(x, y)) { this .selectedTower = this .towers[i]; return true ; } } return false ; } |
Việc nâng cấp tower rất đơn giản. Tuy nhiên nó cần đi kèm với số tiền cần thiết mà người chơi cần bỏ ra để nâng cấp. Cần phải tính toán giữa lượng tiền dùng cho việc nâng cấp và mua tower mới được cân bằng, hợp lý và không quá dễ dàng khiến người chơi cảm thấy tẻ nhạt. Trong ví dụ này, tôi tạm thời sử dụng một công thức đơn giản để áp dụng cho việc nâng cấp mọi loại tower:
1
2
3
4
5
6
7
| this .upgrade = function (){ if ( this .level == 20) return false ; this .upgradePrice = Math.floor( this .upgradePrice * 1.1); this .level++; this .damage += Math.floor( this .damage/10); }; |
Điều khiển quân địch ra lần lượt
Mỗi level sẽ có một số lượt quân địch ra nhất định. Mỗi lượt này thường cách nhau một khoảng thời gian ngắn để người chơi có thể thay đổi chiến thuật, bố trí, nâng cấp,… các tower nhằm sẵn sàng đối đầu với lượng quân địch ngày càng mạnh.
Việc quản lý các lượt ra của quân địch cần có sự kết hợp giữa lớp Map và ControlPanel, vì vậy tôi tạo ra các event trong Map để thực hiện quá trình này:
Việc quản lý các lượt ra của quân địch cần có sự kết hợp giữa lớp Map và ControlPanel, vì vậy tôi tạo ra các event trong Map để thực hiện quá trình này:
this.onReset;
this.onFinishedWave;
this.onFinishedLevel;
this.onFinishedGame;
this.onFinishedWave;
this.onFinishedLevel;
this.onFinishedGame;

Khi sử dụng các event, bạn lưu ý chỉ định nghĩa nó một lần duy nhất. Bởi vì event thực chất là một function và khi định nghĩa lại nó sẽ đè mất nội dung cũ. Nó không có khả năng đăng kí nhiều công việc vào cùng một event, trừ phi bạn thực hiện một vài thay đổi để cải tiến nó.
Tạo in-game popup hiển thị thông điệp
Trong game này tôi sử dụng một popup tự động đóng sau một khoảng thời gian để hiển thị các thông điệp. Khi popup được đóng, một phương thức callback sẽ được thực thi tùy theo yêu cầu của bạn. Ví dụ khi một level kết thúc, ta sẽ hiển thị một thông điệp “Level Completed!” trong hai giây. Sau đó popup này đóng và game tự động chuyển qua level mới.
Việc hiện thực khá đơn giản, chỉ cần viết trong phương thức update(). Dựa vào giá trị của biến message, ta sẽ quyết định thông điệp có được vẽ ra màn hình hay không.
1
2
3
4
5
6
7
8
| // check to close the message popup var tick = ( new Date()).getTime(); if (tick - this .messageStartTime >= this .messageDelay) { this .message = null ; if ( this .onMessageClosed) this .onMessageClosed(); } |
Money Make the World Go Round
Tiền bạc trong game là một thành phần không thể thiếu và là yếu tố quan trọng giúp thể hiện năng lực của người chơi. Cụ thể, người chơi cần phải cân nhắc cẩn thận trong việc mua, bán, nâng cấp gì, làm sao để có được nhiều tiền và cân nhắc giữa việc ưu tiên kiếm tiền hay sức mạnh.
Trong game này, ban đầu người chơi sẽ được một số lượng tiền nhất định tùy theo level. Sau đó họ sẽ kiếm được thêm tiền khi tiêu diệt được một kẻ địch. Ngoài ra, một số game cho phép tăng các chỉ số hoặc xây các loại tower có khả năng tăng thêm lượng tiền kiếm được. Rất đa dạng!
Trong game này, ban đầu người chơi sẽ được một số lượng tiền nhất định tùy theo level. Sau đó họ sẽ kiếm được thêm tiền khi tiêu diệt được một kẻ địch. Ngoài ra, một số game cho phép tăng các chỉ số hoặc xây các loại tower có khả năng tăng thêm lượng tiền kiếm được. Rất đa dạng!

- isDisposed && isDead: Người chơi được nhận tiền.
- isDisposed && !isDead: Người chơi mất một lifepoint do để quân địch về đích.
- isDisposed && !isDead: Người chơi mất một lifepoint do để quân địch về đích.
Kết
Phiên bản này có thể quá dễ hoặc quá khó với người chơi, do tôi cũng chưa tính toán để đưa ra các thông số hợp lý. Loại game này có lẽ phần giao diện không quan trọng lắm nên tôi để nó khá…sơ xác (một phần cũng vì tôi muốn “make things as simple as possible”). Bởi vì game này có nhiều hướng phát triển khác nhau, tốt nhất là ngừng lại và chờ đợi những sự phân tích, góp ý từ các “chuyên gia” trước khi phát triển thêm.
Comments[ 0 ]
Đăng nhận xét