Files
MatchMaster/assets/Script/NumberToImage.ts
T
2026-11-04 13:43:15 +08:00

751 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Learn TypeScript:
// - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
// - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
// - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
import BattlePassArt from './BattlePassArt';
const { ccclass, property } = cc._decorator;
@ccclass
export default class NumberToImage extends cc.Component {
@property(cc.SpriteAtlas)
fontUI: cc.SpriteAtlas = null;
@property(cc.SpriteAtlas)
fontUI2: cc.SpriteAtlas = null;
@property(cc.SpriteAtlas)
fontUI3: cc.SpriteAtlas = null;
@property(cc.SpriteAtlas)
fontUI4: cc.SpriteAtlas = null;
@property(cc.SpriteAtlas)
fontPassCheck: cc.SpriteAtlas = null;
@property(cc.SpriteAtlas)
publicFont: cc.SpriteAtlas = null;
static font: any = null;
static font2: any = null;
static font3: any = null;
static font4: any = null;
static fontPassCheck: any = null;
static publicFont: any = null;
// LIFE-CYCLE CALLBACKS:
onLoad() {
if (this.fontUI != null) {
NumberToImage.font = this.fontUI;
NumberToImage.font2 = this.fontUI2;
NumberToImage.font3 = this.fontUI3;
NumberToImage.font4 = this.fontUI4;
NumberToImage.publicFont = this.publicFont;
NumberToImage.fontPassCheck = this.fontPassCheck;
}
}
//第一个参数 数字, 第二个参数 数字间距 第三个参数 占位宽度 第四个参数 目标节点
static numberToImageNodes(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.font._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
static numberToImageNodes2(number, width, posX, name, targetNode: cc.Node, right: boolean = false) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
let digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
if (numStr[i] == ":") digit = 10;
sprite.spriteFrame = this.font._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
// const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
// 计算总宽度,累加每个节点的宽度和间距
let totalWidth = 0;
for (let i = 0; i < digitNodes.length; i++) {
totalWidth += digitNodes[i].width;
if (i < digitNodes.length - 1) {
totalWidth += width;
}
}
if (right) {
// 新右对齐逻辑:从右向左排列
let currentX = 0; // 最右侧起点
for (let i = digitNodes.length - 1; i >= 0; i--) {
const node = digitNodes[i];
node.x = currentX - node.width;
currentX -= (node.width + width); // 向左累加宽度和间距
if (targetNode) node.parent = targetNode;
}
} else {
let currentX = cha;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = currentX;
currentX += node.width + width;
if (targetNode) node.parent = targetNode;
}
}
}
static numberToImageNodes3(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.font2._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
static numberToImageNodes4(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.font3._spriteFrames[name + digit + ""];
digitNodes.push(node);
node.color = cc.color(17, 154, 25, 255);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
static numberToImageNodes5(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
if (targetNode) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children) {
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
}
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.font3._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
}
static numberToImageNodes6(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.font3._spriteFrames[name + digit + ""];
digitNodes.push(node);
node.color = cc.color(255, 163, 0, 255);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
static numberToImageNodesCoin(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
if (targetNode) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children) {
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
}
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.font4._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
}
static numberToImageNodesNumber(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode) {
if (targetNode.children) {
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
}
}
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.publicFont._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
static numberToImageNodesShop(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
if (!targetNode || !cc.isValid(targetNode, true)) return;
if (targetNode.name === 'progress_1' || targetNode.name === 'progress_2') BattlePassArt.digits(targetNode, number);
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode) {
if (targetNode.children) {
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
}
}
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.font3._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
static numberToImageNodesPassCheck(number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
BattlePassArt.digits(targetNode, number, name === 'all_black_');
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = this.fontPassCheck._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
static getTimeMargin(number, width, name, targetNode: cc.Node) {
let timeArr = [];
let total = 0;
total = number;
let hour = 0;
hour = parseInt((total / 3600) + "");//计算整数小时数
let afterHour = total - hour * 60 * 60;//取得算出小时数后剩余的秒数
let min = parseInt((afterHour / 60) + "");//计算整数分
let m = "" + min;
if (min < 10) m = "0" + min;
let afterMin = total - hour * 60 * 60 - min * 60;//取得算出分后剩余的秒数
let miao = afterMin + "";
if (afterMin < 10) miao = "0" + afterMin;
let result = m + miao;
for (let i = 0; i < result.length; i++) {
const digit = parseInt(result[i], 10);
timeArr.push(digit);
}
if (targetNode.children.length > 0) {
for (let i = 0; i < targetNode.children.length; i++) {
targetNode.children[i].getComponent(cc.Sprite).spriteFrame = this.font._spriteFrames[name + timeArr[i] + ""];
}
}
else {
for (let i = 0; i < 4; i++) {
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
const digit = timeArr[i];
// debugger;
sprite.spriteFrame = this.font._spriteFrames[name + digit + ""];
// 将节点添加到目标节点下
node.x = i * width;
if (i > 1) node.x += 35;
if (targetNode) node.parent = targetNode;
}
}
}
static getTimeMargi3(number, width, name, targetNode: cc.Node) {
let timeArr = [];
let total = 0;
total = number;
let hour = 0;
hour = parseInt((total / 3600) + "");//计算整数小时数
let afterHour = total - hour * 60 * 60;//取得算出小时数后剩余的秒数
let min = parseInt((afterHour / 60) + "");//计算整数分
let m = "" + min;
if (min < 10) m = "0" + min;
let afterMin = total - hour * 60 * 60 - min * 60;//取得算出分后剩余的秒数
let miao = afterMin + "";
if (afterMin < 10) miao = "0" + afterMin;
let result = m + miao;
for (let i = 0; i < result.length; i++) {
const digit = parseInt(result[i], 10);
timeArr.push(digit);
}
if (targetNode.children.length > 0) {
for (let i = 0; i < targetNode.children.length; i++) {
targetNode.children[i].getComponent(cc.Sprite).spriteFrame = this.font3._spriteFrames[name + timeArr[i] + ""];
}
}
else {
for (let i = 0; i < 4; i++) {
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
const digit = timeArr[i];
// debugger;
sprite.spriteFrame = this.font3._spriteFrames[name + digit + ""];
// 将节点添加到目标节点下
node.x = i * width;
if (i > 1) node.x += 35;
if (targetNode) node.parent = targetNode;
}
}
}
static getTimeMargin2(number, width, name, targetNode: cc.Node, middle: boolean = false) {
let timeArr = [];
let total = 0;
total = number;
let hour = 0;
hour = parseInt((total / 3600) + "");//计算整数小时数
let afterHour = total - hour * 60 * 60;//取得算出小时数后剩余的秒数
let min = parseInt((afterHour / 60) + "");//计算整数分
let m = "" + min;
if (min < 10) m = "0" + min;
let afterMin = total - hour * 60 * 60 - min * 60;//取得算出分后剩余的秒数
let miao = afterMin + "";
if (afterMin < 10) miao = "0" + afterMin;
// 将小时部分格式化为两位数
let h = "" + hour;
if (hour < 10) h = "0" + hour;
let result = m + miao;
// 拼接小时、分、秒
if (hour > 0)
result = h + m + miao;
for (let i = 0; i < result.length; i++) {
const digit = parseInt(result[i], 10);
timeArr.push(digit);
}
const digitNodes: cc.Node[] = [];
if (targetNode.children.length > 0) {
for (let i = 0; i < targetNode.children.length; i++) {
const node = targetNode.children[i];
const sprite = node.getComponent(cc.Sprite);
sprite.spriteFrame = this.font._spriteFrames[name + timeArr[i] + ""];
digitNodes.push(node);
}
}
else {
for (let i = 0; i < timeArr.length; i++) {
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
const digit = timeArr[i];
sprite.spriteFrame = this.font._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
}
// 计算总宽度
const totalWidth = (timeArr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (i > 1) node.x += 20;
if (i > 3) node.x += 20;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width;
if (i > 1) node.x += 20;
if (i > 3) node.x += 20;
if (targetNode) node.parent = targetNode;
}
}
}
/** Render reward amounts with the shared big_ digits, multiplier and time units. */
static rewardTextToImages(text: string, target: cc.Node, height: number, maxWidth = 0): void {
const label = target.getComponent(cc.Label);
if (label) label.enabled = false;
target.removeAllChildren();
const tokens: string[] = text.match(/小时|分钟|[0-9x×]/g) || [];
const names = { x: 'cheng', '×': 'cheng', '小时': 'xiaoshi', '分钟': 'fenzhong' };
const digitHeight = this.publicFont.getSpriteFrame('big_0').getRect().height;
const glyphs = tokens.map(token => {
const frame = this.publicFont.getSpriteFrame('big_' + (names[token] || token));
const rect = frame.getRect();
// Keep the multiplier's authored size relative to digits, rather than enlarging it to digit height.
const glyphHeight = token === 'x' || token === '×' ? height * rect.height / digitHeight : height;
return { frame, width: glyphHeight * rect.width / rect.height, height: glyphHeight };
});
const width = glyphs.reduce((sum, glyph) => sum + glyph.width, 0) + Math.max(0, glyphs.length - 1) * 2;
const scale = maxWidth > 0 ? Math.min(1, maxWidth / width) : 1;
let x = -width * scale / 2;
glyphs.forEach(glyph => {
const node = new cc.Node('glyph'); target.addChild(node);
const sprite = node.addComponent(cc.Sprite);
sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
sprite.spriteFrame = glyph.frame;
node.setContentSize(glyph.width * scale, glyph.height * scale);
node.x = x + node.width / 2;
x += node.width + 2 * scale;
});
target.setContentSize(width * scale, height * scale);
}
static durationToImageNodes(seconds: number, targetNode: cc.Node) {
const totalMinutes = Math.max(0, Math.floor(seconds / 60));
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
const frameNames: string[] = [];
const append = (value: number, unit: string) => {
for (const digit of String(value)) frameNames.push("big_" + digit);
frameNames.push(unit);
};
if (hours > 0) append(hours, "big_xiaoshi");
if (minutes > 0 || hours === 0) append(minutes, "big_fenzhong");
targetNode.removeAllChildren();
const glyphs: cc.Node[] = [];
const spacing = 2;
let totalWidth = 0;
for (const frameName of frameNames) {
const glyph = new cc.Node(frameName);
const sprite = glyph.addComponent(cc.Sprite);
sprite.sizeMode = cc.Sprite.SizeMode.TRIMMED;
sprite.spriteFrame = this.publicFont._spriteFrames[frameName];
targetNode.addChild(glyph);
glyphs.push(glyph);
totalWidth += glyph.width;
}
totalWidth += spacing * (glyphs.length - 1);
let x = -totalWidth / 2;
for (const glyph of glyphs) {
glyph.x = x + glyph.width / 2;
x += glyph.width + spacing;
}
}
static numberToImageNodesPublic(UI, number, width, posX, name, targetNode: cc.Node, middle: boolean = false) {
const numStr = number.toString();
let cha = 0;
if (number > 99) cha = -posX
else if (number < 10) cha = posX
if (targetNode.children.length > 0)
targetNode.removeAllChildren();
const digitNodes: cc.Node[] = [];
for (let i = 0; i < numStr.length; i++) {
const digit = parseInt(numStr[i], 10);
const node = new cc.Node();
const sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = UI._spriteFrames[name + digit + ""];
digitNodes.push(node);
}
// 计算总宽度
const totalWidth = (numStr.length - 1) * width + (digitNodes[0]?.width || 0);
if (middle) {
// 计算居中的起始位置
const startX = -totalWidth / 2;
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = startX + i * width;
if (targetNode) node.parent = targetNode;
}
} else {
for (let i = 0; i < digitNodes.length; i++) {
const node = digitNodes[i];
node.x = i * width + cha;
if (targetNode) node.parent = targetNode;
}
}
}
// static calculateAndConvert(num1: number, num2: number, operator: '+' | '-' | '*' | '/', spriteFrames: SpriteFrame[]): Node[] {
// let result: number;
// switch (operator) {
// case '+':
// result = num1 + num2;
// break;
// case '-':
// result = num1 - num2;
// break;
// case '*':
// result = num1 * num2;
// break;
// case '/':
// result = num1 / num2;
// break;
// default:
// throw new Error('不支持的运算符');
// }
// // 处理结果为小数的情况,这里简单取整
// result = Math.floor(result);
// return this.numberToImageNodes(result, spriteFrames);
// }
// update (dt) {}
}