首先,感谢两位大佬的教学,学习两位大佬的技术让我知道了顶点是怎么回事,该怎么操作,大佬地址直通车:
我是用的精灵的mesh渲染模式做的切割来玩的,然后我调整了切割份数后发现,意外形成了爆炸烟雾类的效果
测试代码:
const {ccclass, property} = cc._decorator;
const time_scale = 1; // 动画速度 <0为慢,>0为快
const w = 544;
const h = 544;
@ccclass
export default class TestScene extends cc.Component {
@property(cc.Sprite)
mesh: cc.Sprite = null;
private isMesh: boolean = false;private verts = {
x:[],
y:[],
nv:[],
nu:[],
triangles:[]
};
private initVerts = {
x:[],
y:[],
nv:[],
nu:[],
triangles:[]
}
private mper: number = 0;
private speed: number = 1;
private playBoom: boolean = false;
onLoad () {
this.initMeshVerts();
}
handleBtnMeshTest () {
if (this.isMesh) return;
this.mper = 0;
this.isMesh = true;
}
pushVerts (x, y) {
this.initVerts.x.push(x);
this.initVerts.y.push(y);
this.initVerts.nu.push(x/w);
this.initVerts.nv.push(y/h);
this.initVerts.triangles.push(this.initVerts.x.length-1);
}
initMeshVerts () {
let count = 100; // 均分
if (this.initVerts.x.length === 0) {
for (let c=0; c<count; ++c) {
for (let r=0; r<count; ++r) {
for (let d=0; d<2; ++d) { //上下
let x = r * w / count;
let y = c * h / count;
this.pushVerts(x, y);
this.pushVerts(x + w / count, y + h / count);
if (d === 0) {
this.pushVerts(x + w / count, y);
} else {
this.pushVerts(x, y + h / count);
}
}
}
}
}
this.cloneVerts(this.verts, this.initVerts);
let c = cc.v2(w/2, h/2); // 扩散圆心
let radius = h // 最大扩散半径
for (let i=0; i<this.verts.triangles.length; i+=3) {
let v:cc.Vec2[] = [];
for (let c=0; c<3; ++c) {
let id = this.verts.triangles[c + i];
let p = cc.v2(this.verts.x[id], this.verts.y[id]);
v.push(p);
}
let center = this.getPolygonCenter(v);
let rr, ra; // 随机半径,随机度数
let tv; // 目标点
rr = Math.random() * radius;
ra = Math.random() * 2 * Math.PI;
tv = cc.v2(rr * Math.cos(ra), rr * Math.sin(ra)).add(c);
let dir = center.sub(tv);
v.forEach((_v:cc.Vec2, index)=>{
let nv = _v.sub(dir);
let id = this.verts.triangles[index + i];
this.verts.x[id] = nv.x;
this.verts.y[id] = nv.y;
});
}
//@ts-ignore
this.mesh.spriteFrame.vertices = this.playBoom ? this.initVerts : this.verts;
//@ts-ignore
this.mesh.setVertsDirty();
}
getPolygonCenter (verts:cc.Vec2[]):cc.Vec2 {
let x=0, y=0;
verts.forEach(v=>{
x += v.x;
y += v.y;
})
x /= verts.length;
y /= verts.length;
return cc.v2(x, y);
}
cloneVerts (v1, v2) {
v1.x = v2.x.slice();
v1.y = v2.y.slice();
v1.nv = v2.nv.slice();
v1.nu = v2.nu.slice();
v1.triangles = v2.triangles.slice();
}
updateMeshVerts () {
let nverts = {
x:[],
y:[],
nv:[],
nu:[],
triangles:[]
};
this.cloneVerts(nverts, this.playBoom ? this.initVerts : this.verts);
let tverts = this.playBoom ? this.verts : this.initVerts;
for (let i=0; i<nverts.triangles.length; i+=3) {
let v:cc.Vec2[] = [];
let iv:cc.Vec2[] = [];
for (let c=0; c<3; ++c) {
let id = nverts.triangles[c + i];
let p = cc.v2(nverts.x[id], nverts.y[id]);
v.push(p);
id = tverts.triangles[c + i];
p = cc.v2(tverts.x[id], tverts.y[id]);
iv.push(p);
}
let icenter = this.getPolygonCenter(iv);
let center = this.getPolygonCenter(v);
let dir = center.sub(icenter).mul(this.mper);
v.forEach((_v:cc.Vec2, index)=>{
let nv = _v.sub(dir);
let id = nverts.triangles[index + i];
nverts.x[id] = nv.x;
nverts.y[id] = nv.y;
});
}
//@ts-ignore
this.mesh.spriteFrame.vertices = nverts;
//@ts-ignore
this.mesh.setVertsDirty();
}
update (dt) {
dt *= time_scale;
if (this.isMesh) {
this.mper += dt * this.speed * (this.playBoom ? 10 : 1);
if (this.mper >= 1) {
this.mper = 1;
}
this.updateMeshVerts();
if (this.mper >= 1) {
this.isMeshOpen = !this.playBoom;
this.playBoom = !this.playBoom;
this.isMesh = false;
}
}
}
}