p5js 在主作用域中使用循环函数

p5js use loop function in main scope

所以我在 p5js 中有这个非常基本的例子:

var e = 1;

function setup() {
    window.canvas = createCanvas(200, 200);
}

function draw() {
    fill(255, 255, 0);
    ellipse(50 + e, 50, 30);
    e++;

    noLoop();
}

如果我们暂时忽略 noLoop(),此代码只是复制一个圆并使其向右转。

现在,我试图通过添加以下内容来控制正在播放的帧数:

function makeOneMove() {
    loop();
}

所以每当我调用 makeOneMove() 时,就像在我的脚本中一样,我希望它播放一帧。

但是,遗憾的是我收到了这个错误:

Uncaught ReferenceError: loop is not defined

所以我的问题是,我怎样才能使用那些只能在 p5 的函数(如设置或绘制)中使用的 loop()noLoop() 函数。

要逐帧执行此操作,您需要确保在 setup() 方法中使用 loop(),如下所示:

var e = 1;

function setup() {
  createCanvas(200, 200);
  makeOneMove(); // call makeOneMove in `setup`
}

function makeOneMove() {
  loop();
}

function draw() {
  background(255); // used to remove the "trail" of circles (remove if trail is wanted)
  fill(255, 255, 0);
  ellipse(50 + e, 50, 30);
  e++;
  noLoop();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>

您可以在 draw() 外部和 makeOneMove() 内部控制 draw() 的值,而不是控制何时调用 draw()。这样,当 draw() 被一遍又一遍地重复调用时,它将采用 e 的新值并在新的偏移位置绘制圆。出于演示目的,我添加了一个 mouseClicked() 方法,它会在您单击时调用 makeOneMove()

var e = 1;

function setup() {
  createCanvas(200, 200);
}

function makeOneMove() {
  e++;
}

function draw() {
  background(255); // used to remove the "trail" of circles (remove if trail is wanted)
  fill(255, 255, 0);
  ellipse(50 + e, 50, 30);
}

function mouseClicked() {
  makeOneMove();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>

对于多个 circles/objects,这取决于您如何表现您的 data/objects。最好的方法是使用对象(例如通过创建 Class),并更改每个对象的偏移量(即:e 值):

class Circle {
  constructor(x, y, r, color) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.color = color;
    this.offset = 1; // (circles own `e` value)
  }
}

var objects;

function setup() {
  createCanvas(200, 200);
  objects = [ // store all your onscreen objects in an array
    new Circle(50, 50, 30, color(255, 255, 0)), // original object you had
    new Circle(50, 100, 50, color(0, 255, 0))
  ]; 
}

function makeOneMove(objectIndex) {
  objects[objectIndex].offset++;
}

function draw() {
  background(255); // used to remove the "trail" of circles (remove if trail is wanted)
  for(const circle of objects) {// loop through all objects in your `objects` array
    // Draw the given object/circle
    fill(circle.color);
    ellipse(circle.x + circle.offset, circle.y, circle.r);
  }
}

function mouseClicked() {
  makeOneMove(0); // make object 0 in array move (for demo)
}

function keyPressed() {
  makeOneMove(1); // make object 1 in array move (for demo)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>