string(7723) "{"docs":[{"id":"158579","text":"\u3010Python\u3011Tkinter\u56fe\u5f62\u754c\u9762\u8bbe\u8ba1\uff08GUI\uff09","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"HGNET","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183196","_id":"158579"},{"id":"158620","text":"python\u4e4bgui-tkinter\u53ef\u89c6\u5316\u7f16\u8f91\u754c\u9762 \u81ea\u52a8\u751f\u6210\u4ee3\u7801","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"darkspr","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183190","_id":"158620"},{"id":"158603","text":"python3.6 +tkinter GUI\u7f16\u7a0b \u5b9e\u73b0\u754c\u9762\u5316\u7684\u6587\u672c\u5904\u7406\u5de5\u5177","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"chenyuebai","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183187","_id":"158603"},{"id":"27850","text":"Python GUI\u4e4btkinter\u7a97\u53e3\u89c6\u7a97\u6559\u7a0b\u5927\u96c6\u5408\uff08\u770b\u8fd9\u7bc7\u5c31\u591f\u4e86\uff09 - \u6d2a\u536b","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"shwee","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183186","_id":"27850"},{"id":"158605","text":"Python GUI\u7f16\u7a0b(Tkinter) windows\u754c\u9762\u5f00\u53d1","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"itfat","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183184","_id":"158605"},{"id":"28228","text":"tkinter python\uff08\u56fe\u5f62\u5f00\u53d1\u754c\u9762\uff09","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"yudanqu","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183159","_id":"28228"},{"id":"158613","text":"Tkinter\u56fe\u5f62\u754c\u9762\u8bbe\u8ba1\uff08GUI\uff09","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"pywjh","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183158","_id":"158613"},{"id":"341361","text":"\u91cf\u5316\u5206\u6790\u83b7\u53d6\u6570\u636e\u76843\u79cd\u59ff\u52bf\uff08\u538b\u7bb1\u5e95\u7684\u795e\u5668Tushare\uff09","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"casual","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183069","_id":"341361"},{"id":"238879","text":"\u9762\u5411\u4ea4\u6613\u7684\u65e5\u5185\u9ad8\u9891\u91cf\u5316\u4ea4\u6613\u5e73\u53f0\u7b14\u8bb0","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"TaiYangXiManYouZhe","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183067","_id":"238879"},{"id":"238890","text":"2021 \u6700\u65b0\u91cf\u5316\u6295\u8d44\u4ea4\u6613\u8d44\u6e90\u6c47\u603b","intro":"\u76ee\u5f55\n\nECharts\n\u5f02\u6b65\u52a0\u8f7d\n\n\n\nECharts\r\n\u6570\u636e\u53ef\u89c6\u5316\u5728\u8fc7\u53bb\u51e0\u5e74\u4e2d\u53d6\u5f97\u4e86\u5de8\u5927\u8fdb\u5c55\u3002\u5f00\u53d1\u4eba\u5458\u5bf9\u53ef\u89c6\u5316\u4ea7\u54c1\u7684\u671f\u671b\u4e0d\u518d\u662f\u7b80\u5355\u7684\u56fe\u8868\u521b\u5efa\u5de5\u5177\uff0c\u800c\u662f\u5728\u4ea4\u4e92\u3001\u6027\u80fd\u3001\u6570\u636e\u5904\u7406\u7b49\u65b9\u9762\u6709\u66f4\u9ad8\u7684\u8981\u6c42\u3002\r\nchart.setOption({\r\n color: [\r\n ","username":"xgqfrms","tagsname":"","tagsid":"","catesname":"","catesid":"","createtime":"1641183063","_id":"238890"}],"count":535118}" array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(6) "158579" ["text"]=> string(46) "【Python】Tkinter图形界面设计(GUI)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(5) "HGNET" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183196" ["_id"]=> string(6) "158579" } [1]=> array(10) { ["id"]=> string(6) "158620" ["text"]=> string(60) "python之gui-tkinter可视化编辑界面 自动生成代码" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "darkspr" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183190" ["_id"]=> string(6) "158620" } [2]=> array(10) { ["id"]=> string(6) "158603" ["text"]=> string(66) "python3.6 +tkinter GUI编程 实现界面化的文本处理工具" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(10) "chenyuebai" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183187" ["_id"]=> string(6) "158603" } [3]=> array(10) { ["id"]=> string(5) "27850" ["text"]=> string(80) "Python GUI之tkinter窗口视窗教程大集合(看这篇就够了) - 洪卫" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(5) "shwee" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183186" ["_id"]=> string(5) "27850" } [4]=> array(10) { ["id"]=> string(6) "158605" ["text"]=> string(45) "Python GUI编程(Tkinter) windows界面开发" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(5) "itfat" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183184" ["_id"]=> string(6) "158605" } [5]=> array(10) { ["id"]=> string(5) "28228" ["text"]=> string(39) "tkinter python(图形开发界面)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "yudanqu" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183159" ["_id"]=> string(5) "28228" } [6]=> array(10) { ["id"]=> string(6) "158613" ["text"]=> string(34) "Tkinter图形界面设计(GUI)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(5) "pywjh" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183158" ["_id"]=> string(6) "158613" } [7]=> array(10) { ["id"]=> string(6) "341361" ["text"]=> string(68) "量化分析获取数据的3种姿势(压箱底的神器Tushare)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(6) "casual" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183069" ["_id"]=> string(6) "341361" } [8]=> array(10) { ["id"]=> string(6) "238879" ["text"]=> string(51) "面向交易的日内高频量化交易平台笔记" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(18) "TaiYangXiManYouZhe" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183067" ["_id"]=> string(6) "238879" } [9]=> array(10) { ["id"]=> string(6) "238890" ["text"]=> string(41) "2021 最新量化投资交易资源汇总" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "xgqfrms" ["tagsname"]=> string(0) "" ["tagsid"]=> string(0) "" ["catesname"]=> string(0) "" ["catesid"]=> string(0) "" ["createtime"]=> string(10) "1641183063" ["_id"]=> string(6) "238890" } } ["count"]=> int(535118) } ‎Cocos2d-x 学习笔记(24) ParticleSystem ParticleSystemQuad - 爱码网
deepcho

