本文主要是介绍Creator 3.0 折纸效果!超赞,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
效果
源码链接:http://store.cocos.com/app/detail/2844
实现
整体思路
思路遵循以下几步
初始化一个多边形。
折叠后分割成两个多边形。
如果需要继续分割,对场上的所有多边形进行折叠,折叠出新的多边形的层级正好与原来的相反。
所以,所有的计算和渲染都可以转换成对一个多边形的操作。
为了简化计算,我们约定初始化的多边形为凸多边形。这么做有几个好处。
折叠后生成的仍是凸多边形,并且对于每个多边形只会折叠出两个凸多边形
渲染时,分割凸多边形为三角形特别方便,即能快速计算出顶点索引
计算
主要分为三块
多边形分割
线线交点
轴对称
分割
观察触摸方向和多边形各个点的关系。
可以发现,触摸方向 与 触摸方向中点指向多边形顶点 的夹角决定了分割后的多边形的点。
当夹角大于90度时,该顶点正好是折叠多边形的顶点。
当夹角等于90度时,该顶点是两个多边形的顶点。
当夹角小于90度时,该顶点是底部多边形的顶点。
向量间的点积正好可以帮助我们判断夹角问题。
const dotValue = temp_v2_vector.dot(temp_v2_vector_3)
if (Math.abs(dotValue) === 0) {// 刚好在点上
} else if (dotValue > 0) {// 在前面
} else {// 在后面
}
交点
当被分割的多边形相邻两点与触摸方向的夹角不同时(属于两个多边形的点),需要计算触摸向量的垂直线与该线段的交点。
直线上的一点可以用点和向量表示。
把两直线的点表达式结合,再运用克莱姆法则(Cramer's Rule
)求出交点。
function linelinePoint(p1: Vec2, p1Dir: Vec2, p2: Vec2, p2Dir: Vec2) {const a1 = p1Dir.x, b1 = -p2Dir.x, c1 = p2.x - p1.xconst a2 = p1Dir.y, b2 = -p2Dir.y, c2 = p2.y - p1.yconst d = a1 * b2 - a2 * b1,d1 = c1 * b2 - c2 * b1,d2 = a1 * c2 - c1 * a2const t1 = d1 / d, t2 = d2 / dreturn [t1, t2]
}
这里计算的是比例t
,这个t
不仅可以用来求出顶点坐标,也可以求出相交的纹理坐标。
const posSpilt = Vec2(pos.x + dir.x * t1, pos.y + dir.y * t1)
const uvSpilt = Vec2(uv.x + uvdir.x * t1, uv.y + uvdir.y * t1)
对称点
折叠多边形的顶点正好是原多边形顶点关于触摸垂直轴对称的点。
求对称点同样可以运用向量计算。
求出该顶点与中点的向量
求出该点在触摸方向的单位向量的投影(点乘),这正好是距离的一半
求出对称点坐标(距离乘方向向量+起始点坐标)
Vec2.subtract(temp_v2_vector_4, temp_v2_pos, pos)
const dotLength = temp_v2_vector_4.dot(temp_v2_vector) * 2
temp_v2_pos_2.set((pos.x + temp_v2_vector.x * dotLength), pos.y + temp_v2_vector.y * dotLength)
渲染
渲染一个图形一般是由三角形组成。
对于凸多边形,分割三角形就比较简单。选取其中一个顶点,和其他顶点连接,就可以把多边形分割成三角形。
渲染一个凸多边形采用Assembler
的方式组装顶点数据。
分为以下几步实现:
将引擎中的
Sprite-simple
组装器拷贝出来,作为自己的组装器模板。新建一个类继承
Sprite
,并设置它的组装器到自己的组装器创建变量顶点数组,纹理数组。
编写组装器逻辑
直接看看代码吧:D
凸多边形的类。
// 仅限凸多边形
@ccclass('PolygonSprite')
export class PolygonSprite extends Sprite {@property({ type: [Vec2] })protected _vertices: Vec2[] = [new Vec2(-100, -100), new Vec2(100, -100), new Vec2(100, 100), new Vec2(-100, 100)];// 省略部分代码@property({ type: [Vec2] })protected _uvs: Vec2[] = [new Vec2(0, 0), new Vec2(1, 0), new Vec2(1, 1), new Vec2(0, 1)];// 省略部分代码protected _flushAssembler() {//指向自定义的组装器let assembler = polygonAssembler;if (this._assembler !== assembler) {this.destroyRenderData();this._assembler = assembler;}// 省略部分代码}
}
接下来看组装器内修改部分。
处理顶点数据
// 保存顶点数据
updateVertexData(sprite: PolygonSprite) {//中间变量const renderData = sprite.renderData;if (!renderData) {return;}renderData.vertexCount = renderData.dataLength = sprite.vertices.length// 三角形数量 = 顶点数 - 2// 索引数量 = 三角形数量X3renderData.indicesCount = (renderData.vertexCount - 2) * 3renderData.vertDirty = false;for (let i = 0; i < sprite.vertices.length; ++i) {const xy = sprite.vertices[i];renderData.data[i].x = xy.xrenderData.data[i].y = xy.y}
},
缓存UV坐标,我们定义的纹理坐标是归一化到0-1,在更新数据时再根据实际的纹理坐标(合图)进行转换。
updateUvs(sprite: PolygonSprite) {const renderData = sprite.renderData!;//实际uvconst uv = sprite.spriteFrame!.uv;// 左 下 上 右 const l = uv[0], b = uv[1], t = uv[7], r = uv[6]for (let i = 0; i < sprite.uvs.length; ++i) {const uvs = sprite.uvs[i];renderData.data[i].u = l + (r - l) * uvs.xrenderData.data[i].v = b + (t - b) * uvs.y}renderData.uvDirty = false;
},
填充数据修改,顶点索引就从第一个点开始连接到各个顶点的三角形。
fillBuffers(sprite: PolygonSprite, renderer: any) {//省略代码// 填充顶点for (let i = 0; i < renderData.vertexCount; ++i) {const vert = renderData.data[i];// 计算世界坐标vBuf![vertexOffset++] = a * vert.x + c * vert.y + tx;vBuf![vertexOffset++] = b * vert.x + d * vert.y + ty;vBuf![vertexOffset++] = vert.z;// 填充uvvBuf![vertexOffset++] = vert.u;vBuf![vertexOffset++] = vert.v;Color.toArray(vBuf!, sprite.color, vertexOffset);vertexOffset += 4;}// 填充索引for (let i = 0; i < sprite.vertices.length - 2; ++i) {const start = i;iBuf![indicesOffset++] = vertexId;iBuf![indicesOffset++] = start + 1 + vertexId;iBuf![indicesOffset++] = start + 2 + vertexId;}
},
小结
实现折叠效果可以将问题分解成处理一个多边形的问题,并用assembler
实现合批渲染。
以上为白玉无冰使用 Cocos Creator 3.0.0
实现 "折纸效果!"
的技术分享。欢迎三连(点赞/在看/留言/分享)支持!
告诉大家一个好消息,Cocos Store 五月挑战赛
只要报名上传作品
审核通过就有机会获得 Cocos 周边!
请注意!!!推荐好友上架成功,推荐者也可以获得的哦!而且520也要到了,后面的六一儿童节、端午节、618......各种题材的游戏DMEO、插件、资源都有机会获得官方推荐,机会难得,快来报名吧!
报名链接:https://www.cocos.com/store-activity
欢迎加晓衡微信,愿我们共同成长!
这篇关于Creator 3.0 折纸效果!超赞的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!