如何用 Javascript 创建一个简单的物理引擎 - 第一部分

2025-06-10

如何用 Javascript 创建一个简单的物理引擎 - 第一部分

我们运用物理,观察物理的运作,在日常生活中,我们所做的每一件事都体验着物理。如何在代码中添加物理特性,并让代码也能体验自然的力量?我将在关于物理引擎的文章中向您解释这一点。

什么是物理引擎?

它没什么太复杂的。它是一个包含所有物理相关函数的集合。

物理引擎起什么作用?

物理引擎可以模拟任何代码中的对象的物理。

编写物理引擎需要什么?

答案是数学

是的,您只需要了解基本的数学和一些简单的物理术语,就可以创建您的第一个物理引擎。

让我们从最基础的部分开始。假设你正在创建一个场景,希望你的物体(比如一个球)与另一个物体(比如一堵墙)发生反应。

嗯,最显而易见的办法就是硬编码。但那样还有什么意思呢?:D

我们需要我们的元素与我们抛给它们的所有东西进行互动。

它可以是一根羽毛、一块石头、一头大象,基本上任何物体……好吧,我可能听起来有点儿太过火了。那么,我们开始吧,向你展示如何构建你自己的物理引擎。

您需要开始做的事情:

  • 代码编辑器
  • 物理方程

1.代码编辑器

我们将使用 JavaScript 进行编码,如果使用 JS,所有这些动画最好使用 Canvas。因此,最适合使用的库p5.js。

p5 是一个简单而强大的 JavaScript 库,它拥有绘制、移动或以最简洁的方式对代码元素进行任何操作所需的所有功能。这里有一个很棒的资源,可以帮助您入门 p5。

接下来,我们将从代码编辑器的设置开始。

步骤 1:转到https://editor.p5js.org/(如果您已经有帐户,请注册或登录)并开始在工作区中编码。

步骤 2:好了,完成了。

2. 物理方程

希望你们还留着学校的物理书。我们也可以参考维基百科查找任何我们想要的物理公式。这部分我们将讨论一些简单的概念,比如运动。因为我们使用的是网页编辑器,所以不需要任何设置。p5.js 网页编辑器会帮我们搞定一切。

p5.j​​s也遵循相同的 JavaScript 编码规范。所以,如果您熟悉 Web 概念,那么太好了!您快成功了。

对于新手来说,让我带您快速了解一下编辑器。

这是编辑器。它分为两部分:编码工作区和预览区。(如果您的屏幕看起来不一样,不用担心。我刚刚更改了主题)。

让我们从你在编辑器上看到的元素开始,那就是

  • 菜单栏
  • 开始和停止
  • 自动刷新
  • 姓名
  • 设置
  • 项目文件夹
  • 编码空间
  • 预览

菜单栏:

与其他编辑器一样,这是一个标准的菜单栏。现在我们需要了解“文件”->“新建”。这将创建一个新的项目。

开始和停止:

点击“开始”按钮将编译并运行您的代码,并在预览选项卡上预览。点击“停止”按钮将停止编译。

自动刷新:[不推荐]

虽然我不使用自动刷新功能,但它对其他人来说可能很方便。如果您在运行代码时更改了代码,自动刷新功能会刷新预览。

姓名:

您的项目名称。p5 编辑器将提供有趣的随机名称,您可以选择保留或根据需要更改。

设置:

您猜对了,所有的小调整都可以在设置下进行,以便您制作自己的编辑器。

项目文件夹:

所有项目文件都放在项目文件夹下。您可以根据需要添加其他文件夹,但现在我们先简化操作,只添加一个文件。

编码空间:

一切魔法都在这里发生。你所有的代码和逻辑都将汇聚在一起,形成一件杰作。

预览:

在这里您将看到您的杰作栩栩如生。

在进一步讨论之前,让我们讨论一下项目文件夹下的 3 个默认文件

index.html - 这是 Web 应用的起始页。您将在这里链接脚本 (JS) 文件和样式 (CSS) 文件。

style.css - 这被称为样式表,您可以在其中修改 html 文件或 js 文件中使用的任何元素的所有样式属性。

sketch.js - 这是我们感兴趣的,也是我们将进行更多编程的,这基本上是我们画布的起点。

默认情况下,sketch.js 将为您提供一个样板模板来帮助您入门。

让我们解密每个词的含义。

1. 设置()

function setup() {
  createCanvas(400, 400);
}
Enter fullscreen mode Exit fullscreen mode

在代码编译开始时,setup 函数会被调用一次。

createCanvas 在预览中创建一个具有指定宽度和高度的画布。

2.draw()

function draw() {
  background(220);
}
Enter fullscreen mode Exit fullscreen mode

画布或元素主体中的每个时间戳都会调用 draw 函数。在更新对象的任何更改时,Draw 函数特别有用。

