2009-05-22 6 views
14

Tôi đang phát triển trò chơi có khu vực chơi 2d vuông lớn. Khu vực chơi game là vô ích với các mặt bị chặn (không quấn quanh). Tôi đang cố gắng tìm ra cách tôi có thể phân chia tốt nhất thế giới này để tăng hiệu suất phát hiện va chạm. Thay vì kiểm tra từng thực thể để va chạm với tất cả các thực thể khác, tôi chỉ muốn kiểm tra các thực thể lân cận để tránh va chạm và tránh chướng ngại vật.Cách chia nhỏ thế giới trò chơi 2d để phát hiện va chạm tốt hơn

Tôi có một vài mối quan tâm đặc biệt cho trò chơi thế giới này ...

  • Tôi muốn có thể để có thể sử dụng một số lượng lớn các thực thể trong thế giới game cùng một lúc. Tuy nhiên, một% các thực thể sẽ không va chạm với các thực thể cùng loại. Ví dụ, các projectiles sẽ không va chạm với các projectiles khác.

  • Tôi muốn có thể sử dụng nhiều kích thước đối tượng. Tôi muốn có sự khác biệt về kích thước rất lớn giữa các thực thể nhỏ nhất và lớn nhất.

  • Có rất ít thực thể tĩnh hoặc không di chuyển trong thế giới trò chơi.

Tôi quan tâm trong việc sử dụng một cái gì đó tương tự như những gì được mô tả trong các câu trả lời ở đây: Quadtree vs Red-Black tree for a game in C++?

mối quan tâm của tôi là như thế nào một phân khu cây của thế giới sẽ có thể xử lý chênh lệch kích thước lớn vào đơn vị? Để phân chia thế giới đủ cho các thực thể nhỏ hơn, những người lớn hơn sẽ cần chiếm một số lượng lớn các khu vực và tôi lo ngại về điều đó sẽ ảnh hưởng đến hiệu suất của hệ thống như thế nào.

Mối quan tâm lớn khác của tôi là cách giữ đúng danh sách các khu vực bị chiếm hữu được cập nhật. Vì có rất nhiều thực thể di chuyển và một số thực thể rất lớn, có vẻ như việc chia thế giới sẽ tạo ra một lượng đáng kể chi phí để theo dõi những thực thể nào chiếm lĩnh vực nào.

Tôi chủ yếu đang tìm kiếm bất kỳ thuật toán hay ý tưởng tốt nào sẽ giúp giảm số lần phát hiện va chạm và tránh các tính toán tránh chướng ngại vật.

Trả lời

2

Có rất nhiều cách tiếp cận. Tôi khuyên bạn nên cài đặt một số mục tiêu cụ thể (ví dụ: x thử nghiệm va chạm trên giây với tỷ lệ y giữa nhỏ nhất đến lớn nhất) và thực hiện tạo mẫu để tìm phương pháp đơn giản nhất đạt được các mục tiêu đó. Bạn có thể ngạc nhiên về công việc bạn phải làm để có được những gì bạn cần. (Hoặc nó có thể là một tấn công việc, tùy thuộc vào thông tin cụ thể của bạn.)

Nhiều cấu trúc tăng tốc (ví dụ: BSP tốt) có thể mất một lúc để thiết lập và do đó thường không thích hợp cho hoạt ảnh nhanh.

Có rất nhiều tài liệu về chủ đề này, vì vậy hãy dành thời gian tìm kiếm và nghiên cứu để tìm ra cách tiếp cận danh sách ứng cử viên. Mock chúng lên và hồ sơ.

6

Nếu tôi là bạn, tôi sẽ bắt đầu bằng cách triển khai một cây BSP (phân vùng không gian nhị phân) đơn giản. Vì bạn đang làm việc trong 2D, kiểm tra hộp bị ràng buộc thực sự nhanh chóng.Về cơ bản bạn cần ba lớp: CBspTree, CBspNode và CBspCut (không thực sự cần thiết)

  1. CBspTree có một ví dụ nút gốc của lớp CBspNode
  2. CBspNode có một thể hiện của CBspCut
  3. CBspCut tượng trưng cho cách bạn cắt một tập trong hai bộ rời rạc. Điều này có thể được giải quyết gọn gàng bằng cách giới thiệu đa hình (ví dụ: CBspCutX hoặc CBspCutY hoặc một số đường cắt khác). CBspCut cũng có hai CBspNode

Giao diện hướng tới thế giới bị chia sẽ trải qua lớp cây và có thể là một ý tưởng hay để tạo thêm một lớp trên đó, trong trường hợp bạn muốn thay thế BSP giải pháp với ví dụ một cây quad. Một khi bạn nhận được hang của nó. Nhưng trong kinh nghiệm của tôi, một BSP sẽ làm tốt.