1. ParticleSystem

ParticleData是存储粒子数据的类,ParticleSystem会关联一个ParticleData对象。

ParticleSystem直接继承了Node、TextureProtocol(纹理)、PlayableProtocol(start stop方法)。

ParticleSystem定义了粒子的相关属性。

粒子从ParticleSystem的位置发射。

属性

- float _elapsed

运行时间。

粒子相关属性

- float _startSize, _startSizeVar, _endSize, _endSizeVar

粒子大小及浮动值。

- Color4F _startColor, _startColorVar, _endColor, _endColorVar

粒子颜色值及浮动值。

- float _startSpin, _startSpinVar, _endSpin, _endSpinVar

粒子自身旋转的角度值及浮动值。

- PositionType _positionType

粒子位置模式,有3种:FREE(粒子在世界坐标系移动)、RELATIVE(粒子相对父节点坐标系移动)、GROUPED(粒子跟随发射点移动)。

- float _life, _lifeVar

粒子生存时间及浮动值。

发射相关属性

- float _angle, _angleVar

粒子发射的角度及浮动值。

- Mode _emitterMode

发射器模式。发射有2种模式,用枚举Mode表示:

Gravity:重力模式,Mode A,属性:重力加速度(向量表示)、速度和浮动值(粒子的初速度)、径向加速度和浮动值(与速度方向平行)、切向加速度和浮动值(与速度方向垂直)。

Radius:径向模式,Mode B,属性:起始半径和浮动值(粒子出生时和圆心距离)、结束半径和浮动值(粒子死亡时和圆心距离)、每秒旋转的角度和浮动值。

- float _emissionRate

发射器每秒发射的粒子数。

- int _totalParticles

生存的粒子最大数量。

- int _particleCount

当前生存的粒子数。

- float _duration

发射器工作时长,-1为永远发射。

- Vec2 _sourcePosition, _posVar

发射位置及发射位置的浮动值。

_sourcePosition与bool _sourcePositionCompatible有关,布尔值默认为true表明兼容,位置将被设置到node的位置变量;为false位置将被设置到_sourcePosition变量。

两个静态属性

- static Vector<ParticleSystem*> __allInstances

存储粒子系统的容器。

 

- static float __totalParticleCountFactor

该属性默认为1。在update方法中,最大粒子数_totalParticles乘该系数,得到最大粒子数。

1. 创建

粒子对象的创建可以分为这3种方法:

- 通过代码创建ParticleSystemQuad,并设置属性

- 通过plist文件创建

