用WebGL让目标动起来

Posted H5技术社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用WebGL让目标动起来相关的知识,希望对你有一定的参考价值。

在之前静态的示例中,我们现有的代码已被配置成每15毫秒就重新绘制一次WebGL的场景。但至今为止,每一次所绘制的场景都是相同的。让我们来改变这一点,使我们的正方形动起来。

在这个例子中,我们实际上对2D的正方形进行了三维旋转和移动;这证明即使我们建立的是一个2D的物体,但实际上它也是存在于3D空间中的。

旋转正方形

让我们从旋转正方形开始。首先我们需要一个变量来追踪正方形当前的旋转情况:

  1. var squareRotation = 0.0;

复制代码

现在我们需要更新 drawScene() 函数将当前的旋转状态应用于绘制正方形。在将正方形移动到初始绘制位置后,使用如下方法进行旋转:

  1. mvPushMatrix();

  2. mvRotate(squareRotation, [1, 0, 1]);

复制代码

这段代码存储了当前模型视图矩阵,然后按照squareRotation的值绕X轴和Z轴旋转矩阵。


绘制完成后,需要加载回之前的矩阵:

  1. mvPopMatrix();

复制代码

存储后再重加载原始矩阵的目的是:避免绘制其它图形时也受到这次旋转的影响。但在此例子中并没有绘制更多物体,所以在此这一步并没有实际意义。

为了让物体动起来,我们需要随时改变squareRotation的值。我们可以建立一个新的变量来追踪上一次动作的时间(可以称这个变量为 lastSquareUpdateTime ),并将如下代码添加到 drawScene() 函数的末尾:

  1. var currentTime = Date.now();

  2.   if (lastSquareUpdateTime) {

  3.           var delta = currentTime - lastSquareUpdateTime;

  4.           

  5.           squareRotation += (30 * delta) / 1000.0;

  6.   }

  7.   

  8.   lastSquareUpdateTime = currentTime;

复制代码

这段代码用当前时间与上次动作的时间差更新 squareRotation 决定旋转的角度。

移动正方形

在绘制正方形之前,可以先将图形移动到其它位置。下面的例子展示的是非常基础的动作——当然,在实际操作中一般不会用如此奇怪的变换。

让我们用一些新的变量来追踪每个轴的偏移量:

  1. var squareXOffset = 0.0;

  2. var squareYOffset = 0.0;

  3. var squareZOffset = 0.0;

复制代码

用如下的变量来表示每个轴上的变化量:

  1. var xIncValue = 0.2;

  2. var yIncValue = -0.4;

  3. var zIncValue = 0.3;

复制代码

在之前的旋转代码中加入如下的部分:

  1. squareXOffset += xIncValue * ((30 * delta) / 1000.0);

  2.     squareYOffset += yIncValue * ((30 * delta) / 1000.0);

  3.     squareZOffset += zIncValue * ((30 * delta) / 1000.0);

  4.     

  5.     if (Math.abs(squareYOffset) > 2.5) {

  6.       xIncValue = -xIncValue;

  7.       yIncValue = -yIncValue;

  8.       zIncValue = -zIncValue;

  9.     }

复制代码

最后,将下面的代码加入 drawScene()  函数中:

  1. mvTranslate([squareXOffset, squareYOffset, squareZOffset]);

复制代码

如下所示,正方形在旋转的过程中会缩放,在画布上随机移动且相对于观测者的位置循环地拉近缩远。它看起来更像一个屏幕保护程序。

更多矩阵操作

这个例子中使用了其他一些矩阵操作,包括两个用于保存矩阵的入栈出栈函数,以及一个将矩阵旋转特定的角度的函数。代码如下:

  1. var mvMatrixStack = [];


  2. function mvPushMatrix(m) {

  3.   if (m) {

  4.     mvMatrixStack.push(m.dup());

  5.     mvMatrix = m.dup();

  6.   } else {

  7.     mvMatrixStack.push(mvMatrix.dup());

  8.   }

  9. }


  10. function mvPopMatrix() {

  11.   if (!mvMatrixStack.length) {

  12.     throw("Can't pop from an empty matrix stack.");

  13.   }

  14.   

  15.   mvMatrix = mvMatrixStack.pop();

  16.   return mvMatrix;

  17. }


  18. function mvRotate(angle, v) {

  19.   var inRadians = angle * Math.PI / 180.0;

  20.   

  21.   var m = Matrix.Rotation(inRadians, $V([v[0], v[1], v[2]])).ensure4x4();

  22.   multMatrix(m);

  23. }

复制代码


以上是关于用WebGL让目标动起来的主要内容,如果未能解决你的问题,请参考以下文章

用C#制作推箱子小游戏

时光煮雨 Unity3d 序列目标点的移动①

推箱子

构建WebGL目标时的内存考量

有没有一些类似让网页上的图片动起来的东西?

开博纪念随笔一篇