diff --git a/.gitignore b/.gitignore index 0747ea9..504afef 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,2 @@ node_modules/ package-lock.json -app/dist -app/assets diff --git a/ENGINE_INFO_RU.txt b/ENGINE_INFO_RU.txt new file mode 100644 index 0000000..3295514 --- /dev/null +++ b/ENGINE_INFO_RU.txt @@ -0,0 +1,58 @@ +# Welcome +... + +## Переменные движка + +-- DEBUG +Тип: bool + +В зависимости от значения в консоль будет выхлоп данных для отладки. + +Значение берётся из файла конфигурации `config.json` и устанавливается при инициализации переменной. + +-- canvas +Переменная ссылатся на HTML объект canvas. + +Значение устанавливается в функции `window.onload = function()` + +-- context +Значение устанавливается в функции `window.onload = function()` + +-- cW +Значение устанавливается в функции `window.onload = function()` + +-- cH +Значение устанавливается в функции `window.onload = function()` + +-- landscape_orientation +Хранит значение ориентации экрана. + +Значение устанавливается в функции `window.onload = function()` в true, если ширина canvas больше или равна высоте canvas, в протином случает false. + +-- images +Объект со всеми изображениями квестов + +-- game +В переменной хранятся все данные игрового процесса (сцены, текущий квест, кол-во ответов и прочее). + +-- game.loaded +Тип: bool +Состояние загрузки игры. +Значение false будет до тех пор, пока не будут загружены все шрифты, изображение (возможно что-то ещё). + +-- game.currentQuest +Индекс текущего квеста. + +-- game.finish +Тип: bool +Устанавливается значение true, когда игрок ответил на все вопросы. + +## Главные функции движка +-- window.onload = function() +Инициализирующая функция, в которой устанавливаются значения переменных движка + +-- gameLoop(timeStamp) + +-- update() + +-- draw() diff --git a/TODO.md b/TODO.md index fa61c1a..5a39b48 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,10 @@ -- add quest progress +- loading all quest images with loading +- splash (loading) screen - change quest animation - button hover animation -- splash (loading) screen - make docs/ + +- google: if webpack mode production remove DEBUG code + +## done +- add quest progress [aac38ec] diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..bd7c4a1 --- /dev/null +++ b/app/.gitignore @@ -0,0 +1,2 @@ +dist/ +assets/images/*.jpg diff --git a/app/assets/logo.png b/app/assets/logo.png new file mode 100644 index 0000000..cc14505 Binary files /dev/null and b/app/assets/logo.png differ diff --git a/app/config.json b/app/config.json index 7841c41..638a11c 100644 --- a/app/config.json +++ b/app/config.json @@ -1,8 +1,5 @@ { "gameName": "quizEngine", "gameVersion": [0, 0, 1], - - "scene": { - "backGradient": ["#2f80ff", "#3ccbff"] - } + "debug": true } diff --git a/app/js/draw.js b/app/js/draw.js index 054b53a..8e98818 100644 --- a/app/js/draw.js +++ b/app/js/draw.js @@ -1,17 +1,17 @@ // функции рисоввания -export function clearContext(canvas, config) { +export function clearContext(canvas) { // var:canvas -- канвас, на котором рисуем - // var:config -- используется для получения цветов фона градиента сцены let cW = canvas.width; let cH = canvas.height; let context = canvas.getContext('2d'); let graBack = context.createLinearGradient(cW / 2, 0, cW / 2, cH); - graBack.addColorStop(0, config.scene.backGradient[0]); - graBack.addColorStop(1, config.scene.backGradient[1]); - context.fillStyle = graBack; + // graBack.addColorStop(0, config.scene.backGradient[0]); + // graBack.addColorStop(1, config.scene.backGradient[1]); + // context.fillStyle = graBack; + context.fillStyle = "#444444"; context.fillRect(0, 0, cW, cH); } diff --git a/app/js/game.js b/app/js/game.js index 6009879..2362f69 100644 --- a/app/js/game.js +++ b/app/js/game.js @@ -1,5 +1,13 @@ // функции игры +export function loadingLogo(imagesArray) { + // FIXME: возможно потом просто удалить функцию, если будет реализован imageLoader + let imgLogo = new Image(); + imgLogo.src = 'assets/logo.png'; + + imagesArray.logo = imgLogo; +} + export function clickAnswer(questions, game, answer) { if (questions[game.questIndex].rightAnswer.toLowerCase() == answer.toLowerCase()) { questions[game.questIndex].status = true; @@ -18,9 +26,9 @@ export function clickAnswer(questions, game, answer) { } } -export function shuffleQuestAnswer(answers) { - for (let i = answers.length - 1; i > 0; i--) { +export function shuffle(array) { + for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); - [answers[i], answers[j]] = [answers[j], answers[i]]; + [array[i], array[j]] = [array[j], array[i]]; } } diff --git a/app/js/index.bak.js b/app/js/index.bak.js new file mode 100644 index 0000000..e94410d --- /dev/null +++ b/app/js/index.bak.js @@ -0,0 +1,242 @@ +'use strict'; + +import config from '../config.json'; // game configuration +import gameData from '../gameData.json'; // game data + +import { getMousePos, isInside } from './buttons.js'; +import { clearContext, getCenterH, getCenterV } from './draw.js'; +import { clickAnswer, shuffleQuestAnswer } from './game.js'; + +// Engine variables ------------------------------------- +let DEBUG = true; +let canvas = null; // canvas id +let context = null; // context id +let cW = null; // canvas with +let cH = null; // canvas height +let orientation = null; // screen orientation +let button = null; // buttons array +let area = null; // game areas (buttons, images, etc.) +let game = null; + +// Init ------------------------------------------------- +window.onload = function() { + // init canvas id and sizes + canvas = document.getElementById('game'); + context = canvas.getContext('2d'); + cW = canvas.width; + cH = canvas.height; + + // set screen orientation by carculate canvas width&height + if (cW >= cH) { orientation = true; } + else { orientation = false; } + + if (DEBUG) { + console.log(`Loaded ${gameData.length} quests.`); + } + + game = { + // TODO: change quest by script + questIndex: 0, + quest: null, + questImage: null, + totalRightAnswers: 0, // количество правильных ответов + scene: null, + }; + shuffleQuestAnswer(gameData); // shuffle quest + game.quest = gameData[game.questIndex]; + shuffleQuestAnswer(gameData[game.questIndex].answer); // shuffle first quest answers + + // присваем всем квестам статус не выполнен + gameData.forEach(element => element.status = null); + + if (!orientation) { + area = { + answerButtons: { x: 10, y: cH - 340, w: cW - 20, h: 250 }, + questionLabel: { x: 10, y: cH - 340 - 80, w: cW - 20, h: 70 }, + uiButtons: { x: 10, y: cH - 80, w: cW - 20, h: 70 }, + questProgress: { x: 10, y: 10, w: cW - 20, h: 20 }, + } + area.image = { x: 10, y: area.questProgress.y + area.questProgress.h + 10, + w: cW - 20, h: area.questionLabel.y - area.questProgress.y - (area.questProgress.h * 2) }; + } + // TODO: add areas for landscape mode + + button = { + info: { x: 10, y: cH - 80, w: 70, h: 70 }, + sfx: { x: cW - 80, y: cH - 80, w: 70, h: 70 }, + // TODO: change data: to null + answerButtons: [ + { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, + { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, + { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, + { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, + ], + } + + button.answerButtons.forEach(function callback(value, index, array) { + if (index == 0) + array[index].y = area.answerButtons.y; + else + array[index].y = array[index - 1].y + value.h + 15; + }); + + canvas.addEventListener('click', function(evt) { + let mousePos = getMousePos(canvas, evt); + + // click info button + if (isInside(mousePos, button.info)) { + console.log("info"); + } + + // click sfx button + if (isInside(mousePos, button.sfx)) { + console.log("sfx"); + } + + // click by first answer button + if (isInside(mousePos, button.answerButtons[0])) { + clickAnswer(gameData, game, button.answerButtons[0].data); + } + + // click by second answer button + if (isInside(mousePos, button.answerButtons[1])) { + clickAnswer(gameData, game, button.answerButtons[1].data); + } + + // click by third answer button + if (isInside(mousePos, button.answerButtons[2])) { + clickAnswer(gameData, game, button.answerButtons[2].data); + } + + // click by four answer button + if (isInside(mousePos, button.answerButtons[3])) { + clickAnswer(gameData, game, button.answerButtons[3].data); + } + }, false); + + window.requestAnimationFrame(gameLoop); +}; + + +// GameLoop --------------------------------------------- +function gameLoop(timeStamp) { + update(); + draw(); + + window.requestAnimationFrame(gameLoop); +} + +// Game update func ------------------------------------- +function update() { + // Update answer buttons label + button.answerButtons.forEach(function callback(value, index) { + value.data = game.quest.answer[index]; + }); +} + +// Draw to canvas func ---------------------------------- +function draw() { + clearContext(canvas, config); // flush?! canvas + + // draw question label + context.font = "32px Ubuntu"; + context.textAlign = "center"; + context.fillStyle = "white"; + context.fillText(game.quest.question, cW / 2, area.questionLabel.y + 30); + + // draw answer buttons + context.fillStyle = "purple"; + context.strokeStyle = "navy"; + context.lineWidth = 2; + + for (let i = 0; i <= button.answerButtons.length - 1; i++) { + context.fillRect(button.answerButtons[i].x, button.answerButtons[i].y, + button.answerButtons[i].w, button.answerButtons[i].h); + context.strokeRect(button.answerButtons[i].x, button.answerButtons[i].y, + button.answerButtons[i].w, button.answerButtons[i].h); + } + + // draw answer button label + context.font = "32px Ubuntu"; + context.textAlign = "center"; + context.fillStyle = "white"; + + button.answerButtons.forEach(function callback(value) { + context.fillText(value.data, cW / 2, value.y + 35); + }); + + // draw image + game.questImage = new Image(); + game.questImage.src = 'assets/images/' + game.quest.image; + + // carculate image ratio by area.image size + if (game.questImage.width >= game.questImage.height) { + if (game.questImage.height > area.image.h) { + let ratio = game.questImage.width / area.image.w; + let newImageW = area.image.w / ratio; + let newImageH = area.image.h; + + context.drawImage(game.questImage, getCenterH(cW, newImageW), area.image.y, + newImageW, newImageH); + } + else { + // TODO: draw image center + // TODO: add option to sizeUp images to engine config + } + } + else { + let ratio = game.questImage.height / area.image.h; + let newImageW = area.image.w / ratio; + + context.drawImage(game.questImage, getCenterH(cW, newImageW), area.image.y, + newImageW, area.image.h); + } + + // draw progress bar + let sizeProgressItem = area.questProgress.w / gameData.length; + + context.strokeStyle = "black"; + + for (let i = 0; i < gameData.length; i++) { + // change progress item color by status answer + switch (gameData[i].status) { + case null: + context.fillStyle = "gray"; + break; + case true: + context.fillStyle = "green"; + break; + case false: + context.fillStyle = "red"; + break; + } + + context.fillRect(10 + (i * sizeProgressItem), 10, sizeProgressItem, 20); + context.strokeRect(10 + (i * sizeProgressItem), 10, sizeProgressItem, 20); + } + + // UI ------------------------------------------ + // TODO: переписать это всё г* + context.fillStyle = "red"; + context.strokeStyle = "navy"; + context.lineWidth = 2; + context.fillRect(button.info.x, button.info.y, button.info.w, button.info.h); // info button + context.strokeRect(button.info.x, button.info.y, button.info.w, button.info.h); // info button + context.fillRect(button.sfx.x, button.sfx.y, button.sfx.w, button.sfx.h); // sfx button + context.strokeRect(button.sfx.x, button.sfx.y, button.sfx.w, button.sfx.h); // sfx button + + // draw game areas + if (DEBUG) { + context.strokeStyle = "red"; + context.lineWidth = 2; + + // answer buttons area + if (orientation) + // TODO: draw answer buttons area by landscape + console.log('TODO: draw answer buttons area by landscape'); + else + for (const [key, value] of Object.entries(area)) { + context.strokeRect(value.x, value.y, value.w, value.h); + } + } +} diff --git a/app/js/index.js b/app/js/index.js index 24d2eef..fce4a32 100644 --- a/app/js/index.js +++ b/app/js/index.js @@ -5,18 +5,20 @@ import gameData from '../gameData.json'; // game data import { getMousePos, isInside } from './buttons.js'; import { clearContext, getCenterH, getCenterV } from './draw.js'; -import { clickAnswer, shuffleQuestAnswer } from './game.js'; +import { loadingLogo, clickAnswer, shuffle } from './game.js'; // Engine variables ------------------------------------- -let DEBUG = true; +const DEBUG = config.debug; let canvas = null; // canvas id let context = null; // context id let cW = null; // canvas with let cH = null; // canvas height -let orientation = null; // screen orientation -let button = null; // buttons array -let area = null; // game areas (buttons, images, etc.) -let game = null; +let landscape_orientation = null; // canvas orientation +let game = {}; // main game variable +let areas = null; +let images = {}; +let buttons = {}; + // Init ------------------------------------------------- window.onload = function() { @@ -25,87 +27,50 @@ window.onload = function() { context = canvas.getContext('2d'); cW = canvas.width; cH = canvas.height; + if (DEBUG) + console.log(`Canvas size ${cW} x ${cH}`); - // set screen orientation by carculate canvas width&height - if (cW >= cH) { orientation = true; } - else { orientation = false; } + // set screen orientation by carculate canvas width & height + if (cW >= cH) { landscape_orientation = true; } + else { landscape_orientation = false; } + if (DEBUG) + console.log(landscape_orientation ? "Canvas orientation set to landscape" : "Canvas orientation set to portrait"); - if (DEBUG) { - console.log(`Loaded ${gameData.length} quests.`); - } + loadingLogo(images); - game = { - // TODO: change quest by script - questIndex: 0, - quest: null, - questImage: null, - totalRightAnswers: 0, // количество правильных ответов - scene: null, - }; - shuffleQuestAnswer(gameData); // shuffle quest - game.quest = gameData[game.questIndex]; - shuffleQuestAnswer(gameData[game.questIndex].answer); // shuffle first quest answers + game.loadedState = false; + game.finish = false; + game.currentQuest = 0; + + shuffle(gameData); // shuffle quests + shuffle(gameData[game.currentQuest].answer); // shuffle first quest answers // присваем всем квестам статус не выполнен gameData.forEach(element => element.status = null); - if (!orientation) { - area = { - answerButtons: { x: 10, y: cH - 340, w: cW - 20, h: 250 }, - questionLabel: { x: 10, y: cH - 340 - 80, w: cW - 20, h: 70 }, - uiButtons: { x: 10, y: cH - 80, w: cW - 20, h: 70 }, + if (!landscape_orientation) { + areas = { + btnAnswer: { x: 10, y: cH - 340, w: cW - 20, h: 250 }, + labelQuestion: { x: 10, y: cH - 340 - 80, w: cW - 20, h: 70 }, + btnUi: { x: 10, y: cH - 80, w: cW - 20, h: 70 }, questProgress: { x: 10, y: 10, w: cW - 20, h: 20 }, } - area.image = { x: 10, y: area.questProgress.y + area.questProgress.h + 10, - w: cW - 20, h: area.questionLabel.y - area.questProgress.y - (area.questProgress.h * 2) }; + areas.questImage = { x: 10, y: areas.questProgress.y + areas.questProgress.h + 10, + w: cW - 20, h: areas.labelQuestion.y - areas.questProgress.y - (areas.questProgress.h * 2) }; } // TODO: add areas for landscape mode - button = { - info: { x: 10, y: cH - 80, w: 70, h: 70 }, - sfx: { x: cW - 80, y: cH - 80, w: 70, h: 70 }, - // TODO: change data: to null - answerButtons: [ - { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, - { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, - { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, - { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }, - ], - } - - button.answerButtons.forEach(function callback(value, index, array) { - if (index == 0) - array[index].y = area.answerButtons.y; - else - array[index].y = array[index - 1].y + value.h + 15; - }); - canvas.addEventListener('click', function(evt) { let mousePos = getMousePos(canvas, evt); - // bet inscrease - if (isInside(mousePos, button.info)) { - console.log("info"); - } + // if (isInside(mousePos, button.info)) { + // console.log("info"); + // } - // click by first answer button - if (isInside(mousePos, button.answerButtons[0])) { - clickAnswer(gameData, game, button.answerButtons[0].data); - } - - // click by second answer button - if (isInside(mousePos, button.answerButtons[1])) { - clickAnswer(gameData, game, button.answerButtons[1].data); - } - - // click by third answer button - if (isInside(mousePos, button.answerButtons[2])) { - clickAnswer(gameData, game, button.answerButtons[2].data); - } - - // click by four answer button - if (isInside(mousePos, button.answerButtons[3])) { - clickAnswer(gameData, game, button.answerButtons[3].data); + for (const [key, value] of Object.entries(buttons)) { + if (isInside(mousePos, value)) { + console.log(`click on ${key}`); + } } }, false); @@ -123,114 +88,138 @@ function gameLoop(timeStamp) { // Game update func ------------------------------------- function update() { - // Update answer buttons label - button.answerButtons.forEach(function callback(value, index) { - value.data = game.quest.answer[index]; - }); + // progressBar %percentage updater + // and set gameStateLoaded true + if (!game.loadedState && game.loadingProgress <= 99) { + // TODO: реализовать функционал проверки загрузки изображений and fonts + if (DEBUG) game.loadingProgress += 10; // FIXME: костыль + else game.loadingProgress += 1; + } + else if (game.loadingProgress == 100) + game.loadedState = true; + + if (game.loadedState && !game.finish) { + buttons.answerButton0 = { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }; + buttons.answerButton1 = { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }; + buttons.answerButton2 = { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }; + buttons.answerButton3 = { x: getCenterH(cW, cW / 1.5), y: 0, w: cW / 1.5, h: 50, data: null }; + + let answerButtonsArray = [buttons.answerButton0, buttons.answerButton1, + buttons.answerButton2, buttons.answerButton3]; + + answerButtonsArray.forEach(function callback(value, index, array) { + if (index == 0) + array[index].y = areas.btnAnswer.y; + else + array[index].y = array[index - 1].y + value.h + 15; + }); + + // Update answer buttons label + answerButtonsArray.forEach(function callback(value, index) { + value.data = gameData[game.currentQuest].answer[index]; + }); + } } // Draw to canvas func ---------------------------------- function draw() { - clearContext(canvas, config); // flush?! canvas + clearContext(canvas); // clean canvas - // draw question label - context.font = "32px Ubuntu"; - context.textAlign = "center"; - context.fillStyle = "white"; - context.fillText(game.quest.question, cW / 2, area.questionLabel.y + 30); - - // draw answer buttons - context.fillStyle = "purple"; - context.strokeStyle = "navy"; - context.lineWidth = 2; - - for (let i = 0; i <= button.answerButtons.length - 1; i++) { - context.fillRect(button.answerButtons[i].x, button.answerButtons[i].y, - button.answerButtons[i].w, button.answerButtons[i].h); - context.strokeRect(button.answerButtons[i].x, button.answerButtons[i].y, - button.answerButtons[i].w, button.answerButtons[i].h); - } - - // draw answer button label - context.font = "32px Ubuntu"; - context.textAlign = "center"; - context.fillStyle = "white"; - - button.answerButtons.forEach(function callback(value) { - context.fillText(value.data, cW / 2, value.y + 35); - }); - - // draw image - game.questImage = new Image(); - game.questImage.src = 'assets/images/' + game.quest.image; - - // carculate image ratio by area.image size - if (game.questImage.width >= game.questImage.height) { - if (game.questImage.height > area.image.h) { - let ratio = game.questImage.width / area.image.w; - let newImageW = area.image.w / ratio; - let newImageH = area.image.h; - - context.drawImage(game.questImage, getCenterH(cW, newImageW), area.image.y, - newImageW, newImageH); - } - else { - // TODO: draw image center - // TODO: add option to sizeUp images to engine config - } - } - else { - let ratio = game.questImage.height / area.image.h; - let newImageW = area.image.w / ratio; - - context.drawImage(game.questImage, getCenterH(cW, newImageW), area.image.y, - newImageW, area.image.h); - } - - // draw progress bar - let sizeProgressItem = area.questProgress.w / gameData.length; - - context.strokeStyle = "black"; - - for (let i = 0; i < gameData.length; i++) { - // change progress item color by status answer - switch (gameData[i].status) { - case null: - context.fillStyle = "gray"; - break; - case true: - context.fillStyle = "green"; - break; - case false: - context.fillStyle = "red"; - break; + // render splash screen ----------------------------- + if (!game.loadedState) { + // TODO: change if(! to NaN check + if (!game.loadingProgress) { + game.loadingProgress = 0; } - context.fillRect(10 + (i * sizeProgressItem), 10, sizeProgressItem, 20); - context.strokeRect(10 + (i * sizeProgressItem), 10, sizeProgressItem, 20); - } + context.drawImage(images.logo, getCenterH(cW, images.logo.width), getCenterV(cH, images.logo.height)); - // UI ------------------------------------------ - // TODO: переписать это всё г* - context.fillStyle = "red"; - context.strokeStyle = "navy"; - context.lineWidth = 2; - context.fillRect(button.info.x, button.info.y, button.info.w, button.info.h); // info button - context.strokeRect(button.info.x, button.info.y, button.info.w, button.info.h); // info button - context.fillRect(button.sfx.x, button.sfx.y, button.sfx.w, button.sfx.h); // sfx button - context.strokeRect(button.sfx.x, button.sfx.y, button.sfx.w, button.sfx.h); // sfx button - - // draw game areas - if (DEBUG) { - context.strokeStyle = "red"; + // TODO: check loadedState to final loading game + context.strokeStyle = "black"; context.lineWidth = 2; + context.fillStyle = "yellow"; + + // FIXME: translate to English + // если расстояние от нижнего края картинки до конца канваса меньше ??? + // то рисуем прогрессбар от нижнего края + // если больше, то на расстояние от картинки + let progressBarHeight = cH - (getCenterV(cH, images.logo.height) + images.logo.height) > 301 ? + getCenterV(cH, images.logo.height) + images.logo.height + 70 : cH - 70; + + context.fillRect(50, progressBarHeight, ((cW - 100) / 100 * game.loadingProgress), 20); + context.strokeRect(50, progressBarHeight, cW - 100, 20); + } + + // render game -------------------------------------- + if (!game.finish && game.loadedState) { + // draw progress bar + let sizeProgressItem = areas.questProgress.w / gameData.length; + + context.strokeStyle = "black"; + + for (let i = 0; i < gameData.length; i++) { + // change progress item color by status answer + switch (gameData[i].status) { + case null: + context.fillStyle = "gray"; + break; + case true: + context.fillStyle = "green"; + break; + case false: + context.fillStyle = "red"; + break; + } + + context.fillRect(10 + (i * sizeProgressItem), 10, sizeProgressItem, 20); + context.strokeRect(10 + (i * sizeProgressItem), 10, sizeProgressItem, 20); + } + + // draw question label + context.font = "32px Ubuntu"; + context.textAlign = "center"; + context.fillStyle = "white"; + context.fillText(gameData[game.currentQuest].question, cW / 2, areas.labelQuestion.y + 30); + + // draw answer buttons + context.fillStyle = "purple"; + context.strokeStyle = "navy"; + context.lineWidth = 2; + + let answerButtonsArray = [buttons.answerButton0, buttons.answerButton1, + buttons.answerButton2, buttons.answerButton3]; + + answerButtonsArray.forEach(function(btn) { + context.fillRect(btn.x, btn.y, btn.w, btn.h); + context.strokeRect(btn.x, btn.y, btn.w, btn.h); + }); + + // draw answer button label + context.font = "32px Ubuntu"; + context.textAlign = "center"; + context.fillStyle = "white"; + + answerButtonsArray.forEach(function callback(value) { + context.fillText(value.data, cW / 2, value.y + 35); + }); + } + + // render result game ------------------------------- + if (game.finish) { + // + } + + // draw game areas ---------------------------------- + if (DEBUG && !game.finish && game.loadedState) { + context.strokeStyle = "red"; + context.lineWidth = 1; // answer buttons area - if (orientation) + if (landscape_orientation) // TODO: draw answer buttons area by landscape console.log('TODO: draw answer buttons area by landscape'); else - for (const [key, value] of Object.entries(area)) { + for (const [key, value] of Object.entries(areas)) { context.strokeRect(value.x, value.y, value.w, value.h); } }