Xác định vị trí kết thúc cho chuyển động AI trong các nhóm trong RTS 2D


8

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 ( ).

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?


Một cái gì đó gọi là "đổ xô" có thể rất hữu ích cho bạn và có thể cung cấp cho bạn loại chức năng bạn đang tìm kiếm. Hãy thử: processing.org/examples/flocking.html hoặc chỉ google "đổ xô" hoặc "Boids". Điều đó có thể đưa bạn đi đúng hướng.
Dean Knight

2
Liên quan: gamedev.stackexchange.com/questions/44361 Tôi muốn nói rằng "những trục trặc" mà bạn gặp phải là từ các đơn vị đang cố gắng di chuyển đến một vị trí đã được yêu cầu. Đảm bảo rằng vị trí họ đang di chuyển không phải là mục tiêu cho đơn vị khác và bạn sẽ có kết quả khá tốt.
MichaelHouse

@DeanKnight, tôi biết cách các hành vi đổ xô hoạt động, nhưng điều đó chi phối cách các bot đi từ điểm A đến điểm B, chứ không phải điểm B là gì.
IceCreamYou

@ Byte56: cảm ơn vì liên kết. Tôi thực sự không đặt các đơn vị vào các khe lưới - trong quá trình thực hiện, không có cách nào để nhiều đơn vị được hướng đến cùng một vị trí. Có vẻ như vấn đề là nhiều hơn mà việc phân loại đôi khi bị lẫn lộn.
IceCreamYou 26/07/13

1
Một ý tưởng khác: Swarm Pathfinding . Trong trường hợp này, bạn sẽ không cung cấp cho mỗi đơn vị một điểm cuối khác nhau; bạn chỉ cần dừng lại khi không còn đường dẫn đến điểm cuối (vì tất cả các đơn vị khác đang cản đường) hoặc không dừng lại và để phát hiện va chạm thực hiện công việc của mình.
BlueRaja - Daniel Pflughoeft

Câu trả lời:


2

Dưới đây là những gợi ý của tôi về ý tưởng của bạn:

Nỗ lực 1: Để khắc phục tình trạng này, bạn có thể thực hiện ý tưởng "đủ gần" mà Spencer đưa ra. Tôi sẽ làm một cái gì đó như vẽ một bong bóng xung quanh điểm cuối, nó phát triển dựa trên tỷ lệ số lượng và kích thước của các đơn vị đã có trong đó. Giả sử bong bóng bắt đầu kích thước của một đơn vị, sau đó khi lần đầu tiên đến đó, bán kính tăng gấp đôi cho hai đơn vị tiếp theo, v.v.

Cố gắng 2: Cách khắc phục cho lỗi này, sẽ lấy khoảng cách trung bình của nhóm với nhau, sau đó cắt khoảng cách của các ngoại lệ đến đó, do đó, nhóm kết thúc nhiều hơn so với ban đầu (số liệu có thể ngắn hơn / dài hơn mức trung bình, bất cứ điều gì làm cho nó trông ổn, hoặc có thể đặt kích thước hình thức tối đa dựa trên số lượng / kích thước quân đội một lần nữa) Điều duy nhất bạn phải lo lắng là khi bạn thay đổi đường dẫn của ngoại lệ, bạn ' d phải kiểm tra và chắc chắn rằng nó không can thiệp vào các đường dẫn khác

Nỗ lực 3: Bạn đã cải thiện điều này trong lần thử 4

Nỗ lực 4: Âm thanh như thế này sẽ hoạt động tốt nếu bạn tìm thấy bất kỳ trục trặc nào đang ném nó đi. Tuy nhiên, tôi khuyên bạn nên chơi với các spahes chứ không chỉ là một hình lưới, để làm cho phong trào trông tự nhiên hơn một chút, trừ khi bạn đi theo phong cách quân đội / chủ nghĩa hiện thực, trong trường hợp đó có thể gọn gàng để chúng "hình thành "Trước khi di chuyển, nhưng điều đó có thể gây khó chịu cho người chơi sau một thời gian.

Nỗ lực 4 dường như là cách gần nhất để loại bỏ hành vi phay trong vấn đề của bạn, nhưng về mặt giữ cho chuyển động không bị điều chỉnh ngoài những điều cần thiết, điều tôi thích có lẽ sẽ là cố gắng 2.

Nhưng như một giải pháp hoàn toàn khác, bạn có thể có hai loại đối tượng khi nói đến tìm đường; mỗi đơn vị, cũng như một đối tượng "đội hình" vô hình.

Squad- Bạn xây dựng đối tượng đội hình ở trung tâm của nhóm, giống như các giải pháp khác và sử dụng tính năng dẫn đường của bạn để hướng nó tới mục tiêu.

