import { AssetManager, assetManager, Canvas, Component, director, game, Node, resources, Size, Sprite, UITransform, v2, v3, v4, Vec2, Vec3, Vec4, view, warn } from "cc"; // 检测全局命名空间是否存在 const __Global__ = window ?? globalThis; if(!Reflect.has(__Global__, 'mtec')){ Reflect.set(__Global__, 'mtec', {}); Reflect.set(mtec, '__mtec__', 'Many technologies'); } // 初始化子命名空间 ['sp', 'size', 'vector', 'cc'] .forEach(space_name=>{ if(!Reflect.has(mtec, space_name)){ Reflect.set(mtec, space_name, {}); Reflect.set(Reflect.get(mtec, space_name), '__space_description__', 'This is a mtec subnamespace for ' + space_name); } }); Reflect.defineProperty(mtec.cc, 'initTime', { get() { return Reflect.get(game, '_initTime'); }, enumerable: true, configurable: false, }); Reflect.defineProperty(mtec.cc, 'totalTime', { get() { return game.totalTime; }, enumerable: true, configurable: false, }); Reflect.defineProperty(mtec.cc, 'frameStartTime', { get() { return game.frameStartTime - mtec.cc.initTime; }, enumerable: true, configurable: false, }); Reflect.defineProperty(mtec.cc, 'residueTime', { get() { return mtec.cc.frameStartTime+mtec.cc.frameTime-mtec.cc.totalTime; }, enumerable: true, configurable: false, }); Reflect.defineProperty(mtec.cc, 'frameTime', { get() { return game.frameTime; }, enumerable: true, configurable: false, }); Reflect.defineProperty(mtec.cc, 'is_long_screen', { get(){ let [R, r] = [mtec.size.canvasSize, mtec.size.designSize].map(s=>s.width/s.height); return r > R; }, enumerable: true, configurable: false, }); if(typeof requestIdleCallback !== 'undefined'){ mtec.cc.IdleCallback = function(call, args, complete, options){ if(options){ if(!Reflect.has(options, 'start_stamp')) options.start_stamp = performance.now(); if(!Reflect.has(options, 'timeout')) options.timeout = 100; }else options = {start_stamp: performance.now(), timeout: 100}; requestIdleCallback(()=>{ if(mtec.cc.residueTime>0 || performance.now()-options.start_stamp >= options.timeout){ Promise.resolve(call(...args)).then(r=> typeof complete == 'function' ? complete(r, args) : void 0); }else mtec.cc.IdleCallback(call, args, complete, options); }); } }else if(typeof requestAnimationFrame !== 'undefined'){ mtec.cc.IdleCallback = function(call, args, complete, options){ if(options){ if(!Reflect.has(options, 'start_stamp')) options.start_stamp = performance.now(); if(!Reflect.has(options, 'timeout')) options.timeout = 100; }else options = {start_stamp: performance.now(), timeout: 100}; requestAnimationFrame(()=>{ if(mtec.cc.residueTime>0 || performance.now()-options.start_stamp >= options.timeout){ Promise.resolve(call(...args)).then(r=> typeof complete == 'function' ? complete(r, args) : void 0); }else mtec.cc.IdleCallback(call, args, complete, options); }); } }else{ mtec.cc.IdleCallback = function(call, args, complete, options){ if(options){ if(!Reflect.has(options, 'start_stamp')) options.start_stamp = performance.now(); if(!Reflect.has(options, 'timeout')) options.timeout = 100; }else options = {start_stamp: performance.now(), timeout: 100}; setTimeout(()=>{ if(mtec.cc.residueTime>0 || performance.now()-options.start_stamp >= options.timeout){ Promise.resolve(call(...args)).then(r=> typeof complete == 'function' ? complete(r, args) : void 0); }else mtec.cc.IdleCallback(call, args, complete, options); }, 0); } } mtec.cc.frameWhile = function(list, call){ if(!list || !Array.isArray(list) || list.length<=0) return Promise.resolve(0); let np = new mtec.NudityPromise<0>(); list.forEach((el, i)=> mtec.cc.IdleCallback(call, [el, i, list], ()=>(i==list.length-1) ? np.resolve(0) : void 0) ); return np.promise; } mtec.cc.loadBundle = function(bundle_name){ return new Promise((s, j)=>{ assetManager.loadBundle(bundle_name, null, (err, bundle)=>{ if(err) s(undefined); else if(bundle) s(bundle); else s(undefined); }); }); }; mtec.cc.loadRes = function(path, type, bundle, call){ //@ts-ignore [bundle, call] = mtec.pickValueByType([bundle, call], [['object', resources], ['function', undefined]]); let asset = bundle.get(path, type); if(!asset){ bundle.load(path, type, (err, a)=>{ if(a) call && call(a); else warn('资源加载失败:', path, type, err); }); }else if(call) call(asset); } mtec.cc.loadResAsync = function(path, type, bundle){ bundle = bundle??resources; return new Promise((s, j)=>{ let asset = bundle.get(path, type); if(asset) s(asset); else{ bundle.load(path, type, (err, a)=>{ if(a) s(a); else warn('资源加载失败:', path, type, err); }); } }); } mtec.cc.creatEventHandle = function(options){ return Object.assign(new Component.EventHandler(), options); } mtec.cc.VecAssist = class{ private inner: UITransform; private container: UITransform; private __vec__: Vec3; constructor(node: Node, ref: Node){ if (!node.parent){ mtec.log.tag(`node<${node.name}> 不在场景中,无法使用坐标辅助类的功能!: red`); return void 0; } ref = ref&&ref.isValid ? ref : node.parent; [this.inner, this.container] = [node, ref].map(n=>n.getComponent(UITransform)); this.__vec__ = v3(); } private get container_upper(){ return this.container.height * (1 - this.container.anchorY); } private get container_bottom(){ return this.container.height * this.container.anchorY; } private get container_left(){ return this.container.width * this.container.anchorX; } private get container_right(){ return this.container.width * (1 - this.container.anchorX); } private get inner_upper(){ return this.inner.height * (1 - this.inner.anchorY); } private get inner_bottom(){ return this.inner.height * this.inner.anchorY; } private get inner_left(){ return this.inner.width * this.inner.anchorX; } private get inner_right(){ return this.inner.width * (1 - this.inner.anchorX); } public get top(){ return this.container_upper - this.inner_upper; } public get bottom(){ return this.inner_bottom - this.container_bottom; } public get left(){ return this.inner_left - this.container_left; } public get right(){ return this.container_right - this.inner_right; } public get over_top(){ return this.container_upper + this.inner_bottom; } public get over_bottom(){ return -this.container_bottom - this.inner_upper; } public get over_left(){ return -this.container_left - this.inner_right; } public get over_right(){ return this.container_right + this.inner_left; } public get center(){ let x = (0.5 - this.container.anchorX) * this.container.width + (this.inner.anchorX - 0.5) * this.inner.width; let y = (0.5 - this.container.anchorY) * this.container.height + (this.inner.anchorY - 0.5) * this.inner.height; return v3(x, y, this.inner.node.position.z); } public get vec(){ return this.__vec__; } public getPosition(x: 'center'|`${''|'over_'}${'left'|'right'|'bottom'|'top'}`, y?:'center'|`${''|'over_'}${'top'|'bottom'}`){ if(x.includes('top') || x.includes('bottom')){ let _t = y; y = x; x = _t; _t = undefined; } this.vec.set( x ? x=='center' ? this.center.x : Reflect.get(this, x) : this.inner.node.position.x, y ? y=='center' ? this.center.y : Reflect.get(this, y) : this.inner.node.position.y, this.inner.node.position.z ); return this.vec; } public static getPosition(node: Node, ref?: Node|Dx, x?: Dx|Dy, y?: Dy){ if(typeof ref == 'string'){ [x, y as typeof x] = [ref, x]; ref = undefined; } let va = new mtec.cc.VecAssist(node, ref as Node); let vec = va.getPosition(x??'center', y); va = null; return vec; } } mtec.cc.skinPeeler = function(node, sframe, inner){ let uitrans = node.getComponent(UITransform); let node_size = uitrans.contentSize.clone(); let sfrm_size = sframe.originalSize.clone(); let sprite = node.getComponent(Sprite); if(!sprite) sprite = node.addComponent(Sprite); sprite.spriteFrame = sframe; let ratio: number; inner = inner ?? true; if(typeof inner=='boolean' || inner.width===inner.height){ if(typeof inner!='boolean') inner = inner.width; ratio = Math[inner ? 'min' : 'max'](node_size.width / sfrm_size.width, node_size.height / sfrm_size.height); }else{ let side = inner.width ? 'width' : 'height'; ratio = node_size[side] / sfrm_size[side]; } uitrans.setContentSize(sfrm_size.width * ratio, sfrm_size.height * ratio); } mtec.cc.getWorldPosition = function(node, out){ if(!node || !node.isValid) return void 0; return node.getWorldPosition(out??v3()); } mtec.cc.getLocalPosition = function(local: Node, node: Vec3|Node, out?: Vec3){ if([local && local.isValid, node instanceof Vec3 ? true : (node && node.isValid)].includes(false)) return void 0; return local.getComponent(UITransform).convertToNodeSpaceAR(node instanceof Vec3 ? node : mtec.cc.getWorldPosition(node), out??v3()); }; mtec.cc.v2 = function(__x__, y){ if(__x__ instanceof Vec2) return __x__; let x: number; if(typeof __x__ == 'number'){ x = __x__; y = y??x; }else ({x, y} = __x__); return v2(x, y); } mtec.cc.v3 = function(__x__, y, z){ if(__x__ instanceof Vec3) return __x__; let x: number; if(typeof __x__ == 'number'){ x = __x__; y = y??x; z = z??y; }else if(__x__ instanceof Vec2){ z = y??0; ({x, y} = __x__); }else if(__x__ instanceof Vec4){ ({x, y, z} = __x__); } return v3(x, y, z); } mtec.cc.v4 = function(__x__, y, z, w){ if(__x__ instanceof Vec4) return __x__; let x: number; if(typeof __x__ == 'number'){ x = __x__; y = y??x; z = z??y; w = w??z; }else if(__x__ instanceof Vec2){ w = z??0; z = y??0; ({x, y} = __x__); }else if(__x__ instanceof Vec3){ w = z??0; ({x, y, z} = __x__); } return v4(x, y, z, w); } mtec.cc.adaptBackgroundNode = function(node, container){ container = container ?? node.parent; if(!container || ![node, container].every(n=>n.isValid)) return void 0; let [ui_container, ui_node] = [container, node].map(n=>{ let ui = n.getComponent(UITransform); if(!ui) ui = n.addComponent(UITransform); return ui; }); let node_size: Size; if(node.getComponent(Sprite)) node_size = node.getComponent(Sprite).spriteFrame.originalSize; else node_size = ui_node.contentSize; let [R, r] = [ui_container, node_size].map($=>$.width / $.height); let ratio: number; if(R > r) ratio = ui_container.width / node_size.width; else ratio = ui_container.height / node_size.height; ui_node.setContentSize(node_size.width * ratio, node_size.height * ratio); } Reflect.defineProperty(mtec.cc, 'canvas', { get(){ return director.getScene().getComponentInChildren(Canvas); }, enumerable: true, configurable: false, }); Reflect.defineProperty(mtec.size, 'designSize', { get() { return view.getDesignResolutionSize(); }, enumerable: true, configurable: false, }); Reflect.defineProperty(mtec.size, 'canvasSize', { get() { return mtec.cc.canvas.getComponent(UITransform).contentSize; }, enumerable: true, configurable: false, }); mtec.size.innerRatio = function(target, container){ let [R, r] = [container, target].map(s=>s.width / s.height); /** @type {number} */ let ratio: number; if(r > R) ratio = container.width / target.width; else ratio = container.height / target.height; return ratio; } mtec.size.exterRatio = function(target, filler){ let [R, r] = [target, filler].map(s=>s.width / s.height); /** @type {number} */ let ratio: number; if(R > r) ratio = filler.height / target.height; else ratio = filler.width / target.width; return ratio; } mtec.vector.distance = function(a, b){ if([a, b].map(v=>v instanceof Vec2).includes(true)) return Vec2.subtract(v2(), mtec.cc.v2(a), mtec.cc.v2(b)).length(); if([a, b].map(v=>v instanceof Vec3).includes(true)) return Vec3.subtract(v3(), mtec.cc.v3(a), mtec.cc.v3(b)).length(); return Vec4.subtract(v4(), mtec.cc.v4(a), mtec.cc.v4(b)).length(); }