为什么我的requestAnimationFrame不起作用?

发布于 2025-01-28 21:20:56 字数 2962 浏览 4 评论 0原文

我正在尝试使用requestAnimationFrame使用JavaScript使汽车移动。我在屏幕上有一辆汽车,但汽车没有行驶。由于某种原因,我的动画不起作用。

const canvas = document.getElementById("myCanvas")
canvas.height = window.innerHeight
canvas.width = 200

//Draw the car on canvas
const ctx = canvas.getContext('2d') // use 2d canvas context 
const car = new Car(100, 100, 30, 50)
// car.draw(ctx) // draw the car using the context

//move the car 
animate();

function animate() {
  car.update();
  car.draw(ctx);
  requestAnimationFrame(animate); // calls the animate function again and again as many times as we want
  //give illusion of the movement that we want

}
body {
  margin: 0;
  background: darkgray;
  overflow: hidden;
  text-align: center;
}

#myCanvas {
  background: lightgray;
}
<canvas id="myCanvas"></canvas>
<script>
  class Controls {
    constructor() {
      this.forward = false
      this.left = false
      this.right = false
      this.reverse = false

      this.#addKeyboardListeners(); //# is used here because this is a private method, you can't access this from outside of the controls class
    }

    #addKeyboardListeners() {
      document.onkeydown = (event) => {
        switch (event.key) {
          case "ArrowLeft":
            this.left = true
            break;
          case "ArrowRight":
            this.right = true
            break
          case "ArrowUp":
            this.forward = true
            break
          case "ArrowDown":
            this.reverse = true
            break
        }
//        console.table(this)
      }

      document.onkeyup = (event) => {
        switch (event.key) {
          case "ArrowLeft":
            this.left = false
            break;
          case "ArrowRight":
            this.right = false
            break
          case "ArrowUp":
            this.forward = false
            break
          case "ArrowDown":
            this.reverse = false
            break
        }
//        console.table(this)
      }

    }
  }
</script>
<script>
  class Car {
    constructor(x, y, width, height) {
      this.x = x
      this.y = y
      this.width = width
      this.height = height

      this.controls = new Controls();
    }

    //update the position of the car according to the key pressed
    update() {
      if (this.controls.forward) {
        console.log("going up");
        this.y -= 2

      }
      if (this.controls.reverse) {
        this.y += 2

      }
    }

    //draw a static car
    draw(ctx) {
      ctx.beginPath();
      ctx.rect(
        this.x - this.width / 2,
        this.y = this.height / 2,
        this.width,
        this.height
      );
      ctx.fill();
    }
  }
</script>

I am trying to make the car move using JavaScript by using requestAnimationFrame. I have a car on the screen but the car is not moving; for some reason, my animation is not working.

const canvas = document.getElementById("myCanvas")
canvas.height = window.innerHeight
canvas.width = 200

//Draw the car on canvas
const ctx = canvas.getContext('2d') // use 2d canvas context 
const car = new Car(100, 100, 30, 50)
// car.draw(ctx) // draw the car using the context

//move the car 
animate();

function animate() {
  car.update();
  car.draw(ctx);
  requestAnimationFrame(animate); // calls the animate function again and again as many times as we want
  //give illusion of the movement that we want

}
body {
  margin: 0;
  background: darkgray;
  overflow: hidden;
  text-align: center;
}

#myCanvas {
  background: lightgray;
}
<canvas id="myCanvas"></canvas>
<script>
  class Controls {
    constructor() {
      this.forward = false
      this.left = false
      this.right = false
      this.reverse = false

      this.#addKeyboardListeners(); //# is used here because this is a private method, you can't access this from outside of the controls class
    }

    #addKeyboardListeners() {
      document.onkeydown = (event) => {
        switch (event.key) {
          case "ArrowLeft":
            this.left = true
            break;
          case "ArrowRight":
            this.right = true
            break
          case "ArrowUp":
            this.forward = true
            break
          case "ArrowDown":
            this.reverse = true
            break
        }
//        console.table(this)
      }

      document.onkeyup = (event) => {
        switch (event.key) {
          case "ArrowLeft":
            this.left = false
            break;
          case "ArrowRight":
            this.right = false
            break
          case "ArrowUp":
            this.forward = false
            break
          case "ArrowDown":
            this.reverse = false
            break
        }
//        console.table(this)
      }

    }
  }
</script>
<script>
  class Car {
    constructor(x, y, width, height) {
      this.x = x
      this.y = y
      this.width = width
      this.height = height

      this.controls = new Controls();
    }

    //update the position of the car according to the key pressed
    update() {
      if (this.controls.forward) {
        console.log("going up");
        this.y -= 2

      }
      if (this.controls.reverse) {
        this.y += 2

      }
    }

    //draw a static car
    draw(ctx) {
      ctx.beginPath();
      ctx.rect(
        this.x - this.width / 2,
        this.y = this.height / 2,
        this.width,
        this.height
      );
      ctx.fill();
    }
  }
