Nape反射的激光

作者: ladeng6666 分类: Nape 发布时间: 2014-08-23 15:16 阅读: 6,383

Nape的刚体切割的教程中,我们曾经使用用rayCast()这个函数,不过只是用它来查找被切割的刚体,用法上也简单的一笔带过,今天我们来深入了解一下Nape中的rayCast()函数,并用它来实现射线反射的效果。

rayCast()是Space对象的一个方法,透过它的构造函数可以看的出,在使用之前,我们至少要有一个射线Ray对象,所以我们先来认识一下Ray。

射线Ray类在nape.geom包下,它的构造函数如下:

各个参数说明如下:

  • origin:射线的起始点,一个Vec2对象
  • direction:射线的方向,同样是一个Vec2对象

构造函数中没有定义射线的长度,这时长度默认是无限大的。之后就可以将Ray对象传递给rayCast(),发射一条射线了。

rayCast()执行完之后,会讲检测到与之发生碰撞的形状、碰撞面法向量、碰撞位置等信息保存到一个RayResult对象中并返回。

RayResult包含的属性和对应的碰撞信息说明如下:

  • distance:Number类型。碰撞点与射线起始点origin之间的距离。
  • normal:Vec2类型。碰撞面垂直的法向量,本章将根据normal的方向取射线的对称方向,实现射线的反射。
  • shape:Shape类型。与射线发生碰撞的形状,可以时Shape类的子类circle或polygon

通过下面的示意图,我们可以更清楚的认识这些属性所代表的意义。图中红色箭头表示射线,黑色的圆形是与之发生碰撞的形状。橙色背景的文本是rayCast的输入,即ray的属性;绿色背景的文本时rayCast的输出,即RayResult的属性。

NapeRaycast

遗憾的是RayResult没有为我们提供碰撞点的坐标,不过Ray提供了一个非常好用的方法at。通过调用Ray.at(distance),可以获得射线方向上距离起始点distance距离的坐标。那么碰撞点的坐标就可以通过下面的代码轻松获取了。

接着以这个点为起点,以原始射线相对normal的对称方向为新的方向,重新绘制一条射线,就实现了射线反射的效果了。

NapeRayReflect

关于对称方向的计算,都是一对向量公式,我已经单独写到LDMath.symmetric()函数中,如果你想了解原理,请参考我之前在9ria天地会发布的教程 http://bbs.9ria.com/thread-67614-1-1.html

在Flash中编译后的效果如下图所示(点击图像查看动态效果),射线以舞台中心为起始点,点击舞台任意位置,改变射线方向,射线会经过5次反射后停止下来。按下空格键,可以重新随机创建刚体。

NapeRaySym

代码部分重点在createRays()中,具体如下:

代码中以及进行了详细的备注,我就不再赘述了,其他不尽之处,欢迎跟帖讨论。点击下载完整源文件

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

16条评论
  • Yorhom

    2014 年 8 月 23 日 下午 7:28

    可惜Nape没有js版本,不知道拉登大叔有没有把Nape移植到其他版本的愿望?

    1. ladeng6666

      2014 年 8 月 23 日 下午 10:32

      我Nape的官方论坛上提问了,问作者有没有意向发布HTML5版的Nape,还没有得到回复呢!

      1. Yorhom

        2014 年 8 月 24 日 上午 12:21

        哈哈,感谢登叔~其实有时候出于热情,自己也想写一个物理引擎,可是光说碰撞检测这一块儿就已经把我给难倒了,不知道大叔能不能写一篇与碰撞检测有关的文章?

        1. ladeng6666

          2014 年 8 月 24 日 上午 11:31

          推荐你看《advanced game design with flash》里面详细的讲解了圆对圆,圆对多边形,圆对线段等各种情形的碰撞原理!

  • 棋牌

    2014 年 8 月 30 日 下午 3:21

    1111111111111111111111111111111111

    1. 棋牌

      2014 年 8 月 30 日 下午 3:21

      22222222222222222222

  • kb

    2014 年 9 月 5 日 上午 10:05

    拉登大叔,一直不理解body.totalImpulse()的用法能不能详细讲一下,想算一下碰撞受到了多少力不知道怎么来

    1. ladeng6666

      2014 年 9 月 5 日 上午 10:28

      记得之前你问过我这个问题,不好意思,忘记了,一直也没有回复你。totalImpulse()函数用来计算碰撞过程中,body受到的总的冲量大小,如果参数中的body不为null,则只计算这个两个刚体之间的冲量大小。可以根据返回值大小,实现刚体超出耐受力,被击碎的效果。

    2. ladeng6666

      2014 年 9 月 5 日 上午 10:32

      回头我写篇教程说明一下,额,估计得到月底了…

      1. kb

        2014 年 9 月 5 日 上午 11:17

        但是为什么返回的是一个三维向量,z用来表示什么?

        1. ladeng6666

          2014 年 9 月 5 日 下午 1:51

          没试过,我也不是很确定,我猜应该是扭力

  • 2014 年 9 月 6 日 下午 2:36

    支持下!大叔

    1. ladeng6666

      2014 年 9 月 6 日 下午 9:21

      谢谢支持,我也努力写出更多更好的教程给大家!

  • 奇创游戏

    2014 年 10 月 1 日 上午 9:08

    拉登兄,怎么用最后两点计算一条延长的射线啊,我想用鼠标点击一下就能切开那条射线内的刚体。

  • 2014 年 10 月 4 日 下午 2:04

    Nape入门老师啊,教程很棒!

  • 2014 年 10 月 4 日 下午 2:05

    入门老师,教程很棒呀!!!

发表评论

电子邮件地址不会被公开。 必填项已用*标注