当前位置: 首页 > Web前端 > JavaScript

不懂物理的前端不是好的游戏开发者(一)-物理引擎基础

时间:2023-03-27 01:51:41 JavaScript

概述游戏似乎已经成为了大家无法回避的一种娱乐方式,从大型客户端游戏到手游,到页游,再到各种APP中的H5游戏,以各种方式侵入我们的生活。所以在享受游戏的同时,作为一名前端开发者,我也开始思考如何开发一款游戏,在技术层面应该具备什么?除了基本的游戏画面、动画开发、渲染功能外,还有一个值得探索的地方,那就是物理引擎。一个好的物理引擎可以保证游戏中的交互体验与现实中的相似,为人们提供更好的体验。现在好用的物理引擎有很多,大部分都是现成的,但是有些人可能不明白物理引擎的基础和底层逻辑是什么样子的。从本期开始,我们将分多个部分介绍物理引擎的基础知识,让大家更好地理解它。以下内容部分引用自《游戏物理引擎开发》。什么是发动机?什么是发动机?当然,这是汽车发动机概念的延伸。在汽车中,发动机——将其他能量转化为机械能并提供给汽车的能量转换装置——是汽车能够行驶的核心模块。相应的,开发中的引擎是什么?在我的理解中,它是一个核心模块,可以为项目快速添加功能,并保证功能的运行。渲染引擎可以快速实现内容的渲染。游戏引擎可以快速实现游戏的基础开发。物理引擎可以快速模拟现实中的物理状态。了解了引擎是什么之后,我们就可以关注引擎的特性了。该引擎最大的特点是两个——快速和多功能。能快速实现所需功能,通用性强。它不是针对特定业务而开发的,而是针对一大类情况而开发的,因此它必须具有很强的通用性。快是指功能要齐全,API封装齐全,使用方便。通用是指代码本身的逻辑需要足够底层,应用最基本的逻辑才能实现最大的通用性。物理引擎的基础什么是物理引擎的基础?那就是物理和数学。其实一个物理系统在游戏中的体现就是每个物体在整个物理系统中的位置。每一帧都需要计算物体的位置,使它们出现在正确的位置。因此,符合物理定律的数学运算是物理引擎的基础。下面的一切都基于此。代码中的数学首先查看数学在游戏世界中的作用。无论是在二维还是三维世界中,物体位置的描述都是由向量来完成的。向量的处理不可避免地涉及到向量本身的分解、加减法、点积、向量积等一些知识。所以我们需要先创建一个基本的向量类:z=z}setX(x:number){this.x=x}setY(y:number){this.y=y}setZ(z:number){this.z=z}}向量分解,应用是三角函数的内容,将一个向量通过角度分解到x轴,y轴,z轴,或者根据不同轴上的坐标计算出对应的角度。

p>三角函数

