【问题标题】:How to make class method recursion for gaming loops?如何为游戏循环进行类方法递归?
【发布时间】:2026-02-06 08:35:01
【问题描述】:

我有这个代码:

export default class Main {
  canvas: HTMLCanvasElement | null;

  context: CanvasRenderingContext2D | null;

  constructor() {
    this.canvas = null;
    this.context = null;
  }

  init() {
    this.canvas = <HTMLCanvasElement>document.getElementById('canvas');
    this.context = this.canvas.getContext('2d');

    window.requestAnimationFrame(this.gameLoop);

    return () => { };
  }

  draw() {
    const randomColor = Math.random() > 0.5 ? '#ff8080' : '#0099b0';
    this.context.fillStyle = randomColor;
    this.context.fillRect(100, 50, 200, 175);
  }

  // eslint-disable-next-line no-unused-vars
  gameLoop(timestamp: number) {
    this.draw();

    window.requestAnimationFrame(this.gameLoop);
  }

  core() {
    window.onload = this.init();
  }
}

const main = new Main();
main.core();

我收到的错误是: [错误] TypeError: undefined is not an object (evalating 'this.draw') 游戏循环(main.ts:19)

但实际上,如果我在 gameLoop 中记录 this,我会得到 undefined,这是有道理的,因为 gameLoop 是由 requestAnimationFrame 内部调用的,而不是由我的 Main 类调用的。 由于同样的问题,this.draw 是未定义的。

如何解决?

【问题讨论】:

  • 您需要将bind 方法添加到您的类或使用箭头函数表示法。 window.requestAnimationFrame(this.gameLoop.bind(this));。现在正在寻找一个欺骗问题
  • 可能有一个欺骗问题,但我也找不到,所以我自己做了一个。生病做这个绑定的事情。谢谢。
  • 我能找到的最好的是'this' is undefined in JavaScript class methods,它有一些有用的答案。不确定是否完全欺骗,但它可能会为其他人指明正确的方向。
  • 是的,不完全是这个问题的喜悦,但肯定有用。但我认为最好让这个问题保持活力。您能否发布答案,以便我可以申请作为答案?
  • 仅供参考,there's no recursion here.

标签: javascript class oop recursion


【解决方案1】:

您需要将bind 方法指向您的类,以确保this 指向您的类。

class Main {
  canvas;
  context;
  
  init() {
    this.canvas = document.getElementById('canvas');
    this.context = this.canvas.getContext('2d');

    window.requestAnimationFrame(this.gameLoop.bind(this));
  }

  draw() {
    const randomColor = Math.random() > 0.5 ? '#ff8080' : '#0099b0';
    this.context.fillStyle = randomColor;
    this.context.fillRect(100, 50, 200, 175);
  }
  
  gameLoop(timestamp) {
    this.draw();
    
    window.requestAnimationFrame(this.gameLoop.bind(this));
  }

  core() {
    window.onload = this.init();
  }
}

const main = new Main();
main.core();
&lt;canvas id="canvas"&gt;&lt;/canvas&gt;

【讨论】: