当我们进行游戏开发时,很多时候都需要用到一些几何知识,该文主要是抛砖引玉,通过一个 HTML5 的圈泡泡小游戏介绍下游戏开发中一些几何知识的运用。 游戏 demo 可以看这里:HTML5 圈泡泡小游戏 demo 游戏中一个最主要的操作就是通过鼠标的圈选,捕获选区内的小球并得分(或扣分)。我们一步步来分析这个操作。
Step1:画笔的形成。
首先是,怎样通过鼠标画出一个条条曲线?我们知道,HTML5 游戏的开发中,我们看到游戏里每个动作的更新,都是通过循环中每一帧对游戏元素属性的更新而形成的。因此我们只需要在每次帧更新的时候根据鼠标上一次更新时的位置与本次帧更新的位置画出一条线段,那么在游戏无数次的循环中,鼠标划过的位置就由 N 条线段连成一个轨迹,如果我们把线段都绘制出来,画布上就是一条条曲线或一个个圈。 因此我们也可以说,曲线是一条由多条线段首尾相连的线段组成的 。
Step2:保存线段
由于之前我们已经把曲线划分为一条条线段,因此在代码中,我们最好声明一个线段类,曲线中每条线段生成一个线段对象,并保存在数组中,方便我们后续对它们的访问。
1 2 3 4 |
if(!isPosSame()&&input.mouse.left_pressed){//如果和上次位置不一样并且按着鼠标左键,则生成线段 var newLineSeg=new Line({start:prePos,end:currentPos,lineWidth:5}); list.add(newLineSeg); } |
Step3:怎样知道选区是否闭合了?
判断选区闭合的方法很简单,首先我们需要获取曲线每条线段的对象,如果一条线段除了和它相邻的线段之外,还有和其他的线段相交,就证明线段组成的曲线是闭合的,因此问题现在就变为了如何判断线段的相交。
Step4:相交线段的判断。
线段的相交可以使用判断线段端点是否在另一条线段两边或外积的方法,可以参考 hongru 的一篇文章:关于简单的碰撞检测。该游戏中我使用的是前一种方法。
Step5:小球被圈中了么?
想要得分,我们就需要尽量圈中小球,可是怎样判断小球被圈中呢?游戏中,只要小球的球心被圈中,我们就认为小球被圈中。所以问题就转化为:如何判断点在一个多边形内。 判断点在多边形内有很多方法,这里使用的叫射线法。意思是,从该点向左作一条射线,如果该射线和多边形的交点为奇数,则证明该点在多边形内部。之前已经保存了多边形每条边的线段对象,以及介绍过相交线段的判断,所以我们要做的就只是判断射线和每条线段交点的总个数了。
1 2 3 4 |
var lLine=new Line({start:[ballCenter[0],ballCenter[1]],end:[0,ballCenter[1]],lineWidth:5});//左射线 if(lLine.isCross(lines[i])){ count++; } |
总体来说用到的知识点就以上五点了,当然还有很多细节需要考虑,例如如果点在多边形外部,射线和多边形顶点相交,交点个数也为奇数,这些细节的地方就留给大家当练习吧:)
horizon 2012 年 4 月 18 日
顶 晓思啊。 Cson 的 blog 也挺好的 (^^)