位置: 编程技术 - 正文

cocos2dx 关于拖影(类似dnf传承武器的拖尾效果)的快速实现(cocos2dx drawcall优化)

编辑:rootadmin

推荐整理分享cocos2dx 关于拖影(类似dnf传承武器的拖尾效果)的快速实现(cocos2dx drawcall优化),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:cocos creator拖尾,cocos2d drawcall,cocos2d drawcall,cocos2d drawcall,cocos2d drawcall,cocos2dx shader,cocos creator拖尾,cocos2dx shader,内容如对您有帮助,希望把文章链接给更多的朋友!

序:

当初看到dnf 中有些 拖影的效果,感觉很炫,所以到后面自己做游戏的时候自然的就想到了 那种炫 的拖尾效果~, 于是 我就想 要将效果 的实现写下来,以后 自己做游戏 也可以 用的了啊~~~~, 希望 对大家 有 的用处 ,哈哈~

正文:

先来一张效果图~。

就是 蓝色 的 影子了,直观的看就是几张尾巴的图片坐标不同,透明度不一样,可能还有旋转的角度,是否翻转了。

一般的做法,可能会想到多建立几个精灵对象,然后跟着目标走,每一个精灵逐渐改变透明度等等,没错这是直接的 实现,虽然可以 达到目的,但是仔细想想 会很麻烦,而且不利于通用到每一个 游戏中。

下面从gl的角度说说如果 方便的实现 这种炫炫的 效果~~~

gl贴图,用4个点表示然后映射纹理坐标,想要几个尾巴就 对应的多建立几个顶点 了。每一组顶点要对应的改变属性,透明度这里用透明通道改变,翻转就是交换左右或者上下顶点的位置,旋转只要跟随目标的 旋转度就行了,基本上计算就不复杂了。

下面就直接贴出完整代码.(3.x版本,2.x需要适当做些修改)

cocos2dx 关于拖影(类似dnf传承武器的拖尾效果)的快速实现(cocos2dx drawcall优化)

//SmariShadow.h

#ifndef __SMRITISHADOW_H__#define __SMRITISHADOW_H__#include "cocos2d.h"#include "global.h"USING_NS_CC;class SmritiShadow:public Node{public:~SmritiShadow();void draw(Renderer *renderer, const Mat4 &transform, uint_t flags); CREATE_FUNC(SmritiShadow)bool init();void onDraw();

//设置跟随目标,spr就是跟随的对象,tex尾巴的纹理,如果为null,那么就给出第三个参数精灵帧。void setTarget(Sprite* spr,Texture2D* tex,SpriteFrame *sf=0);

//因为用到了自定义shader,所以这里写个重置shader程序的函数,以便在程序切换前台的时候恢复。static void reset();static GLProgram* pg;Sprite* target;Texture2D *texture2d;Size srcsz;CustomCommand _customCommand;Vertex *Vertices;long pretime;int arrcount;GLuint vertexBuffer;GLuint indexBuffer;};#endif

//SmariShadow.cpp

#include "SmritiShadow.h"GLProgram* SmritiShadow::pg=0;void SmritiShadow::draw(Renderer *renderer, const Mat4 &transform, uint_t flags){_customCommand.init(_globalZOrder);_customCommand.func = CC_CALLBACK_0(SmritiShadow::onDraw, this);renderer->addCommand(&_customCommand);}void SmritiShadow::onDraw(){ struct timeval tv;gettimeofday(&tv,NULL); long ct=tv.tv_sec*&#;tv.tv_usec;

