How to Create the Simon Game with JavaScript
The Simon game is a classic memory game where the player must repeat a growing sequence of colors and sounds. It‘s a great exercise for sharpening your memory and concentration skills, and it‘s also a fun project for learning web development. In this tutorial, we‘ll create the Simon game using HTML, CSS, and JavaScript.
Game Overview
Here are the basic rules of the Simon game:
-
The game shows the first color in the sequence (e.g. blue). The player must click on the blue button.
-
The game shows the next color (e.g. red), the player must remember the sequence is blue, red and click the buttons in that order.
-
The game continues showing new colors and the player must remember and repeat the whole sequence.
-
If the player messes up the sequence, the game is over. The player can click a button to start over.
Building the Interface
We‘ll start by creating the HTML for the game interface. We need four colored buttons for the player to click on, and a couple other buttons to start and reset the game.
<div class="simon">
<div class="button green"></div>
<div class="button red"></div>
<div class="button yellow"></div>
<div class="button blue"></div>
<div class="controls">
<div class="display"></div>
<button class="start">Start</button>
<button class="reset">Reset</button>
</div>
</div>
We‘ll style this with some CSS to layout the buttons in a circle and make them light up when clicked or played by the game:
.simon {
position: relative;
width: 400px;
height: 400px;
}
.button {
width: 200px;
height: 200px;
position: absolute;
opacity: 0.5;
}
.button.green {
background: green;
top: 0;
left: 0;
border-top-left-radius: 100%;
}
.button.red {
background: red;
top: 0;
right: 0;
border-top-right-radius: 100%;
}
.button.blue {
background: blue;
bottom: 0;
right: 0;
border-bottom-right-radius: 100%;
}
.button.yellow {
background: yellow;
bottom: 0;
left: 0;
border-bottom-left-radius: 100%;
}
.button.lit {
opacity: 1;
}
.display {
width: 50px;
height: 30px;
background: #ccc;
margin: 10px auto;
text-align: center;
line-height: 30px;
}
JavaScript Code Walkthrough
Now for the fun part – making the game actually work with JavaScript. Let‘s start by defining some variables to store the game state:
// Track the sequence of colors
let sequence = [];
// Track the player‘s position in the sequence
let position = 0;
// Get the colored buttons
const buttons = document.querySelectorAll(‘.button‘);
// Get the display and control buttons
const display = document.querySelector(‘.display‘);
const startButton = document.querySelector(‘.start‘);
const resetButton = document.querySelector(‘.reset‘);
Next we‘ll create functions to control the game play – playing the sequence, lighting up buttons, and checking the player‘s answers:
// Play the sequence up to the current position
function playSequence() {
let i = 0;
let timer = setInterval(() => {
lightButton(sequence[i]);
i++;
if (i >= sequence.length) {
clearInterval(timer);
}
}, 500);
display.textContent = sequence.length;
}
// Light up a button and play its sound
function lightButton(color) {
const button = document.querySelector(`.button.${color}`);
const sound = document.querySelector(`[data-sound="${color}"]`);
button.classList.add(‘lit‘);
sound.play();
setTimeout(() => {
button.classList.remove(‘lit‘);
}, 300);
}
// Check the player‘s answer against the sequence
function checkAnswer(color) {
if (color !== sequence[position]) {
// Wrong answer, end the game
endGame();
return;
}
position++;
if (position >= sequence.length) {
// Sequence completed, advance to next level after a delay
position = 0;
setTimeout(() => {
nextLevel();
}, 1000);
}
}
// Add a new color to the sequence and play it back
function nextLevel() {
const colors = [‘green‘, ‘red‘, ‘blue‘, ‘yellow‘];
const color = colors[Math.floor(Math.random() * 4)];
sequence.push(color);
playSequence();
}
// Game over, reset everything
function endGame() {
sequence = [];
position = 0;
display.textContent = ‘END!‘;
setTimeout(() => {
display.textContent = ‘--‘;
}, 1000);
}
Finally, we‘ll hook up the buttons to start the game and handle the player‘s input:
// Let the player click on colored buttons
buttons.forEach(button => {
button.addEventListener(‘click‘, () => {
const color = button.getAttribute(‘data-color‘);
checkAnswer(color);
});
});
// Start the game
startButton.addEventListener(‘click‘, () => {
nextLevel();
});
// Reset the game
resetButton.addEventListener(‘click‘, () => {
endGame();
});
Putting It All Together
Here‘s the complete code for our Simon game:
<div class="simon">
<div class="button green" data-color="green"></div>
<div class="button red" data-color="red"></div>
<div class="button yellow" data-color="yellow"></div>
<div class="button blue" data-color="blue"></div>
<div class="controls">
<div class="display"></div>
<button class="start">Start</button>
<button class="reset">Reset</button>
</div>
</div>
<audio data-sound="green" src="sounds/green.mp3"></audio>
<audio data-sound="red" src="sounds/red.mp3"></audio>
<audio data-sound="yellow" src="sounds/yellow.mp3"></audio>
<audio data-sound="blue" src="sounds/blue.mp3"></audio>
.simon {
position: relative;
width: 400px;
height: 400px;
}
.button {
width: 200px;
height: 200px;
position: absolute;
opacity: 0.5;
}
.button.green {
background: green;
top: 0;
left: 0;
border-top-left-radius: 100%;
}
.button.red {
background: red;
top: 0;
right: 0;
border-top-right-radius: 100%;
}
.button.blue {
background: blue;
bottom: 0;
right: 0;
border-bottom-right-radius: 100%;
}
.button.yellow {
background: yellow;
bottom: 0;
left: 0;
border-bottom-left-radius: 100%;
}
.button.lit {
opacity: 1;
}
.display {
width: 50px;
height: 30px;
background: #ccc;
margin: 10px auto;
text-align: center;
line-height: 30px;
}
let sequence = [];
let position = 0;
const buttons = document.querySelectorAll(‘.button‘);
const display = document.querySelector(‘.display‘);
const startButton = document.querySelector(‘.start‘);
const resetButton = document.querySelector(‘.reset‘);
function playSequence() {
let i = 0;
let timer = setInterval(() => {
lightButton(sequence[i]);
i++;
if (i >= sequence.length) {
clearInterval(timer);
}
}, 500);
display.textContent = sequence.length;
}
function lightButton(color) {
const button = document.querySelector(`.button.${color}`);
const sound = document.querySelector(`[data-sound="${color}"]`);
button.classList.add(‘lit‘);
sound.play();
setTimeout(() => {
button.classList.remove(‘lit‘);
}, 300);
}
function checkAnswer(color) {
if (color !== sequence[position]) {
endGame();
return;
}
position++;
if (position >= sequence.length) {
position = 0;
setTimeout(() => {
nextLevel();
}, 1000);
}
}
function nextLevel() {
const colors = [‘green‘, ‘red‘, ‘blue‘, ‘yellow‘];
const color = colors[Math.floor(Math.random() * 4)];
sequence.push(color);
playSequence();
}
function endGame() {
sequence = [];
position = 0;
display.textContent = ‘END!‘;
setTimeout(() => {
display.textContent = ‘--‘;
}, 1000);
}
buttons.forEach(button => {
button.addEventListener(‘click‘, () => {
const color = button.getAttribute(‘data-color‘);
checkAnswer(color);
});
});
startButton.addEventListener(‘click‘, () => {
nextLevel();
});
resetButton.addEventListener(‘click‘, () => {
endGame();
});
You can see a live demo of the completed game on CodePen.
Next Steps
Congratulations, you‘ve built a working Simon game with JavaScript! This is an impressive project for a beginner and there are many ways you can extend it:
- Add more colors and sounds to increase the difficulty
- Keep track of high scores using local storage
- Improve the design and animations
- Turn it into a real-time multiplayer game by integrating with a backend
Be sure to check out these other resources to continue your JavaScript learning journey:
- freeCodeCamp‘s JavaScript Algorithms and Data Structures Certification
- Eloquent JavaScript, a free online book
- JavaScript30, 30 fun vanilla JS projects
- Code Tetris with JavaScript on the freeCodeCamp.org YouTube channel
Thanks for following along with this tutorial. I can‘t wait to see the games you build. Happy coding!