多边形裁剪图片升级啦!Cocos Creator !
时间:2022-07-22
本文章向大家介绍多边形裁剪图片升级啦!Cocos Creator !,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
支持合图,支持
gizmo
添加节点和调整位置,支持缩放旋转。文章底部获取完整项目!
效果预览与使用
原理
回顾
在gizmo入门探索介绍了 gizmo
与多边形裁剪的配合。
在使用 mesh 实现多边形裁剪图片 中介绍了 mesh
和切耳法的相关使用。
相比mask
组件,这种meshRenderer
的实现可以降低两个draw call
。
因为小伙伴使用的比较多,这边对这个多边形裁剪图片进行一次升级,增加易用性!
升级后添加了以下几个特性:
- 升级版本至
Cocos Creator 2.4
(一些接口的变化) - 支持
gizmo
直接添加多边形节点 - 支持节点缩放旋转后,
gizmo
的正确显示 - 支持合图,图片资源可以勾选
packable
接下来就大致讲解主要特性的原理吧。
分割多边形
这次不采用切耳法分割分割了,而是采用poly2tri这个库去分割(注意这个库有严格的限制)。
主要计算顶点索引过程如下。
// 计算顶点索引
const ids = [];
// 多边形切割 poly2tri,支持简单的多边形,确保顶点按顺序且不自交
const countor = this.vertexes.map((p) => { return { x: p.x, y: p.y } });
const swctx = new poly2tri.SweepContext(countor, { cloneArrays: true });
swctx.triangulate();
const triangles = swctx.getTriangles();
triangles.forEach((tri) => {
tri.getPoints().forEach(p => {
const i = countor.indexOf(p as any);
ids.push(i);
});
})
mesh.setIndices(ids);
支持合图
引用一张 @GT
的图。
在 SpriteFrame
里含有这个uv
信息,这里可以做一次转换,先计算 0~1
的比例,再做一次转化坐标。
private _lerp(a: number, b: number, w: number) {
return a + w * (b - a);
}
const uv = this.spriteFrame.uv;
const texture = this.spriteFrame.getTexture();
/**
* t
* l r
* b
*/
const uv_l = uv[0];
const uv_r = uv[6];
const uv_b = uv[3];
const uv_t = uv[5];
// 计算uv
const uvs = [];
for (const pt of this.vertexes) {
const u = this._lerp(uv_l, uv_r, (pt.x + texture.width / 2 + this.offset.x) / texture.width);
const v = this._lerp(uv_b, uv_t, (pt.y + texture.height / 2 - this.offset.y) / texture.height);
uvs.push(cc.v2(u, v));
}
mesh.setVertices(gfx.ATTR_UV0, uvs);
gizmo 增加多边形顶点
整体思路是先根据所有顶点画线段,给线段添加事件监听,在点击位置添加一个节点。
点击转换坐标有个坑,y
的坐标要用一个高度减去后再转换(感谢@GT
的pr)。
start: (x, y, event, param) => {
y = this._view.offsetHeight - y;
// 坐标转换
let position = cc.v2(x, y);
position = Editor.GizmosUtils.snapPixelWihVec2(position);
position = this._view.pixelToWorld(position);
position = node.convertToNodeSpaceAR(position);
}
gizmo 支持旋转缩放
整体来说,就是将坐标点先做缩放,再做旋转处理即可。
this._tool.plot(target.vertexes.map((p) => {
let scaleX = node.scaleX;
let scaleY = node.scaleY;
let angle = -node.angle * Math.PI / 180;
const cos_angle = Math.cos(angle);
const sin_angle = Math.sin(angle);
const v = Editor.GizmosUtils.snapPixelWihVec2(p.mul(this._view.scale));
return cc.v2(
(v.x * cos_angle * scaleX + v.y * sin_angle * scaleY),
-(-v.x * sin_angle * scaleX + v.y * cos_angle * scaleY)
);
}), position);
小结
坐标转换!旋转!跳跃!不停歇!
以上为白玉无冰使用 Cocos Creator v2.4
实现 "多边形裁剪!"
的技术分享。
知识不过是潜在的力量,只有将它组织成明确的行动计划,并指引它朝着某个明确目的发挥作用的时候,知识才是力量。
- 做程序员压力山大,很多人都快疯了
- 小程序让交通出行变得如此简化,看看这些微信小程序你有在用了吗?
- 中小企业如何选择DDoS防御方案?
- “熊医生”出诊正确率超九成 医院:人工智能更多是辅助
- PLC编程优化方法,让程序运行提速!
- 这是硅谷狂人马斯克对未来做出的11个大胆预测,人工智能比核武器更危险
- 在腾讯云上使用自建DNS
- Spring 4.0.2 学习笔记(1) - 最基本的注入
- 关于女神SQLite的疑惑(2)
- WordPress纯代码仿无觅相关文章图文模式功能(增强版)
- 人工智能时代已悄然来临……
- 人民日报发布周鸿祎署名文章:迎接“大安全”时代的新威胁
- Mono 3.2 上跑NUnit测试
- 为WordPress 文章中的链接自动添加 nofollow标签
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- NumPy 数据归一化、可视化
- 迭代器怎么就节省内存了?
- Go 多版本管理
- 空谈分布式系统设计之幂等性
- 空谈发件箱模式(outbox pattern)
- 《一起学sentinel》六、Slot的子类及实现之FlowSlot和DegradeSlot
- Hive UDF/UDAF 总结
- 3分钟短文:用Laravel发一封“漂洋过海”的电子邮件
- leetcode之单词替换
- KMP算法分析
- Spring Boot 系列:最新版优雅停机详解
- 前端学数据结构与算法(八): 单词前缀匹配神器-Trie树的实现及其应用
- 突击并发编程JUC系列-Locksupport 与 Condition
- 01.视频播放器框架介绍
- C#扫描器编写各种问题荟萃