『小熊带你玩科技』KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下,如何用2( 三 )


mouseDown=mousePressed=mouseUpFrames=mouseX=0;onmouseup=e=>mouseDown=0;onmousedown=e=>mousePressed?mouseDown=1:mousePressed=1;onmousemove=e=>mouseX=e.x/window.innerWidth*2-1;
数学函数
这个游戏使用了一些函数来简化代码并减少冗余 。 一些标准的数学函数可以用来对值进行限定(Clamp)并进行线性差值操作(Lerp) 。 「ClampAngle」函数就非常有用 , 因为很多游戏需要将将角度限制在-PI和PI之间 , 而这个函数就可以做到 。
『小熊带你玩科技』KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下,如何用2
文章图片
随机测试样例
R函数的工作原理就像魔法——生成种子随机数 。 它先取当前随机种子的正弦值 , 乘以一个很大的数 , 然后小数部分就是最终的随机数 。 有很多方法可以做到这一点 , 但这是最节约空间的方法之一 。 我不建议使用这项技术来做赌博软件 , 但在我们的项目里 , 它的随机性已经足够了 。 我们将使用这个随机生成器在不需要保存任何数据的情况下创建各种程序 。 例如 , 山脉、岩石和树木的变化并不储存在内存里 。 但我们这里的目标不是减少内存 , 而是消除存储和检索数据所需的代码 。
由于这是一个「真3D」游戏 , 一个3D向量类就显得极为有用了 , 而且它还能让代码容量更小 。 该类只包含这个游戏所必需的基本要素——一个带有加法和乘法函数的构造函数 , 它的参数既可以是标量 , 也可以是向量 。 要确定是否传入了一个标量 , 只需检查它是否小于一个大数 。 使用「isNan」或是检查它的类型是否是「Vec3」当然更好 , 但它们需要更多的空间 。
Clamp=(v,a,b)=>Math.min(Math.max(v,a),b);ClampAngle=(a)=>(a+PI)%(2*PI)+(a+PILerp=(p,a,b)=>a+Clamp(p,0,1)*(b-a);R=(a=1,b=0)=>Lerp((Math.sin(++randSeed)+1)*1e5%1,a,b);classVec3//3dvectorclass{constructor(x=0,y=0,z=0){this.x=x;this.y=y;this.z=z;}Add=(v)=>(v=v<1e5?newVec3(v,v,v):v,newVec3(this.x+v.x,this.y+v.y,this.z+v.z));Multiply=(v)=>(v=v<1e5?newVec3(v,v,v):v,newVec3(this.x*v.x,this.y*v.y,this.z*v.z));}
渲染函数
LSHA使用模板字符串生成一个标准的HSLA(色相、饱和度、光度、透明度)颜色 , 并且刚刚重新排序 , 以便将更多经常使用的组件排列在前面 。 在关卡处发生的全局色调变化也是在这里发生的 。
DrawPoly可以绘制梯形 , 它也会被用于渲染场景中的所有东西 。 使用「|0」将Y分量转换为整数 , 以确保道路多边形完全连接 。 如果进行这项操作 , 在路段之间就会有一条细线 。 出于同样的原因 , 这种渲染技术必须在对角线图形的组件帮助下处理相机的滚动 。
DrawText则被用来渲染显示时间、距离和游戏标题的概述文本 。
LSHA=(l,s=0,h=0,a=1)=>`hsl(${h+hueShift},${s}%,${l}%,${a})`;
//drawatrapazoidshapedpolyDrawPoly=(x1,y1,w1,x2,y2,w2,fillStyle)=>{context.beginPath(context.fillStyle=fillStyle);context.lineTo(x1-w1,y1|0);context.lineTo(x1+w1,y1|0);context.lineTo(x2+w2,y2|0);context.lineTo(x2-w2,y2|0);context.fill();}
//drawoutlinedhudtextDrawText=(text,posX)=>{context.font='9emimpact';//setfontsizecontext.fillStyle=LSHA(99,0,0,.5);//setfontcolorcontext.fillText(text,posX,129);//filltextcontext.lineWidth=3;//linewidthcontext.strokeText(text,posX,129);//outlinetext}
通过过程生成来构建轨道
在游戏开始之前 , 我们必须首先生成整个赛道 , 而每个游戏的赛道都不同 。 为此 , 我们构建一个路段列表 , 它存储了道路在轨道上每个点的位置和宽度 。
轨道发生器很简单 , 它只是在不同频率、振幅和宽度的部分之间逐渐变细 。 赛道长度决定了这段赛道的难度 。


推荐阅读