Hands-on Project: Color Game
August 21, 2018
Overview
In this project, we will create a Color Guess Game from scratch using Javascript. The objective of the game is to guess colors given in the RGB format.
Project Goals
- Learn about using DOM manipulation in Javascript.
- Become familiar with Event Handling and functions.
- Get to know the RGB Color Model.
Our final project will look like this:
An RGB color value is displayed on top, i.e. RGB(213, 213, 40) here. The player has to guess which of the six colors is represented by that value. If you click on a wrong color, the circle will fade out and a “Try Again” message will be shown. If you guess the correct answer, background of all the circles including the header will change to the color of the correct circle. When you click the NEW COLORS button, the game will reset and new colors will be shown to you.
File Structure
For this project we will have only 3 files:
- index.html
- app.js
- app.css
Set up HTML file
We will start by creating the HTML template for our project in index.html.
You probably know HTML from our Learn HTML & CSS course. If not, you can go and learn the basics of HTML and CSS here. We have linked our app.css file in the <head></head>
and our app.js javascript file at the bottom of body in the <script>
tag.
This is the HTML file :
<html>
<head>
<title>Color Game</title>
<link rel="stylesheet" type="text/css" href="app.css">
</head>
<body onload="initialize();">
<h1>The Great <br><span id="colorDisplay">RGB</span><br> Color Game</h1>
<div id="stripe">
<button id="reset">NEW colors</button>
<span id="message"></span>
</div>
<div id="container">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
You may have noticed the line onload=”initialize();”
in the body tag. We will define the initialize()
function later in the Javascript section. When you try to open your index.html file, your website should look something like this :
Set up CSS file
Now we will make our HTML look a little prettier by adding some CSS to it. We have added a few comments about the elements to which the properties are applied.
/*Asterisk means the properties apply to all the elements*/
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: white;
font-family: Lato;
font-weight: 300;
color: #555;
}
/*Wrapper is the white colored div*/
.wrapper {
max-width: 1000px;
width: 80%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
box-shadow: 0px 10px 50px rgba(0, 0, 0, 0.3);
}
/*These are the small 6 colors which will be displayed*/
.circle{
width: 22%;
padding-bottom: 22%;
background: purple;
float: left;
margin: 5.66%;
margin-top: 2%;
border-radius: 50%;
transition: background 0.6s;
}
#container{
max-width: 600px;
margin: 60px auto;
}
/*This h1 is the title of the game*/
h1{
font-weight: 300;
color: white;
margin: 0;
text-align: center;
line-height: 1.1;
background: #EB4D4D;
text-transform: uppercase;
padding: 20px 0;
}
/*This is the RGB contained in h1*/
#colorDisplay{
font-size: 170%;
text-transform: uppercase;
}
/*This is the try again or correct message*/
#message{
margin: 10px auto;
display: block;
min-width: 150px;
width: 20%;
}
#stripe{
padding: 20px 0;
height: 30px;
text-align: center;
}
/*This the new colors button*/
button {
color: #555;
background: none;
border: 1px solid #EB4D4D;
padding: 10px;
border-radius: 5px;
font-family: Lato;
font-size: 20px;
text-transform: uppercase;
cursor: pointer;
font-weight: 300;
transition: background-color 0.3s, color 0.3s;
}
button:hover { font-weight: 600; }
button:focus { outline: none; }
After adding this css to your app.css file, your project should look like this:
Looks pretty good? Wait for till our game comes alive in the next few steps!
Plan out the Javascript file
Now we will add some functionality to our project using Javascript to make it work as we want.
We will break the requirements of this project further and think of what we have to do next.
- Generate 6 random colors for the circles
- Change the background of circles to these colors
- Add event listeners to circles and the New Colors button
- Pick a solution color
- Make a winning state
Generate Random Colors
First, we want to generate some random colors so that we can put them into our 6 circles. The RGB color model is an additive color model in which red, green and blue light are added together in various ways to produce a broad array of colors. The name of the model comes from the initials of the three additive primary colors, Red, Green, and Blue. There are 3 values in the RGB model, and they range from 0 to 255. For eg., rgb(255, 0, 0) is the full red color whereas rgb(0, 255, 0) is the full green color and rgb(0, 0, 255) is the full blue color. You can play with the values and choose any color by the combination of changing these three values.
Next, let’s create a function to generate a random RGB color:
//generateRandom Color is for generating a RGB random color
function generateRandomColor(){
var r = Math.floor((Math.random()) * 255);
var g = Math.floor((Math.random()) * 255);
var b = Math.floor((Math.random()) * 255);
return ("rgb("+r+", "+g+", "+b+")");
}
Here we have made a function which returns a color string. An example output would be rgb(34, 56, 67) .
Here, we have used Javascript’s Math library which contains all the Math functions like sqrt, abs, floor, random etc. Math.random()
function returns a value from 0 to 1. So if we multiply it by 255, we can get value between 0 to 255. But the value will be of float type (could be a number like 235.33), so we need to get its floor to convert it into an integer (so 235 in the 235.33 example) using the Math.floor()
function. Strings are concatenated using the + sign, so finally we concatenate all the colors in rgb format and return it so that we can use it later.
Next, let’s look at some of the variables we will be using for our project.
Variables
var colors = [],
keyColor,
colorDisplay = document.querySelector("#colorDisplay"),
msg = document.querySelector("#message"),
reset = document.querySelector("#reset"),
h1 = document.querySelector("h1"),
circles = document.querySelectorAll(".circle");
First, we declare a colors array which is empty, followed by a few other variables that select various elements by id (colorDisplay, msg, reset) or tag (h1). We have declared a variable named circles which selects all the elements with the circle class. All the selected elements (divs in our example) are stored in form of an array in circles variable. So you can access any circle with the index number, for eg if you see circles[2]
element, it will be the 3rd div of our HTML. Other variables are as follows :
keyColor
: This variable will hold the color which will be the solutioncolorDisplay
: This is the DOM element which displays the keyColor in rgb format inside h1msg
: This is the DOM element which will display a message like “Try Again” or “Correct”reset
: This is the “New Colors” buttonh1
: This the h1 tag inside our HTML
Change background color of circles
//circlesColor function is for giving background colors to the circles
function circlesColor(){
colors = [];
reset.textContent = "new colors";
h1.style.background = " #EB4D4D";
reset.style.borderColor = "#EB4D4D";
msg.textContent = "";
for(var i=0; i<circles.length; i++)
colors.push(generateRandomColor());
pickKeyColor();
}
In the code above, we set the colors array to be empty again even though we declared it empty in the first place because. If we generate 6 colors and store them inside the array and the user has played the game once and wants to play again, we can’t use same colors. Thus, we have to set the colors array to be empty here. Next we set the text content of the NEW COLORS
button to NEW COLORS
because we will display it as PLAY AGAIN
after a win. So we need to change it to NEW COLORS
every time a new game is initialized. We also set the background of h1
to initial color because when a user wins we are going to change that color to the keyColor
. Similarly the message can be “Try Again” or “Correct” depending on if the user has given a wrong answer or won, so we need to change it to empty because we are initializing the game. We have a loop which will run 6 times and generate random colors and push them inside our colors
array. Finally, we also select a solution color which will be done by our pickKeyColor
function which we will implement next.
Pick a solution color
//pickKeyColor function pick one random color for solution from the 6 circles
function pickKeyColor(){
var numCircles = circles.length;
var keyColorIndex = Math.floor((Math.random()) * numCircles);
keyColor = colors[keyColorIndex];
colorDisplay.textContent = keyColor;
}
As you can see we just pick a random number from 0 to 5 as they are indexes of colors in the colors
array. Since we have the picked color, we can change the text content of the colorDisplay
inside h1 to the keyColor.
Add event listeners to circles
//circlesListen is for adding event listeners to the circles
function circlesListen(){
for(var i=0; i<circles.length; i++){
circles[i].style.background = colors[i];
circles[i].addEventListener("click", function() {
if(this.style.background === keyColor) winningState();
else {
this.style.background = "white";
msg.textContent = "Try Again";
}
});
};
}
We loop through each circle and change their background each to a color from colors
array. We also add a “click” event listener so that when a user clicks it will check if the color of the circle on which user has clicked is same as the keyColor
. If it is the same, a winningState
function will be called which we will create shortly. If the colors don’t match, we will change the clicked circle to white background color and show “Try Again” in the message content.
Winning state
//winningState function changes the background of h1 and all the circles
function winningState(){
for(var i=0; i<circles.length; i++)
circles[i].style.background = keyColor;
h1.style.background = keyColor;
msg.textContent = "Correct!";
reset.textContent = "Play Again?";
reset.style.borderColor = keyColor;
}
For the winning state, we loop through each circle and change their background each to the keyColor
. We also change background of the h1
tag and border color of the NEW COLORS button to the keyColor
. We change the textContent of the message to “Correct!” and “NEW COLORS” to “Play Again”.
Miscellaneous
reset.addEventListener("click", initialize);
//We will call this function as soon as the body of HTML loads
function initialize(){
circlesColor();
circlesListen();
}
For the NEW COLORS button to work, we have to add an event listener to it. We have wrapped up the circlesColor() and CirclesListen() functions inside a function named initialize(). If you recall, this is the function that we had kept inside the body tag (onload=”initialize();”). Every time user reloads the page or clicks on the NEW COLORS button, this function will be invoked.
Putting it all together
Our project is now complete and your app.js file should look like this :
var colors = [];
//Colors array holds the 6 random colors
var keyColor;
//keyColor is the solution to the rgb color
var colorDisplay = document.querySelector("#colorDisplay");
//colorDisplay is the variable selecting the one secret color to display in h1 tag
var msg = document.querySelector("#message");
//msg is the variable selecting the message id element for showing messages like try again etc.
var reset = document.querySelector("#reset");
//reset is the NEW COLORS button
var h1 = document.querySelector("h1");
//h1 is the heading
var circles = document.querySelectorAll(".circle");
// circles will be an array holding the 6 circles
//add an event listener to NEW COLORS button
reset.addEventListener("click", initialize);
//We will call this function as soon as the body of HTML loads
function initialize(){
circlesColor();
circlesListen();
}
//circlesColor function is for giving background colors to the circles
function circlesColor(){
colors = [];
reset.textContent = "new colors";
h1.style.background = " #EB4D4D";
reset.style.borderColor = "#EB4D4D";
msg.textContent = "";
for(var i=0; i<circles.length; i++)
colors.push(generateRandomColor());
pickKeyColor();
}
//circlesListen is for adding event listeners to the circles
function circlesListen(){
/*Loop for all 6 circles to change their background colors and add event Listeners*/
for(var i=0; i<circles.length; i++){
circles[i].style.background = colors[i];
circles[i].addEventListener("click", function() {
if(this.style.background === keyColor)
winningState(); //Adding a condition for winning State
else {
this.style.background = "white";
msg.textContent = "Try Again";
}
});
};
}
//winningState function changes the background of h1 and all the circles
function winningState(){
//Loop for setting the background of all circles to keyColor
for(var i=0; i<circles.length; i++)
circles[i].style.background = keyColor;
h1.style.background = keyColor;
msg.textContent = "Correct!";
reset.textContent = "Play Again?";
reset.style.borderColor = keyColor;
}
//pickKeyColor function pick one random color for solution from the 6 circles
function pickKeyColor(){
var numCircles = circles.length; //numCircles will be 6
var keyColorIndex = Math.floor((Math.random()) * numCircles);
//We get a number from 0 to 5 at random
keyColor = colors[keyColorIndex];
colorDisplay.textContent = keyColor;
}
//generateRandom Color is for generating a RGB random color
function generateRandomColor(){
var r = Math.floor((Math.random()) * 255);
var g = Math.floor((Math.random()) * 255);
var b = Math.floor((Math.random()) * 255);
return ("rgb("+r+", "+g+", "+b+")");
}
Open index.html
in your browser, and the game should work as expected.