用户输入 left/right 箭头时的圆周运动

Circular movement when user input left/right arrow

我正在尝试在我的主圈内实现 left/right 圆周运动。 我有 class 个 Circle 和 Ball。 Circle 负责在我放置 Ball 的地方画一个“圆圈”,也就是在里面移动。

class Circle {
  constructor(gameWIdth, gameHeight) {
    this.gameHeight = gameHeight;
    this.gameWIdth = gameWIdth;
    this.circX = 100;
    this.circY = 100;
    this.radius = 55;
  }

  draw(context) {
    context.beginPath();
    context.fillStyle = "white";
    context.arc(
      this.gameWIdth / 2,
      this.gameHeight / 2,
      100,
      0,
      Math.PI * 2,
      false
    ); // outer (filled)
    context.arc(
      this.gameWIdth / 2,
      this.gameHeight / 2,
      this.radius,
      0,
      Math.PI * 2,
      true
    ); // outer (unfills it)
    context.fill();
  }
}

class Ball {
  constructor(gameWIdth, gameHeight) {
    this.gameWIdth = gameWIdth;
    this.gameHeight = gameHeight;
    this.ballX = this.gameWIdth / 2;
    this.ballY = this.gameHeight / 2;
    this.vx = 0.03;
    this.radians = Math.PI * 2;
  }

  draw() {
    context.beginPath();
    context.fillStyle = "green";
    context.arc(this.ballX, this.ballY - 67, 15, 0, Math.PI * 2, false);
    context.fill();
  }

  update(input) {
    if (input.includes("ArrowLeft")) {
      this.ballX = this.ballX + Math.cos(this.radians) * -2;
      this.ballY = this.ballY + Math.sin(this.radians) * -2;
    } else if (input.includes("ArrowRight")) {
      this.ballX = this.ballX + Math.cos(this.radians) * 2;
      this.ballY = this.ballY + Math.sin(this.radians) * 2;
    }
    //circular move
    this.radians += this.vx;
    this.ballX = this.ballX + Math.cos(this.radians) * 2;
    this.ballY = this.ballY + Math.sin(this.radians) * 2;

    console.log(this.ballX, this.ballY);
  }
}

class Input {
  constructor() {
    this.keys = [];
    window.addEventListener("keydown", (e) => {
      if (
        (e.key === "ArrowLeft" || "ArrowRight") &&
        this.keys.indexOf(e.key) === -1
      ) {
        this.keys.push(e.key);
      }
      console.log(e.key, this.keys);
    });
    window.addEventListener("keyup", (e) => {
      if (e.key === "ArrowLeft" || "ArrowRight") {
        this.keys.splice(this.keys.indexOf(e.key), 1);
      }

      console.log(e.key, this.keys);
    });
  }
}

class Game {
  constructor(context, width, height) {
    this.context = context;
    this.width = width;
    this.height = height;
    this.circle = new Circle(canvas.width, canvas.height);
    this.ball = new Ball(canvas.width, canvas.height);
    this.input = new Input();
  }

  draw() {
    this.circle.draw(context);
    this.ball.draw(context);
  }

  update() {
    this.ball.update(this.input.keys);
  }
}

const game = new Game(context, canvas.width, canvas.height);

const drawCanvas = () => {
  context.fillStyle = "#000";
  context.fillRect(0, 0, canvas.width, canvas.height);
};

const animation = () => {
  drawCanvas();
  game.draw();
  game.update();

  requestAnimationFrame(animation);
};

animation();

现在我正在输入左右箭头键,我确实希望我的球根据箭头键改变方向。 我在玩

 if (input.includes("ArrowLeft")) {
      this.ballX = this.ballX + Math.cos(this.radians) * -2;
      this.ballY = this.ballY + Math.sin(this.radians) * -2;
    } else if (input.includes("ArrowRight")) {
      this.ballX = this.ballX + Math.cos(this.radians) * 2;
      this.ballY = this.ballY + Math.sin(this.radians) * 2;
    }

其中 * -2 应该恢复运动,但它没有像我想象的那样工作 这是codesandobx我确实知道这可能比我预期的要复杂一些

通常你通过修改它的速度来改变方向。在这里,我将 this.vx 的值更改为正数或负数。

我还稍微更改了球位的计算,我只是使用了 75 和 66 这样的数字,这似乎是大致正确的,但您可能需要根据需要更改它们。

  update(input) {
    if (input.includes("ArrowLeft")) {
      if (this.vx > 0) this.vx *= -1;
    } else if (input.includes("ArrowRight")) {
      if (this.vx < 0) this.vx *= -1;
    }
    //circular move
    this.radians += this.vx;
    this.ballX = Math.cos(this.radians) * 75 + this.gameWIdth / 2;
    this.ballY = Math.sin(this.radians) * 75 + this.gameHeight / 2 + 66;
  }

添加到 ballXballY 是错误的做法。

一般来说,在圆上得到一个点,比如你的球的位置,看起来是这样的。

x = centerX + Math.cos(angle) * radius
y = centerY + Math.sin(angle) * radius

在你的情况下,唯一改变的是 angle。所以这是您唯一需要更新的东西。

update() {
  if (input === 'ArrowLeft') {
    velocity = -0.03
  } else if (input === 'ArrowRight') {
    velocity = 0.03
  }
  angle += velocity
}

draw() {
  const x = centerX + Math.cos(angle) * pathRadius
  const y = centerY + Math.sin(angle) * pathRadius
  ctx.arc(x, y, ballRadius, 0, Math.PI * 2)
}

最好考虑一下您的程序需要跟踪的最少信息。这里只需要存储angle,然后需要的时候就可以计算xy