2015.3.23优化修改,现在已经能达到稳定60帧了。。

 

本博客地址:http://www.cnblogs.com/wolfred7464/

创意来自于:http://ncase.me/sight-and-light/

 

我要介绍的,就是这样的效果:(创意和素材都来自于上文的网址)

用Cocos2d-x实现2D光线效果

由于原文介绍的过于简练,导致像我这样的小白根本看不懂,所以我想要介绍的更易懂一点。。

一、画线段

在Cocos2d-x中,已经封装了通过Opengl ES的画线函数,只需要创建一个DrawNode对象,就可以画线了,画几条线段,就像这样:

用Cocos2d-x实现2D光线效果

二、画射线和线段的交点及轨迹。

这里需要一点点几何知识了。(我也是恶补的)

     直线的参数表示:

直线可以用直线上的一点P0和方向向量v表示,直线上的所有点P满足 P = P0 + tv。

参数方程最方便的地方在于直线、射线、线段的方程形式是一样的,区别在于参数t。直线的t没有范围限制,射线的t>0,线段的t在0~1之间(t >=0 && t <= 1)。

     直线交点:

设直线分别为 P+t1v 和 Q+t2w,设向量u=QP,设cross(x, y)为向量x和y的叉积,则:

t1 = cross(w, u) / cross(v, w)

t2 = cross(v, u) / cross(v, w)

当cross(v, w) == 0时,两直线平行,无交点。

所以把屏幕中心作为光源,方向指向鼠标所在的位置,画一条射线,t即是光源与交点的距离,选一个最近的交点(即t最小),连接光源和这个点,就会得到这样的效果:

用Cocos2d-x实现2D光线效果

主要代码:

 1 bool HelloWorld::getIntersection(const Line& ray, const Line& segment, 
 2                                  Point& point, float& distance)
 3 {
 4     Vec2 v1(ray.p2 - ray.p1);
 5     Vec2 v2(segment.p2 - segment.p1);
 6     float cross = getCross(v1, v2);
 7     if(cross == 0) {
 8         return false;
 9     }
10     Vec2 u(ray.p1 - segment.p1);
11     float t1 = getCross(v2, u) / cross;
12     float t2 = getCross(v1, u) / cross;
13     if(t1 < 0 || t2 < 0 || t2 > 1) {
14         return false;
15     }
16     point = v1 * t1 + ray.p1;
17     distance = t1;
18     return true;
19 }
射线与线段的交点

相关文章: