Hiệu quả tìm đường cho nhiều kẻ thù đổ xô xung quanh chướng ngại vật


20

Tôi đang cố gắng cải thiện khả năng tìm đường cho kẻ thù trong trò chơi của mình. Ngay bây giờ, về cơ bản, họ chỉ cần liên tục di chuyển về phía vị trí chính xác của người chơi bằng cách tính góc giữa họ và người chơi và di chuyển theo hướng đó. Tôi cũng có một thuật toán đổ xô để ngăn chặn kẻ thù xếp chồng lên nhau, vì vậy chúng sẽ tạo thành nhóm chứ không phải cắt qua nhau.

Tuy nhiên, bây giờ tôi đã thêm một bản đồ dựa trên gạch, tôi cần kẻ thù cũng có thể đi vòng qua chướng ngại vật và tường chẳng hạn. Ban đầu, tôi đã thử thêm một giá trị phân tách vào các ô "không thể đi được" để thuật toán đổ xô sẽ coi các bức tường và chướng ngại vật là các vật thể di chuyển ra xa. Tôi vẫn chưa biết liệu điều này có khả thi hay không bởi vì thử nghiệm ban đầu của tôi cho thấy kẻ thù đâm vào một "bức tường" vô hình, nơi không có gạch không thể đi được, nhưng vì một số lý do, họ đã đánh nó và bắt đầu lóe ra.

Tôi đã tự hỏi nếu nó có thể quá nặng về hiệu suất để tính toán đường dẫn đến người chơi bằng A * và sau đó sử dụng thuật toán đổ xô để ngăn ngừa vón cục. Ban đầu trò chơi của tôi sẽ là một game bắn súng dựa trên sóng, nhưng thay vào đó tôi đã quyết định biến nó thành cấp độ theo mạch của Hotline Miami, vì vậy có khả năng tôi sẽ có ít kẻ thù hơn, với đám đông thỉnh thoảng, và chỉ cần tạo ra họ mạnh mẽ hơn.

Đây có phải là một giải pháp khả thi? Tôi đang sử dụng Java với Slick2D làm công cụ trò chơi của mình. Hoặc có một giải pháp / thuật toán tốt hơn để giải quyết cả hai vấn đề này?


7
Như tôi đã mô tả trong bản chỉnh sửa, "cái này có quá nặng không" là một câu hỏi để hỏi về trình hồ sơ của bạn, bởi vì nó sẽ phụ thuộc vào việc triển khai, phần cứng mục tiêu, ngân sách hiệu suất và bối cảnh trò chơi của bạn - tất cả những thứ mà bạn và trình biên dịch của bạn biết thân mật nhưng người lạ Internet thì không. Nếu bạn muốn có được các bầy dẫn đường một cách hiệu quả, chúng tôi có thể đề xuất các chiến lược để giúp với điều đó, nhưng chỉ có hồ sơ cá nhân của bạn mới có thể trả lời những gì đủ hiệu quả cho nhu cầu của bạn. Nếu bạn lập hồ sơ và xác định một vấn đề hiệu suất cụ thể, chúng tôi cũng có thể giúp bạn tìm cách giải quyết vấn đề đó.
DMGregory

1
Cách bạn thực hiện chúng ảnh hưởng đến hiệu suất. Chẳng hạn, chỉ chạy A * trên các nhà lãnh đạo và dựa vào việc đổ xô cho những người theo dõi.
Gulalek

Nếu trò chơi của bạn chủ yếu dựa trên việc chiến đấu với những kẻ thù này, thuật toán bạn thực hiện sẽ có tác động lớn đến cảm giác của trò chơi. Vì vậy, bạn nên thử các cách tiếp cận khác nhau, ví dụ như có cảm giác như kẻ thù biết cấp độ và vị trí của người chơi hoàn hảo mọi lúc và họ theo dõi anh ta như được chỉ dẫn bởi một AI biết tất cả? - các cách tiếp cận khác có thể là để kẻ thù chạy theo hướng chung nơi người chơi gây ồn ào và chỉ trên đường ngắm trực tiếp chạy về phía anh ta, hoặc la hét và thông báo cho những kẻ thù khác nơi người chơi đang ở ...
Falco

@Falco Vì trò chơi không còn dựa trên sóng và sẽ dựa trên cấp độ, và vì kẻ thù là zombie ... Tôi đã cân nhắc việc tạo ra nó để bạn phải nhìn thấy hoặc gây ồn để họ tìm thấy bạn. Vậy nếu bạn sử dụng vũ khí ồn ào? Nó phát ra âm thanh trong một phạm vi và tất cả kẻ thù trong đường dẫn hướng tới vị trí của âm thanh phát ra, và sau đó sẽ di chuyển ngẫu nhiên quanh khu vực đó.
Darin Beaudreau

Câu trả lời:


49

