Làm cách nào tôi có thể phát hiện các phòng của phòng trong một trò chơi cuộn bên 2D?


24

Tôi đang tìm cách tạo ra một hệ thống nhận ra một số loại tòa nhà và phòng bạn có thể tạo trong trò chơi, giống như cách Terraria phát hiện "nhà ở". Trong trò chơi đó, một ngôi nhà có thể được xây dựng trong một thế giới dựa trên gạch bằng cách xây dựng một khối các khối thỏa mãn một tập hợp các điều kiện:

  1. Khu vực này được cách ly hoàn toàn với "bên ngoài" bởi các khối do người chơi đặt.
  2. Vùng có thể vừa với hình chữ nhật 5x7.
  3. có ít nhất một bàn, một nguồn sáng và ghế trong khu vực kín.
  4. Có một cánh cửa dẫn ra khỏi khu vực.
  5. Terraria có cả lớp gạch nền trước và nền. Toàn bộ nền của khu vực phải được lấp đầy bằng các khối do người chơi đặt.

Làm cách nào tôi có thể phát hiện một cách hiệu quả khi người chơi đã xây dựng một khu vực có kích thước phù hợp và làm cách nào tôi có thể kiểm tra một cách hiệu quả rằng khu vực đó có chứa tất cả các thành phần / đồ đạc cần thiết không?

Ví dụ về một khu vực bên trong đáp ứng tất cả các yêu cầu nhà ở:

nhập mô tả hình ảnh ở đây


5
Bạn có thể giải thích? Bạn có ý nghĩa gì bởi "các loại công trình" và "nơi cư trú" ở Terraria là gì? Hãy nhớ rằng không phải ai cũng chơi trò chơi đó, cũng tập trung vào một câu hỏi nếu bạn muốn mọi người giúp đỡ và đảm bảo rằng câu hỏi đó có câu trả lời chắc chắn (không phải ý kiến)
TomTsagk 23/07/18

1
Với các loại tôi có nghĩa là các thành phần / gạch khác nhau được sử dụng. Câu hỏi của tôi được giải quyết dưới đây. Tôi sẽ cố gắng tạo ra nhiều hơn và cụ thể hơn cho các câu hỏi trong tương lai, cảm ơn vì sự giúp đỡ.
Bernardo Becker

1
Như một bên, đảm bảo rằng có một sự khác biệt giữa một căn phòng và một nơi cư trú . Danh sách đạn của bạn cho thấy rằng bạn xem chúng là cùng một định nghĩa. Lấy Terraria làm ví dụ, kẻ thù không sinh sản trong phòng, ngay cả khi chúng không đủ điều kiện làm nơi cư trú (ví dụ thiếu bàn hoặc chỉ 5x5 về kích thước)
Flater

Câu trả lời:


37

Tôi không quen thuộc với Terraria, nhưng điều đó có thể dễ dàng thực hiện bằng thuật toán lấp đầy .

Thay vì pixel, bạn kiểm tra các ô và với mỗi ô được kiểm tra, bạn đánh giá xem thuật toán có thể tiến hành kiểm tra các ô khác hay không, trong khi lưu trữ trong một mảng hoặc liệt kê các đối tượng được tìm thấy trong quá trình.

Thuật toán bắt đầu tại ô có ký tự. Bạn có thể bắt đầu mỗi 1 giây, 2 ... đó là vấn đề điều chỉnh để tìm khoảng thời gian tốt nhất.

Bạn cũng nên ngăn thuật toán chạy quá lâu, điều này có thể được thực hiện bằng cách giới hạn số ô mà thuật toán có thể chạy trên mỗi lần chạy, nếu không thuật toán của bạn sẽ gây ra độ trễ dài khi ký tự ở trong khu vực mở.

Chỉnh sửa

Như đã nêu trong các bình luận, bạn có thể sử dụng các cách tiếp cận khác khi nào bắt đầu thuật toán, chẳng hạn như khi người chơi thay đổi một ô hoặc các ô có một am I modified?biến, nếu true, bắt đầu thuật toán. Tuy nhiên, bạn phải cẩn thận với phương pháp này:

  • Điều gì sẽ xảy ra nếu một ô là một phần của căn phòng, nhưng không phải là một ô mà nhân vật của bạn đang ở, bị sửa đổi? Có thể ô được thay đổi bởi người chơi khác, hoặc một sự kiện môi trường hoặc thời gian tồn tại của ô kết thúc. Nhân vật của bạn sẽ không biết về việc sửa đổi và sẽ không thực hiện thuật toán để phát hiện phòng được cập nhật, một tình huống dễ xảy ra lỗi.

Bạn có thể thực hiện một số cách tiếp cận để phát hiện các sửa đổi này trên các ô mà nhân vật của bạn không có, nhưng thực hiện thuật toán theo các khoảng thời gian là cách tiếp cận đơn giản nhất và ít bị lỗi hơn. Chỉ cần đảm bảo không thực hiện lấp lũ trên mỗi khung.

Kết thúc chỉnh sửa


9
Tại sao không chỉ lấp đầy trong các ô "khối đặt người chơi"? Điều này có thể ngăn chặn hoặc làm giảm lũ lụt vô hạn ở các khu vực mở (miễn là các hang động / biệt thự không được lấp đầy bằng "các khối do người chơi đặt").
jimbo1qaz

