Canvas Robot Game

Animate a jointed multiple segment robot using HTML 5 Canvas and JavaScript.

HTML

<!-- B. von Konsky                 -->
<!-- Business Web Technologies     -->
<!-- School of Information Systems -->
<!-- Curtin University             -->

<h2>Fun with Robots </h2>
<canvas id="game" width="510px" height="310px"></canvas>
<p>
  <label for="Annotate">Annotate</label>
  <input type="checkbox" onclick="drawWorld()" name="Annotate" checked />
  <br>
  <label for="alpha">Alpha</label>
  <input id="Alpha" value="45" />
  <br>
  <label for="beta"> Beta</label>
  <input id="Beta" value="90" />
  <br>
  <label for="gamma">Gamma</label>
  <input id="Gamma" value="-90" />
  <br>
</p>
<p>
  <button onclick="animateRobot()"> Move </button>
  <button onclick="grab()"> Grab </button>
  <button onclick="release()"> Release </button>
  <button onclick="reset()"> Reset </button>
</p>
<ul>
  <li> If <strong>Annotate </strong>is checked, then show the joint angles on the diagram. </li>
  <li> Press <strong> Move </strong> to set the joint configuration to (alpha, beta, gamma).</li>
  <li> Press <strong> Grab </strong>to pick up the package after first positioning the end of the robot arm over the yellow target.</li>
  <li> Press <strong> Release </strong> to let go of the package.</li>
  <li> Press <strong> Reset </strong> to return to the default configuration. Reset is required after the robot or package collides with the floor, resulting in catastrophic failure.</li>
</ul>

CSS

#game {
  background: darkblue;
  border: 1px solid black;
}

label {
  display: inline-block;
  width: 70px;
}

ul li {
  font-size: xx-small;
  color: gray;
}

JavaScript

var canvas = document.getElementById("game");
    var context = canvas.getContext('2d');

    // Set constants used in this JavaScript
    var radius = 10; // radius of bezeled edge
    var tic = 20; // size of ground tick
    var speed = 1; // Angle incrment for new frame
    var grabDistance = 3; // Max distance for successful grab
    var benchThickness = 40; // Thinckness of the bench

    // Set state variables used in this JavaScript
    var kaboom = false;
    var grabbed = true;
    var robot;
    var parcel;

    // Reset the joint configuration to the default
    function reset() {
      kaboom = false;
      grabbed = false;
      parcel = {x: -200, y: -radius,
                grabX: 40, grabY: 25,
                width: 80, height: 50,
                targetY: -radius,v: 0};
      robot = [{length: 100, angle: 45, target: 90, name: "Alpha"}, 
               {length: 75,  angle: 90, target:  0, name: "Beta"}, 
               {length: 50,  angle:-90, target:  0, name: "Gamma"}];

      for (var i = 0; i < robot.length; i++) {
        document.getElementById(robot[i].name).value = robot[i].target;
      }

      drawWorld();
    }

    function drawBoom(length) {

      // Generate the for the boom perimeter
      context.beginPath();
      context.moveTo(0, radius);
      context.arc(0, 0, radius, Math.PI / 2.0, 3.0 * Math.PI / 2.0, false);
      context.arc(length, 0, radius, 3.0 * Math.PI / 2.0, Math.PI / 2.0, false);
      context.lineTo(0, radius);

      // Draw the perimeter of the boom
      context.strokeStyle = 'black';
      context.stroke();

      // Cut the hole out of the boom
      context.moveTo(length + radius * 0.8, 0);
      context.arc(length, 0, radius * 0.8, 0.0, 2.0 * Math.PI, true);

      // Close the boom path the the cut out hole
      context.closePath();

      // Draw the boom with the hole
      context.fillStyle = 'lightgray';
      context.fill();

      // Draw the perimeter of the hole
      context.beginPath();
     ...