Điều này nghe có vẻ như một trường hợp sử dụng cho Trường lưu lượng.

Trong kỹ thuật này, bạn thực hiện một truy vấn tìm đường dẫn ra bên ngoài từ (các) đối tượng người chơi của bạn, đánh dấu từng ô bạn gặp với ô bạn đã truy cập từ đó.

Nếu tất cả các ô / cạnh của bạn có chi phí truyền tải bằng nhau, thì bạn có thể sử dụng tìm kiếm đầu tiên đơn giản cho việc này. Mặt khác, thuật toán của Dijkstra (như A * không có mục tiêu / heuristic) hoạt động.

Điều này tạo ra một trường dòng chảy: một bảng tra cứu liên kết từng ô với bước tiếp theo hướng tới đối tượng người chơi gần nhất từ ​​vị trí đó.

Giờ đây, kẻ thù của bạn có thể tìm kiếm vị trí hiện tại của chúng trong trường dòng chảy để tìm bước tiếp theo trong con đường tránh chướng ngại vật ngắn nhất của chúng đến đối tượng người chơi gần nhất, mà không cần thực hiện truy vấn tìm đường riêng.

Điều này quy mô tốt hơn và tốt hơn nhiều kẻ thù bạn có trong đàn của bạn. Đối với một kẻ thù, nó đắt hơn A * vì nó tìm kiếm trên toàn bản đồ (mặc dù bạn có thể ra ngoài sớm khi bạn đã đạt được tất cả các tác nhân tìm đường). Nhưng khi bạn thêm nhiều kẻ thù, họ sẽ chia sẻ ngày càng nhiều chi phí tìm đường bằng cách tính toán các phân đoạn đường dẫn được chia sẻ một lần thay vì lặp đi lặp lại. Bạn cũng có được lợi thế từ thực tế là BFS / Dijkdtra đơn giản hơn A * và thường rẻ hơn để đánh giá trên mỗi ô được kiểm tra.

Chính xác là nơi điểm hòa vốn chạm, từ cá nhân A * rẻ hơn, đến A * với khả năng ghi nhớ rẻ hơn (trong đó bạn sử dụng lại một số kết quả cho truy vấn tìm đường trong quá khứ để tăng tốc độ tiếp theo) rẻ hơn, sẽ phụ thuộc vào việc triển khai của bạn, số lượng đại lý và kích thước bản đồ của bạn. Nhưng nếu bạn từng lên kế hoạch cho một nhóm kẻ thù lớn tiếp cận từ nhiều hướng trong một khu vực hạn chế, một trường dòng chảy sẽ gần như chắc chắn rẻ hơn so với A * lặp.

Như một ví dụ cực đoan, bạn có thể thấy một video ở đây với 20 000 tác nhân đồng thời tìm đường trên một lưới nhỏ hợp lý .


Kỹ thuật này nghe thực sự gọn gàng. Tôi sẽ kiểm tra.
Darin Beaudreau

15
Có thể sử dụng thuật toán kết hợp xây dựng trường dòng một phần mà không cần tìm kiếm nhiều bản đồ hơn các cuộc gọi lặp lại đến A * không bao giờ tìm kiếm cùng một vị trí hai lần. Ý tưởng cơ bản là chọn một kẻ thù tùy ý và bắt đầu tìm kiếm A * từ người chơi về phía kẻ thù đó, đánh dấu các ô khi bạn gặp chúng giống như trong thế hệ trường dòng chảy bình thường. Khi tìm kiếm tìm thấy kẻ thù đó, hãy chọn một kẻ thù khác (mà bạn chưa tìm thấy) làm mục tiêu, sắp xếp lại bộ mở theo heuristic mới và tiếp tục tìm kiếm. Dừng lại khi bạn đã tìm thấy tất cả kẻ thù.
Ilmari Karonen

1
Còn việc tránh va chạm thì sao? Điều đó (phần nào) được đề cập trong OP (tránh bị cắt khi họ đến tay người chơi). Dường như với tôi bạn sẽ phải chạy lại toàn bộ djikstras mỗi khi có bất cứ thứ gì di chuyển (hoặc thêm vào một số logic bổ sung)
Sao Hỏa

2
@Mars OP nói về việc đổ xô, vì vậy tôi cho rằng tất cả các cá nhân có thể di chuyển với cùng tốc độ; nơi duy nhất mà các vụ va chạm sẽ trở thành một vấn đề là các nút cổ chai, đòi hỏi một số đàn phải dừng lại và chờ đợi. Tuy nhiên, thực sự không cần thay đổi đường dẫn - một hàng đợi đơn giản có thể hoạt động đủ tốt trong hầu hết các trường hợp và một số xu hướng đường dẫn (một số lựa chọn giả ngẫu nhiên của các đường thay thế có chi phí tương tự) sẽ hoạt động để tạo ra đàn có vẻ tự nhiên hơn dòng chảy cũng tránh cả đàn cố gắng đi qua một khoảng trống gạch đơn đặc biệt :)
Luaan

