Зміст

Архітектура

Структура директорій

index.html                    # Головна сторінка
shared/
  css/
    reset.css                 # Box-sizing, базова типографіка
    theme.css                 # CSS custom properties (кольори, відступи)
    layout.css                # Контейнери ігор, сітки, панелі
    components.css            # Кнопки, картки, модалки, навбар
    animations.css            # @keyframes та класи анімацій
    responsive.css            # Mobile-first медіа-запити
  js/
    nav.js                    # Sticky навбар
    quiz-engine.js            # window.QuizGame
    game-engine.js            # window.FallingGame
    canvas-utils.js           # window.CanvasUtils
    ui-utils.js               # window.UIUtils
    assistant.js              # Помічник-восьминог
    accessibility.js          # Плаваюча панель налаштувань доступності
  templates/
    quiz-question.html        # Шаблон вікторини
    falling-answer.html       # Шаблон гри з падаючими відповідями
data/
  quiz/                       # 23 файли даних вікторин
  falling/                    # 3 файли даних падаючих ігор
  assistant/facts.js          # 50+ фактів для помічника
  games/                      # Дані нових ігор
    solitaire-v2-cossack.js
    bobble-imperial.js
    puzzle-soviet.js
    kafe-independence.js
  pheniks_2/                  # Зображення пазлів (MZP/PTL/SGD)
games/
  narrative/                  # Наративні та унікальні ігри
    tower-defense.html        # Three.js tower defense (Період 5)
  start-pages/               # Вступні сторінки
  quiz-hub/                  # Сітка вікторин
  map/                       # Інтерактивна карта
ar/                          # A-Frame / AR.js сторінки
assets/                      # Зображення, моделі, музика, шрифти
docs/                        # Документація

Shared JS API

QuizGame (shared/js/quiz-engine.js)

window.QuizGame.init({
  dataVar: 'QUIZ_DATA',
  containerId: 'quiz-container'
});

FallingGame (shared/js/game-engine.js)

window.FallingGame.init({
  dataVar: 'FALLING_DATA',
  canvasId: 'game-canvas'
});

CanvasUtils (shared/js/canvas-utils.js)

window.CanvasUtils.setup(canvasId, containerId)
window.CanvasUtils.resize()
window.CanvasUtils.getSize()
window.CanvasUtils.checkCollisionAABB(a, b)  // {x,y,w,h}
window.CanvasUtils.checkCollisionCircle(a, b) // {x,y,radius}
window.CanvasUtils.reflectOffWalls(ball, bounds)
window.CanvasUtils.clear(bgColor)

UIUtils (shared/js/ui-utils.js)

window.UIUtils.showModal(modalId, overlayId)
window.UIUtils.hideModal(modalId, overlayId)
window.UIUtils.updateText(elementId, text)
window.UIUtils.updateScore(scoreId, value)
window.UIUtils.updateLives(livesId, value)
window.UIUtils.showNotification(message, duration)

CSS theming

theme.css визначає CSS custom properties:

Система доступності (shared/js/accessibility.js)

IIFE-модуль, що створює плаваючу кнопку-шестеренку та панель налаштувань через document.createElement (без innerHTML).

CSS-класи

localStorage ключі

Підключення

Додайте перед </body>:

<script src="../../shared/js/accessibility.js"></script>

Запобігання FOUC: на index.html є ранній <script> в <head>, що застосовує збережені класи до рендеру.

Як додати нову гру

1

Створіть файл даних: data/games/my-game-data.js

window.MY_GAME_DATA = { ... };
2

Створіть HTML: games/narrative/my-game.html

<!DOCTYPE html>
<html lang="uk">
<head>
    <link rel="stylesheet" href="../../shared/css/reset.css">
    <link rel="stylesheet" href="../../shared/css/theme.css">
    <link rel="stylesheet" href="../../shared/css/animations.css">
</head>
<body data-nav="overlay" data-home-url="../../index.html">
    <!-- Гра -->
    <script src="../../data/games/my-game-data.js"></script>
    <script>/* Логіка гри */</script>
    <script src="../../shared/js/nav.js"></script>
    <script src="../../shared/js/accessibility.js"></script>
</body>
</html>
3

Додайте посилання в index.html

Як додати дані для quiz/falling шаблонів

Quiz

Створіть data/quiz/crstm-s-{row}-{col}.js:

window.QUIZ_DATA = {
  title: "...",
  questions: [
    { question: "...", answers: ["..."], correct: 0 }
  ]
};

Посилання: shared/templates/quiz-question.html?id={row}-{col}

Falling

Створіть data/falling/period-{n}-{name}.js:

window.FALLING_DATA = { ... };

Посилання: shared/templates/falling-answer.html?id={n}-{name}

Аналітика (shared/js/analytics.js)

Легка, приватна аналітика навчальних сесій. Дані зберігаються тільки в localStorage (ключ: histgame_analytics). Жодних мережевих запитів.

API: window.HLGAnalytics

// Почати сесію (moduleId авто з ?id= або pathname)
HLGAnalytics.startSession('module-id');

// Завершити сесію
HLGAnalytics.endSession({ score: 12, won: true, attempts: 3 });

// Отримати дані
HLGAnalytics.getSessions();      // масив записів
HLGAnalytics.getOverview();      // { totalSessions, totalTime, uniqueModules }
HLGAnalytics.getModuleSummary(id); // { plays, avgScore, avgTime, bestScore }

// Експорт
HLGAnalytics.exportJSON();
HLGAnalytics.exportCSV();
HLGAnalytics.downloadFile('csv');
HLGAnalytics.sendToTeacher();    // mailto: з CSV

// UI
HLGAnalytics.renderDashboard('containerId'); // міні-картка
HLGAnalytics.renderExport('containerId');    // повна таблиця
HLGAnalytics.clearAll();                     // очистити з підтвердженням

Інтеграція в нову гру

1

Додайте <script src="../../shared/js/analytics.js"></script> перед accessibility.js

2

Додайте 2 рядки у код гри:

// На старті гри:
if (window.HLGAnalytics) HLGAnalytics.startSession('my-game');

// При завершенні:
if (window.HLGAnalytics) HLGAnalytics.endSession({
  score: playerScore, won: isVictory
});

Валідація зображень (shared/js/asset-validator.js)

Утиліта для ігор, що використовують зображення від користувача. Якщо файл відсутній, відображає червоний квадрат із назвою очікуваного файлу.

// Створити <img> з fallback:
var img = AssetValidator.createImg(
  '../../data/games/archaeology/TRPL_pot_1.jpg',
  'Трипільський горщик',
  { width: '200px', height: '200px' }
);
container.appendChild(img);

Ігри з валідацією: archaeology, city-builder, culture-gallery

Конвенції