- 直接通过代码使用现成的粒子子类实现特效

plist文件会被转成ValueMap,从而对plist的各项数据进行解析,相关属性值赋给ParticleSystem属性。

2. onEnter() onExit()方法

在执行addChild方法将粒子节点加到父节点时,会调用节点的onEnter方法。

ParticleSystem的onEnter方法中有这两行:

    this->scheduleUpdateWithPriority(1);
    __allInstances.pushBack(this);

先设置update方法将在每帧执行。再将当前粒子类加入静态容器__allInstances中。

ParticleSystem的onExit方法会执行unscheduleUpdate,停止每帧执行update(dt),并从静态容器__allInstances中删除粒子类。

3. update(dt)方法

该方法被调度器Scheduler每帧触发,粒子的更新离不开这个重要的方法。

4. 粒子添加与粒子到期后删除

ParticleSystem成员_particleCount表示当前存在屏幕上的粒子数(当前已生成没销毁的粒子数)。

在update(dt)中,每帧会调用粒子添加的方法addParticles(int count)。

添加数量为count的粒子,实际上是把粒子的数据被添加到ParticleSystem成员中_particleData。

新增的各个粒子各项数据是被修改到从对应的_particleData数组成员的“最末尾”的下标位置开始,要添加多少个粒子,就修改多少个指针。“最末尾”的下标指的是根据_particleCount得出。

粒子到期后删除时,也是在update(dt)方法中删除,但是没有真正执行“删除”操作,而是将_particleData最末尾(数组成员最末尾)的数据复制到当前粒子的位置上,并对_particleCount减1。

我们知道,在update方法中是把_particleData每个数组成员前_particleCount项作为当前存在的粒子的数据并进行更新。所以,“被复制”的数据项位置实际上在之后的update中被“忽略”了,所以该项的数据只会被新增的粒子覆盖,而前面被删除的粒子的数据位置被这个“被复制”的数据项覆盖,保证了数组成员前_particleCount项始终代表着当前存在的粒子的数据。

总结ParticleSystem

ParticleSystem关联一个ParticleData。

每个粒子当前的属性值状态信息等,被保存在ParticleData中。而ParticleSystem中的粒子信息是我们直接设置的,例如浮动值只存储在ParticleSystem成员变量中。

每一次update时,新建的粒子和当前粒子状态各项信息通过计算后,都被保存在ParticleData中。

尽管ParticleData是一个类,我们可以把它理解成是一个“容器”。粒子系统ParticleSystem主要是提供对粒子当前信息ParticleData“容器”的管理,例如对“容器”修改、更新、添加等。所以说,粒子系统ParticleSystem是所有粒子的基类,只负责粒子最基础的创建和存储功能。

2. ParticleSystemQuad

ParticleSystemQuad直接继承了ParticleSystem。所有粒子特效类都是ParticleSystemQuad的子类。

该类在父类的基础上增加了对粒子的绘制功能。

1. 顶点缓存与索引缓存

ParticleSystemQuad有两个重要变量:顶点缓存和索引缓存。

- V3F_C4B_T2F_Quad *_quads

顶点缓存:包含多个顶点数据的一块内存,一个四边形的4个顶点信息作为一个单位进行存储。每一个V3F_C4B_T2F_Quad结构体存储了4个顶点的信息(4个V3F_C4B_T2F结构体对象),每个顶点的信息包括三维顶点坐标、颜色和透明度、纹理UV坐标。

- GLushort *_indices

索引缓存:每6个索引对应一个四边形,OpenGL是通过三角形来绘制四边形的,所以一个四边形需要两个三角形的顶点数据,也就是6个索引对应1个V3F_C4B_T2F_Quad了。

在所有粒子效果类的create方法中,都会调用ParticleSystemQuad的initWithTotalParticles方法进行初始化,该方法会调用allocMemory分配粒子效果类需要的顶点缓存和索引缓存的内存区域。

内存的个数为我们设置的最大粒子数。

对于顶点缓存,每块内存的大小为V3F_C4B_T2F_Quad结构体的大小。对于索引缓存,每块内存为索引的6倍,也就是说把一个四边形需要的所有6个索引作为一个内存区域存储。大致逻辑是:

    memset(_quads, 0, _totalParticles * sizeof(V3F_C4B_T2F_Quad));
    memset(_indices, 0, _totalParticles * 6 * sizeof(GLushort));

