Table of Contents
Tại sao nên xây dựng nền tảng kể chuyện tương tác?
Một nền tảng dựa trên JavaScript cho phép người tạo ra xây dựng các câu chuyện phong phú, chi nhánh chạy hoàn toàn trong trình duyệt, không cần thiết máy chủ nào. Từ việc chọn trò chơi có khả năng tự động đến hư cấu tương tác, nhu cầu cho các trải nghiệm năng động, cá nhân đang phát triển. bài báo này đi qua các cấu trúc, thực hiện và sản xuất sẵn sàng mở rộng của một nền tảng như vậy bằng JavaScript hiện đại.
Quan điểm chung về sự giao tiếp giữa các người
Trước khi viết một dòng mã đơn, bạn phải hiểu những khối cơ bản để tạo nên những tác phẩm tương tác.
- Chương trình kiến trúc giả định: [FLT: 1] nhánh không phải là bảng điều khiển] được liên kết bởi lựa chọn. Biểu đồ tường thuật có thể là một cây, một đồ thị chỉ đạo, hoặc thậm chí cho phép vòng lặp (thời gian đi lại).
- Đặt tên máy ảnh biến số, kiểm tra, cờ, và thăm nút. Việc ổ đĩa có điều kiện và mở khóa đường dẫn mới.
- Giao diện người dùng: Lớp trình bày - vẽ văn bản, nút chọn, nhúng phương tiện. Nó phải có đáp ứng và truy cập được.
- logic: bộ máy phân tích dữ liệu, đánh giá điều kiện, quản lý chuyển tiếp, và tiếp tục tiến trình (localStorage or IndexedDB).
Nghiên cứu các tiêu chuẩn đã có như Twine định dạng câu chuyện (Harlowe, SugarCube, Nhà nguyện) và ) Ngôn ngữ [FLT:] để xem các công cụ thành thục xử lý những khái niệm này như thế nào. Nền tảng của bạn có thể mượn những thực hành tốt nhất trong khi cung cấp một hệ thống ADI cho người dùng cấp cao.
Thiết kế khung khung truyện
Động cơ câu chuyện của bạn cần một mô hình dữ liệu vừa biểu cảm vừa dễ dàng với tác giả.
Đại diện cho một cái gật đầu
Mỗi nút tường thuật (hoặc “qua hệ thống) ” chứa:
- Bộ nhận diện độc đáo (v., , .
- ngữ cảnh: Một dãy các chuỗi hoặc đánh dấu nội dung (có gắn với một bộ chuyển đổi HTML an toàn).
- Các phân loại: một dãy tùy chọn, mỗi nút đích, điều kiện tùy chọn và hiệu ứng tùy chọn trên tình trạng.
- thẻ: Siêu âm cho bộ lọc, khi nó chuyển động, hay âm thanh.
- [FLT: 0] VàoEnter / trên leave: Hooks để chạy JavaScript tùy ý (âm thanh, thay đổi ảnh, cập nhật hình ảnh).
{
"start": {
"text": [
"You stand at the edge of a dark forest.",
"The wind carries a faint whisper."
],
"tags": ["outdoor", "moody"],
"choices": [
{ "text": "Enter the forest", "target": "forest_path",
"effect": "playerStats.fear++" },
{ "text": "Turn back to the village", "target": "village_square",
"condition": "player.hasCompass" }
]
}
}
Quản lý trạng thái
Biến số tiểu bang trực tiếp trong cửa hàng phản ứng. Hãy dùng một đối tượng đơn giản với các nhà thu/ sửa đổi và một hệ thống thông báo thay đổi, vì vậy UI tự động phục hồi các bản cập nhật trạng thái. Ví dụ:
class StoryState {
constructor(initialData) {
this._state = { ...initialData };
this._listeners = [];
}
get(key) { return this._state[key]; }
set(key, value) {
this._state[key] = value;
this._notify();
}
subscribe(fn) { this._listeners.push(fn); }
_notify() { this._listeners.forEach(fn => fn(this._state)); }
}
Mô hình này giải thích logic từ điện thoại của DOP, làm cho nền tảng có thể kiểm tra và dễ dàng mở rộng.
Xây dựng máy JavaScript
Máy đọc dữ liệu câu chuyện (thường được nhập hoặc lấy như JSON) và điều khiển việc định vị.
Đang nạp và vẽ một nút
function renderNode(nodeId, storyData, state) {
const node = storyData[nodeId];
if (!node) throw new Error(`Node ${nodeId} not found`);
// Run hooks before rendering
if (node.onEnter) node.onEnter(state);
const container = document.getElementById('story-content');
container.innerHTML = ''; // Clear previous content
// Render text paragraphs
node.text.forEach(para => {
const p = document.createElement('p');
p.textContent = para; // Use a safe renderer for markdown
container.appendChild(p);
});
// Render choices, filtered by conditions
const choicesContainer = document.getElementById('choices');
choicesContainer.innerHTML = '';
node.choices.forEach(choice => {
if (choice.condition && !evaluateCondition(choice.condition, state)) return;
const btn = document.createElement('button');
btn.textContent = choice.text;
btn.addEventListener('click', () => {
if (choice.effect) applyEffect(choice.effect, state);
renderNode(choice.target, storyData, state);
});
choicesContainer.appendChild(btn);
});
// Run exit hooks
if (node.onLeave) node.onLeave(state);
}
Độ phân giải
Điều kiện có thể là chuỗi đơn giản như đánh giá [FLT:] qua một biểu thức an toàn phân tích (không có [FLT: 6). Hãy dùng biểu thức nhỏ như [FLT: 0] [FLT: 0] [FLT: 1] hoặc viết một phân tích phân tích phân tích phân tích phân tách phân cách lại, mà chỉ cho phép xem biến và các nhà điều hành cơ bản. Đừng bao giờ cho tác giả một mã hoá câu chuyện tùy ý thực hiện trừ khi hộp cát được cất giữ.
Cứu và nạp tiến bộ
Dùng để bền bỉ tình trạng (bao gồm các nút, nút hiện thời và biến). Cung cấp một chức năng tự động phát điện sau mỗi nút chuyển tiếp, và một hướng dẫn lưu/ nạp UI.
function save(state, nodeId) {
localStorage.setItem('story_save', JSON.stringify({
state: state._state,
current: nodeId,
timestamp: Date.now()
}));
}
function load() {
const raw = localStorage.getItem('story_save');
if (!raw) return null;
return JSON.parse(raw);
}
Đối với những câu chuyện lớn hơn, hãy xem phụ lục DB để lưu tài sản nhị phân như hình ảnh hoặc mảnh âm thanh.
Làm tăng thêm kinh nghiệm người dùng
Một giao diện văn bản cơ bản và nút bấm của máy tính, nhưng khán giả hiện đại mong đợi đa phương tiện, thiết kế đáp ứng và khả năng truy cập.
Hợp nhất phương tiện
- Những thẻ:) dùng thẻ giảm dần trong cách chuyển tiếp CN. Hỗ trợ ảnh phụ trong văn bản bằng mẫu như được bộ dịch.
- (FLT:1): Các vòng chung quanh và hiệu ứng âm thanh được gây ra bởi các móc . Hãy dùng mạng để phát lại và điều khiển âm lượng thấp.
- Video: đoạn phim ngắn cho các cảnh quan trọng. Embed qua với điều khiển hay hoạt động tự động (với cử chỉ người dùng).
UI có khả năng đáp ứng và truy cập
- Dùng HTML ngữ nghĩa: , cho các lựa chọn, cho kho thanh bên hay bản ghi.
- Thêm các thuộc tính James: để cập nhật văn bản động, về các hộp chọn.
- Hỗ trợ định hướng bàn phím: Tab thông qua tùy chọn, nhập vào để chọn. Tắt tập trung vào các tùy chọn ẩn.
- Sắc thái khớp với phương tiện điều khiển cho máy tính xách tay.
Thành phần Kiến trúc nền nềnName
Nếu bạn định cân nhắc, hãy xem một khung xem như phản ứng hay Vue. Chúng đơn giản hóa quản lý trạng thái và thay đổi lại. Đối với tiểu thuyết tương tác, một [FLT: 0] máy [FLT: 0] [FLT: 1] thư viện (v. d., [FLT: 2]X [FLT: 3]] có thể mô phỏng những câu chuyện phức tạp với người bảo vệ, hành động và các trạng thái song song. Tuy nhiên, JavaScript giữ các quan hệ phụ thuộc tối thiểu và dạy các khái niệm cốt lõi.
Tính năng nâng cao
Để phân biệt nền tảng của bạn, hãy thêm khả năng mà các tác giả và người chơi khao khát.
Nhiều & bảng màu; biến
Ngoài lựa chọn đơn giản, cho phép:
- Văn bản Condition: Các đoạn khác nhau dựa trên tiểu bang (v. d., “Bạn nhớ lời cảnh báo của ông già chỉ khi ).
- Tính toán tăng dần/ giảm dần: Chọn những tính như can đảm, tin tưởng, hoặc ảo thuật.
- Một danh sách các mục cần thiết hoặc tiêu thụ.
- Cờ thế giới: Biến ngũ kỷ lục các hành động và mở khóa các chi nhánh mới.
Không phải là đường đi bộ qua đường
Cho phép “nhó lại những nút, chọn chương, hoặc xem bản đồ, hoặc xếp chồng các nút thăm viếng lịch sử để người chơi có thể xem lại các đoạn văn mà không mất trạng thái (nhưng hãy coi chừng nghịch lý nếu sự lựa chọn có tác dụng lâu dài).
Đồng bộ thời gian thực sự
Để có công cụ phát âm dựa trên web, hãy dùng các ổ cắm Web (hoặc dịch vụ như Firebase) để cho nhiều nhà văn cùng một bản đồ cùng một câu chuyện. Có thể mở rộng nền tảng của bài báo để bao gồm một biên tập viên trực quan với các nút kéo và thả.
Thử và gỡ lỗi
Các câu chuyện tương tác có số mũ, kiểm tra thủ công là không thể; bạn cần công cụ tự động.
Thử đơn vị
Đánh giá tình trạng thử, đột biến bang, và nút nạp với Jest hay Mocha. Mock the FOR và localStorage.
test('renderNode shows correct text for start node', () => {
document.body.innerHTML = ``;
const storyData = {
start: { text: ['Hello'], choices: [] }
};
const state = new StoryState({});
renderNode('start', storyData, state);
expect(document.getElementById('story-content').innerHTML).toContain('Hello');
});
In đồ thị
Viết một tập lệnh đi qua tất cả các nút có thể đạt được từ đầu, thu thập các đường phụ thuộc vào trạng thái. Bảo đảm rằng mỗi nút có ít nhất một đường dẫn đến hoàn thành (end nút). Cờ đã kết thúc hay nút mồ côi.
Thử ra khả năng truy cập
Chạy kiểm tra rìu tự động trong đường ống CN. Kiểm tra với độc giả màn hình (NVDA, Giọng nói bên trên) và đảm bảo sự tương phản màu đáp ứng tiêu chuẩn WCAG 2. 1A.
Triển khai nền tảng
Một trang mạng tĩnh được phục vụ thông qua CDN là lý tưởng cho viễn tưởng tương tác. Không có hậu phương nào có nghĩa là chi phí thấp hơn và tổ chức đơn giản hơn.
Xây dựng ống dẫn
- Dùng một gói ( đẹp hoặc Webpack) để đóng gói động cơ, dữ liệu kể chuyện và tài sản.
- Những chương dài dòng của sách Luy - ô nếu sách JSON to (được in thành nhiều tập tin).
- Tạo ra một công nhân dịch vụ ngoại tuyến để người chơi có thể tiếp tục mà không cần internet.
Phân tích
Phân tích sự riêng tư thân thiện (v. d., linh hoạt, umami) để xem lựa chọn nào là phổ biến, điểm bỏ điểm dừng và thời gian chơi trung bình. Hãy dùng dữ liệu này để tinh chỉnh câu chuyện.
Nghiên cứu trường hợp: Một minh chứng đơn giản
Hãy tưởng tượng một bản thử nghiệm hai nút cho thấy động cơ hoạt động hoàn chỉnh. Nút đầu trình bày một sự lựa chọn: bước vào nhà bị ma ám hoặc chạy đi. Chọn nhập cờ và dẫn tới nút có ảnh nhảy sợ hãi. Người chơi có thể rút lui hay tiếp tục. Ví dụ nhỏ này xác thực trạng thái chuyển tiếp, tải truyền thông và lưu/load.
Kết luận
Xây dựng một nền tảng tương tác với JavaScript là một dự án bổ ích phối hợp thiết kế, kỹ thuật phần mềm và kinh nghiệm sử dụng. bằng cách mô phỏng cấu trúc câu chuyện như một đồ thị, thực hiện một động cơ phản ứng, tập trung vào sự kết hợp giữa các phương tiện truyền thông và khả năng tiếp cận, bạn có thể tạo ra một công cụ để tạo ra bất cứ ai để tạo ra những câu chuyện. bắt đầu nhỏ, lặp lại với tác giả thật, và thả nền tảng của bạn như là nguồn mở để phát triển một cộng đồng kể chuyện.