Làm thế nào để cây hộp thoại làm việc?


20

Đó là, những gì được kết nối với những gì và làm thế nào để di chuyển giữa các dòng lời nói khi một cuộc trò chuyện phụ kết thúc?

Nếu bạn có bất kỳ ví dụ nào về cây hộp thoại cơ bản trong C #, vui lòng gửi chúng.


Tôi nghĩ rằng nó sẽ là tuyệt vời để có dialog-treethẻ.
dùng1306322

Yêu cầu các mẫu mã thường không được xem xét thuận lợi.
MichaelHouse

Nếu có một số mẫu mã cây 101 hộp thoại đáng để chia sẻ, nó không thể bị tổn thương.
dùng1306322

Vấn đề là trang web này là về việc có được câu trả lời chính xác cho câu hỏi. Nó không phải để thu thập các mẫu mã.
MichaelHouse

Đó là lý do tại sao câu bắt đầu bằng "nếu". Nhưng điều tôi đang hỏi là lời giải thích về cách các dòng hộp thoại kết nối với nhau theo cách có thể được dịch thành mã một cách hiệu quả. Sau tất cả, tôi sẽ viết nó bằng C #.
dùng1306322

Câu trả lời:


24

Tên "cây đối thoại" hơi sai lệch - chúng thường là các biểu đồ được định hướng đơn giản , không chỉ là cây . Cấu trúc dữ liệu cơ bản của các biểu đồ như vậy thường bao gồm một số loại "dữ liệu" cho các nút, đại diện cho các điểm chúng ta đang ở trong cuộc trò chuyện và liên kết từ chúng đến các nút khác, đại diện cho những gì được nói và thực hiện bởi những người tham gia và tùy ý có các điều kiện trên chúng để hạn chế khả năng hiển thị hoặc tập lệnh của chúng để thực hiện các hành động bổ sung khác nhau. Thông thường, một trong các nút là nút bắt đầu mặc định (nhãn điển hình cho "ROOT", "START" và "GREETING") và các nút không có liên kết hợp lệ dẫn đến chúng kết thúc cuộc trò chuyện.

Trong hầu hết các trường hợp, biểu đồ được biểu diễn trong bộ nhớ dưới dạng danh sách các Nodecấu trúc dữ liệu, mỗi cấu trúc có ít nhất một ID và danh sách các Linkcấu trúc dữ liệu 0..n . Danh sách này có thể là cục bộ của NPC hoặc toàn cầu; trường hợp thứ hai được ưu tiên nếu bạn có nhiều NPC chung có thể được nói chuyện để biết thông tin, nhưng không cung cấp các cuộc hội thoại cụ thể nào. Bản thân hệ thống tìm thấy nút hội thoại bắt đầu cho NPC, ghi nhớ ID của nó là ID cuộc trò chuyện hiện tại, trình bày các liên kết hợp lệ hiện tại để người chơi chọn từ (hoặc "[cuộc hội thoại kết thúc]" nếu không có liên kết hợp lệ) và chờ đợi đầu vào. Khi người chơi chọn một liên kết, các dòng đối thoại được liên kết sẽ được hiển thị và mọi tập lệnh liên quan sẽ chạy.

Thay vì có các quy tắc và điều kiện phức tạp trên các liên kết, thay vào đó bạn có thể nhận được bằng một biến boolean "hợp lệ" đơn giản, sau đó có thể được thay đổi từ các tập lệnh của các liên kết hội thoại khác (bao gồm cả các mặc định từ nút bắt đầu) hoặc bên ngoài cơ chế. Nói chung, cách tiếp cận này đơn giản hơn nhưng chỉ phù hợp với các trò chơi có rất ít cuộc hội thoại như vậy, vì nó di chuyển logic của "Khi nào thì phản ứng này có thể?" tránh xa dữ liệu phản hồi


Lưu ý rằng cấu trúc tôi mô tả ở đây hơi khác so với Byte56 ở chỗ các nút không cần phải có bất kỳ dòng đối thoại nào; các liên kết có thể có tất cả. Trong biến thể cơ bản nhất, điều này chuyển sang cấu trúc sau.

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


+1 Để đề cập đến các quy tắc và điều kiện trên các liên kết, một biểu đồ được định hướng đơn giản thường không đủ và mọi thứ có thể trở nên phức tạp khi bạn bắt đầu cần chúng.
Laurent Couvidou

