Overview

Games now seem to have become a form of entertainment that everyone can't avoid. From large-scale mobile games, to web games, to H5 mini games in various APPs, it has invaded our lives in various ways. So while enjoying the game, as a front-end developer, I also began to think about how to develop a game. What should it have at the technical level?

In addition to the basic game graphics, animation development, and rendering functions, there is another thing worth exploring, and that is the physics engine. A good physics engine ensures that the interactive experience in the game is similar to that in reality and provides a better experience.

There are many physics engines that are easy to use, and most of them are used out of the box, but some people may not understand what the basics and underlying logic of the physics engine look like. Starting from this issue, we will introduce the basics of the physics engine in multiple parts to let everyone know more about it. The following content is partly referenced from "Game Physics Engine Development".

What is an engine

What is the engine? Of course, this is an extension of the concept of the engine in the car. In a car, the engine, a device for energy conversion, converts other energy into mechanical energy and provides it to the car. It is the core module for the car to move.

Correspondingly, what is the engine in development? In my understanding, it is a core module that can quickly add each function to the project and ensure that the function runs. The rendering engine can quickly achieve content rendering. The game engine can quickly realize the basic development of a game. The physics engine can quickly simulate the physical state in reality.

After understanding what an engine is, we can pay attention to what are the characteristics of the engine. The biggest feature of the engine is two- fast , general . It can quickly realize the required functions and has strong versatility. It is not developed for a specific business, but for a large class of situations, so it must have strong versatility.

Fast means that the functions need to be complete, the API package is complete, and the use is convenient. Universal means that the logic of the code itself needs to be sufficiently low-level, and the most basic logic can be used to achieve the greatest versatility.

The basis of physics engine

What is the basis of a physics engine? That is physics and mathematics. In fact, the embodiment of a physical system in the game is the position of each object in the entire physical system. Every frame needs to calculate the position of the objects so that they can appear in the right place. Therefore, mathematical operations that conform to the laws of physics are the foundation of a physics engine. Everything below is explained on this basis.

Mathematics in code

The first thing to look at is where mathematics plays a role in the game world. Whether in a two-dimensional or three-dimensional world, the description of the position of an object is done by vectors. The processing of vectors is inevitable with knowledge of decomposition, addition and subtraction, dot product, vector product, etc. of the vector itself.

So we must first establish a basic vector class:

class Vector {
  x: number
  y: number
  z: number
  constructor(x: number,y: number,z: number) {
      this.x = x
      this.y = y
      this.z = z
  }

  setX(x: number) {
    this.x = x
  }

  setY(y: number) {
    this.y = y
  }

  setZ(z: number) {
    this.z = z
  }
}

The decomposition of a vector uses the content of a trigonometric function to decompose a vector into the x-axis, y-axis, and z-axis by angle, or calculate the corresponding angle according to the coordinates on different axes.
<center>

<img src="https://img10.360buyimg.com/ling/jfs/t1/187655/26/15116/36501/60fe5e98E34fe5aa7/0ed9686b387c2d38.png" width=400>
</img>
<p>三角函数</p>

</center>

The calculation principle of vectors will not be elaborated in detail. In the game world, it will be decomposed into the direction of the corresponding coordinate axis for calculation, even if it is a dot product or a vector product. So as long as you are proficient in using trigonometric functions and vector calculation formulas, you can process vectors.

We will add the following calculation methods to the vector:

class VectorOperation {
  add (vectorA: Vector, vectorB: Vector) { //  向量相加
    return new Vector(
        vectorA.x + vectorB.x,
        vectorA.y + vectorB.y,
        vectorA.z + vectorB.z
    )
  }

  minus (vectorA: Vector, vectorB: Vector) { // 向量相减
    return new Vector(
        vectorA.x - vectorB.x,
        vectorA.y - vectorB.y,
        vectorA.z - vectorB.z
    )
  }

  multiply (vectorA: Vector, times: number) { // 向量缩放
    return new Vector(
        vectorA.x * times,
        vectorA.y * times,
        vectorA.z * times
    )
  }

  dotProduct (vectorA: Vector, vectorB: Vector) { // 向量点积
    return vectorA.x* vectorB.x + vectorA.y* vectorB.y + vectorA.z* vectorB.z
  }

  vectorProduct (vectorA: Vector, vectorB: Vector) { // 向量外积
    return new Vector(
      vectorA.y * vectorB.z - vectorA.z * vectorB.y,
      vectorA.z * vectorB.x - vectorA.x * vectorB.z,
      vectorA.x * vectorB.y - vectorA.y * vectorB.x,
      )
  }
}

In game physics, a very important mathematical knowledge is also needed, which is calculus.

