If you're seeing this message, it means we're having trouble loading external resources on our website.

如果你被网页过滤器挡住,请确保域名*.kastatic.org*.kasandbox.org 没有被阻止.

主要内容

多个对象的运动

在现实世界中(我们经常从中寻求灵感),我们有不止一个移动的物体——我们被许多具有不同质量和位置的物体所包围。让我们来看看如何让我们的 Mover 更好地模拟真实世界的物体。
为此,我们需要快速复习一下面向对象编程。同样,我们不会在这里介绍面向对象编程的全部基础知识。然而。因为创建一个充满对象的世界的思想是本单元所有内容的基础,花些时间介绍从只有一个对象到有多个对象的步骤还是值得的。
提醒一下,这是我们现在 Mover 的样子。它跟我们首次引用向量时创建的弹球对象相同,但是有两处添加——mass(质量)和一个新的applyForce()(应用力)方法:
现在我们的对象已经设置好了,我们可以用一个循环,用数组创建二十个 Mover 实例。
var movers = [];

for (var i = 0; i < 20; i++) {
    movers[i] = new Mover();
}
但是现在我们有一个小问题,如果我们引用 Mover 对象的构造函数……
var Mover = function() {
    this.mass = 1;
    this.position = new PVector(30, 30);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
};
……我们发现每个 Mover 对象都会是完全一样的。我们想要的是有 不同 质量和初始位置的 Mover 对象。现在我们需要通过添加参数来提高构造函数的复杂性。
var Mover = function(m, x, y) {
    this.mass = m;
    this.position = new PVector(x, y);
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
};
注意质量和位置不再被设置为硬编码数字,而是通过构建函数传递的参数进行初始化。这意味着我们可以创建各种 Mover 对象:大的,小的,初始位置在屏幕左端的,初始位置在屏幕右端的。
// 窗口左侧的一个大弹球
var m1 = new Mover(10, 0, height/2);
// 窗口右侧的一个小弹球
var m2 = new Mover(0.1, width, height/2);
但是,我们希望使用循环初始化数组里的所有对象。
for (var i = 0; i < 20; i++) {
    movers[i] = new Mover(random(0.1, 5), 0, 0);
}
对于每一个生成的弹球,它的质量会被设成0.1到5之间的一个随机数,起始 x 和 y 位置都设为0。当然,我们可以选择各种方法来初始化对象:这只是提供一种可能性。
当对象数组被声明、创建和初始化之后,剩余的代码就很简单了。我们调整每一个对象,给它们设置环境中的力,然后我们可以欣赏它们的表演了。
draw = function() {
  background(50, 50, 50);

  for (var i = 0; i < movers.length; i++) {
    var wind = new PVector(0.01, 0);
    var gravity = new PVector(0, 0.1);
    movers[i].applyForce(wind);
    movers[i].applyForce(gravity);
    movers[i].update();
    movers[i].display();
    movers[i].checkEdges();
  }
};
下面是程序实际的样子。注意在程序中较小的圆圈比较大的圆圈更快到达屏幕右侧。这是因为我们的公式:加速度 = 力除以质量。质量越大,加速度越小。

“自然模拟”系列课程是由 Daniel Shiffman 的 "编程的本质" 衍生而来,基于 知识共享 著名-非商用性 3.0 本地化许可协议

想加入讨论吗?

尚无帖子。
你会英语吗?单击此处查看更多可汗学院英文版的讨论.