消消方块阵换皮表情
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

239 lines
7.4 KiB

//************************
// Create By 流云
// Time: 2025.01.15
// Desc: 设置图片资源组件
//************************
import { size, Size, Texture2D, UITransform, Vec2 } from 'cc';
import { AssetManager } from 'cc';
import { ImageAsset } from 'cc';
import { _decorator, assetManager, Component, Node, Sprite, SpriteFrame } from 'cc';
import MTools from '../tools/MTools';
const { ccclass, property, executeInEditMode } = _decorator;
/**
* 设置图片资源组件
*/
@ccclass('SpriteLoad')
//@executeInEditMode
export class SpriteLoad extends Component {
@property
private bundleName: string = "icons";
@property({ type: Node })
private SpriteNode: Node = null;
@property
private AdaptSize: boolean = false;
spComp: Sprite = null;
path: string = "";
private _loadedRes = null;
private _initSize: Size = null;
private _curentPath = "";
onLoad() {
this._initSize = this.node.getComponent(UITransform).contentSize.clone();
if (this.SpriteNode) {
this.spComp = this.SpriteNode.getComponent(Sprite);
} else {
this.SpriteNode = this.node;
this.spComp = this.getComponent(Sprite);
}
}
protected onEnable(): void {
// 取消隐藏时预约的释放,避免下一帧 clear 把刚 load 的图清掉(主界面子页 SetActive 切换常见)
this.unschedule(this._deferredClear);
if (this._curentPath != "")
this.loadSprite();
}
/** 与 onDestroy 共用同一引用,便于 unschedule */
private readonly _deferredClear = (): void => {
if (!this.isValid || !this.node?.isValid) return;
// 已重新显示则不再释放(与 onEnable 的 unschedule 双保险,避免同帧/排序边界误清)
if (this.node.activeInHierarchy) return;
this.clear();
};
protected onDisable(): void {
// 关弹窗销毁时:同步 clear 可能与当帧 updateUVs 竞态;延后一帧释放。
// 主界面仅 SetActive(false) 隐藏时:若之后又显示,onEnable 会 unschedule;若仍隐藏则下一帧再释放引用。
this.scheduleOnce(this._deferredClear, 0);
}
protected onDestroy(): void {
this.unschedule(this._deferredClear);
this.clear();
}
/**
* 清除图片
*/
clear() {
if (this.path != "" && this._loadedRes) {
this._loadedRes.decRef();
this._loadedRes = null;
if (this.spComp?.spriteFrame) {
this.spComp.spriteFrame = null;
}
}
}
/**
* 设置图片
* @param path 图片路径(传空则清除当前的图片)
* @param bundleName 资源包名
* @returns
*/
setSprite(path: string, bundleName: string = "", callback = null) {
if (this.spComp == null) return;
if (bundleName != "") {
this.bundleName = bundleName;
}
this.path = path;
let name = path.split("/").pop();
if (this.bundleName == "" || this.path == "") {
return;
}
// this.spComp.spriteFrame = gg.res.getRes(name, this.path, this.bundleName, SpriteFrame);
// return;
this.path += "/spriteFrame";
if (this._curentPath != "" && this._curentPath == this.path && this._loadedRes && this.spComp.spriteFrame) return;
//this.clear();
// this.scheduleOnce(() => {
// this.loadSprite(callback);
// }, 0.1);
this.loadSprite(callback);
}
/**
* 加载远程图片
* @param url 远程url
*/
loadRemote(url: string) {
if (this.spComp == null) return;
if (this.hasImageExtension(url))
this.loadTexture(url);
else
this.loadTextureExt(url);
}
private loadSprite(callback = null) {
this.loadBundle((bundle: AssetManager.Bundle) => {
let res = bundle.get(this.path, SpriteFrame);
if (res) {
if (this.node && this.node.isValid && this.spComp) {
this.spComp.spriteFrame = res;
this._curentPath = this.path;
res.addRef();
this._loadedRes = res;
}
this.adoptSize();
return;
}
bundle.load(this.path, SpriteFrame, (err, sp) => {
if (err) {
console.log(err);
//重新加载
if (callback) {
callback(false);
}
return;
}
if (this.node && this.node.isValid && this.spComp) {
this.spComp.spriteFrame = sp;
this._curentPath = this.path;
this._loadedRes = sp;
this._loadedRes.addRef();
}
if (callback) {
callback(true);
}
this.adoptSize();
});
});
}
private loadBundle(callback) {
let bundle = assetManager.getBundle(this.bundleName);
if (bundle) {
callback(bundle);
return;
}
assetManager.loadBundle(this.bundleName, (err, bundle) => {
if (err) {
console.log(err);
return;
}
callback(bundle);
});
}
private loadTexture(url: string) {
//let remoteUrl = "http://unknown.org/someres.png";
assetManager.loadRemote<ImageAsset>(url, (err, imageAsset) => {
if (err) {
console.log(`远程加载图片${url}出错--err:` + err);
return;
}
let spriteFrame = new SpriteFrame();
let texture = new Texture2D();
texture.image = imageAsset;
spriteFrame.texture = texture;
this.spComp.spriteFrame = spriteFrame;
});
}
private loadTextureExt(url: string, ext: string = ".png") {
// 远程 url 不带图片后缀名,此时必须指定远程图片文件的类型
//remoteUrl = "http://unknown.org/emoji?id=124982374";
assetManager.loadRemote<ImageAsset>(url, { ext: ext }, (err, imageAsset) => {
if (err) {
console.log(`远程加载图片${url}出错--err:` + err);
return;
}
let spriteFrame = new SpriteFrame();
let texture = new Texture2D();
texture.image = imageAsset;
spriteFrame.texture = texture;
this.spComp.spriteFrame = spriteFrame;
});
}
/**
* 判断图片url是否带后缀
* @param url
* @returns
*/
private hasImageExtension(url: string): boolean {
// 正则表达式匹配常见的图片后缀名
let imageExtensionPattern = /\.(jpg|jpeg|png|gif|bmp|webp|svg)$/i;
return imageExtensionPattern.test(url);
}
private adoptSize() {
if (this.spComp == null) return;
if (this.spComp.spriteFrame == null) return;
let spriteFrame = this.spComp.spriteFrame;
let width = spriteFrame.originalSize.width;
let height = spriteFrame.originalSize.height;
if (this.AdaptSize) {
let s = MTools.adaptSize(this._initSize.width, this._initSize.height, width, height);
this.node.getComponent(UITransform).contentSize = size(s.x, s.y);
}
}
}