【Cocos2d-x】视线和光线:如何创建 2D 视觉范围效果

【Cocos2d-x】视线和光线:如何创建 2D 视觉范围效果

论坛看到的一片很好的文章,果断收藏,转过来方便大家查看~

Android客户端下载:sight_and_light-debug.rar


以下翻译转载自:indienova

原文:http://ncase.github.io/sight-and-light/

注意:手机浏览可能会不能加载内嵌网页


今天,我要介绍大家制作如下这个效果:(鼠标移动可看不同效果,可在原文中尝试交互效果)

这个效果被用在了我最新的开源游戏《Nothing To Hide》里面。您可能知道,有不少游戏都有类似的效果,比如《摩纳哥:你的就是我的(Monaco: What’s Yours Is Mine)》、《爆破杰克(Dynamite Jack)》以及《史莱姆吉什(Gish)》等。说不定也会出现在你的游戏中!

我会将自己的实现步骤以及在开发过程中犯过的错误展示出来。首先,是一些预热的内容,下面的演示展示了绘制一些线段并且跟踪鼠标的位置。(提示:一个方形由四条线段组成,以此类推)

接下来是比较数学的一部分。别担心,只是回忆一下之前学过的代数。


我们需要找到视线(也可以是光线,我们用视线来统一代替)和这些线段之间最近的交点。任何一条线都可以这样来表示:

1
Point+Direction*T

这样,我们就可以得到关于视线和线段的四个等式:

1
2
3
4
RayX=r_px+r_dx*T1
RayY=r_py+r_dy*T1
SegmentX=s_px+s_dx*T2
SegmentY=s_py+s_dy*T2

注意:在我们开始之前,要注意检查视线和相对应的线段是否平行,也就是方向是否相同。如果平行,就没有交点,不用处理。


如果它们(视线和相对应的线段)相交,那么交点的 X 和 Y 应该相等,也就是:

2
r_px+r_dx*T1=s_px+s_dx*T2
r_py+r_dy*T1=s_py+s_dy*T2


我们将用下面的方法取得 T1 和 T2

4
5
6
7
8
9
10
11
//IsolateT1forbothequations,gettingridofT1
T1=(s_px+s_dx*T2-r_px)/r_dx=(s_py+s_dy*T2-r_py)/r_dy
//Multiplybothsidesbyr_dx*r_dy
s_px*r_dy+s_dx*T2*r_dy-r_px*r_dy=s_py*r_dx+s_dy*T2*r_dx-r_py*r_dx
//SolveforT2!
T2=(r_dx*(s_py-r_py)+r_dy*(r_px-s_px))/(s_dx*r_dy-s_dy*r_dx)
//PlugthevalueofT2togetT1
T1=(s_px+s_dx*T2-r_px)/r_dx

要确保 T1>0 和 0<T2<1。如果不是这样,那么预计中的交点并不在视线或者线段上,其实也就是无交点。如果由交点,那很好!你找到一个交点。现在用同样一条视线和所有线段计算,以便找到最近的交点(应该是 T1 值最小的那个)。


下面是看起来的样子:(移动鼠标的效果)

很好,现在让我们发射出 50 条视线来:

然后,我想,我只要连接起这些交点来,就可以得到一个看起来不错的多边形,结果看起来是这样:

见鬼。就算我发出 360 条视线,也还是看起来不对劲儿。这个问题困扰了我半天,直到我意识到:我不用向所有方向发出视线,我只需要向每个线段的端点发出视线就可以。

针对每一条(不同的)线段的端点,我直接发出视线,另外增加两条偏移量为 +/- 0.00001 弧度的视线。这两条额外的视线用来去和线段后面的墙来相交。

接下来,我按照这些视线的角度将这些交点排序,这样我就可以简单的按照顺时针顺序将它们连接起来,可以绘制出一个看起来满意的多边形。

最后!看起来确实不错了。我又添加了一些效果,看起来就像下面这样,带有一些模糊的阴影效果。红点代表的是 11 个初始点——是的,11 个多边形。