+1 Tôi thích cấu trúc đó hơn. Mặc dù vậy, tôi sẽ không đề xuất nó như là một lần đầu tiên. Tôi sẽ bắt đầu với một cái gì đó đơn giản hơn. Đó chắc chắn là một mục tiêu tốt hơn để bắn.
MichaelHouse

+1 Cho câu trả lời rất chi tiết. Điều này có thể có ích cho tôi sau này.
Marton

Hình ảnh này rất hữu ích với tôi, nhưng tôi phải tự hỏi tại sao DialogueLine tách biệt với Liên kết? Không phải mỗi liên kết có văn bản phản hồi riêng của nó? Và văn bản của NPC sẽ đi đâu? Nó sẽ không có ý nghĩa để có nó trong nút?
Kyle Baran

@Danjen Trong cấu trúc này, một Liên kết có thể có nhiều Đối thoại, có thể từ các nhân vật khác nhau, cho đến khi lựa chọn đối thoại tiếp theo xuất hiện. Đây cũng là nơi văn bản NPC đi. Khi các dòng lặp lại, các Liên kết khác nhau có thể chia sẻ DialogueLines, có thể sắp xếp lại chúng trong danh sách của chúng (Vector), thay thế các phần của chúng bằng các dòng khác nhau, thêm các phần xen kẽ, v.v.
Martin Sojka

16

Cây đối thoại được tạo ra với cấu trúc đồ thị có hướng .

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

Biểu đồ được duyệt qua dựa trên các quyết định hộp thoại mà người chơi đưa ra. Các tùy chọn hộp thoại được cung cấp cho người dùng đến từ các cạnh xác định đường dẫn đến các nút hộp thoại khác.

Đồ thị có hướng là một cấu trúc dữ liệu cơ bản. Chúng có thể dễ dàng được thực hiện và bạn có thể muốn tự thực hiện nó. Vì bạn sẽ muốn điều chỉnh biểu đồ theo nhu cầu hộp thoại của mình.

Một số nút có thể cần phải có các điều kiện đặc biệt được đáp ứng để hiển thị. Ví dụ, người chơi sẽ yêu cầu một kỹ năng nói ở trên X. Hoặc người chơi cần hoàn thành nhiệm vụ Z trước khi họ có thể tiến xuống một nhánh của hộp thoại. Hoặc họ cần hỏi điều gì đó 4 lần trước khi NPC sẽ thảo luận với họ. Những tính năng này sẽ được tùy chỉnh cho trò chơi của bạn. Nhưng đáng nói khi bạn đang thực hiện truyền tải nút và cạnh. Tất nhiên, tốt nhất là luôn bắt đầu với hình thức đơn giản nhất và xây dựng từ đó.


Tôi chỉ không thể biết phải làm gì trong những trường hợp như "rắc rối Newton" trong bức tranh này. Giống như làm thế nào để thiết lập thứ tự của các dòng đó trong mã mà không lặp lại chúng.
dùng1306322

Bạn sẽ thường thấy rằng hộp thoại có thể được lặp đi lặp lại. Nó thường chỉ được đánh dấu theo một cách nào đó để người dùng biết họ đã chọn đường dẫn hộp thoại đó. Bạn có thể đặt một lá cờ ở các cạnh cho biết nếu chúng đã được chọn trước đó. Vì vậy, tùy thuộc vào bạn cho phép người dùng chọn lại (để tự làm mới) hoặc không hiển thị.
MichaelHouse

1
Thông thường sẽ không được thực hiện với thứ tự các dòng mã, nhưng thông qua các tham chiếu trong cấu trúc dữ liệu.
Kylotan

7

Tôi đã xây dựng một hệ thống hộp thoại đơn giản: http://iki.fi/sol/d3/ bản thân "engine" hiện tại là đơn giản c, nhưng dữ liệu do trình soạn thảo tạo ra khá đơn giản để sử dụng trong mọi ngôn ngữ. Công cụ này xuất ra XML, JSON và một định dạng nhị phân tùy chỉnh.

Khái niệm chính khá đơn giản:

Bạn đang ở trong một mê cung của những đoạn nhỏ ngoằn ngoèo, tất cả đều giống nhau

