无法将这组函数正确地转换为有效的 class (p5.js)

Cant correctly turn this set of functions into a working class (p5.js)

我正在将一组创建树的函数转换为 class,但是在这些函数创建一个大的分支树的地方,class 版本没有正确绘制树,因为它在函数中执行。我对 javascript 和 oop 的经验不多,所以在这里发现问题对我来说非常令人沮丧和困难,如果有人能指出我需要对 class 进行哪些更改,我将不胜感激正确显示。

我已经并排比较了代码,试图找出是否有任何差异,但我觉得问题是由于 class 中函数和方法的差异,这使得它很难我来辨认一下。

我试图修复的代码可以在这里找到:https://editor.p5js.org/remcqueen/sketches/S1ETz7WfV

代码的预期结果与功能版本相同,可以在这里找到:https://editor.p5js.org/remcqueen/sketches/B1HdvWbzN

应该生成一棵完整的无叶树。然而,目前显示的内容却大不相同。

如果有人看到这个问题并帮助解决它,我将不胜感激。

这是我要修复的 class:

class createTree {

  constructor() {
    this.tree = createGraphics(width-10, height-10);
    this.n = 0;
  }

  draw() {
    this.tree.beginShape();
    this.tree.noStroke();
    this.tree.background(0,0);
    for (this.i = 0; this.i < 3; this.i++) {
        this.tree.fill(map(this.i, 0, 2, 60, 20));
        this.branch(width/2, height, 70, -HALF_PI, 150, 0);
    }
    this.tree.endShape();
    image(this.tree, 5, 5);
  }


  branch(x, y, bSize, theta, bLength, pos) {
    this.x = x;
    this.y = y;
    this.bSize = bSize;
    this.theta = theta;
    this.bLength = bLength;
    this.pos = pos;
    this.n += 0.01;
    this.diam = lerp(this.bSize, 0.7 * this.bSize, this.pos / this.bLength);
    this.diam *= map(noise(this.n), 0, 1, 0.4, 1.6);

    this.tree.ellipse(this.x, this.y, this.diam, this.diam);
    if (this.bSize > 0.6) {
        if (this.pos < this.bLength) {
            this.x += cos(this.theta + random(-PI / 10, PI / 10));
            this.y += sin(this.theta + random(-PI / 10, PI / 10));
            this.branch(this.x, this.y, this.bSize, this.theta, this.bLength, this.pos + 1);
        } else {
            this.drawLeftBranch = random(1) > 0.1;
            this.drawRightBranch = random(1) > 0.1;
            if (this.drawLeftBranch) this.branch(this.x, this.y, random(0.5, 0.7) * this.bSize, this.theta - random(PI / 15, PI / 5), random(0.6, 0.8) * this.bLength, 0);
            if (this.drawRightBranch) this.branch(this.x, this.y, random(0.5, 0.7) * this.bSize, this.theta + random(PI / 15, PI / 5), random(0.6, 0.8) * this.bLength, 0);

            if (!this.drawLeftBranch && !this.drawRightBranch) {
                this.tree.push()
                this.tree.translate(this.x, this.y);
                this.tree.rotate(this.theta);
                this.tree.quad(0, -this.diam / 2, 2 * this.diam, -this.diam / 6, 2 * this.diam, this.diam / 6, 0, this.diam / 2);
                this.tree.pop();
            }
        }
    }
  }
}

您正在到处设置实例变量,而您真正想要的是函数的局部变量。当您在实例上设置变量时,它们在递归期间共享,这不是您想要的。例如,您需要函数的所有参数都是函数的局部参数:

将它们添加到 this 会破坏一切:

branch(x, y, bSize, theta, bLength, pos) {
   this.x = x;  // <-- don't do that
   this.y = y;
 // etc
}

这是经过清理的代码段:

var a;
function setup() {
  createCanvas(900, 700);
  colorMode(HSB);
  noLoop();
  noStroke();
  a = new createTree();
  a.draw();
}

class createTree {

  constructor() {
    this.tree = createGraphics(width, height);
    this.n = 0;
  }

  draw() {
    this.tree.beginShape();
    this.tree.noStroke();
    this.tree.background(0,0);
  
    for (let i = 0; i < 3; i++) {
        this.tree.fill(map(i, 0, 2, 60, 20));
        this.branch(width/2, height, 70, -HALF_PI, 150, 0);
    }
    this.tree.endShape();
    image(this.tree, 5, 5);
  }


  branch(x, y, bSize, theta, bLength, pos) {
    
    this.n += 0.01;
    let diam = lerp(bSize, 0.7 * bSize, pos / bLength);
    diam *= map(noise(this.n), 0, 1, 0.4, 1.6);

    this.tree.ellipse(x, y, diam, diam);
    if (bSize > 0.6) {
        if (pos < bLength) {
            x += cos(theta + random(-PI / 10, PI / 10));
            y += sin(theta + random(-PI / 10, PI / 10));
            this.branch( x, y, bSize, theta, bLength, pos + 1);
        } else {
            let drawLeftBranch = random(1) > 0.1;
            let drawRightBranch = random(1) > 0.1;
            if (drawLeftBranch) this.branch(x, y, random(0.5, 0.7) * bSize, theta - random(PI / 15, PI / 5), random(0.6, 0.8) * bLength, 0);
            if (drawRightBranch) this.branch(x, y, random(0.5, 0.7) * bSize, theta + random(PI / 15, PI / 5), random(0.6, 0.8) * bLength, 0);

            if (!drawLeftBranch && !drawRightBranch) {
                this.tree.push()
                this.tree.translate(x, y);
                this.tree.rotate(theta);
                this.tree.quad(0, -diam / 2, 2 * diam, -diam / 6, 2 * diam, diam / 6, 0, diam / 2);
                this.tree.pop();
            }
        }
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>