«ООП» на холсте правильным способом - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь нарисовать что-то на холсте сахарным кодом, который мы получили не так давно.Я использую 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.Спасибо

1 Ответ

0 голосов
/ 30 сентября 2018

Большая часть кода принадлежит вам.Поскольку я предпочитаю использовать 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 для Smart Animating

...