MatchMaster/assets/shop/script/passCheckItem.ts
2026-09-22 13:41:47 +08:00

404 lines
14 KiB
TypeScript

import NumberToImage from "../../Script/NumberToImage";
const { ccclass, property } = cc._decorator;
@ccclass
export default class PassCheckItem extends cc.Component {
@property(cc.Prefab)
passCheckItemLvPrefab: cc.Prefab = null;
@property(cc.Sprite)
leftReward: cc.Sprite = null;
@property(cc.Sprite)
rightReward: cc.Sprite = null;
@property(cc.Node)
leftNum: cc.Node = null;
@property(cc.Node)
rightNum: cc.Node = null;
@property(cc.SpriteAtlas)
texture_atlas: cc.SpriteAtlas = null;
@property(cc.SpriteAtlas)
passCheckFont: cc.SpriteAtlas = null;
// 添加更多图集属性
@property(cc.SpriteAtlas)
newUserAtlas: cc.SpriteAtlas = null;
// @property(cc.SpriteAtlas)
// textureAtlas1: cc.SpriteAtlas = null;
@property(cc.SpriteAtlas)
uiAtlas: cc.SpriteAtlas = null;
@property(cc.SpriteFrame)
skylineHealth: cc.SpriteFrame = null;
@property(cc.SpriteFrame)
iceb: cc.SpriteFrame = null;
@property(cc.SpriteFrame)
chuizi: cc.SpriteFrame = null;
@property(cc.SpriteFrame)
starb: cc.SpriteFrame = null;
// 数据
private data: any = null;
private itemIndex: number = 0;
private isUIInitialized: boolean = false;
private levelNode: cc.Node = null;
// 1001 金币 2001 锤子 2003 魔棒 3001 15分钟无限体力 3002 30分钟 3003 1小时 3004 2小时 3005 3小时
// 添加物品ID到图片名称的映射
private itemImageMap: { [key: number]: { imageName: string, atlas?: string } } = {
1001: { imageName: "coins4", atlas: "texture_atlas" }, // shop/img/texture_atlas-1
2001: { imageName: "iceb" },
2002: { imageName: "chuizi" },
2003: { imageName: "starb" },
3001: { imageName: "skylineHealth" },
3002: { imageName: "skylineHealth" },
3003: { imageName: "skylineHealth" },
// 可以继续添加更多物品ID和对应图片的映射
};
init(data: any, index: number) {
this.data = data;
this.itemIndex = index;
this.updateUI();
}
initUI() {
if (!this.data) {
return;
}
// 处理passCheckItemLv prefab的实例化
if (this.passCheckItemLvPrefab) {
if (this.levelNode) this.levelNode.destroy();
// 实例化并添加新的prefab
const itemLvNode = cc.instantiate(this.passCheckItemLvPrefab);
this.levelNode = itemLvNode;
itemLvNode.parent = this.node.parent;
itemLvNode.setPosition(this.node.x, this.node.y);
itemLvNode.zIndex = 2;
let bright_bg = itemLvNode.getChildByName("bright_bg").getComponent(cc.Sprite);
let levelNum = itemLvNode.getChildByName("levelNum");
let lvNum = this.itemIndex + 1
// NumberToImage.numberToImageNodes(lvNum, 43, 15, "tili_", levelNum, true);
NumberToImage.numberToImageNodesPassCheck(lvNum, 45, 48, "half_black_", levelNum, true);
if (lvNum >= 10 && lvNum <= 19) {
levelNum.x -= 3;
}
if (lvNum >= 20 && lvNum <= 29) {
levelNum.x += 3;
}
if (this.data.free === -1) {
// 未激活状态
if (this.uiAtlas) {
const spriteFrame = this.uiAtlas.getSpriteFrame("no_bright_bg");
if (spriteFrame) {
bright_bg.spriteFrame = spriteFrame;
}
// cc.fx.GameTool.setGray(levelNum, true)
NumberToImage.numberToImageNodesPassCheck(lvNum, 45, 48, "all_black_", levelNum, true);
}
} else {
// 已激活状态
if (this.uiAtlas) {
const spriteFrame = this.uiAtlas.getSpriteFrame("bright_bg");
if (spriteFrame) {
bright_bg.spriteFrame = spriteFrame;
}
}
}
}
// 初始化按钮点击事件(只执行一次)
if (!this.isUIInitialized) this.setupButtonEvents();
// 标记UI已初始化
this.isUIInitialized = true;
// 首次更新UI
this.updateUI();
}
// 专门用于设置按钮事件的方法
private setupButtonEvents() {
let node1 = this.node.getChildByName("leftNode");
let node2 = this.node.getChildByName("rightNode");
const mask = this.node.getChildByName('mask');
if (mask) mask.on('click', () => {
if (!mask.active) return;
for (let node = this.node.parent; node; node = node.parent) {
const pass = node.getComponent('passCheck');
if (pass) { pass.onActivateBtnClick(); return; }
}
}, this);
if (node1) {
let getBtn = node1.getChildByName("getBtn");
if (getBtn) {
getBtn.on('click', () => {
this.onGetRewardClicked(node1);
}, this);
}
}
if (node2) {
let getBtn = node2.getChildByName("getBtn");
if (getBtn) {
getBtn.on('click', () => {
this.onGetRewardClicked(node2);
}, this);
}
}
}
updateUI() {
if (!this.data) {
return;
}
const mask = this.node.getChildByName('mask');
if (mask) mask.active = this.itemIndex >= 35 && this.data.leftAllowed === false;
// 根据数据更新界面元素
let node1 = this.node.getChildByName("leftNode");
let node2 = this.node.getChildByName("rightNode");
if (this.data.ItemID1 !== undefined && this.data.ItemNum1 !== undefined) {
this.setNodeGray(node1, cc.Color.WHITE);
this.setNodeGray(node2, cc.Color.WHITE);
this.setNodeGray(node1.getChildByName('num_1'), cc.Color.WHITE);
this.setNodeGray(node2.getChildByName('num_1'), cc.Color.WHITE);
this.updateItemInfo(this.data.ItemID1, this.data.ItemNum1, node1, this.data.free);
}
if (this.data.ItemID2 !== undefined && this.data.ItemNum2 !== undefined) {
this.updateItemInfo(this.data.ItemID2, this.data.ItemNum2, node2, this.data.passCheck);
}
if (this.data.free !== undefined) {
this.updateRewardState(this.data.free, node1);
}
if (this.data.passCheck !== undefined) {
this.updateRewardState(this.data.passCheck, node2);
}
}
updateRewardState(itemData: any, targetNode: cc.Node) {
// 更新免费状态的UI 0已领 1 未领
let getSpr = targetNode.getChildByName("get")
let getBtn = targetNode.getChildByName("getBtn")
let lock = targetNode.getChildByName("lock")
if (!lock && targetNode.name === 'leftNode' && this.data.leftAllowed === false) {
const source = this.node.getChildByName('rightNode').getChildByName('lock');
if (source) { lock = cc.instantiate(source); targetNode.addChild(lock); }
}
let activate = targetNode.name === 'leftNode' ? this.data.leftAllowed !== false : this.data.rightAllowed !== false;
if (lock) {
lock.active = false;
}
if (itemData === 1) {
getSpr.active = false;
getBtn.active = true;
if (lock && activate == false) {
lock.active = true;
getBtn.active = false;
}
} else if (itemData === 0) {
getSpr.active = true;
getBtn.active = false;
this.setNodeGray(targetNode)
} else {
if (lock && activate == false) {
lock.active = true;
}
getSpr.active = false;
getBtn.active = false;
}
}
updateItemInfo(itemID: number, itemNum: number, node: cc.Node, itemData: any) {
// 更新物品信息的UI
const imageInfo = this.itemImageMap[itemID];
let freeRewardNode = node.getChildByName("freeReward");
let freeReward: cc.Sprite = null;
if (freeRewardNode) {
freeReward = freeRewardNode.getComponent(cc.Sprite);
}
if (imageInfo) {
// 道具使用预制体绑定的图片,金币仍从图集取图。
const targetAtlas: cc.SpriteAtlas = imageInfo.atlas ? this[imageInfo.atlas] : null;
if (freeReward) {
const spriteFrame: cc.SpriteFrame = imageInfo.atlas
? targetAtlas && targetAtlas.getSpriteFrame(imageInfo.imageName)
: this[imageInfo.imageName];
if (spriteFrame) {
freeReward.spriteFrame = spriteFrame;
let imgScale = 1;
switch (itemID) {
case 1001:
imgScale = 1;
break;
case 2001:
imgScale = 0.7;
break;
case 2002:
imgScale = 0.6;
break;
case 2003:
case 3001:
case 3002:
case 3003:
imgScale = 0.6;
break;
default:
imgScale = 1.1;
break;
}
freeRewardNode.scale = imgScale;
} else {
console.warn(`Reward sprite frame ${imageInfo.imageName} not found`);
}
} else {
}
} else {
console.warn(`No image found for item ID: ${itemID}`);
// 使用默认图片
}
const addTime = node.getChildByName("addTiem");
const numberNode = node.getChildByName("num_1");
addTime.active = false;
node.getChildByName("num_x").active = false;
numberNode.active = true;
numberNode.setPosition(addTime.x, addTime.y);
this.updateRewardText(itemID, itemNum, numberNode);
this.setNodeGray(numberNode, itemData === 0 ? cc.color(190, 190, 190, 255) : cc.Color.WHITE);
}
private updateRewardText(itemID: number, itemNum: number, target: cc.Node) {
// 时长由物品 ID 决定,与实际发奖规则保持一致。
const minutes = { 3001: 15, 3002: 30, 3003: 60 }[itemID];
const value = minutes ? (minutes >= 60 ? minutes / 60 : minutes) : itemNum;
const frameNames: string[] = itemID === 1001 ? [] : [minutes ? "jia" : "cheng"];
for (const digit of String(value)) frameNames.push("half_black_" + digit);
if (minutes) frameNames.push(minutes >= 60 ? "xiaoshi" : "fenzhong");
target.destroyAllChildren();
const glyphs: cc.Node[] = [];
const spacing = 2;
let width = 0;
let height = 0;
for (const name of frameNames) {
const glyph = new cc.Node(name);
const sprite = glyph.addComponent(cc.Sprite);
sprite.sizeMode = cc.Sprite.SizeMode.TRIMMED;
sprite.spriteFrame = this.passCheckFont.getSpriteFrame(name);
target.addChild(glyph);
glyphs.push(glyph);
width += glyph.width;
height = Math.max(height, glyph.height);
}
width += spacing * (glyphs.length - 1);
let x = -width / 2;
for (const glyph of glyphs) {
glyph.x = x + glyph.width / 2;
x += glyph.width + spacing;
}
target.setContentSize(width, height);
// 保持原奖励文字约 50 高,长数量或时长限制在卡片内。
target.scale = Math.min(50 / height, 218 / width, 1);
}
updateItem(data: any, index: number) {
// 在这里处理数据更新
this.data = data;
this.itemIndex = index;
this.initUI();
}
// 数据改变时调用
public dataChanged() {
this.updateUI();
}
// 组件生命周期函数
protected onLoad() {
this.isUIInitialized = false;
}
protected start() {
// console.log("PassCheckItem component started");
}
private onGetRewardClicked(targetNode: cc.Node) {
// 确定是左侧还是右侧的奖励
let isLeftReward = targetNode.name === "leftNode";
// 获取对应的物品ID和数量
let itemId = isLeftReward ? this.data.ItemID1 : this.data.ItemID2;
let itemNum = isLeftReward ? this.data.ItemNum1 : this.data.ItemNum2;
console.log("领取物品:", itemId, "数量:", itemNum);
// 调用领取奖励方法
this.claimReward(itemId, itemNum, isLeftReward);
}
private claimReward(itemId: number, itemNum: number, isLeftReward: boolean) {
let passCheckMgr = this.node.parent.parent.parent.parent.getComponent('passCheckMgr');
if (passCheckMgr && typeof passCheckMgr.claimReward === 'function') {
console.log("更新奖励状态到服务器:", itemId, itemNum, isLeftReward);
passCheckMgr.claimReward(this.itemIndex, itemId, itemNum, isLeftReward);
}
}
private claimInfiniteHealth(amount: number, itemId: number) {
}
public updateRewardUIAfterClaim(isLeftReward: boolean) {
let targetNode = isLeftReward ?
this.node.getChildByName("leftNode") :
this.node.getChildByName("rightNode");
let num1 = targetNode.getChildByName("num_1");
let num_x = targetNode.getChildByName("num_x");
console.log("更新奖励UI:", isLeftReward);
if (targetNode) {
let getSpr = targetNode.getChildByName("get");
let getBtn = targetNode.getChildByName("getBtn");
if (getSpr && getBtn) {
getSpr.active = true;
getBtn.active = false;
this.setNodeGray(targetNode);
this.setNodeGray(num1);
}
}
}
private setNodeGray(node: cc.Node, color?: cc.Color) {
let setColor = color || cc.color(190, 190, 190, 255);
if (node) {
for (let i = 0; i < node.children.length; i++) {
// console.log("设置子节点颜色", node.children[i]);
node.children[i].color = setColor;
}
}
}
}