首页 > 解决方案 > 画布中矩形形状的随机移动和旋转

问题描述

我正在尝试在 html 画布上创建一个游戏,在那里我可以控制一辆汽车。还有其他一些由计算机控制的汽车。我可以用四个箭头键(上、下、左、右)来控制我的车。它工作正常。我在生成其他对手汽车时遇到了一些困难,这些汽车将在画布区域内随机移动并像我用四个箭头键控制的汽车一样急转弯。

我已经做了一些代码来使随机生成的汽车移动。但这些都不能正常工作。运动不顺畅,随机,汽车不能正确右转或左转。

最初我显示的是一个矩形而不是汽车。绿色矩形是计算机控制的汽车,蓝色矩形是由用户控制的。

任何人有任何想法来解决这个问题?我完全被困在这里。提前致谢。

我的 js 文件如下所示。

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

canvas.width = 600;
canvas.height = 500;
const canvasW = canvas.width;
const canvasH = canvas.height;

let upPressed = false,
  downPressed = false,
  rightPressed = false,
  leftPressed = false;

let enemies = [];

class PlayerCar {
  constructor(carX, carY, carWidth, carHeight) {
    this.carX = carX;
    this.carY = carY;
    this.carWidth = carWidth;
    this.carHeight = carHeight;
    this.angle = 0;
    this.rot = 0.1; //control how fast it turns
  }
  draw() {
    ctx.fillStyle = "blue";
    ctx.save();
    ctx.beginPath();
    ctx.translate(this.carX, this.carY);
    ctx.rotate(this.angle);
    ctx.rect(
      -this.carWidth / 2,
      -this.carHeight / 2,
      this.carWidth,
      this.carHeight
    );
    ctx.fill();
    ctx.closePath();
    ctx.restore();
  }
  update() {
    if (rightPressed) {
      this.angle += this.rot;
    } else if (leftPressed) {
      this.angle -= this.rot;
    }
    if (upPressed) {
      this.carX += Math.cos(this.angle + toRadians(-90)) * 5;
      this.carY += Math.sin(this.angle + toRadians(-90)) * 5;
    }
    if (downPressed) {
      this.carX += Math.cos(this.angle + toRadians(90)) * 5;
      this.carY += Math.sin(this.angle + toRadians(90)) * 5;
    }
  }
}

class EnemyCar {
  constructor(carX, carY, carWidth, carHeight) {
    this.carX = carX;
    this.carY = carY;
    this.carWidth = carWidth;
    this.carHeight = carHeight;
    this.angle = 0;
    this.rot = 0.1;
  }
  draw() {
    ctx.fillStyle = "green";
    ctx.save();
    ctx.beginPath();
    ctx.rect(this.carX, this.carY, this.carWidth, this.carHeight);
    ctx.fill();
    ctx.closePath();
    ctx.restore();
  }
  update() {
    if (this.carX < 0) this.carX = 0;
    if (this.carX > canvasW - this.carWidth)
      this.carX = canvasW - this.carWidth;
    if (this.carY < 0) {
      this.carY = 0;
    }
    if (this.carY > canvasH - this.carHeight) {
      this.carY = canvasH - this.carHeight;
    }

    let test = Math.random() * 30;
    if (test < 5) {
      this.angle += this.rot;
    } else if (test > 5 && test < 10) {
      this.angle -= this.rot;
    }
    if (test > 10 && test < 20) {
      this.carX += Math.cos(this.angle + toRadians(-90)) * 5;
      this.carY += Math.sin(this.angle + toRadians(-90)) * 5;
    }
    if (test > 20 && test < 30) {
      this.carX += Math.cos(this.angle + toRadians(-90)) * 5;
      this.carY += Math.sin(this.angle + toRadians(-90)) * 5;
    }
  }
}

function toRadians(deg) {
  return (deg * Math.PI) / 180;
}

const playerCar = new PlayerCar(200, 100, 40, 60);
playerCar.draw();

function navigation() {
  const handleKeyDown = (e) => {
    if (e.key === "ArrowUp") {
      upPressed = true;
    }
    if (e.key === "ArrowDown") {
      downPressed = true;
    }
    if (e.key === "ArrowRight") {
      rightPressed = true;
    }
    if (e.key === "ArrowLeft") {
      leftPressed = true;
    }
  };

  const handleKeyUp = (e) => {
    if (e.key === "ArrowUp") {
      upPressed = false;
    }
    if (e.key === "ArrowDown") {
      downPressed = false;
    }
    if (e.key === "ArrowRight") {
      rightPressed = false;
    }
    if (e.key === "ArrowLeft") {
      leftPressed = false;
    }
  };

  document.addEventListener("keydown", handleKeyDown);
  document.addEventListener("keyup", handleKeyUp);
}

function spawnEnemy() {
  enemies.push(new EnemyCar(Math.floor(canvasW / 4), 400, 40, 60));
  enemies.push(new EnemyCar(Math.floor(canvasW / 2), 400, 40, 60));
  enemies.push(new EnemyCar(Math.floor(canvasW / 1.33), 400, 40, 60));
}

spawnEnemy();

function animate() {
  requestAnimationFrame(animate);
  ctx.clearRect(0, 0, canvasW, canvasH);

  if (playerCar.carX < 0) playerCar.carX = 0;
  if (playerCar.carX > canvasW - playerCar.carWidth)
    playerCar.carX = canvasW - playerCar.carWidth;
  if (playerCar.carY < 0) {
    playerCar.carY = 0;
  }
  if (playerCar.carY > canvasH) {
    playerCar.carY = canvasH;
  }

  enemies.forEach((enemy) => {
    enemy.draw();
    enemy.update();
  });

  playerCar.draw();
  playerCar.update();
}

function startGame() {
  animate();
}

function drawCC() {
  ctx.beginPath();
  ctx.arc(100, 200, 50, 0, 2 * Math.PI);
  ctx.stroke();
  ctx.fill();
}

startGame();
navigation();

标签: javascripthtmlcanvas

解决方案


推荐阅读