Week 6 — Audio, Video & Rewards

Games reward good play. This week you embed audio and video with multiple source formats, control them from JavaScript, and build an ordering quiz that celebrates a correct answer with sound and fireworks.

🎯 Objectives

  • Embed media with <audio> / <video> and multiple <source> fallbacks.
  • Control playback from JavaScript: play(), currentTime, muted.
  • Show and hide elements with visibility and display.
  • Create elements at runtime with createElement and appendChild.
  • Add and remove event listeners with addEventListener / removeEventListener.
  • Pick several unique random items from an array.
  • Validate an ordering with a comparison loop.
  • Position game elements with CSS position and inline styles.

🛠 Weekly tasks

  1. Objective 1 — embed media with <audio> / <video> and multiple <source> fallbacks: Activity 1 + build presidentsClick.html.
  2. Objective 2 — control playback with play(), currentTime and muted: Activity 2 + build presidentsClick.html.
  3. Objective 3 — show and hide elements with visibility and display: Activity 3 + build presidentsClick.html.
  4. Objective 4 — create elements at runtime with createElement and appendChild: Activity 4 + build presidentsClick.html.
  5. Objective 5 — add and remove listeners with addEventListener / removeEventListener: Activity 5 + build presidentsClick.html.
  6. Objective 6 — pick several unique random items from an array: Activity 6 + build presidentsClick.html.
  7. Objective 7 — validate an ordering with a comparison loop: Activity 7 + build presidentsClick.html.
  8. Objective 8 — position game elements with CSS position and inline styles: Activity 8 + build presidentsClick.html.
  9. Build your own presidentsClick_yourname.html — using everything you have learned; show the correct order on a wrong answer and add a speed timer. (All objectives)

🎓 Lecture activity Open lecture slides →

A 90-minute session of 35 slides. Each concept is taught four ways: the big idea, a short example with its live output, a line-by-line explanation, and a 5-minute “try it” task. The lab work at 1:00 uses the Lab activity below.

Session plan

  1. 0:0010 minWarm-upReview questions on last week
  2. 0:1010 minGame & objectivesThis week’s game, objectives and key words
  3. 0:2035 minConceptsBig idea → code with live output → line by line → try it
  4. 0:555 minCheck understandingCommon mistakes and a 4-question quiz
  5. 1:0025 minLabBuild the files in the Lab activity below
  6. 1:255 minWrap-upBuild-your-own task, marking guide and recap

Concepts this week

  • 1. Creating elements — Build page elements with code
  • 2. Checking an order — Is the list in order?
  • 3. Audio & video — Players with fallback formats
  • 4. Showing & hiding — Hidden until earned

The slides open as a page on this site. Press F for full screen, the arrow keys to move, N for speaker notes, and P to save as PDF (turn on “Background graphics”).

🧪 Lab activity: work through the files Printable lab sheet

Create a folder named Week6 on your PC. Build the ordering quiz below, writing the code shown for each step. Download the media materials into the folder (hail_to_the_chief.mp3, hail_to_the_chief.ogg, sfire3.*). Save and refresh as you go.

