解说cocos2d-x几种画图方法的用法与思考
CCRenderTexture
自己的理解
CCRenderTexture类似一张空白的“画布“,用户通过自定义笔刷(CCSprite*),在touch事件中把笔刷的移动痕迹“记录”起来,从而“画”出各种艺术效果。记录方法很简单,首先CCRenderTexture调用自己的begin()函数,开启“记录”功能,然后调用笔刷->visit()把自己”画“在这张画布上,最后CCRenderTexture调用end()结束记录,那就OK了。
这里我想CCRenderTexture是通过把笔刷的纹理叠加到自己的纹理(Texture)里,而不是不断创建新纹理,所以消耗比较低,即使画得很频繁,帧数也能保持稳定,是个很赞的类。
CCRenderTexture由于只要begin()开启“记录”功能后,任何之后的CCNode*对象只要调用了visit(),就能将自己“画”在其身上。所以,一般游戏的截屏功能,完全可以使用CCRenderTexture的来实现,具体可以看tests里例子,cocos2d-x已经提供了相关例子,看看源代码就能搞明白的。
优点
用CCRenderTexture可以很简单的实现出理想的画图效果(只要搞一张很小的笔刷图,然后用CCSprite载入来,再适当调用一个CCSprite的visit()就行了),帧数消耗低,还很方便实现出游戏的截屏功能,做《你画我猜》这种项目,第一想到的应该就是它了。
缺点
由于每个Android手机的硬件或者OpenGL版本不一样,导致有些手机用CCRenderTexture会出现花屏,比如HTC。就算是官方提供的tests例子也难逃一花屏,这个致命的缺点导致用它来实现的《你画我猜》不能跨手机,比较坑爹…
这个Bug我想不是cocos2d-x引擎的问题,有牛人说是因为Texture在重复画导致的(只画一次没问题,所以截屏功能应该不受影响),也许是每台Android手机的OpenGL不一样吧,所以问题一直没得到解决,只能等cocos2d-x或者有其他牛人以后可以把它Fixed掉。
因为花屏问题,现阶段不推荐使用(如果有牛人解决了花屏问题,请教教我,谢谢)
[ 花屏参考图 ]
例子
CCRenderTexture大概是大家比较熟悉的,tests里也有相关例子,要知道用法直接看tests的源代码就可以了,效果如图:
用OpenGL-ES实现画图
自己的理解
OpenGL-ES是OpenGL的精简版,由于太精简,很多OpenGL常用的函数都被“简”掉了,导致有很多网上一搜一大把的画图算法用不上。所以用OpenGL-ES画图,这个感觉难度非常高。
在cocos2d-x中,OpenGL-ES一般在draw()这个函数里面调用其相关函数。当然cocos2d-x也封装了几个常用的画图函数:ccDrawLine,ccDrawCircle等,当然cocos2d-x也提供了例子,在tests里可以轻松找到。
优点
暂时没想到,因为我本身对OpenGL-ES不熟…
缺点
实现难度大可以拦截一大批人了,感觉。因为不能像CCRenderTexture那样在touch事件中进行绘图,所以一般会把要画的CCPoint在touch事件的记录下来,然后在draw()这个函数里遍历之,以实现绘图效果。
移动过的点一般都要保存下来,注意的是要全部保存,如果只保存当前点的话,draw()就只会画一个点,画出来的效果就像一个“光点”跟随的鼠标移动,而不是绘图。一般画一幅画,鼠标都会拖动出N个点,如果只是简单的vector保存的话,vector会超大,draw中遍历它也很耗时,导致没一会帧数就掉光了。具体怎么保存看数据结构吧,同事以线段作为数据结构来记录点,这样消耗不大,帧数也能保持稳定。
另外一个缺点就是如果算法实现不好,画出来的效果很坑爹,同事的线段法虽然能很流畅的画线,但是锯齿问题很严重,开了OpenGL的抗锯齿也没效果。如果对OpenGL-ES很熟而且算法也很牛的话,也许draw()是最快最好的一种画图法了。
最后还一个超坑爹的缺点:draw()在Google那台三星手机上,始终画在最顶层显示,然后线条就会把游戏UI遮盖住了,无论怎么设置z-Order都没用,估计是Google的三星手机的OpenGL-ES做过什么特殊处理吧,导致“坑爹啊…”
[ 万恶的锯齿…]
例子
Cocos2d-x提供的相关例子(DrawPrimitivesTest),常见的画直线、画圆、画Bezier线等,都有函数提供,具体还是自己打开tests看看源代码吧,这里就不详述了。
[ DrawPrimitivesTest ]
CCSpriteBatchNode
自己的理解
用CCSpriteBatchNode生成的CCSprite共用一个纹理,这样的好处是生成很多相同的CCSprite很高效,帧数可以很高很稳定。由于这个特点,用来实现粒子效果是一个很好的选择,不过我还没有看过cocos2d-x粒子系统的实现,这里不做推测,以免误导大家。关于CCSpriteBatchNode的用法当然还是tests里面有,有兴趣的朋友可以自己看看。
优点
由于draw()实现难度太高,而CCRenderTexture又有花屏的问题,所以尝试用CCSpriteBatchNode来实现画图,绘图效果很不错,因为是使用CCSprite做自定义笔刷嘛。帧数保持58-60,很稳定(如果只是单纯的创建CCSprite*,然后addChild到Layer里,掉帧会很严重的)
缺点
虽然CCSpriteBatchNode效果很不错,不过也有一个致命的缺点,就是CCSpriteBatchNode*对象不能addChild太多的CCSprite*对象,同事做了一下实验,大概addChild到16000+个CCSprite后,CCSpriteBatchNode就不能addChild了,也就是说,画图画到16000+个点后,画笔就“没墨水”,导致鼠标再怎么拖都没效果。
查看了一下源代码,大概是CCSpriteBatchNode在addChild时会重新分配内存,当需要分配的内存很大时,回导致内存分配失败,从而CCSpriteBatchNode会将这次addChild无效掉。
解决思路有一个,就是来个计数,当CCSpriteBatchNode它addChild到10000个后,用CCRenderTexture截个图保存当前的画图记录,然后清空CCSpriteBatchNode和把计数置零,再来画图。这个操作会有延迟,所以没有实现。
CCRibbon
自己的理解
CCRibbon应该说是一个线段集吧,与上述方法不同的是,它只能是单一颜色。就是说,你将它setColor为红,那么你画过的线条就全部为红,为蓝的话,则线条全部为蓝。
生成一个CCRibbon*对象需要指定:笔刷的宽度,笔刷的图片,线段的长度,笔刷的颜色等参数(Fade最后这个参数暂时还没搞懂意思…)。
CCRibbon提供addPointAt(CCPoint location, float width),将点以多宽加入到CCRibbon中,这里cocos2d-x对这个点的大小进行计算,从而使线条达到“头尾窄,身体宽”的效果。这个可以说是优点也可以说是缺点吧,“头尾窄,身体宽”看起来比较像笔刷,不过想做出均匀的画笔就不行了。
优点
帧数稳定,笔刷效果不错。因为CCRibbon也是用draw()进行画图,所以不用担心CCRenderTexture那样的花屏问题,CCRibbon目前感觉是比较理想的画图方法了。
缺点
如果在(100,100)点上一个点,然后跑去(400,400)再点一个点,CCRibbon会自动将两个点连起来,如果用户想做出平常画图那种“刷刷刷“的排线法,CCRibbon就不行了。解决方法就是每次TouchBegan都生成一个CCRibbon,这样就不会出现这个问题了,不过生成太多的CCRibbon不知道会不会出现其他问题,比如CCSpriteBatchNode那个…
由于CCRibbon是单一颜色的,所以想画彩色图是不行的。解决方法当然还是像上面那样,生个多个CCRibbon*对象,每个CCRibbon*对象的颜色不同就行了。
最后感觉不太人性化的就是画笔只能“头尾窄,身体宽“,如果想画出”头身尾均匀“的线条,用CCRibbon也许做不了。
例子
Cocos2d-x没有直接给出CCRibbon的例子,所以这个不能够在tests上看到使用方法,不过自己稍稍尝试一下就行了,用法挺简单。
解说cocos2d-x几种画图方法的用法与思考的更多相关文章
- fio 2种画图方法 fio_generate_plots 和 gfio
fio 安装fio apt-get install fio 可以把fio的输出数据自动画图的插件gnuplot apt-get install gnuplot 1.输出bw,lat和iops数据并画图 ...
- CSS3与页面布局学习总结(四)——页面布局大全BFC、定位、浮动、7种垂直居中方法
目录 一.BFC与IFC 1.1.BFC与IFC概要 1.2.如何产生BFC 1.3.BFC的作用与特点 二.定位 2.2.relative 2.3.absolute 2.4.fixed 2.5.z- ...
- Linux系统中存储设备的两种表示方法
转:https://blog.csdn.net/holybin/article/details/38637381 一.对于IDE接口的硬盘的两种表示方法: 1.IDE接口硬盘,对于整块硬盘的两种表示方 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- 深入理解javascript选择器API系列第三篇——h5新增的3种selector方法
× 目录 [1]方法 [2]非实时 [3]缺陷 前面的话 尽管DOM作为API已经非常完善了,但是为了实现更多的功能,DOM仍然进行了扩展,其中一个重要的扩展就是对选择器API的扩展.人们对jQuer ...
- javase-常用三种遍历方法
javase-常用三种遍历方法 import java.util.ArrayList; import java.util.Iterator; import java.util.List; public ...
- JS面向对象(3) -- Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- 火狐浏览器如何js关闭窗口的几种解决方法
今天在项目上有一个页面要求在几秒后自动关闭,想着还比较简单,用window.close()就可以了,但是用IE/谷歌/火狐浏览器试了一下,发现IE可以,谷歌用网上的兼容方法也可以实现,但是火狐这里卡住 ...
- java单例的几种实现方法
java单例的几种实现方法: 方式1: public class Something { private Something() {} private static class LazyHolder ...
随机推荐
- Java配置
JAVA_HOME -- JDK安装的路径 PATH -- 加入:;%JAVA_HOME%\bin; CLASSPATH -- 加入:;%JAVA_HOME%\lib\dt.jar;%JAVA_HOM ...
- 在VS2010上使用C#调用非托管C++生成的DLL文件
背景 在项目过程中,有时候你需要调用非C#编写的DLL文件,尤其在使用一些第三方通讯组件的时候,通过C#来开发应用软件时,就需要利用DllImport特性进行方法调用.本篇文章将引导你快速理解这个调用 ...
- 关于MooTools你应该熟知的6个基本知识
MooTools是一个精简.模组化同时也面向对象的JavaScript框架,它设计给中等和进阶的JavaScript开发人员使用.使用 MooTools优美.详细而条理分明的API,可让你写出强大.富 ...
- .NET中DLL“没有可放置在工具箱的组件”—FreeTextBox
主要针对在VS2012.VS2013的工具箱中,通过“选择项”添加自定义的Dll,如.NET类型时,出现“没有可放置在工具箱的组件”问题的常见解决方案.例如在线编辑工具:FreeTextBox 解决方 ...
- Nginx 之二: nginx.conf 配置及基本优化
一:常用功能优化: 1:网络连接的优化: 只能在events模块设置,用于防止在同一一个时刻只有一个请求的情况下,出现多个睡眠进程会被唤醒但只能有一个进程可获得请求的尴尬,如果不优化,在多进程的ngi ...
- mysql里的sql函数
仅作为自己忘记时的查询 时间 now() 返回当前年-月-日 时:分:秒格式的时间 UNIX_TIMESTAMP() 当前的uninx时间戳 date_format(date,格式) date是年月日 ...
- poj 3252
http://poj.org/problem?id=3252//自己搞了很长时间...现在刚刚有点明白.. 1 #include <iostream> using namespace st ...
- 依赖于设备的位图(DDB) ,CreateCompatibleBitmap用法
DDB(Device-dependent bitmap)依赖于具体设备,这主要体现在以下两个方面: DDB的颜色模式必需与输出设备相一致.例如,如果当前的显示设备是256色模式,那么DDB必然也是25 ...
- 首届全球RTB(实时竞价)广告DSP算法大赛
首届全球RTB(实时竞价)广告DSP算法大赛 竞赛指南 RTB (Real Time Bidding, 实时竞价) 是近年来计算广告领域最激动人心的进展之一. 它增加了展示广告的透明度与效率, ...
- hibernate+spring的整合思路加实例(配图解)
首先框架整合我感觉最难的是jar包的引入.因为不同框架的jar容易产生冲突.如果能排除这个因素我想说整合框架还是相对比较容易的. 我整合的框架的一个思想就是:各司其职.因为每个框架处理的事务或者是层次 ...