import { _decorator, Component, Node, Label, Sprite, Color, UITransform, Size, Layout } from 'cc'; import { UITheme } from '../common/UITheme'; import { UIBase } from '../common/UIBase'; const { ccclass, property } = _decorator; /** * 角色面板 - 属性/装备/包裹 * 基于江湖截图:角色属性 + 六边形装备槽 + 物品栏 */ @ccclass('CharacterPanel') export class CharacterPanel extends UIBase { @property(Node) characterInfo: Node = null!; @property(Node) statsArea: Node = null!; @property(Node) equipmentArea: Node = null!; @property(Node) inventoryArea: Node = null!; start() { this.initCharacterInfo(); this.initStatsArea(); this.initEquipmentArea(); this.initInventoryArea(); } /** * 角色基本信息区 * 头像 + 角色名 + 称号 + 气血 */ private initCharacterInfo() { if (!this.characterInfo) return; const layout = this.characterInfo.addComponent(Layout); layout.type = Layout.Type.VERTICAL; // 角色头像区域(圆形) const avatarNode = new Node('Avatar'); const avatarTransform = avatarNode.addComponent(UITransform); avatarTransform.setContentSize(new Size(160, 160)); avatarNode.setParent(this.characterInfo); // 角色名 const nameNode = new Node('Name'); const nameLabel = nameNode.addComponent(Label); nameLabel.string = '角色名'; nameLabel.fontSize = UITheme.FONT_SIZE.LG; nameLabel.color = this.hexToColor(UITheme.COLORS.TEXT_GOLD); nameNode.setParent(this.characterInfo); // 称号 const titleNode = new Node('Title'); const titleLabel = titleNode.addComponent(Label); titleLabel.string = '锐不可挡'; titleLabel.fontSize = UITheme.FONT_SIZE.SM; titleLabel.color = this.hexToColor(UITheme.COLORS.TEXT_ORANGE); titleNode.setParent(this.characterInfo); // 气血 const hpNode = new Node('HP'); const hpLabel = hpNode.addComponent(Label); hpLabel.string = '气血 283098'; hpLabel.fontSize = UITheme.FONT_SIZE.MD; hpLabel.color = this.hexToColor(UITheme.COLORS.HP_BAR); hpNode.setParent(this.characterInfo); } /** * 属性面板 * 攻击/筋骨/力道/身法/眼识 */ private initStatsArea() { if (!this.statsArea) return; const transform = this.statsArea.getComponent(UITransform) || this.statsArea.addComponent(UITransform); transform.setContentSize(new Size(400, 300)); const stats = [ { name: '攻击', value: '92442', color: UITheme.COLORS.TEXT_WHITE }, { name: '筋骨', value: '6031', color: UITheme.COLORS.TEXT_WHITE }, { name: '力道', value: '8963', color: UITheme.COLORS.TEXT_WHITE }, { name: '身法', value: '13249', color: UITheme.COLORS.TEXT_WHITE }, { name: '眼识', value: '3293', color: UITheme.COLORS.TEXT_WHITE }, ]; stats.forEach(stat => { const row = new Node(`Stat_${stat.name}`); const rowTransform = row.addComponent(UITransform); rowTransform.setContentSize(new Size(380, 40)); row.setParent(this.statsArea); const nameNode = new Node('Name'); const nameLabel = nameNode.addComponent(Label); nameLabel.string = stat.name; nameLabel.fontSize = UITheme.FONT_SIZE.MD; nameLabel.color = this.hexToColor(UITheme.COLORS.TEXT_GOLD); nameNode.setParent(row); const valueNode = new Node('Value'); const valueLabel = valueNode.addComponent(Label); valueLabel.string = stat.value; valueLabel.fontSize = UITheme.FONT_SIZE.MD; valueLabel.color = this.hexToColor(stat.color); valueNode.setParent(row); }); } /** * 装备区域 * 六边形装备槽(武器/头盔/衣服/腰带/鞋子/坐骑) */ private initEquipmentArea() { if (!this.equipmentArea) return; const transform = this.equipmentArea.getComponent(UITransform) || this.equipmentArea.addComponent(UITransform); transform.setContentSize(new Size(720, 180)); const slots = ['武器', '头盔', '衣服', '腰带', '鞋子', '坐骑']; slots.forEach((slotName, index) => { const slotNode = new Node(`Slot_${slotName}`); const slotTransform = slotNode.addComponent(UITransform); slotTransform.setContentSize(new Size(100, 100)); slotNode.setParent(this.equipmentArea); // 六边形边框 const borderNode = new Node('Border'); const borderSprite = borderNode.addComponent(Sprite); borderNode.getComponent(UITransform)?.setContentSize(new Size(100, 100)); borderNode.setParent(slotNode); // 装备图标 const iconNode = new Node('Icon'); const iconLabel = iconNode.addComponent(Label); iconLabel.string = '⚔️'; iconLabel.fontSize = UITheme.FONT_SIZE.XL; iconNode.setParent(slotNode); // 槽位名称 const labelNode = new Node('Label'); const label = labelNode.addComponent(Label); label.string = slotName; label.fontSize = UITheme.FONT_SIZE.XS; label.color = this.hexToColor(UITheme.COLORS.TEXT_DIM); labelNode.setParent(slotNode); }); } /** * 物品栏区域 * 分类标签 + 物品格子 */ private initInventoryArea() { if (!this.inventoryArea) return; const transform = this.inventoryArea.getComponent(UITransform) || this.inventoryArea.addComponent(UITransform); transform.setContentSize(new Size(720, 400)); // 分类标签栏 const tabBar = new Node('TabBar'); const tabLayout = tabBar.addComponent(Layout); tabLayout.type = Layout.Type.HORIZONTAL; tabBar.setParent(this.inventoryArea); const tabs = ['全部', '装备', '材料', '药材', '杂物']; tabs.forEach(tabName => { const tabNode = new Node(`Tab_${tabName}`); const tabTransform = tabNode.addComponent(UITransform); tabTransform.setContentSize(new Size(120, 40)); tabNode.setParent(tabBar); const label = tabNode.addComponent(Label); label.string = tabName; label.fontSize = UITheme.FONT_SIZE.SM; label.color = this.hexToColor(UITheme.COLORS.TEXT_NORMAL); }); // 物品格子网格(6列 x 5行) const gridNode = new Node('Grid'); const gridLayout = gridNode.addComponent(Layout); gridLayout.type = Layout.Type.GRID; gridLayout.startAxis = Layout.AxisDirection.HORIZONTAL; gridLayout.cellSize = new Size(100, 100); gridLayout.spacingX = 8; gridLayout.spacingY = 8; gridNode.setParent(this.inventoryArea); for (let i = 0; i < 30; i++) { const itemNode = new Node(`Item_${i}`); const itemTransform = itemNode.addComponent(UITransform); itemTransform.setContentSize(new Size(100, 100)); itemNode.setParent(gridNode); // 物品背景 const bgNode = new Node('Bg'); bgNode.addComponent(Sprite); bgNode.getComponent(UITransform)?.setContentSize(new Size(100, 100)); bgNode.setParent(itemNode); // 物品图标 const iconNode = new Node('Icon'); const iconLabel = iconNode.addComponent(Label); iconLabel.string = '📦'; iconLabel.fontSize = UITheme.FONT_SIZE.XL; iconNode.setParent(itemNode); } } }