Moving On Out

The HTML file:

<head>
 <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
  <script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"> </script>
 <script type="text/x-mathjax-config">
  MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}});
</script>

 <link rel="stylesheet" href="http://mirkwood.cs.edinboro.edu/~bennett/style/hw.css">
</head>

<body>

<h1>Moving On Out</h1>

<canvas id="canvas" width="500" height="500" style="border:1px solid #000000;"></canvas>

<script type="text/javascript" src="scene.js"></script>
<script type="text/javascript" src="ui.js"></script>
<script type="text/javascript" src="guy.js"></script>

<script type="text/javascript">
'use strict'

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext('2d'); 
let width = canvas.width;
let height = canvas.height;

let guy = new Guy;
let shots = [];

canvas.tabIndex = 0;
canvas.addEventListener("keydown", MyHandler);
setInterval(DrawScene, 130);

</script>

</body>

guy.js

"use strict"

const CF = Math.PI/180;

class Shot {
   constructor(x,y, theta){
      this.theta = theta;
      this.x = x;
      this.y = y;
      this.speed = 5;
   }

   Move() {
       this.x += this.speed * Math.cos(this.theta*CF);
       this.y += this.speed * Math.sin(this.theta*CF);
       if (this.x < -width/2 || this.x > width/2 
                     || this.y < -height/2 || this.y > height/2) {
           // shot has died, remove it
           let pos = shots.indexOf(this);
           shots.splice(pos,1);
       } else {
          // shot is ok, draw it.
          this.Draw();
       }
   }

   Draw() {
      ctx.save();

      ctx.fillStyle = "red";

      ctx.beginPath();
      ctx.translate(this.x, this.y);
      ctx.arc(0,0,2,0,2*Math.PI);
      ctx.fill();
      ctx.restore();
   }
}


class Guy {
    x = 0;
    y = 0;
    stepSize = 1;
    theta = 0;

    constructor() {
    }

    Shoot() {
        let x= this.x + 21*Math.cos((this.theta)*CF);
        let y= this.y + 21*Math.sin((this.theta)*CF);

        shots.push(new Shot(x,y,this.theta));
    }

    Right() {
       this.theta--;
    }

    Left() {
       this.theta++;
    }

    Backward() {
       this.x -= this.stepSize * Math.cos(this.theta*CF);
       this.y -= this.stepSize * Math.sin(this.theta*CF);
    }

    Forward() {
       this.x += this.stepSize * Math.cos(this.theta*CF);
       this.y += this.stepSize * Math.sin(this.theta*CF);
    }

    Redraw() {

        ctx.save();
        ctx.translate(this.x,this.y);
        ctx.rotate(this.theta*CF);
        ctx.rotate(-90*CF);
        
        ctx.strokeStyle = "blue";
        ctx.lineWidth = 3;
        ctx.beginPath();

        ctx.moveTo(-5,-5);
        ctx.lineTo(5,-5);
        ctx.lineTo(5,10);
        ctx.lineTo(10,10);
        ctx.lineTo(0,20);
        ctx.lineTo(-10,10);
        ctx.lineTo(-5,10);
        ctx.lineTo(-5,-5);

        ctx.stroke();
        ctx.restore();
    }
}

scene.js

"use strict"

function SetupScene() {
    ctx.setTransform(1, 0, 0, -1, 0, height);
    ctx.translate(width/2, height/2);
}

function DrawScene() {
    ctx.clearRect(0, 0, width, height);
    ctx.save();

    Axis(ctx,width,height);
    SetupScene();

    Scene(ctx, width, height);

    guy.Redraw();

    // draw any shots that exist.
    let i =0;
    while (i < shots.length) {
        shots[i].Move();
        i++
    }

    ctx.restore();
}

function Axis(ctx, w, h) {

    ctx.strokeStyle = "black";
    ctx.beginPath();

    ctx.moveTo(0, h/2);
    ctx.lineTo(w,h/2);

    ctx.moveTo(w/2,0);
    ctx.lineTo(w/2,h);
    ctx.stroke();
}

function Scene() {

    ctx.save();
    ctx.strokeStyle="red";
    ctx.translate(100,100);
    ctx.strokeRect(0,0,30,30);
    ctx.restore();
    

    ctx.save();
    ctx.translate(-200,150);
    ctx.strokeStyle ="Green";

    ctx.beginPath();

    ctx.moveTo(0,0);
    ctx.lineTo(0,50);
    ctx.lineTo(60,50);
    ctx.lineTo(60,30);
    ctx.lineTo(30,30);
    ctx.lineTo(30,0);
    ctx.lineTo(0,0);
    ctx.stroke();

    ctx.restore();

    ctx.save();
    ctx.translate(-150,-150);
    ctx.scale(4,4);

    ctx.beginPath();
    ctx.strokeStyle="cyan";

    ctx.moveTo(-10,-10);
    ctx.lineTo(0,5);
    ctx.lineTo(10,-10);
    ctx.lineTo(-10,-10);
    ctx.stroke();
    ctx.restore();


    ctx.save();
    ctx.translate(150,-100);
    ctx.beginPath();
    ctx.arc(0,0,50,0,2*Math.PI);
    ctx.stroke();
    ctx.restore();

    return;
   
}

ui.js

"use strict"

function MyHandler(evnt){
    let key = evnt.key;

    switch (key) {
        case 'a':
           guy.Left()
           break;
        case 'd':
           guy.Right()
           break;
        case 'w':
           guy.Forward()
           break;
        case 's':
           guy.Backward()
           break;
        case ' ':
           guy.Shoot();
    }

}