In this way, you may not be able to realize it. They are all basic physics content. Why do we use differentiation and integration? Let’s take an example. Let’s take a look at the most basic speed formula. Start with the average speed, which is the distance traveled divided by the time elapsed:
$$ v = \frac {s_{1}-s_{0}}{t_{1}-t_{0}} \tag{average speed}$$

Then there is the calculation of the speed at a certain moment. In fact, based on the average speed, the time difference is reduced to infinitesimal:
$$ v = \lim_{\Delta t \to 0} \frac {\Delta s}{\Delta t} = \frac{ds}{dt} \tag{speed}$$

<center>

<img src="https://img11.360buyimg.com/ling/jfs/t1/185224/37/20023/79749/611cb271E555947b1/fb03f04909f34df0.png" width=400>
</img>
<p>微分的原理</p>

</center>

This is the application of differentiation. What about the application of points?

Let’s take a look at the most basic formulas of speed and distance. The formulas in uniform motion are as follows, where t is the motion time:
$$ s_{1} = s_{0} + v_{0}t \tag{uniform motion}$$

In fact, the essence of this formula should be:
$$ s_{1} = s_{0} + \int_{t_{0}}^{t_{1}}v_{0}dt \tag{uniform motion}$$

The above is just a simple application of calculus, which shows that the use of calculus in the game is also very important, so we should also add the corresponding method to the code.

Physical basis

In a virtual world, if we want to get the same experience as reality, we must also follow the physical laws in reality. It is impossible for an apple to fly upward. From this we first build an object that simulates the real environment.

In the physics engine, what attributes should an object have? The most important thing is the position information mentioned above, then the corresponding information is the information to change the position, that is, the speed. Then another value is derived, which is the information to change the speed, which is the acceleration. On this basis, we can get the attributes that a most basic object should have:

class GameObj {
  pos: Vector
  velocity: Vector
  acceleration: Vector

  constructor(pos?: Vector, velocity?: Vector, acceleration?: Vector) {
      this.pos = pos || new Vector(0, 0, 0)
      this.velocity = velocity || new Vector(0, 0, 0)
      this.acceleration = acceleration || new Vector(0, 0, 0)
  }

  setPos (pos: Vector) {
    this.pos = pos
  }

  setVelocity (velocity: Vector) {
    this.velocity = velocity
  }

  setAcceleration (acceleration: Vector) {
    this.acceleration = acceleration
  }
}

We now have the most basic object. If we want to integrate this object into the physical system to be manipulated by us, we need to combine the object and force. And it is Newton's three laws that combine the two.

The first is Newton's second law, force can change the state of motion of an object. Expressed in a simple formula is:

$$ \vec F = m\vec a \tag{Newton's second law}$$

That is to say, if we want to combine acceleration and force, we need to give the object a variable, which is the mass m. Then we add quality attributes to the above objects:

class GameObj {
  mess: number // 质量不得为 0

  constructor(mess?: number) {
    if (mess > 0) {
      this.mess = mess
    }
  }

  setMess (mess: number) {
    if (mess > 0) {
      this.mess = mess
    }
  }
}

But at this time we have two problems: first, the mass of the object cannot be 0, if it is set to 0, it will cause the quality setting to be wrong; second, for some objects, we need it to have infinite mass, such as the ground, The wall, we need it to remain fixed in the game scene. So on the one hand, 0 is not allowed, and on the other hand, it is infinity, which is difficult to set. What should I do?

A concept called inverse mass was proposed in game physics, which cleverly solved this problem. The inverse mass is actually the reciprocal of the mass, which is $\frac{1}{m}$. In this case, we only need to set the inverse mass of the object to be fixed to 0 to make its mass infinite and avoid The quality is set to 0.

class GameObj {
  inverseMess: number // 质量不得为 0

  constructor(inverseMess?: number) {
    if (inverseMess >= 0) {
      this.inverseMess = inverseMess
    }
  }

  setInverseMess (inverseMess: number) {
    if (inverseMess >= 0) {
      this.inverseMess = inverseMess
    }
  }
}

Concluding remarks

So far, the most basic mathematical and physics knowledge we need has been successfully injected into the physics engine, but this is only the cornerstone of a physics engine. On this basis, we have to add various things. , Such as gravity, resistance, momentum, angular momentum, collision and a series of content. There is still a long way to go behind this, and I will show them one by one in this series.


Welcome to follow the blog of Bump Lab: aotu.io

Or follow the AOTULabs official account (AOTULabs) and push articles from time to time.


凹凸实验室
2.3k 声望5.5k 粉丝

凹凸实验室(Aotu.io,英文简称O2) 始建于2015年10月,是一个年轻基情的技术团队。