Guess The Song by Team 11 is a musical quiz designed for the Code Institute November 2020 Hackathon "Hackathon Hero". Listen to the music clip, type your answer, try to get as many questions as possible right before you loose all 3 of your lives.
A consistent style was maintained throughout using CSS root variables
:root {
/* --background: #f79808; */
--background: #0f7988;
--buttoncolor: #2b78e4;
--textcolor: #eeffdd;
--bordercolor: #000;
--iconcolor: #4D4D4D;
}
The main functionality is provided by a JSON file. This utilises the song ID and the Spotify API to serve the song file directly from Spotify to the HTML page:
let checkSong = () => {
// currentSong.id = 3
fetch(`https://kareoke.p.rapidapi.com/v1/song/spotify?id=${currentSong.id}`)
.then((jsonData) => jsonData.json())
.then((data) => songExists(data));
};
Functionality is included to check that the song ID is still valid before fetching from Spotify, if invalid it moves onto the next ID in the JSON file:
const songExists = (song) => {
if (song.msg === `We couldn't find a data with this id`) {
getSong();
}
};
Javascript validation prevents a null value being entered for the Username value. The player is given feedback that this cannot be left blank.
Whitespace is handled efficiently so that only spaces before and after are stripped away:
//get username
userName = document.getElementById("user-name").value;
// remove white space before and after
userName = userName.replace(/^\s+|\s+$/gm, "");
The option to select song genres was included to give the game more functionality. This is handled by categorising within the JSON file.
As an extra feature, the background of the game screen changes with the selected category.
let main = document.getElementById("game-background");
if (genre === "Rock") {
main.style.backgroundImage = "url('assets/images/drummer.jpg')";
} else if (genre === "Pop") {
main.style.backgroundImage = "url('assets/images/disco-ball.jpg')";
} else if (genre === "Country") {
main.style.backgroundImage = "url('assets/images/guitar.jpg')";
}
To keep the game flowing and improve the user experience, a countdown timer was added to each question. This is displayed on screen so it is clear to see how much time is left to answer the question. Colours on the timer change as your time runs out.
function setRemainingPathColor(timeLeft) {
const { alert, warning, info } = COLOR_CODES;
if (timeLeft <= alert.threshold) {
document
.getElementById("base-timer-path-remaining")
.classList.remove(warning.color);
document
.getElementById("base-timer-path-remaining")
.classList.add(alert.color);
} else if (timeLeft <= warning.threshold) {
document
.getElementById("base-timer-path-remaining")
.classList.remove(info.color);
document
.getElementById("base-timer-path-remaining")
.classList.add(warning.color);
}
}
To account for differing input of answers and special characters contained in the answer strings, some validation is included before comparing the input with the correct answer. This compares both fully lower case strings, and ignores any special characters.
// Strip special characters from answers
const stripAns = answer.replace(/[^a-z0-9]/gi, "").toLowerCase();
let actualAns = currentSong.title.toLowerCase();
actualAns = actualAns.replace(/[^a-z0-9]/gi, "");
When a question is answered correctly, an extra modal pops up allowing the player to answer a bonus question for extra points.
document.getElementById("base-timer-label").innerText = "01:00";
let header = document.querySelector("header");
let bonus = document.createElement("div");
bonus.setAttribute("id", "bonus");
document.body.insertBefore(bonus, header);
let bonusLevel = `
<div id="overlay">
<div class="modal">
<h2>Bonus Question</h2>
<h3>When did <span>${artist}</span> released <span>${title}</span>?</h3>
<div class="button-container">
<button class="bonus-btn">${addAPossibleYear(possible_dates)}</button>
<button class="bonus-btn">${addAPossibleYear(possible_dates)}</button>
<button class="bonus-btn">${addAPossibleYear(possible_dates)}</button>
<button class="bonus-btn">${addAPossibleYear(possible_dates)}</button>
</div>
<div id="bonus-timer"><span>${formatTime(bonusCount)}</span></div>
</div>
</div>`;
bonus.innerHTML = bonusLevel;
Players have 3 lives, these are lost by running out of time or submitting an incorrect answer. Lives lost are displayed visually on screen for players as the game progresses.
const removeLife = () => {
livesLeft -= 1;
let lives = document.getElementsByClassName("life");
if (livesLeft === 2) {
lives[1].src = `assets/images/skull-red.svg`;
} else if (livesLeft == 1) {
lives[2].src = `assets/images/skull-red.svg`;
} else {
window.location.href = "scoreboard.html";
}
Points scored are higher the quicker you answer the question, with bonus points available for correctly answered bonus questions.
const incrementScore = (score) => {
let currentScore = parseInt(document.getElementById("score").innerHTML);
//ads 50 points per question + one second per extra second
currentScore += 50 + score;
document.getElementById("score").innerHTML = currentScore;
localStorage.score = currentScore;
};
Throughout the game, your score is shown and updated on screen within the question box.
The site was deployed to GitHub pages. The steps to deploy are as follows:
The live link can be found here
In order to make a local copy of this project, you can clone it. In your IDE Terminal, type the following command to clone my repository:
git clone https://github.com/Daisy-McG/Guess-The-Song.git
Alternatively, if using Gitpod, you can click below to create your own workspace using this repository.
All files passed through official JS validator:
modal.js
score.js
game.js
All files passed through official CSS validator:
All files passed through official HTML validator:
The game has been tested and played in :
Image of rock band on main game screen taken from - PixaBay
Scoreboard background image from PixaBay
Pop genre background image taken from - Pexels
Rock genre background image taken from - Pexels
Initial game background image taken from - Pexels
Favicon from this Font Awesome project
No Cheating - Console log styling taken from Stack Overflow post, inspired by facebook