首页 > 解决方案 > 画布中的“OOP”正确方式

问题描述

我正在尝试使用我们不久前收到的糖代码在画布上绘制一些东西。我当然在使用 babel。我有两个问题。首先你可以在下面找到我的代码:

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

class Rectangle {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    draw() {
        ctx.beginPath();
        ctx.rect(this.x, this.y, 50, 50);
        ctx.fillStyle = "#000";
        ctx.fill();
        ctx.closePath();
    };

    move() {
        document.addEventListener('keydown', event => {
            if (event.keyCode === 37) {
                ctx.clearRect(0, 0, canvas.width, canvas.height)
                this.x--
                this.draw();
            }
            if (event.keyCode === 39) {
                ctx.clearRect(0, 0, canvas.width, canvas.height)
                this.x++
                this.draw();
            }
        })

    }
}


class Ball {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    draw() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, 10, 0, Math.PI*2);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
    };
}


const rect = new Rectangle(130, 50);
const ball = new Ball(60, 40)

setInterval(() => {
    rect.draw();
    rect.move();
    ball.draw();
}, 100);

我做了两节课。一个是长方形,第二个是球。矩形是可以用箭头移动的。当我移动时,球会消失一秒钟,然后再次出现在屏幕上。在这种情况下我做错了什么?游戏流程应该如何正确显示?第二个问题是:我怎样才能让这两个类相互交互?例如,我希望当矩形触摸球时,会出现简单的 console.log。谢谢

标签: javascriptcanvasecmascript-6html5-canvas

解决方案


大部分代码都是你的。因为我更喜欢使用requestAnimationFrame,所以我为请求添加了一个标识符: let requestId = null;

矩形的move()方法只处理 的值x,并以key为属性。

我还编写了frame逐帧构建动画的函数。

function frame() {
  requestId = window.requestAnimationFrame(frame);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  rect.move(key);
  rect.draw();
  ball.draw();
}

更改变量keydown的值后key,取消当前动画,并调用frame函数开始新动画。

我还添加了一个keyup事件来停止按键上的动画。

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
let key;
let requestId = null;

class Rectangle {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  draw() {
    ctx.beginPath();
    ctx.rect(this.x, this.y, 50, 50);
    ctx.fillStyle = "#000";
    ctx.fill();
    //ctx.closePath();
  }

  move(key) {
    if (key == 37) {
      this.x--;
    }
    if (key == 39) {
      this.x++;
    }
  }
}

class Ball {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, 10, 0, Math.PI * 2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    //ctx.closePath();
  }
}

const rect = new Rectangle(130, 50);
const ball = new Ball(60, 40);

rect.draw();
ball.draw();

function frame() {
  requestId = window.requestAnimationFrame(frame);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  rect.move(key);
  rect.draw();
  ball.draw();
}


document.addEventListener("keydown", event => {
  if (requestId) {
    window.cancelAnimationFrame(requestId);
  }
  key = event.keyCode;
  frame();
});
document.addEventListener("keyup", event => {
  if (requestId) {
    window.cancelAnimationFrame(requestId);
  }
});
canvas{border:1px solid;}
<canvas id="myCanvas"></canvas>

PS:请看这篇文章requestAnimationFrame for Smart Animating


推荐阅读