A walker

   
 
   

The Sprites

Images courtesy of software_atelier at https://opengameart.org/content/cowboy Modified into character sheets by me.

The HTML File

 <h1> A walker</h1>

 <script type="text/javascript" src="code/sprite.js"></script>
 <script type="text/javascript" src="code/scene2.js"></script>

  <canvas id="oldWest" width="400" height="400" style="border:1px solid #000000;"></canvas>
<script type="text/javascript">
Setup("oldWest");
</script>

<table>
<tr>
     <td> &nbsp; </td>
     <td> <button type="button" onclick="StartMove(0,-1)"> ^ </button></td>
     <td>&nbsp;</td>
</tr>
<tr>
     <td><button type="button" onclick="StartMove(-1,0)"> < </button></td>
     <td>&nbsp;</td>
     <td> <button type="button" onclick="StartMove(1,0)"> > </button></td>
</tr>
<tr>
     <td> &nbsp; </td>
     <td> <button type="button" onclick="StartMove(0,1)"> V </button></td>
     <td>&nbsp;</td></tr> 

scene2.js

"use strict"

let guy;

function Setup(canvas) {

   guy = new Sprite(canvas, "cowboy/walkGun.png", 40, 40, 4);

   let theCanvas = document.getElementById(canvas);
   let cx = theCanvas.width/2-20;
   let cy = theCanvas.height/2-20;

   guy.Pos = {x:cx, y:cy};
}

function StartMove(dx, dy){
   guy.Move(dx, dy, 50);
}

sprite.js

"use strict"
const IMAGE_PATH = "img/";

class Sprite{
    constructor (canvasName, imageName = "player.png", 
                 width = 24, height = 30,frames = 8) {

       // canvas info
       this.ctx = document.getElementById(canvasName).getContext("2d");
       this.image = document.createElement("img");
       let path = IMAGE_PATH+ imageName;
       this.image.src = path;

       // don't start drawing  until the image is loaded.
       this.draw = false;

       // let me know when the image is loaded
       this.image.addEventListener("load", this, false);

       // drawing information
       this.width = width;
       this.height = height;

       this.frames = frames;

       this.cycle = 0;

       // dorawing location
       this.x = 0;
       this.y = 0;
       this.oldx = 0;
       this.oldy = 0;

       // moving information
       this.dx = 0;
       this.dy = 0;
       this.steps = 0;
       this.moving = false;
       this.timer = 0;

       // bounds information
       this.maxx = document.getElementById(canvasName).width;
       this.maxy = document.getElementById(canvasName).height;

       return;
    }

    handleEvent(e) {
       this.draw = true;
       this.Draw();
       return;
    }

    get Pos() {
       return {x:this.x, y:this.y};
    }

    set Pos( pos) {
       this.x = pos.x;
       this.y = pos.y;
       return;
    }

    get Bounds() {
        return({width:this.width, height: this.height});
    }

    Draw() {
        if(this.draw) {
            let width = this.width;
            let height = this.height;

            this.ctx.clearRect(this.oldx, this.oldy, width, height);
            this.oldx = this.x;
            this.oldy= this.y;

            this.ctx.drawImage(this.image, 
                            this.cycle*width, 0, width, height,
                            this.x, this.y, width, height);
            this.cycle = (this.cycle + 1) % this.frames;
        }
        return;
    }

    DoMove() {
        // make a bounded move
        let x = this.x + this.dx;
        let y = this.y + this.dy;
        if ( x > 0 && x+this.width < this.maxx && 
             y > 0 && y+this.height < this.maxy) {
           this.x = x;
           this.y = y;
        }

        this.steps--;
        this.Draw();

        // If I am done moving
        if (this.steps <= 0) {
            this.moving = false;
            this.steps =0;
            this.dx = 0;
            this.dy = 0;
        } else {
           // else keep going.
           // .bind(this) is very important
           this.timer = setTimeout(this.DoMove.bind(this), 100);
        }

    }

    Move(dx, dy, steps=100) {
       // do this only if I am not moving.
       if (!this.moving) {
           this.dx = dx;
           this.dy = dy;
           this.steps = steps;
           this.moving = true;
           // .bind(this) is very important
           this.timer = setTimeout(this.DoMove.bind(this), 100);
       }
    }

}