最后,做了些改进,我放了两幅图。然后,将这两幅图混合,就成了我们在开始的时候看到的那个效果那样。

然后我又添加了额外的光源,就成了下面这样

多光源、投射阴影、激光感应炸弹、显示你或者敌人的可视范围……这种 2D 的效果有很强的可扩展性,如果应用得当,加上好的创意,可以大大增强你的游戏的吸引力。

Cocos2d-x实现过程

这个效果最初是在indienova看到的相关介绍,于是就开始琢磨如何在Cocos2d-x中实现这个效果。


第一次尝试:

这个效果是由 背景图(骷髅)和前景(美女)图 叠加形成的,在光线变动的情况下背景保持不变,而前景根据光线的明暗相应的显示对应部分的明暗度,而没有被光线照射到的地方隐藏掉。

首先想到的自然是 DrawNode 绘画出光照射到的多边形区域,然后用ClippingNode 设置DrawNode 为模板来绘制前景图。

但是从效果中可以看出影子中还会区分透明度,越偏离视线的方向的光线越暗,并与前景叠加,前景被分成了几个层次的透明度。

ClippingNode在绘制模板的时候会把模板扣抠掉,如果可以保留模板的绘制的话,就可以将前景与模板的颜色做blend处理,形成多层次透明度。

查阅 ClippingNode 代码,发现ClippingNode在做模板设置的时候设置了 模板测试 从不通过,所以模板怎么都不会被绘制出来。

glStencilFunc(GL_NEVER,mask_layer,mask_layer);
glStencilOp(!_inverted?GL_REPLACE:GL_ZERO,GL_KEEP,GL_KEEP);

可以修改为:

glStencilFunc(GL_GEQUAL,monospace!important; font-size:1em!important; min-height:inherit!important; background:none!important">glStencilOp(GL_KEEP,!_inverted?GL_REPLACE:GL_ZERO);

然后设置前景的blend func 为:

3
autofore=Sprite::create( "foreground.png" );
BlendFuncfunc={GL_DST_COLOR,GL_NONE};
fore->setBlendFunc(func);

此时测试模板和前景是能很好的叠加效果的。


但是接下来使用DrawNode绘制多边形的时候却出现了问题,DrawNode对于处理复杂多边形并不能胜任,画出来的形状都是乱飞的。


第二次尝试:

这次尝试了使用了 前一篇文章 介绍的nanovg 来绘制多边形,首先建了个NvgNode,重载draw 里面写绘制函数,将这个node作为模板,最后发现新问题:

1.nanovg 绘制的效率比较低,简单测试同为使用多边形填充整个屏幕,nanovg 30帧,DrawNode 60帧,差的还是比较多。

2.nanovg 处理多边形是 也是 使用 模板来处理 填充颜色,修改了一番还是不能够很好的和cocos结合,没有再往深处继续研究。


第三次尝试:

这次还是回到了DrawNode上,对于opengl 绘制 复杂多边形上进行资料搜索。

看到几种解决方案(参考):

第一种解决方案:多边形网格化法

对于非简单多边形、非凸多边形或有洞的多边形,OpenGL在GLU库中提供了一个多边形网格化对象GLUtesselator,对多边形进行网格化————将它们分解成一组简单的、能够进行渲染的OpenGL多边形。

经测试这种方法对凹凸多边形和自交、带孔多边形都能正确的渲染。


第二种解决方案:模板缓冲法stencil Buffer

可以参考nanovg中的实现方法


第三种解决方案: 凹多边形凸分解法

思路: 使用算法将凹多边形分解为多个凸多边形或一系列的三角形,然后进行渲染。

这里 列出了许多三角形划分多边形算法的实现,这里选了一个比较靠谱的 Triangulate 来使用。

将最后输出的多边形分解为三角形后调用DrawNode::drawTriangle 来绘制,成功!


项目地址:https://github.com/2youyouo2/sight_and_night


来源网址:http://cocokele.com/sight-and-light/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是