הנדסה תוכנה ותכנות
יצירת פלטפורמת Storytelling מבוססת Javascript
Table of Contents
למה לבנות פלטפורמה אינטראקטיבית של סיפורים?
סיפור אינטראקטיבי הופך את הקוראים למשתתפים, נותן להם סוכנות על כיוון העלילה, החלטות אופי, ואת בניית העולם. פלטפורמה מבוססת JavaScript מאפשר ליוצרים לבנות נרטיבים עשירים, מתפתלים לרוץ לחלוטין בדפדפן, שום שרת לא נדרש.מבחירה - המשחקים שלך מבוסס-שלך ועד בדיוני אינטראקטיבי, הביקוש לחוויות דינמיות, מותאמות אישית גדל.
המונחים: Interactive Narratives
לפני כתיבת קו אחד של קוד, עליך להבין את אבני הבניין היסודיים שהופכים עבודה בדיונית אינטראקטיבית.המרכיבים הבאים הם חיוניים:
- מבנה שטח:0 (Story Structure: FLT:1 ענפים לא לינאריים (nodes) המחוברים על ידי בחירות.גרף הנרטיב יכול להיות עץ, גרף ציליקלי מכוון, או אפילו לאפשר לולאות (מסע בזמן או התחדשות).
- [01:0] ,0] מדינות: ⁇ 1 [המשתנה] מעקב אחר סטטינים, מלאי, דגלים, וביקר בצומתים.המדינה נוהגת בתוכן מותנה ומשחררת נתיבים חדשים.
- (FLT:0User Interface:BuildFLT:1) שכבת המצגת - טקסט, כפתורי בחירה, אמצעי תקשורת הטמיע.
- (FLT:0)JavaScript Logic:FLT:1 המנוע המשווה נתונים לסיפור, מעריך תנאים, ניהול שינויים, וממשיך התקדמות (localStorage or IndexedDB).
למד סטנדרטים קיימים כמו FLT:0 wineFLTOVA:1 פורמטי סיפור (הרלו, סוכר, קפלה) ואת שפת ה-FLT:2 InkuaFLT 3: 3 כדי לראות כיצד כלים בוגרים להתמודד עם מושגים אלה.
עיצוב מסגרת הסיפור
מנוע הסיפור שלך צריך מודל נתונים שהוא גם אקספרסיבי וקל למחבר.ישמה המבוססת על JSON עובדת טוב עבור פלטפורמות אינטרנט.
ייצוג של Node
כל צומת נרטיב (או "סגירה") מכיל:
- (ב) ויקרא י"ד: "וַיָּבְהִיא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא הוּא" (בראשית כ"ד, כ"ד).
- (ב) ⁇ :0) , ⁇ : ⁇ 1 (ב) ,בשורה של מחרוזת או תוכן דמוי סימן (התמסר עם ממיר HTML בטוח).
- (ב) ⁇ :0) ⁇ : 1 (ב) ,ב) ,בכוח של אפשרויות, כל אחת עם מטרה ללא צומת, מצב אופציונלי ואפקט אופציונלי על המדינה.
- (ב) ויקרא י"א: ויקרא י"ד, ויקרא י"א, י"א, י"א)
- (FLT:0onEnter / On Leave:FLT:1 Hooks כדי להפעיל JavaScript שרירותי (צליל, שינויים תמונה, עדכוני סטטינים).
{
"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" }
]
}
}
ניהול המדינה
משתנים ממשלתיים חיים בחנות תגובתית. השתמש באובייקט פשוט עם ממריצים/שחקנים ומערכת התראה לשינוי כך ש-UI באופן אוטומטי חוזר על עדכוני המדינה.
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)); }
}
דפוס זה מקלקל את הלוגיקה של DOM, מה שהופך את הפלטפורמה למבחן וקלה להרחיב.
בניית מנוע JavaScript
המנוע קורא מידע סיפור (במוצבא או מובא כ-JSON) ומפקח על ניווט.כאן יישום מינימלי:
« טעינה וריצה
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);
}
המונחים
תנאים יכולים להיות מיתרים פשוטים כמו FLT:5 נבחנים באמצעות ביטוי בטוח ⁇ (aרִיק (FLT:6) השתמש בהערכה של ביטוי קל משקל כגון FLT:0expr-evaltureFLT:1 או לכתוב ירידה חוזרת כי רק מאפשר תצפיות משתנים ומפעילים בסיסיים.
חיסכון ועומס התקדמות
השתמש ב-FLT:7 כדי להתמיד במצב (כולל נגעים ביקרו, הצומת הנוכחי והמשתנים) לספק פונקציה של autosave כי שריפות לאחר כל מעבר ללא צומת, ומדריך ידני לחסוך / לטעון 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);
}
לסיפורים גדולים יותר, שקול את IndexedDB כדי לחסוך נכסים בינאריים כמו תמונות או קטעי אודיו.
חוויית המשתמש
ממשק טקסט בסיסי ו-buttons פועל, אבל קהלים מודרניים מצפים מולטימדיה, עיצוב תגובתי ונגישות.
אינטגרציה
- (ב) ויקרא י"ד): "התגים אשר נמוגים באמצעות מעברי CSS.
- (ב) ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
- (ב) [WEB וידאו: ⁇ :] קטעי קולנוע קצרים עבור סצינות מפתח. Embed Through (FLT:12 עם בקרות או משחק אוטומטי (עם הפעלת מחווה למשתמש).
אחראי וגישה
- (ב) , (ב) , ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇ ⁇
- מזמורים: (ב) ,516, לעדכוני טקסט דינמיים, על מנת לאפשר את השימוש במיכלים.
- ניווט מקלדת תומך: Tab באמצעות בחירות, היכנס לבחירה.דיסקה על אפשרויות נסתרות.
- ערכת נושא מערכת התאמה עם שאילתות תקשורת של CSS.
אדריכלות מבוססת-פוסט (Optional)
אם אתם מתכננים להגיע לרמה, לשקול מסגרת ראייה כמו React או Vue.הם מפשטים את ניהול המדינה ו-rendering. for Interactive Fiction, aFLT:0finite State MachineveFLT:1 Library (למשל, FLT:2XstateFLT 3: 3) יכול מודל של גרפים מורכבים עם שומרים, פעולות, ומקבילות.
תכונות מתקדמות
כדי להבדיל את הפלטפורמה שלך, להוסיף יכולות המחברים והשחקנים משתוקקים.
מספר רב של ענפים & Variables
מעבר לזוגות פשוטים של בחירה, לאפשר:
- (ב) ויקרא י"א: "וַיְּּאֶשׁ עַמַרְתָּבְתָּבְהוּ" (במדבר כ"ד, כ"ד).
- (ב) ⁇ :0) ,ההתמדה / קביעה: 1:1 לעשות בחירות להשפיע על תכונות כמו אומץ, אמון או קסם.
- (ב) ,0) ,Inventory: 1 (ב) רשימה של פריטים שבהם אפשרויות דורשות או צור פריטים.
- דגלי העולם: ⁇ FLT:1 , משתנה כי להקליט פעולות העבר ולפתוח סניפים חדשים.
ניווט לא-Linear
לאפשר כפתורים "back", בחירת פרק, או תצוגת מפה. ליישם ערימה היסטורית של צמתים לבקר כך שחקנים יכולים לשנות את המעברים ללא לאבד מצב (אך להיזהר מפרדוקסים אם יש אפשרויות יש אפקטים קבועים).
זמן אמיתי Co-Authoring
עבור כלי מבוסס אינטרנט, השתמש WebSockets (או שירות כמו Firebase) כדי לאפשר לכותבים מרובים לערוך את אותו גרף סיפור בו זמנית.פלטפורמת המאמר ניתן להרחיב כדי לכלול עורך חזותי עם צומת גרור ו-drop.
בדיקות ווויכוח
לסיפורים אינטראקטיביים יש ספירות נתיב אקספוננציאליות.מבחן ידני הוא בלתי אפשרי; אתה צריך כלים אוטומטיים.
מבחן יחידה
הערכת מצב מבחן, מוטציות המדינה, ו node לטעון עם Jest או Mocha. Mock the DOM and 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');
});
כיסוי גרפי
כתוב תסריט שחצה את כל הצמתים האפשריים מההתחלה, איסוף ההסתה של המדינה, ודא שלכל צומת יש לפחות דרך אחת לסיים (סוף הצומת) דגל מת או בלוטות יתומים.
נגישות Audits
הפעל בדיקות אקס-core אוטומטיות בצנרת CI שלך.מבחן עם קוראי מסך (NVDA, VoiceOver) ולהבטיח ניגוד צבע לעמוד בסטנדרטים WCAG 2.1 AA.
המונחים: the Platform
אתר סטטי מוגש באמצעות CDN הוא אידיאלי עבור בדיוניות אינטראקטיבית.לא backend פירושו עלויות נמוכות יותר ואירוח פשוט יותר.
בניית צינור
- השתמש בחבילה (Vite or Webpack) כדי לארוז את המנוע, נתוני סיפור ונכסים.
- פרקי סיפור של Lazy-load אם JSON הוא ענק (חלק לתוך קבצים מרובים).
- ליצור עובד שירות לא מקוון, כך שחקנים יכולים להמשיך ללא אינטרנט.
Analytics Analytics Analytics
ניתוח ידידותי לפרטיות (למשל, פלאש, אומיאמי) כדי לראות אילו אפשרויות הן פופולריות, נקודות טיפת נקודות, וזמן משחק ממוצע. השתמש בנתונים אלה כדי לחדד את הסיפור.
סיפור אימה פשוט: סיפור אימה פשוט
תארו לעצמכם דמו של שני צומת המציג את המנוע המלא בפעולה.ההתחלה מציגה בחירה: להיכנס לבית רדוף או לברוח.בחירה להיכנס לדגל 21 ומוביל לצומת עם תמונה מפחידה.השחקן יכול אז לסגת או להמשיך.דוגמה קטנה זו מאשרת מעברים של המדינה, טעינה, לחסוך ולחסוך / עומס.
מסקנה
בניית פלטפורמת סיפורים אינטראקטיבית המבוססת על JavaScript היא פרויקט מתגמל המשלב עיצוב נרטיבי, הנדסת תוכנה וניסיון משתמש.על ידי מודל מבנה סיפור כגרף, יישום מנוע מדינה תגובתי, והתמקדות באינטגרציה תקשורתית, אתה יכול ליצור כלי שמעצים כל אחד כדי ליצור סיפורי ענף.התחל קטן, הוא מתנגן עם סופרים אמיתיים, ושחרר את הפלטפורמה שלך כקוד פתוח כדי לגדול קהילה של סיפורים.