//如果想改变尾巴的长度,请改写下面的~if(ct-pretime>){pretime=ct;arrcount=0;for(int i=0;i<;i&#;=4){Vertices[i].Position[0]=Vertices[i&#;4].Position[0];Vertices[i].Position[1]=Vertices[i&#;4].Position[1];Vertices[i&#;1].Position[0]=Vertices[i&#;5].Position[0];Vertices[i&#;1].Position[1]=Vertices[i&#;5].Position[1];Vertices[i&#;2].Position[0]=Vertices[i&#;6].Position[0];Vertices[i&#;2].Position[1]=Vertices[i&#;6].Position[1];Vertices[i&#;3].Position[0]=Vertices[i&#;7].Position[0];Vertices[i&#;3].Position[1]=Vertices[i&#;7].Position[1];}Size sz=srcsz;Vec2 pos=target->getPosition();Vec2 midp=pos;Size sz1=target->getContentSize();bool bfx=target->isFlippedX();bool bfy=target->isFlippedY();Vec2 ap=target->getAnchorPoint();float rad=CC_DEGREES_TO_RADIANS(target->getRotation());pos.x-=sz1.width*ap.x;pos.y-=sz1.height*ap.y;float s=sin(-rad);float c=cos(-rad);Vertices[].Position[0]=c*pos.x-s*pos.y&#;(1-c)*midp.x&#;s*midp.y;Vertices[].Position[1]=s*pos.x&#;c*pos.y-s*midp.x&#;(1-c)*midp.y;Vertices[].Position[0]=c*(pos.x&#;sz.width)-s*pos.y&#;(1-c)*midp.x&#;s*midp.y;Vertices[].Position[1]=s*(pos.x&#;sz.width)&#;c*pos.y-s*midp.x&#;(1-c)*midp.y;Vertices[].Position[0]=c*pos.x-s*(pos.y&#;sz.height)&#;(1-c)*midp.x&#;s*midp.y;Vertices[].Position[1]=s*pos.x&#;c*(pos.y&#;sz.height)-s*midp.x&#;(1-c)*midp.y;Vertices[].Position[0]=c*(pos.x&#;sz.width)-s*(pos.y&#;sz.height)&#;(1-c)*midp.x&#;s*midp.y;Vertices[].Position[1]=s*(pos.x&#;sz.width)&#;c*(pos.y&#;sz.height)-s*midp.x&#;(1-c)*midp.y;float tempx=0,tempy=0;if(bfx){tempx=Vertices[].Position[0];tempy=Vertices[].Position[1];Vertices[].Position[0]=Vertices[].Position[0];Vertices[].Position[1]=Vertices[].Position[1];Vertices[].Position[0]=tempx;Vertices[].Position[1]=tempy;tempx=Vertices[].Position[0];tempy=Vertices[].Position[1];Vertices[].Position[0]=Vertices[].Position[0];Vertices[].Position[1]=Vertices[].Position[1];Vertices[].Position[0]=tempx;Vertices[].Position[1]=tempy;}if(bfy){tempx=Vertices[].Position[0];tempy=Vertices[].Position[1];Vertices[].Position[0]=Vertices[].Position[0];Vertices[].Position[1]=Vertices[].Position[1];Vertices[].Position[0]=tempx;Vertices[].Position[1]=tempy;tempx=Vertices[].Position[0];tempy=Vertices[].Position[1];Vertices[].Position[0]=Vertices[].Position[0];Vertices[].Position[1]=Vertices[].Position[1];Vertices[].Position[0]=tempx;Vertices[].Position[1]=tempy;}for(int i=;i>=0;i-=4){if(Vertices[i].Position[0]==Vertices[].Position[0]){arrcount&#;=1;}}}glEnable(GL_BLEND);BlendFunc bf=BlendFunc::ALPHA_NON_PREMULTIPLIED;glBlendFunc(GL_ONE,GL_ONE);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);pg->use();pg->setUniformsForBuiltins();GLushort iarr[]={0,1,2,1,2,3,0&#;4,1&#;4,2&#;4,1&#;4,2&#;4,3&#;4,0&#;8,1&#;8,2&#;8,1&#;8,2&#;8,3&#;8,0&#;,1&#;,2&#;,1&#;,2&#;,3&#;,0&#;,1&#;,2&#;,1&#;,2&#;,3&#;};glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);glBufferData(GL_ARRAY_BUFFER,sizeof(Vertex)*,Vertices, GL_STATIC_DRAW);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(iarr),iarr,GL_STATIC_DRAW);GLint _positionLocation = glGetAttribLocation(pg->getProgram(), "a_position");GLint _colorLocation = glGetAttribLocation(pg->getProgram(), "a_color");GLint _textureLocation = glGetAttribLocation(pg->getProgram(), "a_texCoord");GLint _textureUniform = glGetUniformLocation(pg->getProgram(), "CC_Texture0");glEnableVertexAttribArray(_positionLocation);glEnableVertexAttribArray(_colorLocation);glEnableVertexAttribArray(_textureLocation);glVertexAttribPointer(_positionLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Position));glVertexAttribPointer(_colorLocation, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, Color));glVertexAttribPointer(_textureLocation, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),(GLvoid*)offsetof(Vertex, TexCoord));GL::bindTexture2DN(0, texture2d->getName());glUniform1i(_textureUniform, 0);glDrawElements(GL_TRIANGLES,sizeof(iarr)/sizeof(GLushort)-arrcount*6, GL_UNSIGNED_SHORT, 0);glDisable(GL_DEPTH_TEST);glBlendFunc(bf.src, bf.dst);glEnable(GL_DEPTH_TEST);glBindBuffer(GL_ARRAY_BUFFER, 0);}SmritiShadow::~SmritiShadow(){glDeleteBuffers(1, &vertexBuffer);glDeleteBuffers(1, &indexBuffer);delete[] Vertices;}void SmritiShadow::setTarget(Sprite* spr,Texture2D* tex,SpriteFrame *sf){target=spr;Rect texrc;if(sf!=0){texture2d=sf->getTexture();Rect rc=sf->getRectInPixels();Size dd=texture2d->getContentSize();texrc=Rect(rc.origin.x/dd.width,rc.origin.y/dd.height,(rc.origin.x&#;rc.size.width)/dd.width,(rc.origin.y&#;rc.size.height)/dd.height);srcsz=sf->getRectInPixels().size;}else{ texture2d=tex;texrc=Rect(0,0,1,1);srcsz=texture2d->getContentSize();}Size sz=srcsz;Size sz1=spr->getContentSize();Vec2 pos=spr->getPosition();CCPoint ap=target->getAnchorPoint();pos.x-=sz1.width*ap.x;pos.y-=sz1.height*ap.y;for(int i=0;i<;i&#;=4){Vertices[i].Position[0]=pos.x;Vertices[i].Position[1]=pos.y;Vertices[i].Position[2]=0;Vertices[i].TexCoord[0]=texrc.origin.x;Vertices[i].TexCoord[1]=texrc.size.height;Vertices[i&#;1].Position[0]=pos.x&#;sz.width;Vertices[i&#;1].Position[1]=pos.y;Vertices[i&#;1].Position[2]=0;Vertices[i&#;1].TexCoord[0]=texrc.size.width;Vertices[i&#;1].TexCoord[1]=texrc.size.height;Vertices[i&#;2].Position[0]=pos.x;Vertices[i&#;2].Position[1]=pos.y&#;sz.height;Vertices[i&#;2].Position[2]=0;Vertices[i&#;2].TexCoord[0]=texrc.origin.x;Vertices[i&#;2].TexCoord[1]=texrc.origin.y;Vertices[i&#;3].Position[0]=pos.x&#;sz.width;Vertices[i&#;3].Position[1]=pos.y&#;sz.height;Vertices[i&#;3].Position[2]=0;Vertices[i&#;3].TexCoord[0]=texrc.size.width;Vertices[i&#;3].TexCoord[1]=texrc.origin.y;}}void SmritiShadow::reset(){if(pg==0){pg=new CCGLProgram();}pg->reset();pg->initWithVertexShaderByteArray(vertshader,fragshader);pg->link();pg->updateUniforms();}bool SmritiShadow::init(){struct timeval tv;gettimeofday(&tv,NULL); long ct=tv.tv_sec*&#;tv.tv_usec;pretime=ct;arrcount=0;Vertices=new Vertex[4*6];for(int i=0;i<;i&#;=4){Vertices[i].Color[3]=0.2*(i/4&#;1);Vertices[i].TexCoord[0]=0;Vertices[i].TexCoord[1]=1;Vertices[i&#;1].Color[3]=0.2*(i/4&#;1);Vertices[i&#;1].TexCoord[0]=1;Vertices[i&#;1].TexCoord[1]=1;Vertices[i&#;2].Color[3]=0.2*(i/4&#;1);Vertices[i&#;2].TexCoord[0]=0;Vertices[i&#;2].TexCoord[1]=0;Vertices[i&#;3].Color[3]=0.2*(i/4&#;1);Vertices[i&#;3].TexCoord[0]=1;Vertices[i&#;3].TexCoord[1]=0;}glGenBuffers( 1, &vertexBuffer );glGenBuffers( 1, &indexBuffer );texture2d=0;target=0; if(pg==0){pg=new GLProgram();pg->initWithVertexShaderByteArray(vertshader,fragshader);pg->link();pg->updateUniforms();}return true;}

