Skip to content

Commit 2ef788e

Browse files
authored
Game App
Game app with HTML, CSS and JavaScript. The questions are fetched through api
1 parent bcf48f8 commit 2ef788e

11 files changed

+833
-0
lines changed

end.js

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
const username = document.getElementById('username');
2+
const saveScoreBtn = document.getElementById('saveScoreBtn');
3+
const finalScore = document.getElementById('finalScore');
4+
const mostRecentScore = localStorage.getItem('mostRecentScore');
5+
6+
7+
8+
const highScores = JSON.parse(localStorage.getItem("highScores")) || [];
9+
10+
const MAX_HIGH_SCORES = 20;
11+
12+
13+
finalScore.innerText = mostRecentScore;
14+
15+
username.addEventListener("keyup", () => {
16+
console.log(username.value);
17+
saveScoreBtn.disabled = !username.value
18+
});
19+
20+
21+
saveHighScore = (e) => {
22+
console.log(e)
23+
e.preventDefault();
24+
25+
26+
const score = {
27+
score: Math.floor(Math.random() * 100),
28+
name: username.value
29+
};
30+
highScores.push(score);
31+
highScores.sort((a, b) => b.score - a.score);
32+
highScores.splice(20);
33+
localStorage.setItem("highScores", JSON.stringify(highScores));
34+
window.location.assign("index.html");
35+
36+
};

gamepage.css

+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
* {
2+
box-sizing: border-box;
3+
margin: 0;
4+
padding: 0;
5+
}
6+
7+
body {
8+
9+
background-color: rgb(202, 235, 197);
10+
font-family: Work Sans, sans-serif, Arial, Helvetica, sans-serif;
11+
}
12+
13+
/* Quiz Title */
14+
.mytitle {
15+
padding-top: 1.5rem;
16+
padding-bottom: 3rem;
17+
text-align: center;
18+
font-size: 3rem;
19+
color: rgb(88, 85, 85);
20+
}
21+
22+
/* Container */
23+
24+
.container {
25+
display: flex;
26+
justify-self: center;
27+
justify-content: center;
28+
align-items: center;
29+
width: 60%;
30+
margin: 0 auto;
31+
background: rgb(151, 209, 185);
32+
border-radius: 7px;
33+
padding-bottom: 1rem;
34+
padding-top: 1rem;
35+
box-shadow: 3px 3px 1px 2px rgba(102, 96, 96, 0.32);
36+
-webkit-box-shadow: 3px 3px 1px 2px rgba(102, 96, 96, 0.32);
37+
-moz-box-shadow: 3px 3px 1px 2px rgba(102, 96, 96, 0.32);
38+
}
39+
40+
/* HUD */
41+
42+
#hud {
43+
display: flex;
44+
justify-content: space-around;
45+
font-size: 1.5rem;
46+
color: rgb(100, 117, 126);
47+
48+
}
49+
50+
.justify-center {
51+
justify-content: center;
52+
flex-direction: column;
53+
}
54+
55+
.question {
56+
justify-self: center;
57+
text-align: center;
58+
margin: 0 auto;
59+
max-width: 50%;
60+
}
61+
62+
.choice-container {
63+
margin-bottom: 1rem;
64+
display: flex;
65+
justify-self: center;
66+
align-items: center;
67+
max-width: 100%;
68+
font-size: 1.5rem;
69+
border-top-left-radius: 7px;
70+
border-bottom-left-radius: 7px;
71+
border: none;
72+
background-color: #fff;
73+
}
74+
75+
.choice-container:hover {
76+
cursor: pointer;
77+
transform: translateY(-0.1rem);
78+
transition: transform 150ms;
79+
border-top-left-radius: 7px;
80+
border-bottom-left-radius: 7px;
81+
}
82+
83+
.choice-prefix {
84+
background: #146356;
85+
margin-right: 1.8rem;
86+
width: 3rem;
87+
border: none;
88+
border-radius: 7px;
89+
font-size: 2rem;
90+
color: rgb(100, 117, 126);
91+
}
92+
93+
.choice-prefix:hover {
94+
background-color: rgb(100, 117, 126);
95+
color: #fff;
96+
}
97+
98+
.choice-text {
99+
color: rgb(100, 117, 126);
100+
font-size: 1.8rem;
101+
}
102+
103+
.btn {
104+
margin: 0 auto;
105+
color: #fff;
106+
font-size: 1.5rem;
107+
background: rgb(100, 117, 126);
108+
border-radius: 5px;
109+
border: none;
110+
padding: 0.7rem 20rem;
111+
text-align: center;
112+
text-decoration: none;
113+
}
114+
115+
.correct {
116+
background-color: #28a745;
117+
}
118+
119+
.incorrect {
120+
background-color: #dc3545;
121+
}
122+
123+
/* LOADER */
124+
125+
#loader {
126+
position: absolute;
127+
border: 1.6rem solid #fff;
128+
border-radius: 50%;
129+
border-top: 1.6rem solid #56a5eb;
130+
width: 12rem;
131+
height: 12rem;
132+
animation: spin 2s linear infinite;
133+
}
134+
135+
@keyframes spin {
136+
0% {
137+
transform: rotate(0deg);
138+
}
139+
140+
100% {
141+
transform: rotate(360deg)
142+
}
143+
}