Want a head start? A scaffold file starter.html is provided — choose it in the preview dropdown, copy it into your Week6 folder, and complete its TODOs.

  1. Create your Week6 folder

    On your own PC — do this once before starting.

    1. Create a folder named Week6 on your PC.
    2. Download the media materials above into it.
    3. Open your Week6 folder in VS Code or Sublime Text.
  2. presidentsClick.html Objectives 1–8

    Week6\presidentsClick.html — order the presidents.

    1. [Obj 1, 8] Create presidentsClick.html and add this scaffold code.
      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <title>Ordering Quiz with Rewards</title>
        <style>
          .thing { position: absolute; left: 0px; top: 0px; border: 2px double; background-color: white; margin: 5px; padding: 5px; }
          audio  { visibility: hidden; }
          video  { visibility: hidden; display: none; position: absolute; }
        </style>
      </head>
      <body onload="init();">
        <audio id="ruffles" controls preload="auto">
          <source src="hail_to_the_chief.mp3" type="audio/mpeg">
          <source src="hail_to_the_chief.ogg" type="audio/ogg">
          Your browser does not accept the audio tag.
        </audio>
        <video id="vid" width="50%" muted preload="auto">
          <source src="sfire3.webmvp8.webm" type="video/webm">
          <source src="sfire3.mp4">
          Your browser does not accept the video tag.
        </video>
      
        <h1>Order the Presidents</h1>
        Put the presidents in the right order by the time they were in office.
        <br />Click the boxes in the order you believe correct.
        <br />Reload for a new game. <br />
      
        Your order: <div id="answer"></div>
        Result: <div id="results"></div>
      
        <script>
          // TODO: add the facts array and the game variables
          // TODO: add setupgame(), pickelement() and checkorder()
          function init() {
            // TODO: set up the game
          }
        </script>
      </body>
      </html>
    2. [Obj 6] Add the facts array — one entry per president, top to bottom in order (the false means "not used yet") — then the game variables. col1 / row1 / rowsize decide where the boxes are placed.
      var facts = [
        ["George Washington", false],
        ["John Adams", false],
        ["Thomas Jefferson", false],
        ["James Madison", false],
        ["James Monroe", false],
        ["John Quincy Adams", false],
        ["Andrew Jackson", false],
        ["Martin Van Buren", false],
        ["William Harrison", false],
        ["John Tyler", false],
        ["James Polk", false],
        ["Zachary Taylor", false],
        ["Millard Fillmore", false],
        ["Franklin Pierce", false],
        ["James Buchanan", false],
        ["Abraham Lincoln", false],
        ["Andrew Johnson", false],
        ["Ulysses Grant", false],
        ["Rutherford Hayes", false],
        ["James Garfield", false],
        ["Chester Arthur", false],
        ["Grover Cleveland (1)", false],
        ["Benjamin Harrison", false],
        ["Grover Cleveland (2)", false],
        ["William McKinley", false],
        ["Theodore Roosevelt", false],
        ["William Taft", false],
        ["Woodrow Wilson", false],
        ["Warren Harding", false],
        ["Calvin Coolidge", false],
        ["Herbert Hoover", false],
        ["Franklin Roosevelt", false],
        ["Harry Truman", false],
        ["Dwight Eisenhower", false],
        ["John Kennedy", false],
        ["Lyndon Johnson", false],
        ["Richard Nixon", false],
        ["Gerald Ford", false],
        ["Jimmy Carter", false],
        ["Ronald Reagan", false],
        ["George H. W. Bush", false],
        ["Bill Clinton", false],
        ["George W. Bush", false],
        ["Barack Obama", false],
        ["Donald Trump", false],
        ["Joseph Biden", false]
      ];
      
      var thingelem;
      var nq = 4;               // number of facts presented
      var col1 = 20, row1 = 200, rowsize = 50;
      var slots = [];           // added to by each call of pickelement
      var answertext = " ";     // the numbers chosen so far
      var song, functionreference, v, res, ans;
    3. [Obj 4, 5, 6, 8] Add setupgame(). The inner do…while keeps picking a random fact until it finds one that is not used yet, so the boxes are all different.
      function setupgame() {
        slots = [];
        answertext = "";
        var mx = col1;
        var my = row1;
        var d, uniqueid, c;
      
        // mark all facts as not being used
        for (var i = 0; i < facts.length; i++) { facts[i][2] = false; }
      
        for (var i = 0; i < nq; i++) {
          do { c = Math.floor(Math.random() * facts.length); }
          while (facts[c][1] == true);      // get an unused fact
          facts[c][1] = true;
      
          uniqueid = "p" + String(c);
          d = document.createElement("pres");
          d.innerHTML = "<div class='thing' id='" + uniqueid + "'>placeholder</div>";
          document.body.appendChild(d);
      
          thingelem = document.getElementById(uniqueid);
          thingelem.textContent = String(i + 1) + ": " + facts[c][0];
          thingelem.style.top = String(my) + "px";
          thingelem.style.left = String(mx) + "px";
          thingelem.addEventListener("click", pickelement);
      
          my += rowsize;
        }
      }
    4. [Obj 5, 6] Add pickelement(). Each box knows its original position from its id (for example p7 → 7), and removing its listener locks it so it cannot be picked twice.
      function pickelement(ev) {
        var positiont = this.id.substring(1);            // drop the leading "p"
        var answert = this.textContent.substring(0, 1);  // the number 1, 2, ...
        answertext = answertext + answert + " ";
        ans.innerHTML = answertext;
      
        var positionn = Number(positiont);
        this.style.backgroundColor = "gold";
        this.removeEventListener("click", functionreference);   // lock this box
        slots.push(positionn);
      
        if (slots.length == nq) { checkorder(); }
      }
    5. [Obj 2, 3, 5, 7] Add checkorder() to validate the order and reward a correct answer with sound and video.
      function checkorder() {
        var ok = true;
        for (var i = 0; i < nq - 1; i++) {
          if (slots[i] > slots[i + 1]) { ok = false; break; }
        }
        if (ok) {
          res.innerHTML = "CORRECT";
          song.style.visibility = "visible";
          song.currentTime = 4;   // skip the silent start
          song.play();
          v.style.visibility = "visible";
          v.style.display = "block";
          v.currentTime = 0;
          v.play();
        } else {
          res.innerHTML = "WRONG";
        }
      }
    6. [Obj 2, 8] Fill in init(), which runs from onload. It finds the elements, remembers pickelement for the later removeEventListener, and starts the boxes halfway down the window.
      function init() {
        res = document.getElementById("results");
        ans = document.getElementById("answer");
      
        functionreference = pickelement;      // needed by removeEventListener
        song = document.getElementById("ruffles");
        v = document.getElementById("vid");
      
        row1 = 0.5 * window.innerHeight;      // start the boxes halfway down
        setupgame();
      }
    7. Save and refresh, then play the quiz.
Finished example output

Click the boxes in the order the items happened in history. The boxes are positioned absolutely, so their top and left styles are set in JavaScript.

📚 Media formats used