向量的计算原理就不细说了。在游戏世界中,最终会被分解到对应坐标轴的方向进行计算,哪怕是点积或者向量积。所以只要熟练使用三角函数和向量计算公式,就可以对向量进行处理。我们将向数量增加以下计算方法:classVectorOperation{add(vectorA:Vector,vectorB:Vector){//向数量增加returnnewVector(vectorA.x+vectorB.x,vectorA.y+vectorB.y,vectorA.z+vectorB.z)}minus(vectorA:Vector,vectorB:Vector){//向量相减returnnewVector(vectorA.x-vectorB.x,vectorA.y-vectorB.y,vectorA.z-vectorB.z)}multiply(vectorA:Vector,times:number){//向量缩小returnnewVector(vectorA.x*times,vectorA.y*times,vectorA.z*times)}dotProduct(vectorA:Vector,vectorB:Vector){//向量积分returnvectorA.x*vectorB.x+vectorA.y*vectorB.y+vectorA.z*vectorB.z}vectorProduct(vectorA:Vector,vectorB:Vector){//向量积分returnnewVector(vectorA.y*vectorB.z-vectorA.z*vectorB.y,vectorA.z*vectorB.x-vectorA.x*vectorB.z,vectorA.x*vectorB.y-vectorA.y*vectorB.x,)}}而在游戏物理学中,还需要用到一门很重要的数学知识,那就是微积分。这样一来,你可能没有意识到这是一些基础的物理内容。为什么要使用差异化和整合?举个例子,让我们看一下最基本的速度公式,从平均速度开始,也就是行驶的距离除以经过的时间:$$v=\frac{s_{1}-s_{0}}{t_{1}-t_{0}}\tag{平均速度}$$那么计算某一时刻的速度其实就是在平均速度的基础上把时间差缩小到无穷小:$$v=\lim_{\Deltat\to0}\frac{\Deltas}{\Deltat}=\frac{ds}{dt}\tag{speed}$$

区分原理

/中心>这是差异应用程序。积分的应用呢?让我们来看看最基本的速度和距离公式。匀速运动中的公式如下,其中t为运动时间:$$s_{1}=s_{0}+v_{0}t\tag{匀速运动}$$其实这个公式的本质应该是:$$s_{1}=s_{0}+\int_{t_{0}}^{t_{1}}v_{0}dt\tag{uniformmotion}$$ormore这只是一个简单的应用的微积分,由此可见微积分在游戏中的运用也是非常重要的,所以我们也应该在代码中添加相应的方法。物理基础是在虚拟世界中。我们要想得到和现实一样的体验,就必须遵循现实中的物理规律。苹果不可能飞上天。因此,让我们首先构建一个模拟真实环境的对象。在物理引擎中,对象应该具有哪些属性?最重要的就是上面说的位置信息,所以对应的信息就是改变位置信息,也就是速度。然后又引出一个值,就是改变速度的信息,也就是加速度。在此基础上,我们可以得到一个最基本的对象应该具备的属性:=位置||newVector(0,0,0)this.velocity=速度||newVector(0,0,0)this.acceleration=加速度||newVector(0,0,0)}setPos(pos:Vector){this.pos=pos}setVelocity(velocity:Vector){this.velocity=velocity}setAcceleration(acceleration:Vector){this.acceleration=加速度}}我们现在有了最基本的物体,想要让这个物体融入物理系统并被我们随意操纵,就需要将物体与力结合起来。两者合起来就是牛顿三定律。第一个是牛顿第二定律,它指出施加的力可以改变物体的运动状态。用一个简单的公式表示:$$\vecF=m\veca\tag{牛顿第二定律}$$也就是说,如果我们要把加速度和力结合起来,就需要给物体一个变量,即质量m。然后我们给上面的对象添加质量属性:){if(mess>0){this.mess=mess}}}但是这时候我们会遇到两个问题:第一,物体的质量不能为0,如果设置为0,会导致质量设置错误;第二,一些物体,我们需要它们具有无限的质量,比如地面和墙壁,我们需要它们在游戏场景中保持固定。所以一方面0是不允许的,另一方面是无穷大是很难设置的。我们应该做什么?在游戏物理学中,提出了一个叫做反质量的概念,巧妙地解决了这个问题。反质量实际上是质量的倒数,即$\frac{1}{m}$,在这种情况下,我们只需要将要固定的物体的反质量设置为0,使其质量无穷大,并且还要避免质量设置为0的情况。classGameObj{inverseMess:number//mass不能为0constructor(inverseMess?:number){if(inverseMess>=0){this.inverseMess=inverseMess}}setInverseMess(inverseMess:number){if(inverseMess>=0){this.inverseMess=inverseMess}}}结论至此,我们需要的最基本的数学和物理知识已经成功注入物理引擎,但这只是基础一个物理引擎。在此基础上,我们还需要加上各种东西,比如重力、阻力、动量、角动量、碰撞等等。这背后还有很长的路要走,我将在本系列中展示。欢迎关注傲兔实验室博客:aotu.io或关注傲兔实验室公众号(傲兔实验室),不定期推送文章。