索引缓存是对顶点缓存的映射,这样可以对于重复的顶点使用一个内存进行存储。

在刚才说的initWithTotalParticles方法进行两个缓存内存的分配之后,对索引缓存设置索引值,设置索引指向的顶点位置。具体步骤如下:

    for(int i = 0; i < _totalParticles; ++i)
    {
        const unsigned int i6 = i*6;
        const unsigned int i4 = i*4;
        _indices[i6+0] = (GLushort) i4+0;
        _indices[i6+1] = (GLushort) i4+1;
        _indices[i6+2] = (GLushort) i4+2;

        _indices[i6+5] = (GLushort) i4+1;
        _indices[i6+4] = (GLushort) i4+2;
        _indices[i6+3] = (GLushort) i4+3;
    }

另外,在setTotalParticles(int tp)方法中,根据参数最大粒子数,对顶点缓存_quads和索引缓存_indices大小更新并初始化,使用的也是类似上面的思路。

2. initTexCoordsWithRect(rect)

initTexCoordsWithRect(rect)方法,通过纹理更新每个粒子在的UV坐标。

该方法2个使用位置:

设置粒子的纹理时,使用setTexture方法,需要重新设置新纹理的UV坐标。

重新设置粒子最大数时,使用setTotalParticles方法,因为粒子总数发生改变,需要重新初始化顶点缓存和索引缓存,需要重新设置顶点缓存内的UV坐标。

该方法要求传入的参数rect是根据纹理坐标系(Texture coordinates,OpenGL坐标系)表示的,而不能是像素坐标系(Pixel coordinates)。

纹理坐标系(OpenGL坐标系)左下角为原点(0,0);像素坐标系是图片数据原始的坐标系,左上角为原点(0,0)。

接下来通过计算,得出矩形四个顶点的UV坐标。此时的UV坐标需要存入顶点缓存中,而顶点缓存是直接面向GPU的,所以不采用纹理OpenGL坐标系,而是像素坐标系。使用像素坐标系的结果是顶部的坐标值为0,与底部的坐标值交换了。

该方法最终向顶点缓存中存入一个矩形的4个顶点像素坐标系下的UV坐标:

    for(unsigned int i=start; i<end; i++) 
    {
        // bottom-left vertex:
        quads[i].bl.texCoords.u = left;
        quads[i].bl.texCoords.v = bottom;
        // bottom-right vertex:
        quads[i].br.texCoords.u = right;
        quads[i].br.texCoords.v = bottom;
        // top-left vertex:
        quads[i].tl.texCoords.u = left;
        quads[i].tl.texCoords.v = top;
        // top-right vertex:
        quads[i].tr.texCoords.u = right;
        quads[i].tr.texCoords.v = top;
    }

3. updateParticleQuads()

该方法在ParticleSystem的每帧update最后执行。

在ParticleSystem的中,该方法为空,调用的是ParticleSystemQuad的该方法。

update方法在updateParticleQuads之前是把本帧的粒子数据修改到ParticleData中,之后执行该方法,用来把ParticleData中生存的粒子数据写到顶点缓存中,是对位置和颜色分别在顶点缓存进行更新。

把顶点坐标写入顶点缓存前,根据3种粒子位置类型计算当前粒子位置,之后执行updatePosWithParticle方法写入顶点缓存。该方法通过位置坐标、旋转角度、矩形大小,计算出矩形4个顶点坐标,存入顶点缓存中。

存入顶点缓存的坐标是像素坐标系的坐标,所以updatePosWithParticle方法会将旋转角度取反。

4. 其它

ParticleSystemQuad重写了Node的draw方法,使用了顶点缓存和索引缓存。

initWithTotalParticles方法调用setupVBO或setupVBOandVAO方法加载VBO VAO。


本文原创地址:https://www.cnblogs.com/deepcho/ ,如果您在非本网址看到此文章,说明网站是爬虫采集抄袭而成。

分类:

技术点:

相关文章:

  • 2021-05-16
  • 2021-09-07
  • 2019-10-19
  • 2019-08-16
  • 2021-09-10
  • 2021-11-13
  • 2019-08-27
  • 2020-04-23
猜你喜欢
  • 2019-08-22
  • 2019-07-23
  • 2019-10-23
  • 2019-07-19
  • 2019-10-23
  • 2022-01-02
  • 2021-10-28
相关资源
相似解决方案