帧动画:
引擎版本:2.4.1
webmobile模式
前置函数准备:https://blog.csdn.net/GrimRaider/article/details/106996232
1.resources下资源动态加载:
const { ccclass, property } = cc._decorator;
@ccclass
export class TestSpriteAtlas extends cc.Component {
private _loadLocalFrameAnim() {
cc.resources.load(`${本地resources下资源路径}`, cc.SpriteAtlas, (err, sprAtlas: cc.SpriteAtlas) => {
let sprFrmAry = sprAtlas.getSpriteFrames();
this._createAnim(sprFrmAry);
});
}
@property(cc.Sprite)
spr: cc.Sprite = null;
@property(cc.Animation)
sprAnim: cc.Animation = null;
private _createAnim(frames: cc.SpriteFrame[]) {
let clip: cc.AnimationClip = cc.AnimationClip.createWithSpriteFrames(frames, frames.length);
clip.name = `${clip名称}`;
clip.speed = 0.5;
clip.sample = 24;// 一般是导出plist时有相关信息
clip.wrapMode = cc.WrapMode.Normal;
this.sprAnim.addClip(clip);
this.sprAnim.play(`${clip名称}`);
}
}
2.加载本地资源:
// 加载图片
private _curTexture: cc.Texture2D = null;
public loadImg() {
let fileAccept = ".png";
// 使用input方式选取本地文件
openLocalFile(fileAccept, (file: File) => {
if (file) {
// File转base64
readLocalFile(file, READ_FILE_TYPE.DATA_URL, (result: string | ArrayBuffer) => {
let fileBase64 = result.toString();
// base64转cc.Texture2D
base64ToTexture2D(fileBase64, (texture: cc.Texture2D) => {
this._curTexture = texture;
this._curTexture.setPremultiplyAlpha(true);// 预乘,根据需要添加
});
});
}
});
}
// 加载plist
private _curPlistData: any = null;
public loadPlist() {
let fileAccept = ".plist";
openLocalFile(fileAccept, (file: File) => {
if (file) {
readLocalFile(file, READ_FILE_TYPE.TEXT, (plistResult: string | ArrayBuffer) => {
if (plistResult) {
let plistStr = plistResult.toString();
if (plistStr) {
cc.assetManager.parser.parsePlist(plistStr, null, (err: Error, data: any) => {
this._curPlistData = data;
this._checkSpriteFrames();
});
}
}
});
}
});
}
// 这个当时卡了好久,不知道怎么解析{
{1,2},{3,4}}这种字符串,参考了这个
// https://github.com/zhefengzhang/load-remote-plist/blob/master/LoadRemotePlist.js
// 如果有更好方法的大神,希望能够指点在下,感激不尽
private _parseRect(rectStr: string): cc.Rect {
let rect = new cc.Rect();
const BRACE_REGEX = /[\{\}]/g;
let strAry = rectStr.replace(BRACE_REGEX, "").split(',');
rect.x = ~~strAry[0];
rect.y = ~~strAry[1];
rect.width = ~~strAry[2];
rect.height = ~~strAry[3];
return rect;
}
// 同上
private _parseVec2(vec2Str: string): cc.Vec2 {
let v2 = cc.v2();
const BRACE_REGEX = /[\{\}]/g;
let strAry = vec2Str.replace(BRACE_REGEX, "").split(',');
v2.x = ~~strAry[0];
v2.y = ~~strAry[1];
return v2;
}
// 同上
private _parsSize(sizeStr: string): cc.Size {
const BRACE_REGEX = /[\{\}]/g;
let strAry = sizeStr.replace(BRACE_REGEX, "").split(',');
let w = ~~strAry[0];
let h = ~~strAry[1];
let size = new cc.Size(w, h);
return size;
}
// 自己写的针对cc.SpriteAtlas对象的plist解析器
// 引擎自带的没有单独解析器,好像是通过打包成import类型资源,使用处理json的方式创建的,在引擎代码里没翻到。。。
private _checkSpriteFrames() {
if (this._curPlistData && this._curTexture) {
let sprFrmAry: cc.SpriteFrame[] = [];
let frames = this._curPlistData['frames'];
for (let k in frames) {
let frameData = frames[k];
let rect = this._parseRect(frameData.frame);
let offset = this._parseVec2(frameData.offset);
let originalSize = this._parsSize(frameData.sourceSize);
let sprFrm = new cc.SpriteFrame(this._curTexture, rect, frameData.rotated, offset, originalSize);
sprFrmAry.push(sprFrm);
}
this._createAnim(sprFrmAry);
}
}
// 需要展现帧动画的cc.Sprite
@property(cc.Sprite)
spr: cc.Sprite = null;
@property(cc.Animation)
sprAnim: cc.Animation = null;
private _createAnim(frames: cc.SpriteFrame[]) {
let clip: cc.AnimationClip = cc.AnimationClip.createWithSpriteFrames(frames, frames.length);
clip.name = `${clip名字}`;
clip.speed = 0.5;// 动画播放速度
clip.sample = 24;// 每秒播放帧数
clip.wrapMode = cc.WrapMode.Normal;
this.sprAnim.addClip(clip);
this.sprAnim.play(`${clip名字}`);
}
参考:
https://docs.cocos.com/creator/manual/zh/animation/scripting-animation.html?h=addit
https://github.com/zhefengzhang/load-remote-plist/blob/master/LoadRemotePlist.js