Câu trả lời của Philipp đã cho thấy hướng đi đúng đắn. Tôi chỉ nghĩ rằng cấu trúc dữ liệu là dài dòng không cần thiết. Các văn bản ngắn hơn sẽ dễ dàng hơn để viết và đọc.
Ngay cả khi các văn bản ngắn hơn sẽ làm cho thuật toán phức tạp hơn một chút, điều đó đáng để thực hiện, bởi vì bạn chỉ viết thuật toán một lần, nhưng phần lớn thời gian của bạn sẽ được dành để viết và duy trì câu chuyện. Do đó tối ưu hóa để làm cho phần dễ dàng hơn bạn sẽ dành nhiều thời gian để làm.
var story = [
{ m: "Hi!" },
{ m: "This is my new game." },
{ question: "Do you like it?", answers: [
{ m: "yes", next: "like_yes" },
{ m: "no", next: "like_no" },
] },
{ label: "like_yes", m: "I am happy you like my game!", next: "like_end" },
{ label: "like_no", m: "You made me sad!", next: "like_end" },
{ label: "like_end" },
{ m: "OK, let's change the topic" }
];
Một số giải thích cho thiết kế này:
Toàn bộ câu chuyện được viết trong một mảng. Bạn không phải cung cấp số, chúng được cung cấp tự động theo cú pháp mảng: mục đầu tiên có chỉ số 0, mục tiếp theo có chỉ mục 1, v.v.
Trong hầu hết các trường hợp, không cần thiết phải viết số của bước sau. Tôi giả định rằng hầu hết các dòng văn bản không phải là chi nhánh. Hãy đặt "bước tiếp theo là mục sau" thành một giả định mặc định và chỉ tạo ghi chú khi nó khác.
Đối với bước nhảy, sử dụng nhãn , không phải số. Sau đó, nếu sau này bạn thêm hoặc xóa một vài dòng, logic của câu chuyện sẽ được giữ nguyên và bạn không phải điều chỉnh các con số.
Tìm một sự thỏa hiệp hợp lý giữa sự rõ ràng và ngắn gọn. Ví dụ, tôi đề nghị viết "m" thay vì "message", bởi vì đó sẽ là lệnh được sử dụng thường xuyên nhất từ trước đến nay, vì vậy việc viết ngắn sẽ khiến văn bản dễ đọc hơn. Nhưng không cần phải rút ngắn các từ khóa còn lại. (Tuy nhiên, hãy làm như bạn muốn. Điều quan trọng là làm cho nó dễ đọc nhất đối với bạn . Ngoài ra, bạn có thể hỗ trợ cả "m" và "message" làm từ khóa hợp lệ.)
Thuật toán cho trò chơi nên giống như thế này:
function execute_game() {
var current_line = 0;
while (current_line < story.length) {
var current_step = story[current_line];
if (undefined !== current_step.m) {
display_message(current_step.m);
if (undefined !== current_step.next) {
current_line = find_label(current_step.next);
} else {
current_line = current_line + 1;
}
} else if (undefined !== current_step.question) {
// display the question: current_step.question
// display the answers: current_step.answers
// choose an answer
// and change current_line accordingly
}
}
}
Nhân tiện, những ý tưởng này được lấy cảm hứng từ Ren'Py , đây không phải là chính xác những gì bạn muốn (không phải JavaScript, không phải web), nhưng dù sao cũng có thể cung cấp cho bạn một số ý tưởng hay.