20
Tại sao bạn lại chạy cái này trong một khoảng thời gian cố định? Chắc chắn bạn chỉ có thể chạy nó khi một khối được đặt (hoặc bị phá hủy, nếu có thể, và cả hai trường hợp đó có thể được thực hiện trong thời gian không đổi được khấu hao cho mỗi khối) hoặc khi tải một phần cụ thể của bản đồ, sau đó lưu trữ kết quả từ ở đó
Không phải

3
@immibis: Tôi khá chắc chắn rằng Terraria không yêu cầu bạn thay đổi sàn. Tôi cũng không mong đợi một trò chơi thay đổi hành vi nhận biết phòng của nó dựa trên người đã đặt gạch. Điều gì xảy ra nếu tôi xây dựng một căn phòng liền kề với một vách đá?
Flater

3
Terraria yêu cầu người ta phải đặt các bức tường nền và sẽ không tạo thành một ngôi nhà với nền / đá bẩn tự nhiên. Nó thực sự chỉ kiểm tra các khối do người chơi đặt.
loa_in_

3
Để tiết kiệm CPU, tôi chỉ chạy thuật toán thay đổi khối và sau đó lưu trữ trạng thái cho từng khối. Với điều này, thật đơn giảnisRoom()
Herr Derb 24/07/18

3

Giống như @Ferreira da Selva đã nói, hãy thử thuật toán lấp đầy. Mặc dù vậy, bạn có thể sử dụng một vài tiêu chí khác nhau khi chạy thuật toán để xác định xem nó có được bao quanh hay không.

Ví dụ: đối với mỗi ô bạn kiểm tra xem có lát nền nào không và nếu không có thì bạn biết rằng nó không được bao quanh. Hoặc bạn có thể yêu cầu nó thực hiện trì hoãn bằng cách tách nó trên một số khung, do đó làm giảm tải cho bộ xử lý và giảm độ trễ. Hoặc bạn có thể tạo giới hạn kích thước phòng mà người chơi sẽ phải tuân thủ.

Sử dụng kết hợp những thứ này sẽ cho phép bạn thực hiện nó hiệu quả hơn và hiệu quả hơn.


3

Có 2 vấn đề khó khăn trong khoa học máy tính. Đặt tên mọi thứ, vô hiệu hóa bộ đệm và lỗi off-by-one.

Đây là một vấn đề vô hiệu hóa bộ đệm.

Nếu bạn có một bản ghi "là cái này bên trong", bất cứ khi nào một khối được đặt hoặc gỡ bỏ, việc cập nhật nó và khu vực của nó thông qua việc lấp lũ là khá dễ dàng.

Để tối ưu hóa điều này, bạn có thể muốn có một tập hợp các "độ trong".

"Ô" là một khu vực được bao quanh bởi các khối do người chơi đặt (lên đến một kích thước nhất định).

Một "căn phòng" là một ô có gạch nền.

"Bên trong" là một căn phòng có cửa, đèn và ghế.

Khi bạn đặt một khối tiền cảnh do người chơi đặt, hãy đi bộ theo chiều kim đồng hồ / ngược chiều kim đồng hồ để xem một ô mới có được hình thành không. Khi bạn loại bỏ khối nền trước do người chơi đặt, hãy kiểm tra xem nó có phá vỡ bất kỳ ô nào không - nếu vậy, hãy xem liệu một ô mới có được hình thành hay không bằng cách hợp nhất hai ô đó.

Khi một ô mới được hình thành hoặc không được định dạng, hãy kiểm tra xem nó là một căn phòng hay bên trong.

Các tế bào có thể theo dõi có bao nhiêu gạch nền mà chúng cần là một căn phòng. Sau đó, một số đếm đơn giản khi một ô được hình thành, một ô nền được thêm hoặc xóa khỏi ô, có thể xác định nếu đó là một phòng.

Tương tự, các tế bào có thể theo dõi có bao nhiêu ghế và nguồn sáng (và trên thực tế là các loại vật thể) nằm trong chúng. Sau đó kiểm tra bên trong là tầm thường.

Một số lượng lối vào cũng có thể được thực hiện.


Vì vậy, chúng tôi tăng cường bản đồ với "các tế bào". Khi gạch được thêm hoặc xóa, chúng tôi kiểm tra ô của vị trí và tăng / giảm số lượng trong ô.

Sử dụng đi bộ theo chiều kim đồng hồ / ngược chiều kim đồng hồ để xác định bên trong và bên ngoài của một ô khi một khối nền trước được thêm hoặc xóa. Khi kích thước của các ô bị giới hạn, bước đi này sẽ có một số bước giới hạn.

Như một phần thưởng, bây giờ bạn có một cách rẻ tiền để nói về các phòng "sang trọng" hoặc "phòng được ban phước bởi một đài phun nước thần thánh", hoặc bất cứ điều gì khác về một căn phòng, vì các phòng có số lượng từng loại đối tượng trong đó. (Hoặc, khi các phòng bị giới hạn về kích thước, chỉ cần thực hiện một lần lặp; việc này sẽ xóa bộ đệm).

Mỗi vị trí nằm trong tối đa một ô, vì vậy bạn có thể lưu trữ id ô của từng vị trí trên bản đồ chính.


0

Khi sử dụng thuật toán lấp đầy, hãy tạo một biến, sẽ tăng theo từng ô được kiểm tra, vì vậy nếu nó cao hơn 35 (7 * 5, kích thước tối đa của phòng) thì nó chỉ dừng kiểm tra!


7 * 5 là hình chữ nhật kích thước tối thiểu phải vừa trong phòng
Rick
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.