Skip to content

Weslley Araujo

Building a Simon Says game with React/Redux

React, Redux3 min read

I always enjoyed writing small games using javascript.

Well, I do believe that by doing this kind of projects you take SO MUCH learnings out of it, and it’s just amazing the fact that with some few (many) lines of code you can build your favorite childhood games and spending hours (again) having fun with it!

Anyway, a few weeks ago I was on holidays with many sparing time then I decided that I really needed to try it out the awesome library that’s been gathering more and more attention in the past few days called styled-components!

First of all, I needed a project to work with.

I simply googled “fun games to code” that led me to this article and there it was a Simon game!

The original Simon Says | [Playable game](http://weslleyaraujo.github.io/react-simon-says/)

So basically the idea of the game is 4 colored pads, that each one of it will lighten up and play a specific note. You as a player should reproduce the sequence played before, and so on continuously.

Hands on! style out of it

I designed a few styled-components very quickly. I could see lots of benefits on having CSS in JS such as composition, readability… and most important, having access to the components props right in your styles is so convenient. Instead of having an .active class for example, I could just merge active styles in my component based on my props and that’s amazing! (thanks Max Stoiber)

Pad component

Not mentioning small tricks like decrease/increase font-size:

Score component

The possibilities are endless

Make it sing

After having some thoughts over it, I came up with a simple redux state tree:

App state

the key pads is where I am holding the game pads (duh). As you can see we have an active prop… this is how I will identify which Pad component needs to light up.

Also based on that I wrote a component called Player which is responsible for:

1. Whenever state updates
2. Checks which pad are active and select its id

3. Play a specific mp3 file based on that id using a HTML audio tag

Player component

So now, I just need to update the active pad on my state. A simple action + some reducer work will do:

Reducers and actions

and boom! sings like a bird ♬

Now let’s talk about the state keys game and match.

On game I store some info such as singing, which tells me if there is or not a pad being lightened up and playing at the moment. Having that available, I built a component called Game which using that prop it will toggle the css to pointer-events: none. The reason is to avoid the user to accidentally click on something when the song is still playing.

Also, that’s where I store score/ highscore /gameOver values, but the key match is probably the most exciting one.

match will hold which pads needs to lighten up + which pads were guessed by the player during the match… this will allow me in the future to check something like:

and to generate it randomly I just input one of the available id’s (red, green, blue, yellow) on the action payload:

Welcome to async land

So my challenge was read a bunch of id’s [‘red’, ‘blue’, ‘green’] and then run something like:

start -> LIGHTEN_PAD -> sleep -> LIGHTEN_OFF_PAD -> sleep -> redo

Simon got to sing.

Probably there are many many ways to solve that like sagas, promises, setIntervals… I've chosen to go with redux-thunk + es6 async functions ❤️

I created a simple helper named sleep which will just return a promise and resolve it after x milliseconds:

now together with the power of await, my thunk actions are written like:

yay! we have a functional Simon game!

Learnings and overview

This is of course just a surface of how it was built, and there are many small implementation details that you can find on the repo.

Managing the app state with redux was extremely easy! On top of that, it was my first real case using async functions, and it’s amazing how readable asynchronous code turns out to be when using it.

I want to mention styled-components once again, which was the reason in the first place of why I built this project. And if you haven't used it yet go check it out right away!

Links and References

Past stuff I've played with