I have a working code of a 10 text questions' trivia game with a timer (html, javascript, css).
- How the questions can be served from a simple .txt file (so I can scale)?
- How the javascript can choose the questions in a random order, every time the games starts?
I have studied 1 to get an idea. However, my javascript coding skills are very limited. I would appreciate if you can point me to the right direction.
(function() {
const playButton = document.querySelector("#play");
const letsstartButton = document.querySelector("#lets-start");
const playagainButton = document.querySelector("#play-again");
const howToPlayButton = document.querySelector("#how-to-play-button");
const closeHowToButton = document.querySelector("#close-how-to");
const howToPlayScreen = document.querySelector(".how-to-play-screen");
const mainScreen = document.querySelector(".main-screen");
const triviaScreen = document.querySelector(".trivia-screen");
const resultScreen = document.querySelector(".result-screen");
playButton.addEventListener("click", startTrivia);
letsstartButton.addEventListener("click", startTrivia);
playagainButton.addEventListener("click", startTrivia);
howToPlayButton.addEventListener("click", function() {
howToPlayScreen.classList.remove("hidden");
mainScreen.classList.add("hidden");
});
closeHowToButton.addEventListener("click", function() {
howToPlayScreen.classList.add("hidden");
mainScreen.classList.remove("hidden");
});
const questionLength = 10;
let questionIndex = 0;
let score = 0;
let questions = [];
let timer = null;
function startTrivia() {
//show spinner
questionIndex = 0;
questions = [];
score = 0;
window.setTimeout(function() {
//get questions from server
mainScreen.classList.add("hidden");
howToPlayScreen.classList.add("hidden");
resultScreen.classList.add("hidden");
triviaScreen.classList.remove("hidden");
questions = [{
answers: ["Roma", "Athens", "London", "Japan"],
correct: "Roma",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma1", "Athens1", "London1", "Japan1"],
correct: "Athens1",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma2", "Athens2", "London2", "Japan2"],
correct: "London2",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma3", "Athens3", "London3", "Japan3"],
correct: "London3",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma4", "Athens4", "London4", "Japan4"],
correct: "Athens4",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma5", "Athens5", "London5", "Japan5"],
correct: "Athens5",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma6", "Athens6", "London6", "Japan6"],
correct: "Roma6",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma7", "Athens7", "London7", "Japan7"],
correct: "Japan7",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma8", "Athens8", "London8", "Japan8"],
correct: "London8",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma9", "Athens9", "London9", "Japan9"],
correct: "Japan9",
text: "YOUR TEXT HERE."
}
];
const questionCount = document.getElementById("question-count");
questionCount.innerHTML = questionLength.toString();
displayNextQuestion();
}, 50);
}
const isTriviaCompleted = function() {
return questionLength === questionIndex;
};
function displayNextQuestion() {
const answersContainer = document.getElementById("answers-container");
const answerButtons = answersContainer.querySelectorAll(".default-button");
answerButtons.forEach(function(element) {
element.disabled = false;
element.classList.remove("correct");
element.classList.remove("wrong");
});
if (isTriviaCompleted()) {
showScores();
} else {
startProgressbar();
timer = window.setTimeout(function() {
guess(null);
}, 10000);
setQuizText("This is from");
const textElement = document.getElementById("question-placement");
textElement.innerHTML = questions[questionIndex].text;
const choices = questions[questionIndex].answers;
for (let i = 0; i < choices.length; i ) {
const element = document.getElementById(`answer${i}`);
element.innerHTML = choices[i];
element.addEventListener("click", handleAnswerClick);
}
showProgress();
}
}
function handleAnswerClick(e) {
const el = e.currentTarget;
const answer = el.innerHTML;
el.removeEventListener("click", handleAnswerClick);
guess(answer);
}
function showProgress() {
const questionIndexElement = document.getElementById("question-index");
const index = questionIndex 1;
questionIndexElement.innerHTML = index.toString();
}
function guess(answer) {
clearTimeout(timer);
const answersContainer = document.getElementById("answers-container");
const answerButtons = answersContainer.querySelectorAll(".default-button");
answerButtons.forEach((element) => {
element.disabled = true;
if (element.innerHTML === questions[questionIndex].correct) {
element.classList.add("correct");
}
});
stopProgressbar();
if (questions[questionIndex].correct === answer) { // correct answer
score ;
setQuizText("Fantastic … Correct!");
} else if (answer) { // incorrect answer
setQuizText("Nice try … You were close.");
answerButtons.forEach((element) => {
if (element.innerHTML === answer) {
element.classList.add("wrong");
}
});
} else {
setQuizText("Your time is out! Oh no!");
}
questionIndex ;
window.setTimeout(function() {
displayNextQuestion();
}, 2500);
}
function setQuizText(text) {
const el = document.getElementById("trivia-text");
el.innerHTML = text;
}
function showScores() {
const scoreElement = document.getElementById("score");
const scoreTotalElement = document.getElementById("score-total");
const scoreNameElement = document.getElementById("score-name");
scoreElement.innerHTML = score.toString();
scoreTotalElement.innerHTML = questionLength.toString();
if (score < 4) {
scoreNameElement.innerHTML = "Newbie";
} else if (score < 7) {
scoreNameElement.innerHTML = "Rookie";
} else if (score < 10) {
scoreNameElement.innerHTML = "Expert";
} else {
scoreNameElement.innerHTML = "Grandmaster";
}
triviaScreen.classList.add("hidden");
resultScreen.classList.remove("hidden");
}
function startProgressbar() {
// select div turn into progressbar
const progressbar = document.getElementById("progress-bar");
progressbar.innerHTML = "";
// create div changes width show progress
const progressbarInner = document.createElement("span");
// Append progressbar to main progressbardiv
progressbar.appendChild(progressbarInner);
// When all set start animation
progressbarInner.style.animationPlayState = "running";
}
function stopProgressbar() {
const progressbar = document.getElementById("progress-bar");
const progressbarInner = progressbar.querySelector("span");
progressbarInner.style.animationPlayState = "paused";
}
}());
*,
*:after,
*:before {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Verdana', cursive;
text-transform: uppercase;
color: #ccc;
letter-spacing: 2px;
}
.container {
background: #999999;
}
.wrapper {
max-width: 800px;
margin: auto;
}
.screen-section {
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
padding: 20px 20px 70px;
position: relative;
}
.hidden {
display: none;
}
.trivia-screen-step {
color: #ccc;
}
.trivia-image-wrapper {
max-width: 100%;
margin: 50px auto;
position: relative;
}
.trivia-image {
max-width: 100%;
width: 300px;
position: relative;
z-index: 1;
}
.trivia-timer {
width: 550px;
max-width: 100%;
height: 20px;
border-radius: 3em;
margin-bottom: 50px;
padding: 5px 6px;
}
.trivia-timer span {
display: inline-block;
background: linear-gradient(90deg, #fff, #06c);
height: 10px;
vertical-align: top;
border-radius: 3em;
animation: progressbar-countdown;
animation-duration: 10s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
animation-play-state: paused;
animation-timing-function: linear;
}
@keyframes progressbar-countdown {
0% {
width: 100%;
}
100% {
width: 0%;
}
}
.trivia-question {
margin-bottom: 50px;
}
.how-to-play-screen .default-button {
margin-bottom: 60px;
margin-top: 30px;
}
.button-container {
display: flex;
flex-wrap: wrap;
margin-bottom: 50px;
width: 600px;
max-width: 100%;
}
.button-outer {
flex-basis: 100%;
text-align: center;
margin-bottom: 20px;
max-width: 100%;
}
.default-button {
background: #333333;
border-radius: 3em;
font-family: 'Verdana', cursive;
font-size: 18px;
color: #fff;
letter-spacing: 2.45px;
padding: 10px 8px;
text-transform: uppercase;
transition: background .2s;
outline: none;
width: 250px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.default-button:hover {
background: #222;
}
.default-button[disabled] {
background: transparent;
color: #222;
cursor: default;
}
.default-button[disabled]:hover {
background: transparent;
}
.default-button.correct {
cursor: default;
background: #2bb24a;
color: #fff;
}
.default-button.correct:hover {
background: #2bb24a;
color: #fff;
}
.default-button.wrong {
cursor: default;
background: #F6484C;
color: #fff;
}
.default-button.wrong:hover {
background: #F6484C;
color: #fff;
}
.title {
font-size: 32px;
margin-top: 100px;
}
.text {
line-height: 24px;
font-size: 16px;
font-family: 'Verdana', sans-serif;
text-align: center;
color: #ffffff;
text-transform: none;
}
.trivia-logo {
position: absolute;
bottom: 20px;
}
.trivia-corner-logo {
position: absolute;
left: 0;
top: 15px;
width: 100px;
}
.close-button {
position: absolute;
top: 50px;
right: 0;
background: transparent;
border: none;
color: #fff;
font-family: 'Verdana', cursive;
font-size: 34px;
outline: none;
text-transform: none;
cursor: pointer;
transition: color .2s;
}
.close-button:hover {
color: #eee;
}
.score-name {
margin: 0 0 28px;
font-size: 46px;
}
.score {
font-size: 18px;
margin-bottom: 10px;
}
.description {
text-align: center;
font-family: Verdana, sans-serif;
font-size: 16px;
color: #fff;
text-transform: none;
line-height: 24px;
display: inline-block;
margin-bottom: 30px;
}
@media screen and (min-width: 700px) {
.screen-section {
padding: 50px;
}
<div >
<div >
<div >
<div >
<img alt="LOGO" src="./assets/Game-Logo.png" >
</div>
<h1>Trivia</h1>
<div >
<div >
<button id="play" type="button">Play</button>
</div>
<div >
<button id="how-to-play-button" type="button">How to play?</button>
</div>
</div>
<div >
<img alt="logo" src="./assets/-Logo.png">
</div>
</div>
<div >
<img alt="LOGO" src="./assets/Game-Logo.png" >
<button id="close-how-to" type="button">X</button>
<h2 >How to Play</h2>
<p>Answer questions to score points.</p>
<button id="lets-start" type="button">Ok. Let's start</button>
<div >
<img alt="logo" src="./assets/-Logo.png">
</div>
</div>
<div >
<div ><span id="question-index">1</span> out of <span id="question-count">10</span></div>
<div >
<p id="question-placement"></p>
</div>
<div id="progress-bar"></div>
<div id="trivia-text"></div>
<div id="answers-container">
<div >
<button id="answer0" type="button"></button>
</div>
<div >
<button id="answer1" type="button"></button>
</div>
<div >
<button id="answer2" type="button"></button>
</div>
<div >
<button id="answer3" type="button"></button>
</div>
</div>
<div >
<img alt="logo" src="./assets/-Logo.png">
</div>
</div>
<div >
<div >
<img alt="Trivia LOGO" src="./assets/Game-Logo.png" >
</div>
<p ><span id="score">0</span> out of <span id="score-total">10</span></p>
<h1 id="score-name">Trivia</h1>
<span >you will learn more.</span>
<button id="play-again" type="button">Play again</button>
<div >
<img alt=" logo" src="./assets/-Logo.png">
</div>
</div>
</div>
</div>
CodePudding user response:
In your case the best way would be to create an API (for example https://fastapi.tiangolo.com/) that would return a random question, but if you want to have it in a separate file you would simply have to move the variable questions
to another javascript file and import it into the <head>
of your web page.
To randomize the JSON you can use the following function:
function shuffleQuestions(questions) {
for (let i = questions.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i 1));
[questions[i], questions[j]] = [questions[j], questions[i]];
}
}
(function() {
const playButton = document.querySelector("#play");
const letsstartButton = document.querySelector("#lets-start");
const playagainButton = document.querySelector("#play-again");
const howToPlayButton = document.querySelector("#how-to-play-button");
const closeHowToButton = document.querySelector("#close-how-to");
const howToPlayScreen = document.querySelector(".how-to-play-screen");
const mainScreen = document.querySelector(".main-screen");
const triviaScreen = document.querySelector(".trivia-screen");
const resultScreen = document.querySelector(".result-screen");
playButton.addEventListener("click", startTrivia);
letsstartButton.addEventListener("click", startTrivia);
playagainButton.addEventListener("click", startTrivia);
howToPlayButton.addEventListener("click", function() {
howToPlayScreen.classList.remove("hidden");
mainScreen.classList.add("hidden");
});
closeHowToButton.addEventListener("click", function() {
howToPlayScreen.classList.add("hidden");
mainScreen.classList.remove("hidden");
});
const questionLength = 10;
let questionIndex = 0;
let score = 0;
let questions = [];
let timer = null;
function startTrivia() {
//show spinner
questionIndex = 0;
questions = [];
score = 0;
window.setTimeout(function() {
//get questions from server
mainScreen.classList.add("hidden");
howToPlayScreen.classList.add("hidden");
resultScreen.classList.add("hidden");
triviaScreen.classList.remove("hidden");
questions = [{
answers: ["Roma", "Athens", "London", "Japan"],
correct: "Roma",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma1", "Athens1", "London1", "Japan1"],
correct: "Athens1",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma2", "Athens2", "London2", "Japan2"],
correct: "London2",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma3", "Athens3", "London3", "Japan3"],
correct: "London3",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma4", "Athens4", "London4", "Japan4"],
correct: "Athens4",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma5", "Athens5", "London5", "Japan5"],
correct: "Athens5",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma6", "Athens6", "London6", "Japan6"],
correct: "Roma6",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma7", "Athens7", "London7", "Japan7"],
correct: "Japan7",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma8", "Athens8", "London8", "Japan8"],
correct: "London8",
text: "YOUR TEXT HERE."
},
{
answers: ["Roma9", "Athens9", "London9", "Japan9"],
correct: "Japan9",
text: "YOUR TEXT HERE."
}
];
shuffleQuestions(questions);
const questionCount = document.getElementById("question-count");
questionCount.innerHTML = questionLength.toString();
displayNextQuestion();
}, 50);
}
const isTriviaCompleted = function() {
return questionLength === questionIndex;
};
function displayNextQuestion() {
const answersContainer = document.getElementById("answers-container");
const answerButtons = answersContainer.querySelectorAll(".default-button");
answerButtons.forEach(function(element) {
element.disabled = false;
element.classList.remove("correct");
element.classList.remove("wrong");
});
if (isTriviaCompleted()) {
showScores();
} else {
startProgressbar();
timer = window.setTimeout(function() {
guess(null);
}, 10000);
setQuizText("This is from");
const textElement = document.getElementById("question-placement");
textElement.innerHTML = questions[questionIndex].text;
const choices = questions[questionIndex].answers;
for (let i = 0; i < choices.length; i ) {
const element = document.getElementById(`answer${i}`);
element.innerHTML = choices[i];
element.addEventListener("click", handleAnswerClick);
}
showProgress();
}
}
function handleAnswerClick(e) {
const el = e.currentTarget;
const answer = el.innerHTML;
el.removeEventListener("click", handleAnswerClick);
guess(answer);
}
function showProgress() {
const questionIndexElement = document.getElementById("question-index");
const index = questionIndex 1;
questionIndexElement.innerHTML = index.toString();
}
function guess(answer) {
clearTimeout(timer);
const answersContainer = document.getElementById("answers-container");
const answerButtons = answersContainer.querySelectorAll(".default-button");
answerButtons.forEach((element) => {
element.disabled = true;
if (element.innerHTML === questions[questionIndex].correct) {
element.classList.add("correct");
}
});
stopProgressbar();
if (questions[questionIndex].correct === answer) { // correct answer
score ;
setQuizText("Fantastic … Correct!");
} else if (answer) { // incorrect answer
setQuizText("Nice try … You were close.");
answerButtons.forEach((element) => {
if (element.innerHTML === answer) {
element.classList.add("wrong");
}
});
} else {
setQuizText("Your time is out! Oh no!");
}
questionIndex ;
window.setTimeout(function() {
displayNextQuestion();
}, 2500);
}
function setQuizText(text) {
const el = document.getElementById("trivia-text");
el.innerHTML = text;
}
function showScores() {
const scoreElement = document.getElementById("score");
const scoreTotalElement = document.getElementById("score-total");
const scoreNameElement = document.getElementById("score-name");
scoreElement.innerHTML = score.toString();
scoreTotalElement.innerHTML = questionLength.toString();
if (score < 4) {
scoreNameElement.innerHTML = "Newbie";
} else if (score < 7) {
scoreNameElement.innerHTML = "Rookie";
} else if (score < 10) {
scoreNameElement.innerHTML = "Expert";
} else {
scoreNameElement.innerHTML = "Grandmaster";
}
triviaScreen.classList.add("hidden");
resultScreen.classList.remove("hidden");
}
function startProgressbar() {
// select div turn into progressbar
const progressbar = document.getElementById("progress-bar");
progressbar.innerHTML = "";
// create div changes width show progress
const progressbarInner = document.createElement("span");
// Append progressbar to main progressbardiv
progressbar.appendChild(progressbarInner);
// When all set start animation
progressbarInner.style.animationPlayState = "running";
}
function stopProgressbar() {
const progressbar = document.getElementById("progress-bar");
const progressbarInner = progressbar.querySelector("span");
progressbarInner.style.animationPlayState = "paused";
}
function shuffleQuestions(questions) {
for (let i = questions.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i 1));
[questions[i], questions[j]] = [questions[j], questions[i]];
}
}
}());
*,
*:after,
*:before {
box-sizing: border-box;
}
body {
margin: 0;
font-family: 'Verdana', cursive;
text-transform: uppercase;
color: #ccc;
letter-spacing: 2px;
}
.container {
background: #999999;
}
.wrapper {
max-width: 800px;
margin: auto;
}
.screen-section {
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
padding: 20px 20px 70px;
position: relative;
}
.hidden {
display: none;
}
.trivia-screen-step {
color: #ccc;
}
.trivia-image-wrapper {
max-width: 100%;
margin: 50px auto;
position: relative;
}
.trivia-image {
max-width: 100%;
width: 300px;
position: relative;
z-index: 1;
}
.trivia-timer {
width: 550px;
max-width: 100%;
height: 20px;
border-radius: 3em;
margin-bottom: 50px;
padding: 5px 6px;
}
.trivia-timer span {
display: inline-block;
background: linear-gradient(90deg, #fff, #06c);
height: 10px;
vertical-align: top;
border-radius: 3em;
animation: progressbar-countdown;
animation-duration: 10s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
animation-play-state: paused;
animation-timing-function: linear;
}
@keyframes progressbar-countdown {
0% {
width: 100%;
}
100% {
width: 0%;
}
}
.trivia-question {
margin-bottom: 50px;
}
.how-to-play-screen .default-button {
margin-bottom: 60px;
margin-top: 30px;
}
.button-container {
display: flex;
flex-wrap: wrap;
margin-bottom: 50px;
width: 600px;
max-width: 100%;
}
.button-outer {
flex-basis: 100%;
text-align: center;
margin-bottom: 20px;
max-width: 100%;
}
.default-button {
background: #333333;
border-radius: 3em;
font-family: 'Verdana', cursive;
font-size: 18px;
color: #fff;
letter-spacing: 2.45px;
padding: 10px 8px;
text-transform: uppercase;
transition: background .2s;
outline: none;
width: 250px;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.default-button:hover {
background: #222;
}
.default-button[disabled] {
background: transparent;
color: #222;
cursor: default;
}
.default-button[disabled]:hover {
background: transparent;
}
.default-button.correct {
cursor: default;
background: #2bb24a;
color: #fff;
}
.default-button.correct:hover {
background: #2bb24a;
color: #fff;
}
.default-button.wrong {
cursor: default;
background: #F6484C;
color: #fff;
}
.default-button.wrong:hover {
background: #F6484C;
color: #fff;
}
.title {
font-size: 32px;
margin-top: 100px;
}
.text {
line-height: 24px;
font-size: 16px;
font-family: 'Verdana', sans-serif;
text-align: center;
color: #ffffff;
text-transform: none;
}
.trivia-logo {
position: absolute;
bottom: 20px;
}
.trivia-corner-logo {
position: absolute;
left: 0;
top: 15px;
width: 100px;
}
.close-button {
position: absolute;
top: 50px;
right: 0;
background: transparent;
border: none;
color: #fff;
font-family: 'Verdana', cursive;
font-size: 34px;
outline: none;
text-transform: none;
cursor: pointer;
transition: color .2s;
}
.close-button:hover {
color: #eee;
}
.score-name {
margin: 0 0 28px;
font-size: 46px;
}
.score {
font-size: 18px;
margin-bottom: 10px;
}
.description {
text-align: center;
font-family: Verdana, sans-serif;
font-size: 16px;
color: #fff;
text-transform: none;
line-height: 24px;
display: inline-block;
margin-bottom: 30px;
}
@media screen and (min-width: 700px) {
.screen-section {
padding: 50px;
}
<div >
<div >
<div >
<div >
<img alt="LOGO" src="./assets/Game-Logo.png" >
</div>
<h1>Trivia</h1>
<div >
<div >
<button id="play" type="button">Play</button>
</div>
<div >
<button id="how-to-play-button" type="button">How to play?</button>
</div>
</div>
<div >
<img alt="logo" src="./assets/-Logo.png">
</div>
</div>
<div >
<img alt="LOGO" src="./assets/Game-Logo.png" >
<button id="close-how-to" type="button">X</button>
<h2 >How to Play</h2>
<p>Answer questions to score points.</p>
<button id="lets-start" type="button">Ok. Let's start</button>
<div >
<img alt="logo" src="./assets/-Logo.png">
</div>
</div>
<div >
<div ><span id="question-index">1</span> out of <span id="question-count">10</span></div>
<div >
<p id="question-placement"></p>
</div>
<div id="progress-bar"></div>
<div id="trivia-text"></div>
<div id="answers-container">
<div >
<button id="answer0" type="button"></button>
</div>
<div >
<button id="answer1" type="button"></button>
</div>
<div >
<button id="answer2" type="button"></button>
</div>
<div >
<button id="answer3" type="button"></button>
</div>
</div>
<div >
<img alt="logo" src="./assets/-Logo.png">
</div>
</div>
<div >
<div >
<img alt="Trivia LOGO" src="./assets/Game-Logo.png" >
</div>
<p ><span id="score">0</span> out of <span id="score-total">10</span></p>
<h1 id="score-name">Trivia</h1>
<span >you will learn more.</span>
<button id="play-again" type="button">Play again</button>
<div >
<img alt=" logo" src="./assets/-Logo.png">
</div>
</div>
</div>
</div>