让我们从第一个例子开始。

  • 开始一个新项目
  • 选择Sketch -> 添加文件。这会提示你输入文件名。输入“Ball”作为文件名,你会看到你的文件列在项目文件夹下。
  • 让我们向Ball.js添加一些代码。
class Ball {
  constructor() {
    this.location = createVector(width / 2, height / 2);
    this.velocity = createVector(2, 3);
  }

  display() {
    fill(255);
    ellipse(this.location.x, this.location.y, 40, 40);
  }

  move() {
    this.location.add(this.velocity);
  }

  bounce() {
    if (this.location.x < 20 || this.location.x > width - 20) {
      this.velocity.x = this.velocity.x * -1;
    }
    if (this.location.y < 20 || this.location.y > height - 20) {
      this.velocity.y = this.velocity.y * -1;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

这是怎么回事?是不是有点困惑?让我来解释一下

我们刚刚创建了一个 Ball 类,并为其提供了一些函数。很简单吧?别被这些数学知识搞糊涂了。

constructor(){
  this.location = createVector(width/2,height/2);
  this.velocity = createVector(2,3);
}
Enter fullscreen mode Exit fullscreen mode

我们使用构造函数创建了两个向量。在数学中,向量不过是一个具有 x 和 y 值(或根据定义,大小和方向)的对象。就像你在图表上绘制的点一样,我们将根据坐标系绘制对象。

在这种情况下,我们将创建一个位置向量,它将跟踪我们的对象相对于画布的位置,我们将创建另一个速度向量,它将跟踪对象的移动速度,因为速度就是你移动的速度,对吗?

display(){
  fill(255);
  ellipse(this.location.x,this.location.y,40,40)
}
Enter fullscreen mode Exit fullscreen mode

让我们在画布上显示 Ball 对象。我们将创建一个名为 display 的用户定义函数,然后绘制一个椭圆。椭圆是 p5.js 预定义的形状。我们想要一个圆形,因此我们为椭圆传递相同的半径。我们将使用在构造函数中创建的位置向量来显示椭圆。

move(){
  this.location.add(this.velocity);
}
Enter fullscreen mode Exit fullscreen mode

让我们根据球体的速度来移动它。因此,任何位于 x1, y1 的物体,要到达另一个位置 x2, y2,都必须以一定的速度移动才能到达 x2, y2。因此,我们将在位置向量上添加一个恒定速度。这样,对于每个时间戳,我们都会得到一个新的位置,它是上一个位置与速度之和。

bounce(){
  if(this.location.x<20 || this.location.x>width-20){
    this.velocity.x = this.velocity.x*-1;
  }
  if(this.location.y<20 || this.location.y>height-20){
    this.velocity.y = this.velocity.y*-1;
  }
}
Enter fullscreen mode Exit fullscreen mode

让我们添加一个 bounce 函数,让它更有趣一些。它的作用是寻找画布边界,并将球保持在画布内。

当现实生活中的球撞到墙壁时,墙壁会对球施加相等的力,但由于球比墙壁轻得多,所以球会移动或反弹,而墙壁则会保持不变。

在代码中,我们无法让边界推动球,所以我们将球的速度设为负数,这样当球碰到任何边界时,它都会朝相反的方向移动。真是太简单了。

现在让我们在sketch.js中添加一些代码

let ball;

function setup() {
  createCanvas(600, 600);
  ball = new Ball();
}

function draw() {
  background(0);
  ball.move();
  ball.bounce();
  ball.display();
}
Enter fullscreen mode Exit fullscreen mode

让我们创建一个 ball 变量,以便在 setup 函数中创建 Ball 类的实例。现在,ball 变量可以访问 Ball 类的所有函数。

对于每个绘制循环,球都会移动,球对象会检查弹跳并改变位置,然后球对象会显示在循环时间戳中的位置。

一切都结束了吧?点击“运行”按钮,一切就开始了,对吧?

不行!!!每个程序员都会犯这个错误。就连我也花了好几个小时来找它为什么运行不起来。原因如下。

永远不要忘记在 index.html 中的脚本下添加你的 js 文件。

现在你已经准备好了!继续并单击“运行”按钮,这样你就有了第一个物理模拟程序。

您将看到以下内容:

好了,你的第一个物理引擎就完成了。接下来的步骤中,我们将讨论如何让它看起来更逼真。现在就来尝试调整一下数值吧。

在本系列文章的第 2 部分中,我们将讨论:

1. 加速度

2. 力量

3. 弥撒

鏂囩珷鏉ユ簮锛�https://dev.to/soorajsnblaze333/how-to-create-a-simple-physicals-engine-part-1-2ofh
PREV
在卸载组件上使用 React SetState 避免内存泄漏
NEXT
为您的 Web 应用构建“可插入式”小部件 GenAI LIVE!| 2025 年 6 月 4 日