Move to mouse position

by bc_rikko

HTML

<div id="app"></div>

CSS

canvas {
  border: solid 1px;
  margin: 30px;
}

JavaScript

class Game {
  constructor(el) {
    /** Canvas */
    this.canvas = document.createElement("canvas");
    this.canvas.width = 256;
    this.canvas.height = 224;
    this.ctx = this.canvas.getContext("2d");
    document.querySelector(el).appendChild(this.canvas);

    /** Controller */
    this.tap = { isTap: false };
    this.canvas.addEventListener("mousedown", e => {
      this.tap = {
        isTap: true,
        x: e.layerX,
        y: e.layerY
      };
    });
    this.canvas.addEventListener("mousemove", e => {
      if (this.tap.isTap) {
        this.tap = {
          isTap: true,
          x: e.layerX,
          y: e.layerY
        };
      }
    });
    this.canvas.addEventListener("mouseup", () => {
      this.tap = {
        isTap: false
      };
    });

    this.items = [];
  }

  add(item) {
    this.items.push(item);
  }

  remove(item) {
    this.items = this.items.filter(a => a !== item);
  }

  start() {
    this.tick();
  }

  stop() {
    cancelAnimationFrame(this.timer);
  }

  tick() {
    this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
    this.items.forEach(a => {
      a.update(this);
      a.draw(this);
    });

    this.timer = requestAnimationFrame(this.tick.bind(this));
  }
}

class BaseItem {
  constructor(opt) {
    this.x = opt.x || 0;
    this.y = opt.y || 0;
    this.w = opt.w || 10;
    this.h = opt.h || 10;
  }

  draw(game) {}
  update(game) {}
}

class Player extends BaseItem {
  constructor() {
    super({ w: 16, h: 16 });

    // 速度の定数
    this.v = 3;
    // 実際のx/y軸方向の速度
    this.vx = this.vy = 0;
    // 現在座標〜タップした座標の距離
    this.dx = this.dy = 0;

    // タップした座標
    this.x1 = this.y1 = 0;
    // タップした場所に表示する円の半径
    this.r = 0;

  }

  draw(game) {
    game.ctx.save();
    // オブジェクトの描画
    game.ctx.fillRect(this.x, this.y, this.w, this.h);

    // タップした場所
    if (this.x1 > 0 && this.y1 > 0) {
      game.ctx.strokeStyle = "gray";
      game.ctx.beginPath();
      game.ctx.arc(this.x1, this.y1, this.r, 0,...