p5.js 重复相同的功能

p5.js repetition of the same function

我正在学习 p5.js,但我不太明白如何在 y 轴上重复我的函数,以便线条出现在另一条之上。我知道我需要制作一个 class 对象,但我成功做的只是冻结编辑器 XD。你能帮我弄清楚如何让我的函数以不同的 Y 起点重复自身吗?

let walkers = []; // creation of an array 
this.xoff = 0; //changed to go outside of the walker class 
this.yoff = 0; //changed to go outside of the walker class
this.x = 0;
y = 200;

function setup() {
  createCanvas(600, 600);
  background(250);
  for (let i = 0; i < 10; i++) {  //mix array and class
    walkers[i] = new walker(y);
  }

}


function draw() {
  for (i = 0; i < walkers.length; i++) {  // consider the array lenght
    walker[i].acceleration(); // call the class and it's function
    walker[i].velocity();
    walker[i].update();
    walker[i].display();
  }

}

class walker {
  constructor(y) {  //divide the class in multiple function 
    this.y = y
  }


  acceleration() {
    this.accX = 0.1;
    this.accY = 0.1;
    this.px = this.x;
    this.py = this.y;
  }

  velocity() {
    this.velocityY = random(-20, 20);
    this.velocityX = 5;
  }

  update() {
    this.x = this.x + this.accX + this.velocityX * noise(this.xoff);
    this.y = this.y + this.accY + this.velocityY * noise(this.yoff);
  }

  display() {
    for (this.y < 200; this.y > 400; this.y + 20) {
      line(this.x, this.y, this.px, this.py);
    }
    this.xoff = this.xoff + 1;
    this.yoff = this.yoff + 100;
    this.px = this.x;
    this.py = this.y;
  }

}

使用 class 肯定会更容易。在 class 中创建不同的函数,它们负责更新、移动等。您也可以创建一个显示函数,您可以在其中使用 For 循环设置 y co-ordinate。这样一来,yco-ordinate.

的不断变化就会变得非常容易

如果要一次显示多行,执行以上所有操作,并使用数组存储 y co-ordinate,然后在 For 循环中显示它们。

如果您需要有关实际代码的帮助,请告诉我。

您的代码的行为有很多问题。

这里有几个问题:

  • walkers 它使用的数组:例如walkers[i].acceleration();,而不是 walker[i].acceleration();(其余调用同样适用)
  • 如果您打算使用变量,请初始化它们(否则使用数学运算符 update() 将以 NaN 结束:例如 this.x, this.xoff, this.yoff,等等
  • 不清楚你在追求位置、速度、加速度、柏林噪声等方面的运动行为(顺便说一下,这些行为会以奇怪的增量更新 ( this.yoff = this.yoff + 100;))

代码大多因此而冻结:

for (this.y < 200; this.y > 400; this.y + 20) 

不清楚你想在那里做什么:this.y < 200; this.y > 400 让我觉得你想要一个 if 条件只在 Y 轴上绘制 200-400 像素之间的线,但是 this.y + 20 让我觉得你出于某种原因想要增加 y ?

也不清楚为什么 x,xoff,yoff 移出 walker class ? 围绕 classes、实例和 this 关键字可能会有一些理解。 根据 JS 命名约定,class 名称应为首字母大写。

我可以告诉您,您已经付出了一些努力来尝试构建更复杂的草图,但是除非您了解代码的所有部分,否则增加复杂性对您没有帮助。这就是掌握基础知识的回报。

我推荐:

  • 回到pen/paper画草图,直到你的想法更清晰
  • 考虑如何通过将复杂的任务分解成更小的步骤来实现这一目标
  • 为每个 step/component
  • 编写基本测试草图

最后,一次将一个组件带入主程序,在组件与另一个组件交互时再次测试。请务必查看 Kevin Workman's How to Program guide.

FWIW,这是您的代码的修改版本,通过调整将每个 Walker 的初始 y 位置设置在彼此之上:

let walkers = []; // creation of an array 

y = 200;

function setup() {
  createCanvas(600, 600);
  background(250);
  for (let i = 0; i < 10; i++) {  //mix array and class
    // incrementally add 10 pixels to y so the initially lines start on top of each other
    walkers[i] = new Walker(y + (i * 10));
  }
}


function draw() {
  for (let i = 0; i < walkers.length; i++) {  // consider the array length
    // walkers, not walker
    walkers[i].acceleration(); // call the class and it's function
    walkers[i].velocity();
    walkers[i].update();
    walkers[i].display();
  }

}

class Walker {
  constructor(y) {  //divide the class in multiple function 
    this.y = y;
    // remember to init all variables you plan to use
    this.xoff = 0; //changed to go back inside of the walker class 
    this.yoff = 0; //changed to go back inside of the walker class
    this.x = 0;
  }

  acceleration() {
    this.accX = 0.1;
    this.accY = 0.1;
    this.px = this.x;
    this.py = this.y;
  }

  velocity() {
    this.velocityY = random(-20, 20);
    this.velocityX = 5;
  }

  update() {
    this.x = this.x + this.accX + this.velocityX * noise(this.xoff);
    this.y = this.y + this.accY + this.velocityY * noise(this.yoff);
  }

  display() {
    // what were you trying ?
    //for (this.y < 200; this.y > 400; this.y + 20) {
      line(this.x, this.y, this.px, this.py);
  //}
    this.xoff = this.xoff + 1;
    this.yoff = this.yoff + 1;
    this.px = this.x;
    this.py = this.y;
    // reset x, y to 0
    if(this.x > width){
      this.x = 0;
    }
    if(this.y > height){
      this.y = 0;
    }
    
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.min.js"></script>