Посібник розробника
index.html → окремі ігриfile:// протоколомwindow.* глобальні об'єкти (без ES modules)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/ # Документація
window.QuizGame.init({
dataVar: 'QUIZ_DATA',
containerId: 'quiz-container'
});
window.FallingGame.init({
dataVar: 'FALLING_DATA',
canvasId: 'game-canvas'
});
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)
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)
theme.css визначає CSS custom properties:
--color-bg-primary, --color-accent-blue, тощо--glass-bg, --glass-border, --glass-blur--space-xs через --space-3xl--text-xs через --text-4xl--game-accent, --game-bg — для кастомізації на рівні сторінкиIIFE-модуль, що створює плаваючу кнопку-шестеренку та панель налаштувань через document.createElement (без innerHTML).
.theme-light на <body> — світла тема.font-lg, .font-xl на <html> — збільшений / великий шрифт.reduce-motion на <html> — зменшення анімацій.high-contrast на <html> — висока контрастністьhistgame_theme — 'dark' або 'light'histgame_fontsize — 'normal', 'large', 'xlarge'histgame_reducemotion — 'true' або 'false'histgame_highcontrast — 'true' або 'false'Додайте перед </body>:
<script src="../../shared/js/accessibility.js"></script>
Запобігання FOUC: на index.html є ранній <script> в <head>, що застосовує збережені класи до рендеру.
Створіть файл даних: data/games/my-game-data.js
window.MY_GAME_DATA = { ... };
Створіть 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>
Додайте посилання в index.html
Створіть data/quiz/crstm-s-{row}-{col}.js:
window.QUIZ_DATA = {
title: "...",
questions: [
{ question: "...", answers: ["..."], correct: 0 }
]
};
Посилання: shared/templates/quiz-question.html?id={row}-{col}
Створіть data/falling/period-{n}-{name}.js:
window.FALLING_DATA = { ... };
Посилання: shared/templates/falling-answer.html?id={n}-{name}
shared/js/analytics.js)Легка, приватна аналітика навчальних сесій. Дані зберігаються тільки в localStorage (ключ: histgame_analytics). Жодних мережевих запитів.
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(); // очистити з підтвердженням
Додайте <script src="../../shared/js/analytics.js"></script> перед accessibility.js
Додайте 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
my-game.html, my-data.js)window.* глобальні об'єкти../../shared/, ../../assets/<a> замість nav.js