├── end.html
├── end.js
├── game.css
├── game.html
├── game.js
├── highscores.css
├── highscores.html
├── highscores.js
├── index.html
└── style.css
/end.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Document
7 |
8 |
9 |
10 |
11 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/end.js:
--------------------------------------------------------------------------------
1 | const username = document.querySelector('#username')
2 | const saveScoreBtn = document.querySelector('#saveScoreBtn')
3 | const finalScore = document.querySelector('#finalScore')
4 | const mostRecentScore = localStorage.getItem('mostRecentScore')
5 |
6 | const highScores = JSON.parse(localStorage.getItem('highScores')) || []
7 |
8 | const MAX_HIGH_SCORES = 5
9 |
10 | finalScore.innerText = mostRecentScore
11 |
12 | username.addEventListener('keyup', () => {
13 | saveScoreBtn.disabled = !username.value
14 | })
15 |
16 | saveHighScore = e => {
17 | e.preventDefault()
18 |
19 | const score = {
20 | score: mostRecentScore,
21 | name: username.value
22 | }
23 |
24 | highScores.push(score)
25 |
26 | highScores.sort((a,b) => {
27 | return b.score - a.score
28 | })
29 |
30 | highScores.splice(5)
31 |
32 | localStorage.setItem('highScores', JSON.stringify(highScores))
33 | window.location.assign('/')
34 |
35 |
36 | }
--------------------------------------------------------------------------------
/game.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #fff;
3 | }
4 |
5 | .choice-container {
6 | display: flex;
7 | margin-bottom: 0.8rem;
8 | width: 100%;
9 | border-radius: 4px;
10 | background: rgb(18, 93, 255);
11 | font-size: 3rem;
12 | min-width: 80rem;
13 | }
14 |
15 | .choice-container:hover {
16 | cursor: pointer;
17 | box-shadow: 0 0.4rem 1.4rem 0 rgba(6, 103, 247, 0.5);
18 | transform: scale(1.02);
19 | transform: transform 100ms;
20 | }
21 |
22 | .choice-prefix {
23 | padding: 2rem 2.5rem;
24 | color: white;
25 | }
26 |
27 | .choice-text {
28 | padding: 2rem;
29 | width: 100%;
30 | }
31 |
32 | .correct {
33 | background: linear-gradient(32deg, rgba(11, 223, 36) 0%, rgb(41, 232, 111) 100%);
34 | }
35 |
36 | .incorrect {
37 | background: linear-gradient(32deg, rgba(230, 29, 29, 1) 0%, rgb(224, 11, 11, 1) 100%);
38 | }
39 |
40 | /* Heads up Display */
41 | #hud {
42 | display: flex;
43 | justify-content: space-between;
44 | }
45 |
46 | .hud-prefix {
47 | text-align: center;
48 | font-size: 2rem;
49 | }
50 |
51 | .hud-main-text {
52 | text-align: center;
53 | }
54 |
55 | #progressBar {
56 | width: 20rem;
57 | height: 3rem;
58 | border: 0.2rem solid rgb(11,223,36);
59 | margin-top: 2rem;
60 | border-radius: 50px;
61 | overflow: hidden;
62 | }
63 |
64 | #progressBarFull {
65 | height: 100%;
66 | background: rgb(11,223,36);
67 | width: 0%;
68 | }
69 |
70 | @media screen and (max-width: 768px) {
71 | .choice-container {
72 | min-width: 40rem;
73 | }
74 | }
--------------------------------------------------------------------------------
/game.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Quiz Page
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Question
17 |
18 |
21 |
22 |
23 |
24 | Score
25 |
26 |
27 | 0
28 |
29 |
30 |
31 |
What is the answer to this question
32 |
36 |
37 |
B
38 |
Choice 2
39 |
40 |
41 |
C
42 |
Choice 3
43 |
44 |
45 |
D
46 |
Choice 4
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/game.js:
--------------------------------------------------------------------------------
1 | const question = document.querySelector('#question');
2 | const choices = Array.from(document.querySelectorAll('.choice-text'));
3 | const progressText = document.querySelector('#progressText');
4 | const scoreText = document.querySelector('#score');
5 | const progressBarFull = document.querySelector('#progressBarFull');
6 |
7 | let currentQuestion = {}
8 | let acceptingAnswers = true
9 | let score = 0
10 | let questionCounter = 0
11 | let availableQuestions = []
12 |
13 | let questions = [
14 | {
15 | question: 'What is 2 + 2?',
16 | choice1: '2',
17 | choice2: '4',
18 | choice3: '21',
19 | choice4: '17',
20 | answer: 2,
21 | },
22 | {
23 | question:
24 | "The tallest building in the world is located in which city?",
25 | choice1: "Dubai",
26 | choice2: "New York",
27 | choice3: "Shanghai",
28 | choice4: "None of the above",
29 | answer: 1,
30 | },
31 | {
32 | question: "What percent of American adults believe that chocolate milk comes from brown cows?",
33 | choice1: "20%",
34 | choice2: "18%",
35 | choice3: "7%",
36 | choice4: "33%",
37 | answer: 3,
38 | },
39 | {
40 | question: "Approximately what percent of U.S. power outages are caused by squirrels?",
41 | choice1: "10-20%",
42 | choice2: "5-10%",
43 | choice3: "15-20%",
44 | choice4: "30%-40%",
45 | answer: 1,
46 | }
47 | ]
48 |
49 | const SCORE_POINTS = 100
50 | const MAX_QUESTIONS = 4
51 |
52 | startGame = () => {
53 | questionCounter = 0
54 | score = 0
55 | availableQuestions = [...questions]
56 | getNewQuestion()
57 | }
58 |
59 | getNewQuestion = () => {
60 | if(availableQuestions.length === 0 || questionCounter > MAX_QUESTIONS) {
61 | localStorage.setItem('mostRecentScore', score)
62 |
63 | return window.location.assign('/end.html')
64 | }
65 |
66 | questionCounter++
67 | progressText.innerText = `Question ${questionCounter} of ${MAX_QUESTIONS}`
68 | progressBarFull.style.width = `${(questionCounter/MAX_QUESTIONS) * 100}%`
69 |
70 | const questionsIndex = Math.floor(Math.random() * availableQuestions.length)
71 | currentQuestion = availableQuestions[questionsIndex]
72 | question.innerText = currentQuestion.question
73 |
74 | choices.forEach(choice => {
75 | const number = choice.dataset['number']
76 | choice.innerText = currentQuestion['choice' + number]
77 | })
78 |
79 | availableQuestions.splice(questionsIndex, 1)
80 |
81 | acceptingAnswers = true
82 | }
83 |
84 | choices.forEach(choice => {
85 | choice.addEventListener('click', e => {
86 | if(!acceptingAnswers) return
87 |
88 | acceptingAnswers = false
89 | const selectedChoice = e.target
90 | const selectedAnswer = selectedChoice.dataset['number']
91 |
92 | let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect'
93 |
94 | if(classToApply === 'correct') {
95 | incrementScore(SCORE_POINTS)
96 | }
97 |
98 | selectedChoice.parentElement.classList.add(classToApply)
99 |
100 | setTimeout(() => {
101 | selectedChoice.parentElement.classList.remove(classToApply)
102 | getNewQuestion()
103 |
104 | }, 1000)
105 | })
106 | })
107 |
108 | incrementScore = num => {
109 | score +=num
110 | scoreText.innerText = score
111 | }
112 |
113 | startGame()
--------------------------------------------------------------------------------
/highscores.css:
--------------------------------------------------------------------------------
1 | body {
2 | color: #fff;
3 | }
4 |
5 | #highScoresList {
6 | list-style: none;
7 | margin-bottom: 4rem;
8 | }
9 |
10 | .high-score {
11 | font-size: 2.8rem;
12 | margin-bottom: 0.5rem;
13 | }
--------------------------------------------------------------------------------
/highscores.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | High Scores
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
Leaderboard
15 |
16 |
Go Home
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/highscores.js:
--------------------------------------------------------------------------------
1 | const highScoresList = document.querySelector('#highScoresList')
2 | const highScores = JSON.parse(localStorage.getItem("highScores")) || []
3 |
4 | highScoresList.innerHTML =
5 | highScores.map(score => {
6 | return `${score.name} - ${score.score}`
7 | }).join("")
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Home page
7 |
8 |
9 |
10 |
11 |
18 |
19 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Nova+Square&display=swap');
2 |
3 | :root {
4 | background-color: rgb(29, 26, 26)
5 | }
6 |
7 | * {
8 | box-sizing: border-box;
9 | margin: 0;
10 | padding: 0;
11 | font-size: 62.5%;
12 | font-family: 'Nova Square', cursive;
13 | }
14 |
15 | h1 {
16 | font-size: 5.4rem;
17 | color: #fff;
18 | margin-bottom: 5rem;
19 | }
20 |
21 |
22 |
23 | h2 {
24 | font-size: 4.2rem;
25 | margin-bottom: 4rem;
26 |
27 | }
28 |
29 | .container {
30 | width: 100vw;
31 | height: 100vh;
32 | display: flex;
33 | justify-content: center;
34 | align-items: center;
35 | max-width: 80rem;
36 | margin: 0 auto;
37 | padding: 2rem;
38 | }
39 |
40 | .flex-column {
41 | display: flex;
42 | flex-direction: column;
43 | }
44 |
45 | .flex-center {
46 | justify-content: center;
47 | align-items: center;
48 | }
49 |
50 | .justify-center {
51 | justify-content: center;
52 | }
53 |
54 | .text-center {
55 | text-align: center;
56 | }
57 |
58 | .hidden {
59 | display: none;
60 | }
61 |
62 | .btn {
63 | font-size: 2.4rem;
64 | padding: 2rem 0;
65 | width: 30rem;
66 | text-align: center;
67 | margin-bottom: 1rem;
68 | text-decoration: none;
69 | color: rgb(28, 26, 26);
70 | background: linear-gradient(90deg, rgb(18, 92, 255) 0%, rgb(0, 102, 255) 100%);
71 | border-radius: 4px;
72 | }
73 |
74 | .btn:hover {
75 | cursor: pointer;
76 | box-shadow: 0 0.4rem 1.4rem 0 rgba(8, 114, 244, 0.6);
77 | transition: transform 150ms;
78 | transform: scale(1.03);
79 | }
80 |
81 | .btn[disabled]:hover {
82 | cursor: not-allowed;
83 | box-shadow: none;
84 | transform: none;
85 | }
86 |
87 | #highscore-btn {
88 | background: linear-gradient(90deg, rgb(255, 247, 9) 0%, rgb(240, 221, 6) 100%);
89 | }
90 |
91 | #highscore-btn:hover {
92 | box-shadow: 0 0.4rem 1.4rem 0 rgba(255,255,0,0.5)
93 | }
94 |
95 | .fa-crown {
96 | font-size: 2.5rem;
97 | margin-left: 1rem;
98 | }
99 |
100 | /* End Page CSS */
101 | .end-form-container {
102 | width: 100%;
103 | display: flex;
104 | flex-direction: column;
105 | align-items: center;
106 | max-width: 30rem;
107 | }
108 |
109 | input {
110 | margin-bottom: 1rem;
111 | width: 20rem;
112 | padding: 1.5rem;
113 | font-size: 1.8rem;
114 | border: none;
115 | box-shadow: 0 0.1rem 1.4rem 0 rgba(86, 185, 235, 0.5);
116 | }
117 |
118 | input::placeholder {
119 | color: #aaa;
120 | }
121 |
122 | #username {
123 | margin-bottom: 3rem;
124 | width: 100%;
125 | outline: none;
126 | }
127 |
128 | #end-text {
129 | font-size: 2.4rem;
130 | color: #fff;
131 | text-align: center;
132 | }
133 |
134 | #saveScoreBtn {
135 | border: none;
136 | }
137 |
138 | .fa-home {
139 | margin-left: 1rem;
140 | font-size: 2rem;
141 | color: rgb(28, 26, 26)
142 | }
--------------------------------------------------------------------------------