Week 3 Lab Sheet — Animation, Inputs & Media

Web Games Development · Animation & media · ~150 minutes

Objectives

  1. Repeat code with setInterval and stop it with clearInterval.
  2. Erase and redraw the canvas every frame.
  3. Represent motion with position and velocity.
  4. Detect collisions with the walls and reverse velocity.
  5. Read numbers from form fields with Number().
  6. Use HTML5 input validation (type="number", min, max).
  7. Draw images with drawImage and embed video with <video>.

Instructions

Create a folder named Week3 and copy the materials (candy.png, reunion.jpg, pearl.jpg, readers.jpg, the talk video files) into it. Create each file below, writing the code shown. Save and refresh after each change. Tick each checkpoint.

Files

1. bouncingballinputs.html Objectives 1, 2, 3, 4, 5

Week3\bouncingballinputs.html

  1. [Obj 1, 5] Create the file and add this scaffold code.
    <!DOCTYPE html>
    <html lang="en">
    <head><title>Bouncing Ball with inputs</title></head>
    <body>
      <canvas id="canvas" width="400" height="300"></canvas>
      <br />
      <form name="f" onsubmit="return change();">
        Horizontal velocity <input name="hv" value="4" type="number" min="-10" max="10" />
        Vertical velocity <input name="vv" value="8" type="number" min="-10" max="10" />
        <input type="submit" value="CHANGE" />
      </form>
    
      <script>
        var ctx = document.getElementById("canvas").getContext("2d");
        var boxx = 20, boxy = 30, boxwidth = 350, boxheight = 250;
        var ballrad = 10, ballx = 50, bally = 60, ballvx = 4, ballvy = 8;
        var boxboundx = boxwidth + boxx - ballrad;
        var boxboundy = boxheight + boxy - ballrad;
        var inboxboundx = boxx + ballrad;
        var inboxboundy = boxy + ballrad;
    
        function moveball() {
          // TODO: clear, move, bounce and draw
        }
        function change() {
          // TODO: read the inputs with Number()
          return false;
        }
        // TODO: setInterval(moveball, 100)
      </script>
    </body>
    </html>
  2. [Obj 2, 3] Clear, move and draw each frame.
    function moveball() {
      ctx.clearRect(boxx, boxy, boxwidth, boxheight);
      moveandcheck();
      ctx.beginPath();
      ctx.fillStyle = "rgb(200,0,50)";
      ctx.arc(ballx, bally, ballrad, 0, Math.PI * 2, true);
      ctx.fill();
      ctx.strokeRect(boxx, boxy, boxwidth, boxheight);
    }
  3. [Obj 4] Add moveandcheck() for the wall bounce.
    function moveandcheck() {
      var nballx = ballx + ballvx, nbally = bally + ballvy;
      if (nballx > boxboundx || nballx < inboxboundx) { ballvx = -ballvx; }
      if (nbally > boxboundy || nbally < inboxboundy) { ballvy = -ballvy; }
      ballx = nballx; bally = nbally;
    }
  4. [Obj 1, 5] Add change() and start the animation.
    function change() {
      ballvx = Number(document.f.hv.value);
      ballvy = Number(document.f.vv.value);
      return false;
    }
    setInterval(moveball, 100);
Checkpoint: the ball animates and bounces; the form changes its speed (Objectives 1-5).

2. bouncingballinputsvalidate.html Objective 6

Week3\bouncingballinputsvalidate.html

  1. [Obj 6] Create the file and add this scaffold code (your bouncing ball with a style block).
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Bouncing Ball with inputs</title>
      <style>
        form { width: 330px; margin: 20px; background-color: brown; padding: 20px; }
        /* TODO: style valid and invalid inputs */
      </style>
    </head>
    <body>
      <canvas id="canvas" width="400" height="300"></canvas>
      <form name="f" onsubmit="return change();">
        Horizontal velocity <input name="hv" value="4" type="number" min="-10" max="10" />
        Vertical velocity <input name="vv" value="8" type="number" min="-10" max="10" />
        <input type="submit" value="CHANGE" />
      </form>
      <script>
        // paste your bouncing ball code here
      </script>
    </body>
    </html>
  2. [Obj 5] Copy your bouncing ball code from bouncingballinputs.html into the script block.
  3. [Obj 6] Add the valid / invalid input styles.
    input:valid { background: green; }
    input:invalid { background: red; }
  4. [Obj 6] Add required to one input and test it.
    <input name="hv" type="number" min="-10" max="10" required />
Checkpoint: invalid input is blocked and shown in red (Objective 6).

3. bouncingcandybackground.html Objectives 1, 2, 7

