Plan and done for April 15 - May 05

What will I learn today?

FreeCodeCamp projects: Simon game - start coding.

Done

Simon game app

The user story and the desired result.

Game process

  1. On Start game load the game engine.
  2. Choose a random sequence and keep it as current.
  3. Save current game position - 1.
  4. Play sequence from beginning to the current position inclusive.
  5. Wait for user input.
  6. Compare each entered element with corresponding element in sequence.
  7. On error: show message; buzz.
  8. On success: move current position one element right; repeat from step 3.
  9. On success in strict mode: repeat from step 2.

Challenges

  1. What is the Simon game?
  2. How to get sectors?
  3. How to play sound?
  4. How to make color of the sector blink lighter on click or touch?
  5. How to produce a sequence of sounds?
  6. How to make the shape of active element not squared?
  7. How to inform user about winning in the game?
  8. How to make delays to handle state changes in UI more smoothly?
  9. How to synchronize ending of Web Audio API Oscillator play with UI?

Solutions

  1. Explanation on the Simon game.

  2. We can get circle sectors by CSS hacking for div elements with special background filling or trasformations. It's many lines of an unintuitive code. My way is to set a background image for each sector to inline SVG. Code is very intelligible and clear:

    <svg
       xmlns="http://www.w3.org/2000/svg"
       viewBox="0 0 200 200"
       id="fourColorsCircle">
      <path fill="red"    d="M100,100 L100,0   A100,100 1 0,1 200,100 z" id="sector_XY" />
      <path fill="blue"   d="M100,100 L200,100 A100,100 1 0,1 100,200 z" id="sector_Xy" />
      <path fill="yellow" d="M100,100 L100,200 A100,100 1 0,1 0,100   z" id="sector_xy" />
      <path fill="green"  d="M100,100 L0,100   A100,100 1 0,1 100,0   z" id="sector_xY" />
    </svg>
    
  3. Use Web Audio API to make sounds out of HTML. Great explanation with a working code is at CSS tricks. Oscilator with sine wave form at a given frequency with Gain node to control fade out.

  4. There is SVG modified for any touched element or inner shadow for the element (but it doesn't work with SVG). There is lighten function in LESS but I don't want to add another framework (even if it's just CSS post-processing framework) just because of one function. I've tried to use filter: opacity in CSS as described in the post, but it produces different result on different colors - works best on green and worse on red. Finally I replace SVG for a second on key pressed to its brighter version.

  5. The problem is the Web Audio API oscilators are played at once despite they are played in a loop. The way to manage sequences I need to set exact time spot for each note to be played, schedule it. Here is the first short and the second much thorough explanation.

  6. I want the game to be accessible, but I don't like the shape of common active outline. Couldn't find any advices on making it more acceptable - not just plain squared, but something that repeats the form of the original element. Variant - to implement the whole keyboard layout to play the game with ARIA description on key mapping.

  7. I want some fanfare-like sound. And the only thing that come to my mind is ta-da-da-daaa-da-da from hockey matches timeouts. Looked at Wiki and after a while I've found it is the Charge!. In order to play it through the tone generator I had to implement additional function which let me to play chords and set note duration.

  8. One way to do it is to put setTimeout() everywhere I want a delay. But it makes it harder to deal with a sequence of delays or a sequence of UI interactions. I want a Promise() power to chain all interactions in a highly visible structure. SO gives an example of such implementation.

  9. I want to pause listening on buttons while the app is playing a sequence: it could be inconsistent for a user to press a button during the play and wait for it to be consumed by an app as a sequential input. The problem is that an osicllator neither has callback nor returns a promise. After a little research I've found a solution in the form of an onended event of an Oscillator node (here is description). The final solution is to implement a sequence player to return a promise of all promises and a tone player to return a promise on onended event. But there is another problem. Gain node provides a fade-out and goes on even when the sound is barely audible but the UI is still frozen. It's inconsistent for a user to hear or see nor activity from an app but being unable to interact with it. In order to produce more reliable behavior I exluded the last tone from a waiting list and during it's play the user may start interact with the app.