gamepage.html

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"
9+
integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
10+
<!-- <link rel="stylesheet" href="vanillaquiz.css"> -->
11+
<link rel="stylesheet" href="gamepage.css">
12+
<title>Game Page</title>
13+
</head>
14+
15+
<body>
16+
<p class="mytitle"> Vanilla Quiz</p>
17+
<div class="container">
18+
<!-- <div id="loader" class=""></div> -->
19+
<div id="game" class="justify-center flex-column hidden">
20+
21+
<div id="hud">
22+
23+
<div id="hud-item">
24+
<p class="hud-prefix">
25+
Question
26+
</p>
27+
<h1 class="hud-main-text" id="questionCounter">
28+
29+
</h1>
30+
</div>
31+
<div id="hud-item">
32+
<p class="hud-prefix">
33+
Score
34+
</p>
35+
<h1 class="hud-main-text" id="score">
36+
0
37+
</h1>
38+
</div>
39+
</div>
40+
<h3 class="question" id="question"></h3>
41+
<div class="choice-container">
42+
<button class="choice-prefix">A</button>
43+
<p class="choice-text" data-number="1"></p>
44+
</div>
45+
<div class="choice-container">
46+
<button class="choice-prefix">B</button>
47+
<p class="choice-text" data-number="2"></p>
48+
</div>
49+
<div class="choice-container">
50+
<button class="choice-prefix">C</button>
51+
<p class="choice-text" data-number="3"></p>
52+
</div>
53+
<div class="choice-container">
54+
<button class="choice-prefix">D</button>
55+
<p class="choice-text" data-number="4"></p>
56+
</div>
57+
<a href="gamescore.html" class="btn" id="saveScoreBtn">Submit</a>
58+
</div>
59+
</div>
60+
<a id="scroll-up" class="secondary-color" style="display: inline;">
61+
<i class="fa fa-angle-up"></i>
62+
</a>
63+
<script src="gamepage.js"></script>
64+
</body>
65+
66+
</html>