Có các chiến lược khác nhau về cách lưu trữ các mục của bạn trong cây. Ý tôi là, bạn có thể chọn để có ví dụ một số loại thùng chứa trong mỗi nút chứa tham chiếu đến các đối tượng chiếm khu vực đó. Điều này có nghĩa là mặc dù (như bạn đang tự hỏi mình) rằng các mặt hàng lớn sẽ chiếm nhiều lá, tức là sẽ có nhiều tài liệu tham khảo cho các đối tượng lớn và các mục rất nhỏ sẽ xuất hiện ở các lá đơn.

Theo kinh nghiệm của tôi, điều này không có tác động lớn. Tất nhiên nó quan trọng, nhưng bạn phải làm một số thử nghiệm để kiểm tra xem nó thực sự là một vấn đề hay không. Bạn sẽ có thể giải quyết vấn đề này bằng cách đơn giản bỏ những thứ đó ở các nút nhánh trong cây, tức là bạn sẽ không lưu trữ chúng trên "cấp độ lá". Điều này có nghĩa là bạn sẽ tìm thấy những vật thể đó nhanh chóng trong khi đi ngang qua cây.

Khi nói đến câu hỏi đầu tiên của bạn. Nếu bạn chỉ sử dụng phân mục này để thử nghiệm va chạm và không có gì khác, tôi đề nghị rằng những thứ không bao giờ va chạm không bao giờ được đưa vào cây. Một tên lửa ví dụ như bạn nói, không thể va chạm với tên lửa khác. Điều đó có nghĩa là bạn thậm chí không cần phải cất tên lửa trong cây.

Tuy nhiên, bạn có thể muốn sử dụng bsp cho những thứ khác nữa, bạn không chỉ định điều đó nhưng hãy ghi nhớ điều đó (để chọn các đối tượng có nghĩa là chuột). Nếu không, tôi đề nghị bạn lưu trữ mọi thứ trong bsp, và giải quyết xung đột sau này. Chỉ cần hỏi bsp của một danh sách các đối tượng trong một khu vực nhất định để có được một tập giới hạn các ứng cử viên va chạm có thể và thực hiện kiểm tra sau đó (giả sử các đối tượng biết những gì họ có thể va chạm với, hoặc một số cơ chế bên ngoài khác).

Nếu bạn muốn tăng tốc độ điều gì đó, bạn cũng cần phải chăm sóc mergechia, tức là khi mọi thứ được đưa ra khỏi cây, rất nhiều nút sẽ trở nên trống rỗng hoặc số lượng các mục dưới đây một số mức nút sẽ giảm xuống dưới một số ngưỡng hợp nhất. Sau đó, bạn muốn kết hợp hai subtrees thành một nút chứa tất cả các mục. Tách ra sẽ xảy ra khi bạn chèn các mục vào thế giới. Vì vậy, khi số lượng các mục vượt quá một số ngưỡng tách bạn giới thiệu một cắt mới, mà chia tách thế giới trong hai. Các ngưỡng hợp nhất và chia này phải là hai hằng số mà bạn có thể sử dụng để điều chỉnh hiệu quả của cây.

Hợp nhất và chia nhỏ chủ yếu được sử dụng để giữ cho cây cân bằng và để đảm bảo rằng nó hoạt động hiệu quả như nó có thể theo thông số kỹ thuật của nó. Đây thực sự là những gì bạn cần phải lo lắng. Di chuyển mọi thứ từ một vị trí và do đó việc cập nhật cây là nhanh. Nhưng khi nói đến sáp nhập và tách nó có thể trở nên đắt tiền nếu bạn làm điều đó quá thường xuyên.

Điều này có thể tránh được bằng cách giới thiệu một số loại hệ thống tách và hợp nhất lười biếng, tức là bạn có một số loại gắn cờ hoặc sửa đổi dơ bẩn. Hợp nhất tất cả các hoạt động có thể được nhóm, tức là di chuyển 10 đối tượng và chèn 5 đối tượng có thể là một lô.Một khi lô hoạt động đó kết thúc, bạn kiểm tra xem cây có bị bẩn hay không và sau đó bạn thực hiện các thao tác hợp nhất và/hoặc chia tách cần thiết.

Đăng một số nhận xét nếu bạn muốn tôi giải thích thêm.

Chúc mừng!


Sửa

