Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >移动残影效果

移动残影效果

作者头像
异名
发布于 2020-06-09 05:01:21
发布于 2020-06-09 05:01:21
78300
代码可运行
举报
文章被收录于专栏:异名异名
运行总次数:0
代码可运行

游戏中的人物移动带起残影,用来表达速度是很有视觉表现力的。异名的实现思路是从“白玉无冰”那里参照过来的,在具体的实现上面添加了一些异名自己的理解。

demo

实现思路

投影到多个画布

“白玉无冰”的这张图解析得很清晰,我们在实现的时候会在移动的角色中新建一个独立摄像机的子节点,专门拍摄需要移动的角色,然后投影到五个不同透明度的Sprite中。当角色移动的时候,我们也让作为残影的五个Sprite,分别有延迟地移动到角色当前的位置,这样子在视觉上就有五个残影在跟随了。

detail

在具体的实现有两个注意点,一个是因为摄像机仅仅只需拍摄移动的角色,所以要为角色新建一个分组,相机只拍摄这个分组;还有一个就是相机拍摄出来的画面投影在RenderTexture上是一个上下颠倒的镜像图像,所以要设置每个Sprite所在节点的scaleY = -1

这块的具体实现上我和白玉无冰的做法不一样,白玉无冰直接在编辑器上对残影所在的Sprite节点做上述提到的透明处理、层级管理、颠倒处理,异名会觉得把这块的设置放到代码层面处理比较好,一来是编辑器的功能最好还是专职于布局,比如像这个残影透明参数和层级管理确实可以通过编辑器来配置,但是透明度的细微变化和变量绑定的先后顺序这些微小区别,其实是不利于后面的维护和他人接手的,后面阅读代码逻辑的时候也无法看出整个实现的思路。二来就是在代码内做设置参数可以随时在代码上做调整,比如我的残影透明度的初始值,用代码赋值的方式就会比在编辑器中设置会更加一目了然。

代码如下?

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const roleZindex = 10;
this.role.zIndex = roleZindex;

const texture = new cc.RenderTexture();
texture.initWithSize(this.node.width, this.node.height);
const spriteFrame = new cc.SpriteFrame();
spriteFrame.setTexture(texture);
this.roleCamera.targetTexture = texture;
this.ghostCanvasList.forEach((ghost, idx) => {
  ghost.node.scaleY = -1;
  ghost.node.zIndex = roleZindex - idx;
  ghost.node.opacity = 100 - idx * 15;
  ghost.spriteFrame = spriteFrame;
});

角色移动

因为我们的实现是把相机作为子节点绑定在角色节点下面,当角色移动的时候我们的相机也跟着移动了,我们就需要把相机投影所在的Sprite节点们分别做一个延时移动,带出”残影“效果。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.schedule(this.ghostFollow, 0.1, cc.macro.REPEAT_FOREVER);
this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveEvent, this);

touchMoveEvent(evt: cc.Event.EventTouch) {
  this.role.x += evt.getDeltaX();
  this.role.y += evt.getDeltaY();
}

ghostFollow() {
  this.ghostCanvasList.forEach((ghost, i) => {
    const dis = (ghost.node.position as any).sub(this.role.position).mag();
    if (dis < 0.5) return;
    ghost.node.stopAllActions();
    ghost.node.runAction(cc.moveTo(i * 0.04 + 0.02, this.role.x, this.role.y));
  });
}

这里注意到,我们并不是在每次touchMoveEvent的时候去调用ghostFollow函数,而是启用了一个无限重复的定时器去同步,为什么呢?大家去试一试就知道了原因了,其实cc.Node.EventType.TOUCH_MOVE是帮我们做了节流的,大部分时候我们受益于这个节流,但是在这个功能里面,节流调用会导致我们的位置同步不及时而导致残影不流畅,所以我们需要单开一个定时器去实时同步,同时记得在destroy之前别忘了去销毁它。

