Trong một trò chơi dựa trên lưới mà tôi đang làm việc, tôi muốn thêm các đối tượng chiếm nhiều hơn một ô của lưới. Có bất kỳ thuật toán hoặc kỹ thuật để tìm đường dẫn cho loại đối tượng này không?
Trong một trò chơi dựa trên lưới mà tôi đang làm việc, tôi muốn thêm các đối tượng chiếm nhiều hơn một ô của lưới. Có bất kỳ thuật toán hoặc kỹ thuật để tìm đường dẫn cho loại đối tượng này không?
Câu trả lời:
Nói chung, bạn sẽ điều chỉnh các thuật toán tìm đường hiện có để nhạy cảm với chiều rộng. Chủ yếu điều đó có nghĩa là thích nghi A *, mặc dù trò chơi của bạn dựa trên lưới, bạn có thể thấy thuật toán để giải các mê cung chất béo hữu ích.
Đối với A *, giải pháp cơ bản nhất là chỉ cần thêm một xác nhận về chiều rộng cho các tính toán của bạn, theo quy tắc di chuyển của bạn. Tuy nhiên, điều này sẽ làm rối tung mã tìm đường của bạn và làm chậm quá trình tìm đường cho bất kỳ thực thể có kích thước thông thường nào.
Ngoài ra, bạn có thể coi lưới của mình là mạng tìm đường dựa trên nút và đối với các thực thể lớn hơn của bạn, bạn có thể tạo một mạng thứ cấp chiếm kích thước của chúng và sử dụng mạng đó để di chuyển và tìm đường. Điều này có lợi ích là cho phép bạn điều chỉnh đường dẫn của mình cho các thực thể lớn hơn để nó hoạt động như mong đợi, nhưng có nghĩa là tạo nhiều bản đồ cho mỗi cảnh và giữ chúng trong bộ nhớ, có thể ảnh hưởng đến các trò chơi trên nền tảng di động.
Nếu cả hai phương pháp đó không phù hợp với mục đích của bạn, bạn có thể tìm cảm hứng trong các thuật toán tìm đường lưới điều hướng , vốn đã nhận biết chiều rộng.
Một tùy chọn sẽ là tính toán lưới thứ hai có tính đến kích thước của đối tượng bằng cách "vẽ" nó lên lưới, như vậy. Đây là lưới ban đầu:
#########
#..b....#
#.#.....#
#.####..#
#.......#
#.......#
#..#.#..#
#a.#.#..#
#########
Chúng tôi muốn xem liệu một đối tượng 2x2 có thể nhận được từ a
đến b
. Chúng tôi tính toán một lưới thứ hai trong đó mỗi khi chúng tôi có một bức tường ( #
), chúng tôi thêm các bức tường ở trên và bên trái của nó ( x
), biến mỗi phân đoạn tường đơn thành một hình 2x2. Bây giờ nó trông giống như:
xxxxxxxxxx
x#########
x#xxb...x#
x#x#xxx.x#
x#x####.x#
x#......x#
x#.xxxx.x#
x#.x#x#.x#
x#ax#x#xx#
x#########
Sau đó, chúng ta có thể tìm đường dẫn trên lưới này bằng cách coi đối tượng là 1x1 vì chính lưới sẽ tính kích thước của chúng.
Bạn có thể mở rộng câu trả lời của munificent để lưu trữ một lưới hỗ trợ duy nhất, thay vì lưu trữ khả năng vượt qua cho từng kích thước đối tượng khác nhau, nó lưu trữ trường khoảng cách ghi lại số độ rộng nửa ô giữa vị trí này và hàng rào gần nhất. (Hoặc cách khác, chiều rộng của đối tượng lớn nhất có thể tập trung vào ô này mà không cần nhấn bất cứ thứ gì)
Bạn có thể điền vào lưới này bằng cách khởi tạo bản đồ thành một số nguyên lớn hơn kích thước bản đồ của bạn trong các khoảng trống và -1 tại các trang web trên tường. Sau đó, lặp đi lặp lại đặt từng ô> 0 đến mức tối thiểu của hàng xóm cộng với hai.
Bây giờ trong thuật toán tìm đường, bạn thay thế
if (!IsPassable(PassabilityMap[x, y])) continue;
với
if (DistanceToObstacleMap[x, y] < pathfindingAgent.size) continue;
Giờ đây, bạn có thể xử lý tìm đường cho bất kỳ kích thước đơn vị nào với một bản đồ duy nhất và việc lưu trữ / kiểm tra khả năng vượt qua vẫn có thể so sánh về chi phí với trường hợp một bool-per-brick.