用户输入左/右箭头时循环移动

发布于 2025-01-27 01:56:49 字数 3528 浏览 0 评论 0原文

我正在尝试在主圆圈内实现左/右圆形运动。 我有班级和球。 Circle负责绘制一个“圆圈”,我将球放在里面。

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 我确实可以知道这可以比我预期的要复杂一些

I am trying to achieve left/right circular movement inside my main circle.
I have class Circle and Ball. Circle is responsible for drawing a "circle" where I am placing my Ball, that is moving inside.

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();

For now I am inputing left right arrow press and i do want my ball to change direction based on arrow press.
I was playing with

 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;
    }

where * -2 should revert movement, but it is not working as I thought it will
Here is codesandobx I do get that this can be a bit more complicated than I anticipated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蓝眼泪 2025-02-03 01:56:49

通常,您会通过修改其速度来改变方向。在这里,我将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;
  }

Usually you make something change direction by modifying its speed. Here I change the value of this.vx to be either positive or negative.

I also changed the calculations for ball position slightly, I just used numbers like 75 and 66 that seemed to be approximately correct, but you might need to change those for your needs.

  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;
  }
成熟稳重的好男人 2025-02-03 01:56:49

添加到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在需要时。

Adding to ballX and ballY is the wrong approach here.

In general, getting a point on a circle, like your ball's position, looks like this.

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

In your case, the only thing that changes is angle. So this is the only thing you need to update.

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)
}

It's good to think about the minimum information your program needs to keep track of. Here, you only need to store angle, and then you can calculate x and y when you need them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文