用法:

SmritiShadow* temp=SmritiShadow::create();

temp->setTarget(obj,tex);//obj跟随对象,tex设置的尾巴纹理。

如果 有 什么 不懂的或者 有啥问题 可以 互相 交流交流~~,end。

cocos2d-x 3.x 使用cocos studio导出的.csb资源 引言:最近用cocos2dx写了个小游戏,完全使用API画图形的,没有用到任何资源。但是通常都是美术画好UI给开发使用的,所以就自己摸索一下如何在代码

cocos2d-x 3.2版本Mac下移植到android手机打包流程 1、准备好ndk,ndk,adt(包含sdk和eclipse),jdk等软件;2、配置好环境变量,直接拖进终端去即可;3、先安装jdk,再打开eclipse软件,导入准备好要打包项目中

Cocos2d-x 3.2打包错误总结 1、在打包的时候,环境一定要配置好,否则会出现各种的错误。如果配置好了环境,但是之后把文件的路径给改了,会提示找不到该路径的错误,因此

标签: cocos2dx drawcall优化

本文链接地址:https://www.jiuchutong.com/biancheng/368877.html 转载请保留说明!

上一篇:cocos2d-x 3.x 引入【#include "cocos-ext.h"】头文件出现编译错误(cocos2dx4.0教程)