3
@Luaan Trong một trò chơi xếp gạch, bạn sẽ ngạc nhiên về mức độ thường xuyên xảy ra va chạm. Cá nhân, tôi thấy tùy chọn "xếp hàng" là ít hơn tối ưu. Ngoài ra, nếu các đơn vị không thể đi qua nhau, bạn sẽ cần tính toán lại khi các đơn vị bắt đầu vào vị trí cuối cùng của chúng và một loạt các trường hợp cạnh khác. Đổ xô là khó khăn;)
Sao Hỏa

8

A * không phải là hiệu suất nặng. Tôi sẽ tiếp cận tình huống này bằng cách thay đổi các thuật toán. Thỉnh thoảng thực hiện A * và giữa các lần kiểm tra xem bước tiếp theo có tự do bước lên hay bạn cần trốn tránh.

Ví dụ: theo dõi khoảng cách người chơi từ vị trí mục tiêu A *, nếu nó vượt quá ngưỡng tính toán lại * và sau đó chỉ cần thực hiện các chuyển động cập nhật. Hầu hết các trò chơi sử dụng kết hợp các điểm cách, ví dụ: lưới đơn giản hóa để tìm đường và logic xử lý chuyển động giữa các điểm tham chiếu với thuật toán điều khiển trốn tránh bằng cách sử dụng sóng. Các đặc vụ cố gắng chạy đến một điểm xa bằng cách điều động xung quanh các chướng ngại vật ở gần họ là cách tiếp cận tốt nhất theo ý kiến ​​của tôi.

Tốt nhất là làm việc với các máy trạng thái hữu hạn ở đây và đọc cuốn sách "Lập trình trò chơi AI theo ví dụ" của Mat Buckland. Cuốn sách cung cấp các kỹ thuật đã được chứng minh cho vấn đề của bạn và chi tiết toán học cần thiết. Mã nguồn từ cuốn sách có sẵn trên web; cuốn sách ở dạng C ++ nhưng một số bản dịch (bao gồm cả Java) có sẵn.


2
Với cách tiếp cận A * cập nhật không thường xuyên, có thể hữu ích để ngăn chặn các cập nhật của bạn, duy trì ngân sách cho bao nhiêu kẻ thù được phép đi lại trên một khung. Bằng cách đó, bạn có thể giữ chi phí tìm đường dẫn cao nhất cho mỗi khung hình được giới hạn và xử lý mạnh mẽ hơn nhiều đường dẫn AI bằng cách khấu hao tổng chi phí của chúng qua một số khung. Một AI sử dụng đường dẫn cũ cho một hoặc hai khung khi vượt quá ngân sách cho khung hoặc rơi vào việc tính toán chết nếu đóng, thường sẽ không bị gián đoạn.
DMGregory

2
Có thể nói rõ điều này ở đây, nhưng nếu bạn chỉ cập nhật một số đường dẫn của mình trong một khung nhất định, bạn có thể muốn có một hệ thống ưu tiên dựa trên khoảng cách với người chơi. Nó có thể quan trọng hơn đối với những kẻ thù ở gần người chơi để cập nhật đường đi của chúng, trong khi những kẻ thù ở xa có thể sử dụng một con đường cũ.
AC

4

Không chỉ khả thi, tôi tin rằng nó đã được thực hiện trong một trò chơi thương mại vào những năm 90 - BattleZone (1998).

Trò chơi đó có các đơn vị 3D với chuyển động không dựa trên gạch miễn phí và xây dựng cơ sở dựa trên gạch.

Đây là cách nó dường như hoạt động:

Đầu tiên, A * hoặc một cái gì đó tương tự (có thể là một biến thể của A * với các giới hạn nghiêm ngặt về thời gian mà nó có thể tìm thấy, do đó, nó không bao giờ mất quá nhiều tài nguyên để chạy nhưng không phải lúc nào cũng tìm thấy một con đường đến đích) sẽ được sử dụng để tìm đường cho một hovertank đi đến đích mà không bị kẹt trong các chướng ngại vật trên nền gạch.

Sau đó, chiếc xe tăng sẽ bay xung quanh cho đến khi không gian như thể nó bị thu hút vào trung tâm của một viên gạch gần đó trên đường đi của nó, và bị đẩy lùi bởi các chướng ngại vật, các xe tăng khác gần đó, v.v.


1
Vì vậy, một cách tốt để xử lý theo con đường, nhưng không chính xác? Nếu tôi cho phép vào cua kiddy, tôi cần có khả năng ngăn chặn kẻ thù va chạm với góc của một chướng ngại vật. Tôi có nên giữ hành vi đổ xô cho cả kẻ thù và chướng ngại vật và thêm A * để đối phó với những tình huống đó không?
Darin Beaudreau
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.