gamepage.js

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
const question = document.getElementById("question");
2+
const choices = Array.from(document.getElementsByClassName("choice-text"));
3+
const questionCounterText = document.getElementById('questionCounter');
4+
const loader = document.getElementById("loader");
5+
const game = document.getElementById("game");
6+
const scoreText = document.getElementById('score');
7+
let difficulty = localStorage.getItem('difficulty') || 'easy';
8+
let numQuestions = localStorage.getItem('numQuestions') || 10;
9+
10+
function setDifficulty(difficultyLevel) {
11+
difficulty = difficultyLevel;
12+
}
13+
14+
document.querySelectorAll('.radiobtn').forEach(difficultyRadio => {
15+
difficultyRadio.addEventListener('change', (e) => {
16+
difficulty = e.target.dataset.difficulty;
17+
18+
})
19+
})
20+
21+
console.log({ difficulty }, localStorage.getItem('difficulty'))
22+
23+
let currentQuestion = {};
24+
let acceptingAnswers = false;
25+
let score = 0;
26+
let questionCounter = 0;
27+
let availableQuestions = [];
28+
let questions = [];
29+
30+
function startQuiz() {
31+
32+
}
33+
34+
fetch(`https://opentdb.com/api.php?amount=${numQuestions}&category=9&difficulty=${difficulty}&type=multiple`)
35+
.then(res => {
36+
return res.json();
37+
})
38+
.then(({ results }) => {
39+
console.log(results);
40+
questions = results.map(loadedQuestion => {
41+
const formattedQuestion = {
42+
question: loadedQuestion.question
43+
};
44+
45+
const answerChoices = [...loadedQuestion.incorrect_answers];
46+
formattedQuestion.answer = Math.floor(Math.random() * 3) + 1;
47+
answerChoices.splice(
48+
formattedQuestion.answer - 1, 0, loadedQuestion.correct_answer
49+
);
50+
51+
answerChoices.forEach((choice, index) => {
52+
formattedQuestion["choice" + (index + 1)] = choice;
53+
});
54+
return formattedQuestion;
55+
});
56+
57+
58+
startGame()
59+
// questions = loadedQuestions;
60+
// startGame();
61+
})
62+
63+
64+
.catch(err => {
65+
console.error(err);
66+
});
67+
68+
69+
//CONSTANTS//
70+
const CORRECT_BONUS = 10;
71+
const MAX_QUESTIONS = numQuestions;
72+
console.log(questions);
73+
74+
startGame = () => {
75+
questionCounter = 0;
76+
score = 0;
77+
questionCounter = 0;
78+
availableQuestions = [...questions];
79+
getNewQuestion();
80+
game.classList.remove("hidden");
81+
loader.classList.add("hidden");
82+
83+
};
84+
getNewQuestion = () => {
85+
if (availableQuestions.length === 0 || questionCounter >= MAX_QUESTIONS) {
86+
localStorage.setItem("mostRecentScore", score);
87+
88+
//go to the end page
89+
return window.location.assign('gamescore.html');
90+
}
91+
questionCounter++;
92+
93+
// questionCounterText.innerText = questionCounter + "/" + MAX_QUESTIONS;
94+
questionCounterText.innerText = `${questionCounter} /${availableQuestions.length}`;
95+
96+
const questionIndex = Math.floor(Math.random() * availableQuestions.length);
97+
currentQuestion = availableQuestions[questionIndex];
98+
question.innerHTML = currentQuestion.question;
99+
100+
choices.forEach(choice => {
101+
const number = choice.dataset['number'];
102+
choice.innerHTML = currentQuestion['choice' + number];
103+
});
104+
105+
availableQuestions.splice(questionIndex, 1);
106+
acceptingAnswers = true;
107+
};
108+
109+
choices.forEach(choice => {
110+
choice.addEventListener('click', e => {
111+
if (!acceptingAnswers) return;
112+
acceptingAnswers = false;
113+
const selectedChoice = e.target;
114+
const selectedAnswer = selectedChoice.dataset['number'];
115+
116+
//class to apply after selection
117+
// const classToApply = 'incorrect';
118+
// if (selectedAnswer == currentQuestion.answer) {
119+
// classToApply = 'correct';
120+
// }
121+
//Another way to do this is with tenary operator
122+
const classToApply = selectedAnswer == currentQuestion.answer ? "correct" : "incorrect";
123+
if (classToApply === "correct") {
124+
incrementScore(CORRECT_BONUS)
125+
}
126+
selectedChoice.parentElement.classList.add(classToApply);
127+
setTimeout(() => {
128+
selectedChoice.parentElement.classList.remove(classToApply);
129+
getNewQuestion();
130+
}, 1000);
131+
132+
});
133+
134+
})
135+
incrementScore = num => {
136+
score += num;
137+
scoreText.innerText = score;
138+
}
139+
140+

0 commit comments

Comments
 (0)