mark~~
马住~~~
帮忙解释一下 这里的0.97 和0.015,怎么来的
假定缩放倍数为k,如果需要中心对齐的话那么
new_uv = uv * (1/k) + (k-1)/2k
mark 住
好棒的火舞(不是,火焰效果),学习一下火焰描边,不过我描边没有用放大+填色+叠加的方案,这个方案有点问题,因为所有的点都在从中心点往外扩的,那些角度大于180°的边就会出现问题。选择另一种描边方案,是对图片取样8次,分别往8个不同的方向偏移取样,获取到描边颜色后,思路和楼主一样的,不过没有用噪声图片取而代之用代码实现的噪声纹理采样,最后效果如图
还是不太明白,辛苦大佬再解释下呢?
根据引擎版本有关系吗?复制effec你的代码拿来用,完全是买家秀和卖家秀
2.4.6
你的头像引起了我的注意,可否借一步说话~
怎么推导的我忘了… 反正大概意思 是先缩放,再平移 保证缩放、平移前后 中心点对齐
试了下 这个方案,效果也有 ,但是如果源图像是plist中的一帧 结果就不对了(感觉采样重复了 好像) 不知道大佬有没有plist中图片的解决方案
plist中的uv不是从0~1的 你在计算的时候需要先把uv坐标还原到0~1然后在纹理采样的时候将uv坐标还原到图集里面的范围区间内去
你可以打印一下spf身上的uv字段 合图里面的uv不是从0-1开始的 需要自己把真实的uv边界传进去 然后你自己clamp裁剪一下 不然会取样到附近图片的纹理的
好的 谢谢大佬 我试试
updateWorldVerts(sprite) {
let local = this._local;
let verts = this._renderData.vDatas[0];
let matrix = sprite.node._worldMatrix;
let matrixm = matrix.m,
a = matrixm[0], b = matrixm[1], c = matrixm[4], d = matrixm[5],
tx = matrixm[12], ty = matrixm[13];
let vl = local[0], vr = local[2],
vb = local[1], vt = local[3];
let floatsPerVert = this.floatsPerVert;
let vertexOffset = 0;
if (CC_NATIVERENDERER) {
verts[vertexOffset] = vl;
verts[vertexOffset + 1] = vb;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = vr;
verts[vertexOffset + 1] = vb;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = vl;
verts[vertexOffset + 1] = vt;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = vr;
verts[vertexOffset + 1] = vt;
} else {
let justTranslate = a === 1 && b === 0 && c === 0 && d === 1;
if (justTranslate) {
// left bottom
verts[vertexOffset] = vl + tx;
verts[vertexOffset + 1] = vb + ty;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = vr + tx;
verts[vertexOffset + 1] = vb + ty;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = vl + tx;
verts[vertexOffset + 1] = vt + ty;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = vr + tx;
verts[vertexOffset + 1] = vt + ty;
} else {
let al = a * vl, ar = a * vr,
bl = b * vl, br = b * vr,
cb = c * vb, ct = c * vt,
db = d * vb, dt = d * vt;
// left bottom
verts[vertexOffset] = al + cb + tx;
verts[vertexOffset + 1] = bl + db + ty;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = ar + cb + tx;
verts[vertexOffset + 1] = br + db + ty;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = al + ct + tx;
verts[vertexOffset + 1] = bl + dt + ty;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = ar + ct + tx;
verts[vertexOffset + 1] = br + dt + ty;
}
}
vertexOffset = 0;
let min = cc.v2(verts[0],verts[0 + 1]);
let max = cc.v2(verts[floatsPerVert * 3],verts[floatsPerVert * 3 + 1]);
let off = cc.v2(max.x - min.x, max.y - min.y);
// cc.log('Simple updateWorldVerts',sprite.node.name,verts,min.x +','+min.y +'-'+max.x +','+max.y);
// 2(2x32): uv offset // 1(4x8=32): color offset
// ATTR_POSITION 0-1(2xfloat32)
// ATTR_UV0 2-3(2xfloat32)
// ATTR_COLOR 4(4xint8=32)
// a_frameInfo 5-8 (4xfloat32)
let texx = sprite.node.width * sprite.node.scaleX;
let texy = sprite.node.height * sprite.node.scaleY;
vertexOffset = 0;
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
}
需要自定义顶点数据,计算好正确uv传给shader,我这里的
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
就是计算后的uv
给一个完整的
CustomFrameUVSimpleAssembler.ts
// https://forum.cocos.org/t/topic/120337
// https://forum.cocos.org/t/topic/95087
// 自定义Assembler 把frame的相关信息传进shader
//@ts-ignore
let gfx = cc.gfx;
const vfmtCustom = new gfx.VertexFormat([
{ name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
{ name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
{ name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
{ name: "a_frameInfo", type: gfx.ATTR_TYPE_FLOAT32, num: 4 }, // xy textureSize(width * scale) // zw localUV
]);
export default class CustomFrameUVSimpleAssembler extends cc.Assembler {
floatsPerVert = 9;
verticesCount = 4;
indicesCount = 6;
uvOffset = 2;
colorOffset = 4;
protected _renderData: cc.RenderData = null;
protected _local: any = null; // 中间结果。[l,b,r,t]。node对象左下、右上顶点的本地坐标,即相对于锚点的偏移
init(comp: cc.RenderComponent) {
super.init(comp);
// cc.Assembler2D的初始化放在constructor里
// 此处把初始化放在init里,以便成员变量能够有机会修改
this._renderData = new cc.RenderData();
this._renderData.init(this);
this.initLocal();
this.initData();
}
// todo: mixin this part
initData() {
let data = this._renderData;
// createFlexData支持创建指定格式的renderData
data.createFlexData(0, this.verticesCount, this.indicesCount, this.getVfmt());
// createFlexData不会填充顶点索引信息,手动补充一下
let indices = data.iDatas[0];
let count = indices.length / 6;
for (let i = 0, idx = 0; i < count; i++) {
let vertextID = i * 4;
indices[idx++] = vertextID;
indices[idx++] = vertextID + 1;
indices[idx++] = vertextID + 2;
indices[idx++] = vertextID + 1;
indices[idx++] = vertextID + 3;
indices[idx++] = vertextID + 2;
}
}
initLocal() {
this._local = [];
this._local.length = 4;
}
get verticesFloats() {
return this.verticesCount * this.floatsPerVert;
}
getVfmt() {
return vfmtCustom;
}
getBuffer() {
//@ts-ignore
return cc.renderer._handle.getBuffer("mesh", this.getVfmt());
}
updateColor(comp, color) {
// render data = verts = x|y|u|v|color|x|y|u|v|color|...
// 填充render data中4个顶点的color部分
let uintVerts = this._renderData.uintVDatas[0];
if (!uintVerts) return;
color = color != null ? color : comp.node.color._val;
let floatsPerVert = this.floatsPerVert;
let colorOffset = this.colorOffset;
for (let i = colorOffset, l = uintVerts.length; i < l; i += floatsPerVert) {
uintVerts[i] = color;
}
}
updateRenderData(sprite) {
this.packToDynamicAtlas(sprite, sprite._spriteFrame);
if (sprite._vertsDirty) {
this.updateUVs(sprite);
this.updateVerts(sprite);
sprite._vertsDirty = false;
}
}
updateVerts(sprite) {
let node = sprite.node,
cw = node.width, ch = node.height,
appx = node.anchorX * cw, appy = node.anchorY * ch,
l, b, r, t;
if (sprite.trim) {
l = -appx;
b = -appy;
r = cw - appx;
t = ch - appy;
}
else {
let frame = sprite.spriteFrame,
ow = frame._originalSize.width, oh = frame._originalSize.height,
rw = frame._rect.width, rh = frame._rect.height,
offset = frame._offset,
scaleX = cw / ow, scaleY = ch / oh;
let trimLeft = offset.x + (ow - rw) / 2;
let trimRight = offset.x - (ow - rw) / 2;
let trimBottom = offset.y + (oh - rh) / 2;
let trimTop = offset.y - (oh - rh) / 2;
l = trimLeft * scaleX - appx;
b = trimBottom * scaleY - appy;
r = cw + trimRight * scaleX - appx;
t = ch + trimTop * scaleY - appy;
}
let local = this._local;
local[0] = l;
local[1] = b;
local[2] = r;
local[3] = t;
this.updateWorldVerts(sprite);
}
updateUVs(sprite) {
let uv = sprite._spriteFrame.uv;
// this.logOnce(sprite._spriteFrame.uv)
let uvOffset = this.uvOffset;
let floatsPerVert = this.floatsPerVert;
let verts = this._renderData.vDatas[0];
for (let i = 0; i < 4; i++) {
let srcOffset = i * 2;
let dstOffset = floatsPerVert * i + uvOffset;
verts[dstOffset] = uv[srcOffset];
verts[dstOffset + 1] = uv[srcOffset + 1];
}
}
updateWorldVerts(sprite) {
let local = this._local;
let verts = this._renderData.vDatas[0];
let matrix = sprite.node._worldMatrix;
let matrixm = matrix.m,
a = matrixm[0], b = matrixm[1], c = matrixm[4], d = matrixm[5],
tx = matrixm[12], ty = matrixm[13];
let vl = local[0], vr = local[2],
vb = local[1], vt = local[3];
let floatsPerVert = this.floatsPerVert;
let vertexOffset = 0;
if (CC_NATIVERENDERER) {
verts[vertexOffset] = vl;
verts[vertexOffset + 1] = vb;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = vr;
verts[vertexOffset + 1] = vb;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = vl;
verts[vertexOffset + 1] = vt;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = vr;
verts[vertexOffset + 1] = vt;
} else {
let justTranslate = a === 1 && b === 0 && c === 0 && d === 1;
if (justTranslate) {
// left bottom
verts[vertexOffset] = vl + tx;
verts[vertexOffset + 1] = vb + ty;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = vr + tx;
verts[vertexOffset + 1] = vb + ty;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = vl + tx;
verts[vertexOffset + 1] = vt + ty;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = vr + tx;
verts[vertexOffset + 1] = vt + ty;
} else {
let al = a * vl, ar = a * vr,
bl = b * vl, br = b * vr,
cb = c * vb, ct = c * vt,
db = d * vb, dt = d * vt;
// left bottom
verts[vertexOffset] = al + cb + tx;
verts[vertexOffset + 1] = bl + db + ty;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset] = ar + cb + tx;
verts[vertexOffset + 1] = br + db + ty;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset] = al + ct + tx;
verts[vertexOffset + 1] = bl + dt + ty;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset] = ar + ct + tx;
verts[vertexOffset + 1] = br + dt + ty;
}
}
vertexOffset = 0;
let min = cc.v2(verts[0],verts[0 + 1]);
let max = cc.v2(verts[floatsPerVert * 3],verts[floatsPerVert * 3 + 1]);
let off = cc.v2(max.x - min.x, max.y - min.y);
// cc.log('Simple updateWorldVerts',sprite.node.name,verts,min.x +','+min.y +'-'+max.x +','+max.y);
// 2(2x32): uv offset // 1(4x8=32): color offset
// ATTR_POSITION 0-1(2xfloat32)
// ATTR_UV0 2-3(2xfloat32)
// ATTR_COLOR 4(4xint8=32)
// a_frameInfo 5-8 (4xfloat32)
let texx = sprite.node.width * sprite.node.scaleX;
let texy = sprite.node.height * sprite.node.scaleY;
vertexOffset = 0;
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
vertexOffset += floatsPerVert;
// right bottom
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
vertexOffset += floatsPerVert;
// left top
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
vertexOffset += floatsPerVert;
// right top
verts[vertexOffset + 5] = texx;
verts[vertexOffset + 6] = texy;
verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
}
// updateWorldVerts(comp) {
// if (CC_NATIVERENDERER) {
// this.updateWorldVertsNative(comp);
// } else {
// this.updateWorldVertsWebGL(comp);
// }
// }
// updateWorldVertsNative(sprite) {
// let local = this._local;
// let verts = this._renderData.vDatas[0];
// let floatsPerVert = this.floatsPerVert;
// let vl = local[0],
// vr = local[2],
// vb = local[1],
// vt = local[3];
// let vertexOffset: number = 0;
// // left bottom
// verts[vertexOffset] = vl;
// verts[vertexOffset+1] = vb;
// vertexOffset += floatsPerVert;
// // right bottom
// verts[vertexOffset] = vr;
// verts[vertexOffset+1] = vb;
// vertexOffset += floatsPerVert;
// // left top
// verts[vertexOffset] = vl;
// verts[vertexOffset+1] = vt;
// vertexOffset += floatsPerVert;
// // right top
// verts[vertexOffset] = vr;
// verts[vertexOffset+1] = vt;
// vertexOffset = 0;
// let min = cc.v2(verts[0],verts[0 + 1]);
// let max = cc.v2(verts[floatsPerVert * 3],verts[floatsPerVert * 3 + 1]);
// let off = cc.v2(max.x - min.x, max.y - min.y);
// cc.log('Simple updateWorldVerts',sprite.node.name,verts,min.x +','+min.y +'-'+max.x +','+max.y);
// // 2(2x32): uv offset // 1(4x8=32): color offset
// // ATTR_POSITION 0-1(2xfloat32)
// // ATTR_UV0 2-3(2xfloat32)
// // ATTR_COLOR 4(4xint8=32)
// // a_frameInfo 5-8 (4xfloat32)
// let texx = sprite.node.width * sprite.node.scaleX;
// let texy = sprite.node.height * sprite.node.scaleY;
// vertexOffset = 0;
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// vertexOffset += floatsPerVert;
// // right bottom
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// vertexOffset += floatsPerVert;
// // left top
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// vertexOffset += floatsPerVert;
// // right top
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// }
// updateWorldVertsWebGL(sprite) {
// let local = this._local;
// let verts = this._renderData.vDatas[0];
// let matrix = sprite.node._worldMatrix;
// let matrixm = matrix.m,
// a = matrixm[0], b = matrixm[1], c = matrixm[4], d = matrixm[5],
// tx = matrixm[12], ty = matrixm[13];
// let vl = local[0], vr = local[2],
// vb = local[1], vt = local[3];
// let floatsPerVert = this.floatsPerVert;
// let vertexOffset = 0;
// let justTranslate = a === 1 && b === 0 && c === 0 && d === 1;
// if (justTranslate) {
// // left bottom
// verts[vertexOffset] = vl + tx;
// verts[vertexOffset + 1] = vb + ty;
// vertexOffset += floatsPerVert;
// // right bottom
// verts[vertexOffset] = vr + tx;
// verts[vertexOffset + 1] = vb + ty;
// vertexOffset += floatsPerVert;
// // left top
// verts[vertexOffset] = vl + tx;
// verts[vertexOffset + 1] = vt + ty;
// vertexOffset += floatsPerVert;
// // right top
// verts[vertexOffset] = vr + tx;
// verts[vertexOffset + 1] = vt + ty;
// } else {
// let al = a * vl, ar = a * vr,
// bl = b * vl, br = b * vr,
// cb = c * vb, ct = c * vt,
// db = d * vb, dt = d * vt;
// // left bottom
// verts[vertexOffset] = al + cb + tx;
// verts[vertexOffset + 1] = bl + db + ty;
// vertexOffset += floatsPerVert;
// // right bottom
// verts[vertexOffset] = ar + cb + tx;
// verts[vertexOffset + 1] = br + db + ty;
// vertexOffset += floatsPerVert;
// // left top
// verts[vertexOffset] = al + ct + tx;
// verts[vertexOffset + 1] = bl + dt + ty;
// vertexOffset += floatsPerVert;
// // right top
// verts[vertexOffset] = ar + ct + tx;
// verts[vertexOffset + 1] = br + dt + ty;
// }
// vertexOffset = 0;
// let min = cc.v2(verts[0],verts[0 + 1]);
// let max = cc.v2(verts[floatsPerVert * 3],verts[floatsPerVert * 3 + 1]);
// let off = cc.v2(max.x - min.x, max.y - min.y);
// cc.log('Simple updateWorldVerts',sprite.node.name,verts,min.x +','+min.y +'-'+max.x +','+max.y);
// // 2(2x32): uv offset // 1(4x8=32): color offset
// // ATTR_POSITION 0-1(2xfloat32)
// // ATTR_UV0 2-3(2xfloat32)
// // ATTR_COLOR 4(4xint8=32)
// // a_frameInfo 5-8 (4xfloat32)
// let texx = sprite.node.width * sprite.node.scaleX;
// let texy = sprite.node.height * sprite.node.scaleY;
// vertexOffset = 0;
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// vertexOffset += floatsPerVert;
// // right bottom
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// vertexOffset += floatsPerVert;
// // left top
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// vertexOffset += floatsPerVert;
// // right top
// verts[vertexOffset + 5] = texx;
// verts[vertexOffset + 6] = texy;
// verts[vertexOffset + 7] = (verts[vertexOffset] - min.x) / off.x;
// verts[vertexOffset + 8] = 1 - (verts[vertexOffset + 1] - min.y) / off.y;
// }
fillBuffers(comp, renderer) {
if (renderer.worldMatDirty) {
this.updateWorldVerts(comp);
}
let renderData = this._renderData;
let vData = renderData.vDatas[0];
let iData = renderData.iDatas[0];
// @ts-ignore
let buffer = this.getBuffer(renderer);
let offsetInfo = buffer.request(this.verticesCount, this.indicesCount);
// buffer data may be realloc, need get reference after request.
// fill vertices
let vertexOffset = offsetInfo.byteOffset >> 2,
vbuf = buffer._vData;
if (vData.length + vertexOffset > vbuf.length) {
vbuf.set(vData.subarray(0, vbuf.length - vertexOffset), vertexOffset);
} else {
vbuf.set(vData, vertexOffset);
}
// fill indices
let ibuf = buffer._iData,
indiceOffset = offsetInfo.indiceOffset,
vertexId = offsetInfo.vertexOffset;
for (let i = 0, l = iData.length; i < l; i++) {
ibuf[indiceOffset++] = vertexId + iData[i];
}
}
packToDynamicAtlas(comp, frame) {
if (CC_TEST) return;
if (!frame._original && cc.dynamicAtlasManager && frame._texture.packable && frame._texture.loaded) {
let packedFrame = cc.dynamicAtlasManager.insertSpriteFrame(frame);
// @ts-ignore
if (packedFrame) {
frame._setDynamicAtlasFrame(packedFrame);
}
}
let material = comp._materials[0];
if (!material) return;
if (material.getProperty('texture') !== frame._texture._texture) {
// texture was packed to dynamic atlas, should update uvs
comp._vertsDirty = true;
comp._updateMaterial();
}
}
}
a_frameInfo.xy 是我自己传入的textureSize我有别的用
a_frameInfo.zw 就是图集中的换算后的uv
SpriteWithFrameUV.ts
@ccclass
export default class AvatarSprite extends cc.Sprite {
// _resetAssembler() {
// this.setVertsDirty();
// let assembler = this._assembler = new CustomFrameUVAssembler();
// assembler.init(this);
// }
}
cc.Assembler.register(AvatarSprite,{
getConstructor(sp) {
let ctor = CustomFrameUVSimpleAssembler;
if(sp.type === cc.Sprite.Type.SLICED){
ctor = CustomFrameUVSlicedAssembler;
}
return ctor;
}
})
nice 感谢大佬 ,已经用到我的游戏中了
实现了,但是怎么让火焰横着飘呢?
大佬,复制你的 CCEffect ,为什么弄出来是这样的静态图?
如果可以的话,把这个整成demo就好了