Các đơn vị- Các đơn vị bỏ qua hoàn toàn mục tiêu và thay vào đó sử dụng tính năng tìm đường để giữ trong một khoảng cách nhất định (hoặc đội hình hoặc bất kỳ số liệu nào khác kết thúc làm cho chuyển động trông tốt nhất) từ đối tượng đội hình.

Điều này phân tách các khía cạnh khác nhau của tìm đường và cho phép bạn điều chỉnh một trong hai bên cách ly để kiểm soát nhiều hơn về giao diện của nó.


Câu trả lời chính xác. Cảm ơn những ý tưởng mới. Cách tiếp cận Squad + Unit rất thú vị, có lẽ yêu cầu các đơn vị có thể di chuyển nhanh hơn trong chế độ "bắt kịp"
IceCreamYou

Vâng, một giải pháp được đặt là tốc độ di chuyển của đối tượng "đội hình" xuống một chút dưới mức tối đa mà các đơn vị có thể di chuyển, để cho phép chúng di chuyển xung quanh nếu cần mà không bị tụt lại phía sau.
David M

2

Nỗ lực 3 có thể hoạt động, nhưng nó cần một chút tinh chỉnh.

Hãy suy nghĩ về khái niệm của một đội hình (lưới của bạn là một sự khởi đầu). Một đội hình nên có một vị trí (tức là tọa độ nhấp chuột, hoặc lính mục tiêu / tòa nhà) và một vòng quay (điều này có thể được cố định, ngẫu nhiên hoặc xác định). Đội hình phải có cùng số lượng vị trí với số lượng binh sĩ được chọn.

Một ví dụ đơn giản hình thành có thể là một vòng tròn xung quanh mục tiêu. Vị trí không gian bằng nhau xung quanh và tăng bán kính vòng tròn để phù hợp với tất cả các binh sĩ mà không va chạm.

Vấn đề tiếp theo là quyết định người lính nào đi đến vị trí nào trong đội hình. Một giải pháp đơn giản có thể là làm cho mỗi người lính di chuyển đến vị trí gần anh ta nhất. Nếu người đó đã được 'chọn' bởi một người lính khác, hãy chọn vị trí gần nhất tiếp theo, v.v.

Sự hình thành có thể trở nên khá thú vị. Dưới đây là hình ảnh của 'đội hình sừng bò' được Shaka the Zulu sử dụng rất thành công . (Hình ảnh xuất phát từ Mod hình thành TotalWar )

hình thành sừng bò


"Vấn đề tiếp theo là quyết định người lính nào đi đến vị trí nào trong đội hình." Trên thực tế, đó là toàn bộ vấn đề của câu hỏi này. :) Được khuyến khích cho đề xuất hình thành vòng tròn thay vì lưới, nhưng điều đó không hiệu quả đối với nhiều quân nhân và việc di chuyển binh lính đến vị trí gần họ nhất gây ra nhiều xung đột hơn giải pháp của tôi ở trên là sắp xếp các đơn vị theo vị trí.
IceCreamYou

0

Khi người dùng nhấp chuột, vẽ một vectơ từ mỗi người lính đến vị trí được nhấp. Lấy góc vectơ trung bình từ các vectơ được vẽ cho mỗi người lính và di chuyển mỗi người lính theo chiều dài của vectơ riêng của họ theo hướng đó với cùng một góc. Điều này sẽ làm cho sự xuất hiện của các đơn vị di chuyển theo đội hình đến điểm và sẽ giữ cho các đơn vị không bị vón cục.

Nếu bạn muốn các đơn vị di chuyển ra khỏi đội hình, bạn có thể chỉ ra góc của mọi người lính trực tiếp tại vị trí được nhấp. Tuy nhiên, không va chạm, các đơn vị sẽ bắt đầu hội tụ. Để khắc phục điều này, hãy thêm va chạm và buộc các đơn vị ngừng di chuyển một khi chúng "đủ gần" đến điểm được nhấp. Các đơn vị đầu tiên đến sẽ chính xác vào điểm và những đơn vị cuối cùng đến sẽ được chỉ dẫn dừng di chuyển một khi chúng đủ gần hoặc một khoảng thời gian nhất định đã trôi qua.

Bạn có thể tính toán độ dài của đường dẫn và tốc độ đơn vị để xác định khi nào một đơn vị sẽ đến và sau đó buộc đơn vị dừng di chuyển nếu vượt quá thời gian đó thêm một lượng nhất định. Bạn sẽ cần chơi với số đó một chút.


Giải pháp véc tơ mà bạn đề xuất giống như Thử 2 của tôi ở trên. Một trong những yêu cầu của câu hỏi này là các đơn vị được chọn có thể không ở trong một đội hình.
IceCreamYou

Và tôi đã viết về một giải pháp trong đó họ sẽ không di chuyển theo đội hình. (Đoạn 2)
Spencer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.