如何使用 JS 和 p5.js 使 class 中的对象物理移动
How to make a Object in a class physically move using JS and p5.js
到目前为止,我已经创建了一个 class 来生成一个圆圈。我一直在尝试使这个圆 move/vibrate 不断变化,但我不确定使用 OOP 添加移动功能的最佳方法是什么。此外,当我在绘制函数中创建 'face' 对象时,我的页面崩溃了。
function setup() {
createCanvas(350, 350, WEBGL);
background('white')
let face = new Face();
}
class Face {
constructor() {
this.basicFace(100, random(10,30),0,0);
}
basicFace(radius, steps, centerX, centerY) {
var xValues = [];
var yValues = [];
for (var i = 0; i < steps; i++) {
let rad = radius + random(-radius / 50, radius / 50)
xValues[i] = (centerX + rad * cos(2 * PI * i / steps));
yValues[i] = (centerY + rad * sin(2 * PI * i / steps));
}
beginShape();
strokeWeight(4)
for (let i = 0; i < xValues.length; i++) {
curveVertex(xValues[i], yValues[i]);
}
endShape(CLOSE);
}
}
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"></script>
首先,在 draw()
函数中创建新的 Face
实例可能导致页面挂起的一个原因是 draw()
函数每秒运行多次,并且在 JavaScript 中,大量分配(例如创建 class 的新实例)可能对性能不利。但是,每次调用 draw()
时简单地分配一个 class 实例通常不会导致问题。另一方面,如果您将这些实例添加到数据结构(例如数组)中,这可能会导致您的页面使用过多的内存并最终挂起。没有看到导致挂起的确切代码,很难说。
如果你想以面向对象的方式实现上面的草图,那么你应该采取以下步骤:
- 为您的 class 提供一些定义其属性的构造函数参数,例如位置和大小,并将它们存储为实例字段。
- 将您的 class 行为与构造函数分开(即给它一个方法使其显示。
- 实例化一次,然后在
draw()
中调用该实例方法,以便每一帧显示它。
let face;
function setup() {
createCanvas(350, 350, WEBGL);
face = new Face(100, random(10, 30), 0, 0);
}
function draw() {
background('white');
face.show();
}
class Face {
constructor(radius, steps, centerX, centerY) {
this.radius = radius;
this.steps = steps;
this.centerX = centerX;
this.centerY = centerY;
}
show() {
var xValues = [];
var yValues = [];
for (var i = 0; i < this.steps; i++) {
let rad = this.radius + random(-this.radius / 50, this.radius / 50)
xValues[i] = (this.centerX + rad * cos(2 * PI * i / this.steps));
yValues[i] = (this.centerY + rad * sin(2 * PI * i / this.steps));
}
strokeWeight(4);
beginShape();
for (let i = 0; i < xValues.length; i++) {
curveVertex(xValues[i], yValues[i]);
}
endShape(CLOSE);
}
}
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"></script>
此外,当您显示曲线时,不必在一个循环中为 x 和 y 值创建数组,然后在单独的循环中调用 curveVertex()
。相反,您可以组合这些循环并避免不必要的数组分配。
show() {
strokeWeight(4);
beginShape();
for (let i = 0; i < this.steps; i++) {
let rad = this.radius + random(-this.radius / 50, this.radius / 50);
curveVertex(
this.centerX + rad * cos(2 * PI * i / this.steps),
this.centerY + rad * sin(2 * PI * i / this.steps)
);
}
endShape(CLOSE);
}
到目前为止,我已经创建了一个 class 来生成一个圆圈。我一直在尝试使这个圆 move/vibrate 不断变化,但我不确定使用 OOP 添加移动功能的最佳方法是什么。此外,当我在绘制函数中创建 'face' 对象时,我的页面崩溃了。
function setup() {
createCanvas(350, 350, WEBGL);
background('white')
let face = new Face();
}
class Face {
constructor() {
this.basicFace(100, random(10,30),0,0);
}
basicFace(radius, steps, centerX, centerY) {
var xValues = [];
var yValues = [];
for (var i = 0; i < steps; i++) {
let rad = radius + random(-radius / 50, radius / 50)
xValues[i] = (centerX + rad * cos(2 * PI * i / steps));
yValues[i] = (centerY + rad * sin(2 * PI * i / steps));
}
beginShape();
strokeWeight(4)
for (let i = 0; i < xValues.length; i++) {
curveVertex(xValues[i], yValues[i]);
}
endShape(CLOSE);
}
}
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"></script>
首先,在 draw()
函数中创建新的 Face
实例可能导致页面挂起的一个原因是 draw()
函数每秒运行多次,并且在 JavaScript 中,大量分配(例如创建 class 的新实例)可能对性能不利。但是,每次调用 draw()
时简单地分配一个 class 实例通常不会导致问题。另一方面,如果您将这些实例添加到数据结构(例如数组)中,这可能会导致您的页面使用过多的内存并最终挂起。没有看到导致挂起的确切代码,很难说。
如果你想以面向对象的方式实现上面的草图,那么你应该采取以下步骤:
- 为您的 class 提供一些定义其属性的构造函数参数,例如位置和大小,并将它们存储为实例字段。
- 将您的 class 行为与构造函数分开(即给它一个方法使其显示。
- 实例化一次,然后在
draw()
中调用该实例方法,以便每一帧显示它。
let face;
function setup() {
createCanvas(350, 350, WEBGL);
face = new Face(100, random(10, 30), 0, 0);
}
function draw() {
background('white');
face.show();
}
class Face {
constructor(radius, steps, centerX, centerY) {
this.radius = radius;
this.steps = steps;
this.centerX = centerX;
this.centerY = centerY;
}
show() {
var xValues = [];
var yValues = [];
for (var i = 0; i < this.steps; i++) {
let rad = this.radius + random(-this.radius / 50, this.radius / 50)
xValues[i] = (this.centerX + rad * cos(2 * PI * i / this.steps));
yValues[i] = (this.centerY + rad * sin(2 * PI * i / this.steps));
}
strokeWeight(4);
beginShape();
for (let i = 0; i < xValues.length; i++) {
curveVertex(xValues[i], yValues[i]);
}
endShape(CLOSE);
}
}
<script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.js"></script>
此外,当您显示曲线时,不必在一个循环中为 x 和 y 值创建数组,然后在单独的循环中调用 curveVertex()
。相反,您可以组合这些循环并避免不必要的数组分配。
show() {
strokeWeight(4);
beginShape();
for (let i = 0; i < this.steps; i++) {
let rad = this.radius + random(-this.radius / 50, this.radius / 50);
curveVertex(
this.centerX + rad * cos(2 * PI * i / this.steps),
this.centerY + rad * sin(2 * PI * i / this.steps)
);
}
endShape(CLOSE);
}