first commit

This commit is contained in:
2026-03-30 09:39:59 +08:00
parent 6c52425fca
commit 5ac73d3c6d
4484 changed files with 1144395 additions and 0 deletions

View File

@@ -0,0 +1,114 @@
import { Component, Graphics, Node, Size, UITransform, _decorator } from 'cc';
const { ccclass, property, requireComponent } = _decorator;
@ccclass('UIMgrLoading')
@requireComponent(UITransform)
export default class UIMgrLoading extends Component {
@property(Node)
private loading: Node;
@property({ tooltip: '动画的尺寸' })
private size: Size = new Size(60, 60);
@property({ tooltip: '等待几秒后开始动画' })
private delay = 0;
private progress = 0;
private ringScale = 1;
private reverse = false;
private angleSpeed = 120;
private ringSpeed = 0.02;
private inited = false;
private drawing = false;
private timedown = 0;
init() {
if (this.inited) return;
this.inited = true;
this.progress = 0;
this.ringScale = 1;
this.loading.angle = 0;
this.reverse = false;
this.drawing = false;
this.timedown = this.delay;
this.loading.getComponent(Graphics).clear();
}
clear() {
this.inited = false;
this.drawing = false;
}
/**
* 需要重写
*/
private onDraw() {
const graphics = this.loading.getComponent(Graphics);
const uiTransform = this.loading.getComponent(UITransform);
const centerX = this.size.width * (0.5 - uiTransform.anchorX);
const centerY = this.size.height * (0.5 - uiTransform.anchorY);
const r = Math.min(this.size.width / 2, this.size.height / 2);
const allPI = Math.PI;
const offst = 0;
graphics.clear();
if (this.reverse) {
const start = 0.5 * Math.PI + offst;
const end = 0.5 * Math.PI + this.progress * 2 * allPI + offst;
graphics.arc(centerX, centerY, r, start, end, true);
} else {
const start = 0.5 * Math.PI - offst;
const end = 0.5 * Math.PI - this.progress * 2 * allPI - offst;
graphics.arc(centerX, centerY, r, start, end, false);
}
graphics.stroke();
}
protected update(dt: number): void {
if (!this.inited) return;
// 倒计时
if (!this.drawing) {
if (this.timedown > 0) {
this.timedown -= dt;
}
if (this.timedown <= 0) {
this.drawing = true;
} else {
return;
}
}
// 旋转
this.loading.angle -= this.angleSpeed * dt;
if (this.loading.angle >= 360 || this.loading.angle <= -360) {
this.loading.angle = this.loading.angle % 360;
}
// 进度
if (this.ringScale > 0) {
this.progress = Math.min(1, this.progress + this.ringSpeed * this.ringScale);
if (this.progress == 1) {
this.ringScale = -1;
this.reverse = !this.reverse;
}
} else {
this.progress = Math.max(0, this.progress + this.ringSpeed * this.ringScale);
if (this.progress == 0) {
this.ringScale = 1;
this.reverse = !this.reverse;
}
}
this.onDraw();
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "4a8e5697-ae78-4a4a-8d08-17acc6823a27",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,167 @@
import { Camera, Color, Component, Director, Material, RenderTexture, Sprite, SpriteFrame, UIOpacity, UITransform, _decorator, director } from 'cc';
import Core from '../../../Core';
const { ccclass, property, requireComponent } = _decorator;
@ccclass('UIMgrShade')
@requireComponent(Sprite)
@requireComponent(UIOpacity)
export default class UIMgrShade extends Component {
@property(Material)
private blurMaterial: Material = null;
@property(SpriteFrame)
private shadeFrame: SpriteFrame = null;
@property
private _delay = 0;
@property
get delay() { return this._delay; }
set delay(v) { this._delay = Math.max(v, 0); }
@property
private _begin = 0;
@property
get begin() { return this._begin; }
set begin(v) { if (v >= 0 && v <= 255) this._begin = v; }
@property
private _end = 255;
@property
get end() { return this._end; }
set end(v) { if (v >= 0 && v <= 255) this._end = v; }
@property
private _speed = 10;
@property
get speed() {
if (this.begin == this.end) {
return 0;
} else if (this.begin > this.end) {
return this._speed > 0 ? -this._speed : this._speed;
} else {
return this._speed >= 0 ? this._speed : -this._speed;
}
}
set speed(v) { this._speed = v; }
private get sprite() {
return this.node.getComponent(Sprite);
}
private get opacity() {
return this.node.getComponent(UIOpacity);
}
private inited = false;
private drawing = false;
private timedown = 0;
private blurFrame: SpriteFrame = null;
init(delay: number, begin: number, end: number, speed: number, blur: boolean) {
if (blur) {
director.targetOff(this);
this.inited = false;
this.drawing = false;
this.sprite.color = Color.WHITE;
this.sprite.customMaterial = null;
this.sprite.spriteFrame = this.blurFrame;
if (this.blurFrame) this.blurFrame.flipUVY = false;
let count = 0;
const cameras = director.getScene().getComponentsInChildren(Camera);
director.on(Director.EVENT_BEFORE_RENDER, () => {
count++;
const renderTexture = new RenderTexture();
const size = this.node.getComponent(UITransform);
renderTexture.reset({ width: size.width / 2, height: size.height / 2 });
renderTexture.addRef();
Core.inst.manager.ui.screenshot(renderTexture, {
cameraList: cameras
});
if (count === 1) {
this.blurFrame = new SpriteFrame();
this.blurFrame?.texture?.decRef();
this.blurFrame.texture = renderTexture;
this.blurFrame.flipUVY = true;
this.sprite.spriteFrame = this.blurFrame;
this.sprite.customMaterial = this.blurMaterial;
this.blurMaterial.setProperty('blurLevel', 2);
return;
}
if (count === 5) {
director.targetOff(this);
this.sprite.spriteFrame.flipUVY = false;
this.sprite.customMaterial = null;
return;
}
this.blurFrame?.texture?.decRef();
this.blurFrame.texture = renderTexture;
this.blurFrame.flipUVY = true;
this.sprite.spriteFrame = this.blurFrame;
this.sprite.customMaterial = this.blurMaterial;
this.blurMaterial.setProperty('blurLevel', count === 2 ? 3 : 1);
}, this);
} else {
director.targetOff(this);
this.sprite.spriteFrame = this.shadeFrame;
this.sprite.color = Color.BLACK;
this.sprite.customMaterial = null;
}
this.delay = delay;
this.begin = begin;
this.end = end;
this.speed = speed;
this.drawing = true;
if (this.inited) return;
this.inited = true;
this.timedown = this.delay;
// 初始透明度
this.opacity.opacity = this.timedown > 0 ? 0 : this.begin;
}
clear() {
this.inited = false;
this.drawing = false;
director.targetOff(this);
this.blurFrame?.texture?.decRef();
this.blurFrame?.destroy();
this.blurFrame = null;
this.sprite.spriteFrame = null;
}
protected update(dt: number) {
if (!this.inited) return;
if (!this.drawing) return;
if (this.timedown > 0) {
this.timedown -= dt;
if (this.timedown > 0) return;
// 初始透明度
this.opacity.opacity = this.begin;
}
const uiOpacity = this.opacity;
if (this.speed > 0) {
uiOpacity.opacity += this.speed * dt;
if (uiOpacity.opacity > this.end) {
uiOpacity.opacity = this.end;
}
} else if (this.speed < 0) {
uiOpacity.opacity += this.speed * dt;
if (uiOpacity.opacity < this.end) {
uiOpacity.opacity = this.end;
}
}
if (uiOpacity.opacity == this.end) {
this.drawing = false;
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "d0295d9b-b01d-493c-9e31-5ed78e6c33ab",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,111 @@
import { Component, NodePool, Prefab, Tween, UIOpacity, UITransform, _decorator, instantiate, tween, view } from 'cc';
import UIMgrToastCell from './UIMgrToastCell';
const { property, ccclass, requireComponent } = _decorator;
@ccclass('UIMgrToast')
@requireComponent(UITransform)
export default class UIMgrToast extends Component {
@property(Prefab)
private cell: Prefab = null;
/**每条信息显示几秒 */
private lifeTime = 2;
/**消失时花费几秒渐隐 */
private outTime = 0.2;
/**挤压基础速度 */
private squeezeSpeed = 200;
/**节点缓存池子 */
private pool = new NodePool();
add(data: {
message: string,
timeout?: number
}) {
const cell = this.pool.get() || instantiate(this.cell);
cell.setPosition(0, 0, 0);
cell.parent = this.node;
cell.active = true;
cell.getComponent(UIMgrToastCell).init(data.message);
cell.getComponent(UIOpacity).opacity = 255;
tween(cell.getComponent(UIOpacity))
.delay(data.timeout || this.lifeTime)
.to(this.outTime, { opacity: 0 })
.call(() => {
this.pool.put(cell);
})
.start();
}
clear() {
const children = this.node.children;
for (let index = children.length - 1; index >= 0; index--) {
Tween.stopAllByTarget(children[index].getComponent(UIOpacity));
children[index].destroy();
}
}
get size() {
return this.node.children.length;
}
protected onDestroy() {
this.pool.clear();
}
protected update(dt: number) {
const children = this.node.children;
for (let index = children.length - 1, recovery = false; index >= 0; index--) {
const zero = index === children.length - 1;
const curr = children[index];
// 直接触发回收逻辑
if (recovery) {
Tween.stopAllByTarget(curr.getComponent(UIOpacity));
this.pool.put(curr);
continue;
}
if (zero) {
const currUT = curr.getComponent(UITransform);
const lastMaxY = 0 - currUT.height / 2;
const currMinY = curr.position.y + lastMaxY;
if (currMinY > lastMaxY) {
// 存在空隙
const addLen = Math.max(-this.squeezeSpeed * dt * (children.length - index), lastMaxY - currMinY);
curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z);
}
} else {
const last = children[index + 1];
const currUT = curr.getComponent(UITransform);
const lastUT = last.getComponent(UITransform);
const currMinY = curr.position.y - currUT.height / 2 - 6;//6像素的间隔
const lastMaxY = last.position.y + lastUT.height / 2;
if (currMinY < lastMaxY) {
// 存在重叠
const addLen = Math.min(this.squeezeSpeed * dt * (children.length - index - 1), lastMaxY - currMinY);
curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z);
const winSize = view.getVisibleSize();
if (currMinY > winSize.height / 2) {
// 触发回收逻辑
recovery = true;
Tween.stopAllByTarget(curr.getComponent(UIOpacity));
this.pool.put(curr);
}
} else if (currMinY > lastMaxY) {
// 存在空隙
const addLen = Math.max(-this.squeezeSpeed * dt * (children.length - index), lastMaxY - currMinY);
curr.setPosition(curr.position.x, curr.position.y + addLen, curr.position.z);
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "cde1528c-f66c-40f4-bdd2-27bf138ce1df",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,26 @@
import { Component, Label, UIOpacity, UITransform, _decorator } from 'cc';
const { ccclass, property, requireComponent } = _decorator;
@ccclass('UIMgrToastCell')
@requireComponent(UIOpacity)
@requireComponent(UITransform)
export default class UIMgrToastCell extends Component {
@property(Label)
private title: Label = null;
init(title: string) {
if (title.split('\n').find((v) => v.length > 30)) {
this.title.overflow = Label.Overflow.RESIZE_HEIGHT;
this.title.getComponent(UITransform).width = 600;
} else {
this.title.overflow = Label.Overflow.NONE;
}
this.title.string = title;
this.title.updateRenderData(true);
}
unuse() {
this.title.string = '';
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "6cc631d6-b08e-4ee3-8bde-e307c4288734",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,68 @@
import { _decorator, Component, Director, director, Node } from 'cc';
const { ccclass } = _decorator;
@ccclass('UIMgrZOrder')
export default class UIMgrZOrder extends Component {
private zOrder = false;
private tempArr: Node[] = [];
protected onLoad() {
this.checkUpdateZOrder();
this.node.on(Node.EventType.CHILD_ADDED, this.onChildAdded, this);
this.node.on(Node.EventType.CHILD_REMOVED, this.onChildRemoveed, this);
if (Node.EventType.CHILDREN_ORDER_CHANGED) {
this.node.on(Node.EventType.CHILDREN_ORDER_CHANGED, this.checkUpdateZOrder, this);
} else {
this.node.on(Node.EventType.SIBLING_ORDER_CHANGED, this.checkUpdateZOrder, this);
}
}
protected onDestroy() {
director.off(Director.EVENT_AFTER_UPDATE, this.updateZOrder, this);
this.node.off(Node.EventType.CHILD_ADDED, this.onChildAdded, this);
this.node.off(Node.EventType.CHILD_REMOVED, this.onChildRemoveed, this);
if (Node.EventType.CHILDREN_ORDER_CHANGED) {
this.node.off(Node.EventType.CHILDREN_ORDER_CHANGED, this.checkUpdateZOrder, this);
} else {
this.node.off(Node.EventType.SIBLING_ORDER_CHANGED, this.checkUpdateZOrder, this);
}
}
private onChildAdded(child: Node) {
this.checkUpdateZOrder();
child.on(Node.EventType.TRANSFORM_CHANGED, this.checkUpdateZOrder, this);
}
private onChildRemoveed(child: Node) {
child.off(Node.EventType.TRANSFORM_CHANGED, this.checkUpdateZOrder, this);
}
private checkUpdateZOrder() {
if (this.zOrder) return;
this.zOrder = true;
director.once(Director.EVENT_AFTER_UPDATE, this.updateZOrder, this);
}
/**
* 更新节点树排序
*/
public updateZOrder() {
if (!this.zOrder) return;
Array.prototype.push.apply(this.tempArr, this.node.children);
this.tempArr
.sort((a, b) => {
return (a.position.z - b.position.z)
|| (a.getSiblingIndex() - b.getSiblingIndex());
})
.forEach((child, index) => {
child.setSiblingIndex(index);
});
// 一定要放到最后再设置false
// 避免更新过程中设置siblingIndex
// 导致无限重复调用
this.zOrder = false;
this.tempArr.length = 0;
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "ad5cb510-639e-40c2-acdd-399ad00629b9",
"files": [],
"subMetas": {},
"userData": {}
}