下一篇:cocos2d-x 3.x 使用cocos studio导出的.csb资源(cocos2dx4.0教程)

  • 抵进项税分录
  • 应交税费科目的借贷方向
  • 平台收取的佣金开具什么发票
  • 资产处置收益计入利润总额吗
  • 跨越发票冲红,填了红字信息表,没有负数发票
  • 申报后发现成本算错了
  • 购买土地契税和印花税什么时候交
  • 银行结息收入怎么做分录
  • 外贸公司代理出口退税怎么入账
  • 工业企业会计报告
  • 购买房产怎么确认收入
  • 房地产 结转
  • 单位的收入是刷卡怎么做账
  • 计提出口关税会计分录
  • 常用的索赔费用计算方法
  • 营改增后房地产公司税种及税率
  • 季度不含税收入30万以内免增值税
  • 预提成本的会计处理
  • 日记账登记错了怎么办
  • 当月认证抵扣的进项税发票一定要入帐做成本吗?
  • php二维数组的遍历
  • 融资性售后回租承租方为什么不交税
  • 工业总产值 工业销售产值
  • Sa-Token v.1.31.0 新增拦截器 SaInterceptor 功能说明,以及旧代码迁移示例
  • 员工购买住房公积金申请
  • 税务文书送达回证企业要盖章吗
  • HTML+CSS+JS+Jquery+练手项目+...合集(前端学习必备,持续更新中...)
  • 傅里叶变换的过程
  • php识别验证码的库高级
  • php zmq
  • 微信支付php代码
  • git主干
  • 明星身价几十亿
  • 固定资产盘盈为什么计入以前年度损益调整
  • 国家给农民的青春有哪些
  • 企业合并兼并收购的区别和联系
  • 公司缴纳的印花税会计分录
  • 年报超时了可以补报吗
  • 双重数组
  • 企业发生的汇兑差额
  • 记账凭证银行利息怎么写
  • 在excel中怎么制作
  • 银行转账付款会计分录
  • 长期借款的会计分录怎么写
  • SQL Server 2008 数据库有哪些版本?
  • mysql 大量数据
  • 资产负债表的其他应收款怎么算出来的
  • 现金流量表的编制依据
  • 购销合同印花税计税依据
  • 报销为什么不能打给投保人
  • 受疫情影响较大的上市公司
  • 印花税计入哪个会计分录
  • 主营业务成本如何做分录
  • 电子承兑汇票怎么查询
  • 建筑公司需要什么人员
  • 赊销是什么意思 视频
  • mysql触发器语句
  • xp系统有什么用
  • swupdtmr.exe - swupdtmr进程是什么意思 什么作用
  • cyb2k.exe是安全进程吗 cyb2k进程危险吗
  • The file /boot/grub/stage1 not read cor 解决办法
  • cocos lua js
  • android游戏开发框架
  • javascript几种类型
  • 编写程序实现将两个文本文件的内容合并
  • python中random模块用法
  • 关于javascript中数组的说法不正确
  • 以下关于js函数说法错误的是
  • Node.js+jade+mongodb+mongoose实现爬虫分离入库与生成静态文件的方法
  • unity游戏换皮教程
  • 利用python中的运算符可以编程解决你身边的哪些问题
  • java 视频教程
  • easyui treegrid重新加载
  • python数据类型详细介绍
  • 河北云办税厅2.0登录
  • 法制建设包括哪三个方面
  • 美团上满30减12的券在哪啊
  • 为什么经常收到税务短信
  • 北京车船税新标准
  • 非中山户籍学生可以自己买医保吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设