Đó 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.
Đó 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.
Câu trả lời:
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 Node
cấ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 Link
cấ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.
Cây đối thoại được tạo ra với cấu trúc đồ thị có hướng .
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 đã 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:
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ì.
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 ...
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 currentNode
biế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();
}
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)
dialog-tree
thẻ.