Tôi đã viết một trò chơi RTS (bản demo cho một công cụ trò chơi, thực tế), trong đó tương tác cơ bản của người dùng với trò chơi là chọn một nhóm binh sĩ và sau đó nhấp chuột phải vào bản đồ để di chuyển chúng đến vị trí đã chỉ định. Đây là JavaScript và bạn có thể chơi với nó ở đây ( mã ).
Bỏ qua vấn đề làm thế nào các binh sĩ di chuyển từ vị trí hiện tại của họ đến đích của họ, câu hỏi của tôi là về việc xác định đích đến thực sự của họ là gì. Đây là những gì tôi đã thử cho đến nay:
- Nỗ lực 1: Yêu cầu tất cả các binh sĩ được chọn di chuyển đến tọa độ mà chuột đã nhấp. Điều này có hành vi kỳ quặc rằng tất cả các binh sĩ sau đó sẽ đi xung quanh mục tiêu một cách không tự nhiên.
- Nỗ lực 2: Tìm tọa độ trung bình của tất cả các binh sĩ đã chọn, sau đó tìm phần bù từ điểm trung tâm đó cho mỗi người lính và cuối cùng dịch phần bù đó xung quanh tọa độ chuột. Điều này hoạt động tốt, ngoại trừ nếu các binh sĩ được chọn của bạn cách xa nhau, họ sẽ không đến gần mục tiêu.
- Cố gắng 3: Xây dựng lưới xung quanh tọa độ chuột và đặt từng người lính được chọn vào một ô của lưới. Nếu mỗi người lính làm cho nó vào ô được chỉ định của họ, điều này hoạt động rất tốt. Tuy nhiên, các binh sĩ được chỉ định vào các ô lưới theo thứ tự các binh sĩ được sinh ra, vì vậy đôi khi họ va chạm (tức là tất cả các binh sĩ ở phía bên phải sẽ cố gắng đi về phía bên trái) trông có vẻ không tự nhiên.
- Cố gắng 4: Sử dụng lưới như trước, nhưng trước tiên hãy sắp xếp các binh sĩ theo vị trí sao cho họ xếp hàng hợp lý, tức là nếu bạn nhấp vào bên dưới nhóm thì những người lính ở dưới cùng của nhóm sẽ kết thúc ở dưới cùng của lưới khi họ đạt đến đích của họ. Điều này hoạt động khá tốt nhưng đôi khi có trục trặc và tôi không chắc tại sao.
Đây là chức năng xác định tọa độ đích:
function moveSelectedSoldiersToMouse() {
var w = 0, h = 0, selected = [];
// Get information about the selected soldiers.
myTeam.soldiers.forEach(function(soldier) {
if (soldier.selected) {
selected.push(soldier);
w += soldier.width;
h += soldier.height;
}
});
var numSelected = selected.length, k = -1;
if (!numSelected) return;
// Build a grid of evenly spaced soldiers.
var sqrt = Math.sqrt(numSelected),
rows = Math.ceil(sqrt),
cols = Math.ceil(sqrt),
x = Mouse.Coords.worldX(),
y = Mouse.Coords.worldY(),
iw = Math.ceil(w / numSelected), // grid cell width
ih = Math.ceil(h / numSelected), // grid cell height
wg = iw*1.2, // width of gap between cells
hg = ih*1.2; // height of gap between cells
if ((rows-1)*cols >= numSelected) rows--;
w = iw * cols + wg * (cols-1); // total width of group
h = ih * rows + hg * (rows-1); // total height of group
// Sort by location to avoid soldiers getting in each others' way.
selected.sort(function(a, b) {
// Round to 10's digit; specific locations can be off by a pixel or so
var ax = a.x.round(-1), ay = a.y.round(-1), bx = b.x.round(-1), by = b.y.round(-1);
return ay - by || ax - bx;
});
// Place the grid over the mouse and send soldiers there.
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var s = selected[++k];
if (s) {
var mx = x + j * (iw+wg) - w * 0.5 + s.width * 0.5,
my = y + i * (ih+hg) - h * 0.5 + s.height * 0.5;
// Finally, move to the end destination coordinates
s.moveTo(mx, my);
}
}
}
}
Bạn có thể dán chức năng này vào bảng điều khiển JavaScript của trình duyệt khi xem bản demo và tìm hiểu kỹ về nó để thay đổi hành vi của những người lính.
Câu hỏi của tôi là: có cách nào tốt hơn để xác định vị trí mục tiêu cho mỗi người lính di chuyển đến không?