位置: 编程技术 - 正文

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教程)

  • 车船税规定怎么缴纳
  • 非营利组织企业所得税
  • 增值税普通发票和电子普通发票的区别
  • 资本公积转实收资本要交税吗
  • 凭证附件的粘法
  • 借款当月算利息吗
  • 人力资源公司代招的岗位可以去吗
  • 加计扣除和研发费不一致
  • 应付福利费直接计入未分配利润
  • 小规模纳税人改为一般纳税人需要什么材料
  • 专票金额和实际报销金额不符
  • 固定资产认证进项在勾选平台勾吗
  • 个人户转账公户用途
  • 德邦物流增值税发票怎么开
  • 风险纳税人原因查询
  • 中药税率什么时候变为9
  • 转让商业承兑汇票显示银行拒绝交易
  • "税务 政策"
  • 主营业务收入和产值
  • 平均年限法如何计算
  • 存货跌价准备怎么计提
  • 工会会费可以一年交两个单位吗
  • 增值税小规模纳税人减免增值税政策
  • 应付股利会计分录例题
  • 资本公积 税务
  • 买车的发票可以抵扣吗?
  • 单位探望病人如何报销费用?
  • 海尔笔记本最新款
  • 税前净利润等于什么
  • 长期待摊费用摊销会计分录
  • 公司成立之初
  • 入账成本包括增值税税额吗
  • vue上传文件和后端upload
  • 房产税城镇土地使用税申报期限
  • phpsubstr_replace
  • 金店个体户报什么税
  • javascript生成器
  • ValueError: The device should not be ‘gpu‘, since PaddlePaddle is not compiled with CUDA问题解决(Paddle)
  • 基建项目招标流程
  • 激光器原理及应用
  • 关于高德地图的分析报告
  • 试生产产品计入研发费用吗
  • 外贸企业代理出口退税给谁
  • 百度ai修复照片
  • db2入门教程
  • 分公司产生的费用怎么报销
  • 即征即退收入不能税前扣除
  • 购入不动产进项税额怎么抵扣
  • 航空运输电子客票行程单查验
  • /kill @p
  • 车辆保险费印花税计税金额含进项税吗
  • 小规模纳税人的增值税计入成本吗
  • 待认证进项税额月末怎么处理
  • 中小企业开发票税率是多少
  • 可供分配的利润分配顺序
  • 公司日常费用支出表怎么做
  • 股权激励有几种形式
  • 综合所得的个人所得税有哪些筹划技巧
  • 劳务公司的工资表怎么做账
  • 营业成本如何设一级科目
  • system表空间满了怎么处理
  • mysql的用户管理与权限管理
  • mysql5.5安装配置教程
  • sql实现分页查询语句
  • win8更改桌面位置
  • 组策略 guest
  • win8最新版本
  • django 实例
  • 视锥是什么意思
  • 如何用dos修复引导
  • 设计shell程序
  • python数据结构之数组
  • node js模块
  • div.remove
  • Javascript字符串出现次数
  • 外经证的有效期是多久
  • 农用三轮车免征增值税文件
  • 沈阳车辆税务管理局电话
  • 车船使用税2021
  • 船舶吨税的税目
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设