Mỗi nút (mà tôi gọi là "thẻ", như với tương tự ở trên) của hộp thoại bao gồm văn bản câu hỏi và không hoặc nhiều câu trả lời. Mỗi câu trả lời dẫn đến một thẻ khác.

Ngoài ra còn có một hệ thống thẻ trong đó các câu trả lời nhất định chỉ được hiển thị cho người dùng nếu thẻ được đặt (hoặc thẻ không được đặt). Nhập một bộ thẻ (hoặc bỏ đặt) các thẻ được chỉ định.

Đây là tất cả mọi thứ người ta cần làm về bất kỳ loại hộp thoại nào trong trò chơi. "Văn bản câu hỏi" có thể là văn bản thuần túy hoặc nó có thể là một tập lệnh để điều khiển hoạt hình hoặc không có gì.


4

Bạn có thể sử dụng TreeSharp và cây hành vi để mô hình hóa một hệ thống đối thoại. TreeSharp là một thư viện cung cấp thực hiện cây hành vi đơn giản. Các bot IA cho wow được thực hiện với điều này, vì vậy nó đã trưởng thành ... :)

Việc triển khai của tôi có các nút cho phép chọn giữa các câu trả lời và mỗi câu trả lời có thể được tham gia để tạo ra cuộc đối thoại hoặc một hành động, hoặc một chuỗi các hành động, hoặc một nút cho phép đi đến một hộp thoại khác ... hoặc những gì bạn muốn ...

Tôi đã sử dụng trình soạn thảo não để làm cho nó trực quan ... nhưng cuối cùng, nó tạo ra mã c # dựa trên treesharp ...

http://www.youtube.com/watch?v=6uGg6bUYyUU


2

Bạn muốn một đồ thị có hướng (có thể theo chu kỳ).

Bạn sẽ mô hình hóa các nút dưới dạng các đối tượng và tất cả các mũi tên đi trong nút của đồ thị cũng được mô hình thành các đối tượng riêng biệt. Nút có một danh sách các mũi tên đi và mỗi đối tượng "mũi tên" có một văn bản để hiển thị và tham chiếu đến đích. Không chắc chắn, nhưng tôi nghĩ trong các đối tượng C # luôn được tham chiếu, vì vậy bạn chỉ cần tạo các đối tượng trước, sau đó khi bạn tạo các đối tượng mũi tên, cắm cùng một đối tượng vào trường đích của hai mũi tên. (Trong C ++, bạn sử dụng loại tham chiếu hoặc loại con trỏ, Nút & hoặc Nút *)

Để tải những thứ như thế này từ đĩa, người ta thường cung cấp cho mỗi nút một số ID duy nhất, sau đó tải tất cả các nút vào một mảng trong đó chỉ mục là số duy nhất đó. Sau đó, các mũi tên được nối tiếp bằng cách viết số, không phải đối tượng thực tế.

Khi bạn tải một mũi tên, bạn sử dụng mảng và ID để có được một tham chiếu đến nút mà nó trỏ tới. Nếu bạn đã viết ra đối tượng hai lần, bạn sẽ nhận được hai đối tượng riêng biệt trông giống hệt nhau, đó có thể không phải là điều bạn muốn.

Xử lý một cây hộp thoại trở nên rất đơn giản. Bạn chỉ cần đặt nút gốc trong một currentNodebiến, hiển thị toàn bộ bằng cách nào đó, sau đó khi lựa chọn được thực hiện, đặt thành rootNodeđích của mũi tên. Trong mã giả:

Node&    currentNode = dialogTree.node[0];
while( currentNode != END_CONVERSATION_PSEUDO_NODE )
{
    stage.displayNode( currentNode );
    currentNode = stage.waitForUserToChoose();
}

1

Gần đây tôi đã phải phát triển một cái gì đó như thế này bằng Node và chọn một cấu trúc tệp văn bản rất cơ bản để biểu diễn một đồ thị có hướng của các nút hội thoại.

Bạn có thể xem mã kết quả và định dạng văn bản tại:

https://github.com/scottbw/dialoguejs

Nó không hỗ trợ các điều kiện hoặc trình kích hoạt sự kiện (nhưng), nhưng có lẽ đủ đơn giản để bắt đầu với nhiều nhà phát triển trò chơi.

(Bản thân mã trong GPL, btw)


Câu hỏi yêu cầu C #.
Seth Battin

D'oh - xin lỗi về điều đó.
Scott Wilson
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.