Có rất nhiều thứ có thể được tối ưu hóa trong cây. Nhưng như bạn đã biết, tối ưu hóa sớm là gốc rễ của mọi điều ác. Vì vậy, bắt đầu đơn giản. Ví dụ, bạn có thể tạo một số hệ thống gọi lại chung mà bạn có thể sử dụng khi duyệt qua cây. Bằng cách này bạn không phải truy vấn cây để lấy danh sách các đối tượng khớp với hộp "câu hỏi" bị ràng buộc, thay vào đó bạn có thể duyệt qua cây và thực hiện cuộc gọi đó mỗi lần bạn nhấn vào một cái gì đó. "Nếu hộp ràng buộc này tôi cung cấp giao cắt bạn, sau đó thực hiện gọi lại này với các thông số"

4

mối quan tâm của tôi là như thế nào một phân khu cây của thế giới sẽ có thể xử lý chênh lệch kích thước lớn trong tổ chức ? Để chia thế giới thành đủ cho các thực thể nhỏ hơn, các đối tượng lớn hơn sẽ cần chiếm một số lượng lớn các khu vực và tôi là liên quan đến cách thức này sẽ ảnh hưởng đến hiệu suất của hệ thống.

Sử dụng cây quad. Đối với các đối tượng tồn tại ở nhiều khu vực, bạn có một vài tùy chọn:

  • Lưu trữ đối tượng ở cả hai nhánh, xuống hết cỡ. Tất cả mọi thứ kết thúc trong các nút lá nhưng bạn có thể kết thúc với một số lượng đáng kể các con trỏ thêm. Có thể thích hợp cho những thứ tĩnh.

  • Tách đối tượng trên đường viền vùng và chèn từng phần vào vị trí tương ứng của chúng. Tạo ra rất nhiều đau đớn và không được xác định rõ ràng cho rất nhiều đối tượng.

  • Lưu trữ đối tượng ở điểm thấp nhất trong cây bạn có thể. Bộ các đối tượng hiện tồn tại trong các nút lá và không lá, nhưng mỗi đối tượng có một con trỏ đến nó trong cây. Có lẽ tốt nhất cho các đối tượng sẽ di chuyển.

Nhân tiện, lý do bạn sử dụng cây quad là vì nó thực sự rất dễ làm việc. Bạn không có bất kỳ sáng tạo dựa trên heuristic như bạn có thể với một số triển khai BSP. Nó đơn giản và nó được hoàn thành công việc.

Mối quan tâm lớn khác của tôi là cách giữ đúng danh sách các khu vực bị chiếm giữ . Vì có rất nhiều của các thực thể di chuyển và một số rất các đối tượng lớn, có vẻ như việc chia thế giới sẽ tạo ra một khoản tiền đáng kể là để theo dõi trong đó các thực thể chiếm khu vực.

Sẽ có phí để giữ cho các thực thể của bạn ở đúng vị trí trên cây mỗi lần di chuyển, có, và điều đó có thể đáng kể. Nhưng toàn bộ vấn đề là bạn đang làm việc ít hơn nhiều trong mã xung đột của mình.Mặc dù bạn đang thêm một số chi phí với việc duyệt cây và cập nhật nó sẽ nhỏ hơn nhiều so với chi phí mà bạn vừa xóa bằng cách sử dụng cây.

Rõ ràng tùy thuộc vào số lượng đối tượng, kích thước của thế giới trò chơi, v.v., việc giảm giá có thể không đáng giá. Thông thường nó trở thành một chiến thắng, nhưng thật khó để biết mà không làm điều đó.

1

Tôi muốn bị cám dỗ chỉ để phủ một lưới thô trên khu vực phát để tạo thành một băm 2D. Nếu lưới ít nhất là kích thước của thực thể lớn nhất thì bạn chỉ có 9 ô vuông lưới để kiểm tra va chạm và nó đơn giản hơn nhiều so với quản lý cây quad hoặc cây BSP tùy ý. Chi phí của việc xác định hình vuông lưới thô nào bạn thường chỉ là 2 phép tính số học và khi thay đổi được phát hiện, lưới chỉ cần xóa một tham chiếu/ID/con trỏ khỏi danh sách của một ô vuông và thêm vào cùng một ô vuông khác.

Các lợi ích khác có thể có từ việc giữ các viên đạn ra khỏi hệ thống tra cứu lưới/cây/vv - vì bạn có thể nhanh chóng xác định vị trí của đường đạn trong lưới, bạn biết ô vuông lưới nào để truy vấn các xung đột tiềm năng. Nếu bạn kiểm tra va chạm chống lại môi trường cho mỗi lần phóng, thì không cần các đối tượng khác kiểm tra các xung đột đối với các projectiles ngược lại.