ghostFollow函数主要是同步残影和角色的位置,白玉无冰在这里也有两个小的疏忽。一个是在计算dis的时候,正确的做法是拿残影的位置去和角色的位置做距离运算的,这个失误白玉无冰有在公众号留言中提到,但是还没有在代码仓库中修正过来,大家借鉴的时候要注意。还有一个就是判断是否静止,异名的判断条件是dis < 0.5就认为它们已经重合了,0.5的像素差别在画面上人眼是看不出来的,那为什么不能是if(dis > 0) { xxxxx }呢?在现代的语言中,浮点数计算是有误差的,dis的结果是通过向量计算得出的,经过了加减乘除,中间的计算过程肯定产生了浮点数,它产生出来的结果肯定也是有误差的,大家可以在控制台把dis变量打印出来,你会发现,每次静止的时候,理论上静止了,dis的结果应该为0,但是实际上有可能每次产生的dis值都是不一样的,可能是0也有可能是0.00012340.1222222等等,但是这个值我们已经可以认为它们已经静止了。因此大家要有意识,当涉及到精确判断的时候,要做容错处理,if(dis > 0) { xxxxx }这种写法其实没有考虑到容错。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 异名 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
cocos creator | 用摄像机实现残影幻影拖尾效果
利用摄像机拍摄角色,然后投影到多个显示画布,给画布节点设置不同的透明度,最后让画布节点跟随角色移动。
张晓衡
2019/10/08
1.5K0
cocos creator | 用摄像机实现残影幻影拖尾效果
放大镜效果
对画面的某个位置进行放大和缩小,是某些类型游戏里面必不可少的功能,比如常见的地图缩放,局部细节放大等等。它核心是对相机应用,异名基于此实现一个放大镜的demo
张晓衡
2020/04/22
1.9K0
放大镜效果
如何使用 Creator【摄像机组件】实现局部缩放的效果?
多摄像机的支持可以让你轻松实现高级的自定义效果,比如双人分屏效果,或者场景小地图的生成。
张晓衡
2019/09/27
1.1K0
如何使用 Creator【摄像机组件】实现局部缩放的效果?
Golang语言情怀--第118期 全栈小游戏开发:第9节:精灵帧资源(SpriteFrame)
Cocos Creator 的 SpriteFrame 是 UI 渲染基础图形的容器。其本身管理图像的裁剪和九宫格信息,默认持有一个与其同级的 Texture2D 资源引用。
李海彬
2023/11/22
3810
Golang语言情怀--第118期 全栈小游戏开发:第9节:精灵帧资源(SpriteFrame)
渐变过渡的相册(shader)
相册是一个大家比较熟悉的场景,一般我们是实现的都是那种跑马灯式的轮播相册,这里异名给大家提供一个利用shader实现图片渐变过渡的相册思路
异名
2020/06/09
4570
追光效果
追光效果是在舞台全场黑暗的情况下用光柱来突出角色或其他特殊物体,还可以通过操控光源来跟随人物移动。追光效果主要用来突出角色主体以及主体和环境的关系,在游戏中可以用来营造沉浸式氛围以及聚焦玩家视线焦点
异名
2020/06/09
7970
CocosCreator常用API函数库(一)_基础入门
给sprite动态改变图片 首先将存放图片最外层文件夹命名为resources changeBj: function(){ var url = 'globalUI/video/gVideoPlayClick'; var _this = this; cc.loader.loadRes(url,cc.SpriteFrame,function(err,spriteFrame){ _this.isPlay.spriteFrame = spriteFrame; }); } ****跳转**** cc.direct
bering
2019/12/02
1K0
实战 Creator 2.x 项目升级 3.x!避坑要点与基础 API 写法差异总结
最近,我将自己在 Cocos Store 上的一个 2D 项目《球球要回家》从 Creator 2.2.2 升级到 Creator 3.6.2,编程语言也从 JavaScript 全面升级至 TypeScript 并适配微信小游戏,目前在微信审核中!
张晓衡
2023/01/03
2.9K0
实战 Creator 2.x 项目升级 3.x!避坑要点与基础 API 写法差异总结
RenderTexture实现小地图和炫酷的传送门!(干货收藏)
本篇文章对应 Nowpaper 老师在B站发布的视频《 如何在3D场景中实现炫酷传送门,和简单的小地图功能,RenderTexture技术应用》!
张晓衡
2021/10/12
1.1K0
RenderTexture实现小地图和炫酷的传送门!(干货收藏)
[Cocos Creator] 微信小游戏接入好友排行榜
对于一个微信小游戏来说,好友排行榜绝对是必不可少的功能,能一定程度上增加玩家的战斗力和活跃度,实实在在地增加小游戏的曝光量。
陈皮皮
2020/07/10
3.4K3
cocos creator基本操作
var node = cc.find("Canvas/bg");//通过访问路径来获取节点
Lee坚武
2020/04/10
2.8K0
前端er开发cocos小游戏快速入门
前段时间一直在更 vue2的源码系列,最近换了换口味,学了一下 cocos ,照猫画虎的写了一个「挑战1024」小游戏。
windliang
2022/12/21
1.1K0
前端er开发cocos小游戏快速入门
开源 2D 实时水面反射效果,源码详解!
引言:插件 Easy NavMesh、BenchMark 性能检测的作者孙二喵,从开发者王师傅的论坛分享中获得启发,实现了 2D 实时水面反射效果,Demo 免费开源。
张晓衡
2023/02/23
7070
开源 2D 实时水面反射效果,源码详解!
看完这篇,你也可以实现一个360度全景插件
本文从绘图基础开始讲起,详细介绍了如何使用 Three.js开发一个功能齐全的全景插件。
ConardLi
2019/05/23
9K0
抖音国庆小游戏是如何实现的?
经过若干个月的点滴积累,我有幸参与到抖音国庆活动的开发,这是我第一次完整参与大型活动项目的开发,它是全员关注的一个重点项目,致力于让用户领略美好中国,指导用户在抖音中搜索与获取旅行攻略和出游信息。
ConardLi
2021/12/02
1.5K0
抖音国庆小游戏是如何实现的?
连“捉阔”是什么都不知道就不要混了!如何优化看这里!
在游戏开发中,DrawCall 作为一个非常重要的性能指标,直接影响游戏的整体性能表现。
张晓衡
2020/07/09
2.3K0
连“捉阔”是什么都不知道就不要混了!如何优化看这里!
【Unity面试篇】Unity 面试题总结甄选 |Unity基础篇 | ❤️持续更新❤️
答:Awake —> OnEnable —> Start —> FixedUpdate —>Update —> LateUpdate—> OnGUl —> OnDisable —> OnDestroy
呆呆敲代码的小Y
2023/07/24
3.2K0
【Unity面试篇】Unity 面试题总结甄选 |Unity基础篇 | ❤️持续更新❤️
Unity面试题(包含答案)
在主线程运行的同时开启另一段逻辑处理,来协助当前程序的执行,协程很像多线程,但是不是多线程,Unity的协程实在每帧结束之后去检测yield的条件是否满足。
bering
2019/12/02
3.4K0
推荐阅读
相关推荐
cocos creator | 用摄像机实现残影幻影拖尾效果
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验