Making a RGB Colour Guessing Game in JavaScript – Part 2
In the first post in the making the colour guessing game we left off with a functional game and the last thing that we needed to do was neaten the page up (style the page etc) and add a bit more functionality (like a reset button or the difficulty button).
You can see a working example of where we’re currently at by visiting this link. Similarly, if you’d like to catch up on how we got to this point then it may be a good idea to read the part 1 (visit Making a RGB Colour Guessing Game in JavaScript – Part 1) of this 2 post exercise.
The first thing that can be done is to add some functionality that resets the colours. In the web development lesson that I’m following, this is going to be done via a link in the “navigation” menu of the app. We’ve already created a div (with an “id” of message) that displays some text to the user based on their choice.
<div id="navMenu">
<button id="reset">Reset Colours</button>
<span id="message"></span>
</div>
This new reset option is going to go in the same place. The way it works is; if it is the end of the game the text will display “play again” but if the game is still going and the player wants to reset the game the button will say “Reset Colours”. This was implemented using the following code.
reset.addEventListener("click", function(){
// Generate 6 new random colours
colours = randomColours(6);
// Choose new winning colour
colourPicked = pickColour();
// Change the display message to contain new colour
winningColour.textContent = colourPicked;
// Assign the 6 new colours to the squares
for(var i=0 ; i<colours.length ; i++){
squares[i].style.backgroundColor = colours[i];
}
h1.style.backgroundColor = "#232323";
reset.textContent = "Reset Colours";
});
The message in the reset button needed to be changed (as it kept saying “play again” once it had appeared) as well as the background of the h1 tag (the winning colour persisted when the game was reset).
The next phase is to add the two buttons that control the difficulty of the game (decides whether we’re trying to guess between 3 or 6 squares) and was done by firstly adding the buttons to the HTML document.
<div id="navMenu">
<button id="reset">Reset Colours</button>
<span id="message"></span>
<button id="easy">Easy</button>
<button id="hard">Hard</button>
</div>
Which gives us the following:
Now we want the button to be “active” depending on where the user is situated (looking at 3 or 6 squares) and we do that by creating a class and then toggling the class on and off. For now the class was just set to have a background colour of blue.
.active {
background: blue;
}
The buttons were selected so that event listeners could be setup
var easyButton = document.querySelector("#easy");
var hardButton = document.querySelector("#hard");
Each of the respective event listeners added a class to the correct button and removed it from the other.
easyButton.addEventListener("click", function () {
easyButton.classList.add("active");
hardButton.classList.remove("active");
});
hardButton.addEventListener("click", function () {
hardButton.classList.add("active");
easyButton.classList.remove("active");
});
You can see what this has done up to this point by taking a look at the current version of the game which you can see by visiting this link. As you can see, the two buttons are there and the styling is working they just look horrendous and don’t actually do anything.
When the page loads up the setting is automatically set to “hard” and the page loads 6 squares so what needs to be done is, when the user clicks on the “easy” button, the game just needs to be reset, only this time containing 3 squares (and when the user clicks “hard” the game resets with 6 squares etc). We’re not deleting the squares from the game when we do this, we’re just hiding them.
When the easy button is pressed the event listener was adapted to include the following which changed to include the same functionality as in the code we wrote earlier to reset the game.
colours = randomColours(3);
colourPicked = pickColour();
winningColour.textContent = colourPicked;
for(var i=0 ; i<squares.length ; i++){
squares[i].style.backgroundColor = colours[i];
if (i > 2) {
squares[i].style.display = "none";
}
}
The solution given in the course I am following was slightly different to mine in that their if statement was a little more succinct than mine (as shown below).
for(var i=0 ; i<squares.length ; i++){
if (squares[i]) {
squares[i].style.backgroundColor = colours[i];
} else {
squares[i].style.display = "none";
}
When the “hard” button is pressed again the same needs to happen only this time the colours array needs to have 6 items in it and the last 3 squares need to have the display = none element removed to show the 6 blocks again.
colours = randomColours(6);
colourPicked = pickColour();
winningColour.textContent = colourPicked;
for(var i=0 ; i<squares.length ; i++){
squares[i].style.backgroundColor = colours[i];
if (squares[i].style.display === "none"){
squares[i].style.display = "block";
}
squares[i].style.backgroundColor = colours[i];
}
Click here to see what the game looks like after I made those changes.
There is one more bug in the game at the moment however and that is if you set the game to only have 3 squares (easy mode) and then reset the game, one of the last 3 squares (that aren’t shown on the page) might be the winning colour and that is because when we reset the program the program creates a new array of 6.
To fix this we need to create a variable that keeps track of what “mode” the game is in so that the reset button knows how many colours to create. To do this a new variable called “number” was created and initialised to 6 initially. Then when the user clicks on easy this number was changed to 3. That essentially hept track of how many squares were supposed to be shown on the page and in all of the locations where either the number 6 or the number 3 was hard coded, the number was simply replaced with the new “number” variable.
To see the really ugly version of the completed (in terms of functionality and not style) then visit this link here. I think that is a good place to leave it. This is going to turn into a 3 Part series as I now begin to take this game from looking like it is, to how it’s supposed to look as shown below from a screenshot of the web development course I’m doing.