Week3\bouncingcandybackground.html

  1. [Obj 1] Create the file and add this scaffold code.
    <!DOCTYPE html>
    <html lang="en">
    <head><title>Bouncing cotton candy!</title></head>
    <body>
      <canvas id="canvas" width="400" height="300"></canvas>
      <br />
      <button onclick="return stopcc();">STOP</button>
      <button onclick="return resume();">RESUME</button>
    
      <script>
        var ctx = document.getElementById("canvas").getContext("2d");
        var ballrad = 10, ballx = 50, bally = 60, ballvx = 4, ballvy = 8;
        var tid;
        // TODO: create and load the images
        function moveball() {
          // TODO: draw the background and the ball
        }
        // TODO: add stopcc() and resume()
      </script>
    </body>
    </html>
  2. [Obj 7] Add the images.
    var bkg = new Image();  bkg.src = "reunion.jpg";
    var ball = new Image(); ball.src = "candy.png";
  3. [Obj 2, 3, 7] Add the movement, bounce and drawing in moveball().
    ctx.clearRect(0, 0, 400, 300);
    ballx = ballx + ballvx;
    bally = bally + ballvy;
    if (ballx > 400 || ballx < 0) { ballvx = -ballvx; }
    if (bally > 300 || bally < 0) { ballvy = -ballvy; }
    ctx.drawImage(bkg, 0, 0, 4000, 3000, 0, 0, 400, 300);
    ctx.drawImage(ball, 0, 0, 388, 435, ballx - ballrad, bally - ballrad, 388/10, 435/10);
  4. [Obj 1] Start the animation.
    tid = setInterval(moveball, 100);
  5. [Obj 1] Add STOP and RESUME.
    function stopcc() { clearInterval(tid); return false; }
    function resume() { tid = setInterval(moveball, 100); return false; }
Checkpoint: the candy image bounces over the photo and can be stopped (Objectives 1, 2, 7).

4. bouncintballinputsimggradients.html Objectives 2, 3, 7

Week3\bouncintballinputsimggradients.html

  1. [Obj 2, 7] Create the file and add this scaffold code.
    <!DOCTYPE html>
    <html lang="en">
    <head><title>Bouncing Ball with inputs</title></head>
    <body>
      <canvas id="canvas" width="400" height="300"></canvas>
      <br />
      <form name="f" onsubmit="return change();">
        Horizontal velocity <input name="hv" value="4" type="number" min="-10" max="10" />
        Vertical velocity <input name="vv" value="8" type="number" min="-10" max="10" />
        <input type="submit" value="CHANGE" />
      </form>
    
      <script>
        var ctx = document.getElementById("canvas").getContext("2d");
        var boxx = 20, boxy = 30, boxwidth = 350, boxheight = 250;
        var ballrad = 10, ballx = 50, bally = 60, ballvx = 4, ballvy = 8;
        var img = new Image();
        img.src = "pearl.jpg";
        var grad;
        // TODO: build a gradient and draw the walls and the ball
      </script>
    </body>
    </html>
  2. [Obj 2] Add a linear gradient.
    grad = ctx.createLinearGradient(boxx, boxy, boxx + boxwidth, boxy + boxheight);
    grad.addColorStop(0, "red");
    grad.addColorStop(1, "blue");
    ctx.fillStyle = grad;
  3. [Obj 2, 3, 7] Add moveball() to move and draw.
    function moveball() {
      ctx.clearRect(boxx, boxy, boxwidth, boxheight);
      ballx = ballx + ballvx;
      bally = bally + ballvy;
      if (ballx > boxx + boxwidth - ballrad || ballx < boxx + ballrad) { ballvx = -ballvx; }
      if (bally > boxy + boxheight - ballrad || bally < boxy + ballrad) { ballvy = -ballvy; }
      ctx.drawImage(img, ballx - ballrad, bally - ballrad, 2 * ballrad, 2 * ballrad);
      ctx.fillRect(boxx, boxy, boxwidth, ballrad);
      ctx.fillRect(boxx, boxy + boxheight - ballrad, boxwidth, ballrad);
      ctx.fillRect(boxx, boxy, ballrad, boxheight);
      ctx.fillRect(boxx + boxwidth - ballrad, boxy, ballrad, boxheight);
    }
    setInterval(moveball, 100);
Checkpoint: the walls use a gradient and the ball image moves (Objectives 2, 3, 7).

5. bouncingVideoOk2.html Objectives 2, 7

Week3\bouncingVideoOk2.html

  1. [Obj 7] Create the file and add this scaffold code.
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>Bouncing Video</title>
      <style>
        #videoE { position: absolute; display: none; }
      </style>
    </head>
    <body>
      <video id="videoE" controls width="300">
        <source src="talk.webmvp8.webm" type="video/webm" />
        <source src="talk.mp4video.mp4" type="video/mp4" />
        <source src="talk.theora.ogv" type="video/ogg" />
      </video>
      <button onclick="startV()">Click to start</button>
    
      <script>
        var v, ballx = 250, bally = 260, ballvx = 14, ballvy = 18;
        function startV() {
          v = document.getElementById("videoE");
          // TODO: play the video and start moving it
        }
        // TODO: add moveball() that moves the video and bounces at the edges
      </script>
    </body>
    </html>
  2. [Obj 7] Add startV() to play the video and start moving it.
    function startV() {
      v = document.getElementById("videoE");
      v.style.display = "block";
      v.play();
      setInterval(moveball, 100);
    }
  3. [Obj 2] Add moveball() to move the video and bounce at the edges.
    function moveball() {
      ballx = ballx + ballvx;
      bally = bally + ballvy;
      if (ballx > 600 || ballx < 0) { ballvx = -ballvx; }
      if (bally > 400 || bally < 0) { ballvy = -ballvy; }
      v.style.left = ballx + "px";
      v.style.top = bally + "px";
    }
Checkpoint: the video plays and moves around the page (Objectives 2, 7).

Marking rubric

CriterionPointsScore
Animation with setInterval and clear/redraw3
Velocity and wall collision handled3
Form inputs read with Number()2
Input validation applied2
Images drawn with drawImage2
Video element with multiple sources2
Runs with no console errors1
Total15

Common errors

Progress and quiz scores are also tracked on the Week 3 lab page in the class website.