</script>

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

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

发布评论

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

评论(1

回心转意 2025-02-04 21:20:56

我上班了!我已经修复了错字,并重新组织了您的代码。要在汽车上移动或向下移动时阻止主文档滚动,请使用event.preventdefault(),它阻止浏览器接收箭头键按。

我已经使用Tabindexfocus()从一开始就将键盘加入画布(元素需要一个选项卡的位置才能集中精力)。

ctx.ClearRect(0,0,canvas.width,canvas.height);在绘制新框架之前清除了上一个屏幕以提供运动。

  class Controls {
    constructor() {
      this.forward = false
      this.left = false
      this.right = false
      this.reverse = false
      this.#addKeyboardListeners();
    }

    #addKeyboardListeners() {
      document.onkeydown = (event) => {
        event.preventDefault()
        switch (event.key) {
          case "ArrowLeft":
            this.left = true
            break;
          case "ArrowRight":
            this.right = true
            break
          case "ArrowUp":
            this.forward = true
            break
          case "ArrowDown":
            this.reverse = true
            break
        }
      }

      document.onkeyup = (event) => {
        switch (event.key) {
          case "ArrowLeft":
            this.left = false
            break;
          case "ArrowRight":
            this.right = false
            break
          case "ArrowUp":
            this.forward = false
            break
          case "ArrowDown":
            this.reverse = false
            break
        }
      }

    }
  }

  class Car {
    constructor(x, y, width, height) {
      this.x = x
      this.y = y
      this.width = width
      this.height = height
      this.controls = new Controls();
    }

animate() { 
 
      if (this.controls.forward) this.y -= 2
      if (this.controls.reverse) this.y += 2
      if (this.controls.left) this.x -= 2
      if (this.controls.right) this.x += 2

      ctx.clearRect(0, 0, canvas.width, canvas.height);        
      ctx.fillRect(
        this.x - this.width / 2,
        this.y - this.height / 2,
        this.width,
        this.height
        );

    }
  }

const canvas = document.getElementById("myCanvas")
canvas.height = window.innerHeight
canvas.width = 200
canvas.tabIndex = 0;
const ctx = canvas.getContext('2d') 
const car = new Car(100, 100, 30, 50)
canvas.focus()

animate();
function animate() {
  car.animate();
  requestAnimationFrame(animate); 
  }
body {
  margin: 0;
  background: darkgray;
  overflow: hidden;
  text-align: center;
}

#myCanvas {
  background: lightgray;
}
<canvas id="myCanvas"></canvas>

I got it to work! I have fixed the typo and reorganised your code a bit. To stop the main document from scrolling when the car is moved up or down, use event.preventDefault(), which prevents the browser from receiving the arrow key press.

I have used tabIndex and focus() to give the keypresses to the canvas from the start (an element needs a tab position in order to be to be focused).

ctx.clearRect(0, 0, canvas.width, canvas.height); clears the previous screen before the new frame is drawn to give the movement.

  class Controls {
    constructor() {
      this.forward = false
      this.left = false
      this.right = false
      this.reverse = false
      this.#addKeyboardListeners();
    }

    #addKeyboardListeners() {
      document.onkeydown = (event) => {
        event.preventDefault()
        switch (event.key) {
          case "ArrowLeft":
            this.left = true
            break;
          case "ArrowRight":
            this.right = true
            break
          case "ArrowUp":
            this.forward = true
            break
          case "ArrowDown":
            this.reverse = true
            break
        }
      }

      document.onkeyup = (event) => {
        switch (event.key) {
          case "ArrowLeft":
            this.left = false
            break;
          case "ArrowRight":
            this.right = false
            break
          case "ArrowUp":
            this.forward = false
            break
          case "ArrowDown":
            this.reverse = false
            break
        }
      }

    }
  }

  class Car {
    constructor(x, y, width, height) {
      this.x = x
      this.y = y
      this.width = width
      this.height = height
      this.controls = new Controls();
    }

animate() { 
 
      if (this.controls.forward) this.y -= 2
      if (this.controls.reverse) this.y += 2
      if (this.controls.left) this.x -= 2
      if (this.controls.right) this.x += 2

      ctx.clearRect(0, 0, canvas.width, canvas.height);        
      ctx.fillRect(
        this.x - this.width / 2,
        this.y - this.height / 2,
        this.width,
        this.height
        );

    }
  }

const canvas = document.getElementById("myCanvas")
canvas.height = window.innerHeight
canvas.width = 200
canvas.tabIndex = 0;
const ctx = canvas.getContext('2d') 
const car = new Car(100, 100, 30, 50)
canvas.focus()

animate();
function animate() {
  car.animate();
  requestAnimationFrame(animate); 
  }
body {
  margin: 0;
  background: darkgray;
  overflow: hidden;
  text-align: center;
}

#myCanvas {
  background: lightgray;
}
<canvas id="myCanvas"></canvas>

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