feat(scripts): PoC 阶段 2 - Layer10_Protocol + Widget 锚定
computeWidgetAlignment(spirit) 简化版 (水平+垂直居中): _alignFlags = 16 | 8 _horizontalCenter = x + w/2 - 640 _verticalCenter = 360 - (y + h/2) emitPrefabJson 仅在 Spirit 父节点是 group (非 Layer 根) 时调用; root / group-X envelope 沿用默认 _alignFlags=45 全屏铺满. PoC 验证: Layer00010.xml Protol_Layer (group 37, 4 spirits) 生成 Protol_Layer.prefab — 6 Widget 节点 (1 root + 1 group-37 + 4 spirit), 4 spirit widget 全部 _alignFlags=24.
This commit is contained in:
@@ -114,6 +114,39 @@ export function computeContentSize(spirit) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算 Spirit 在其所属 group 内的 cc.Widget 锚定参数 (PoC 阶段 2 简化版).
|
||||
*
|
||||
* 数据源权威: 公式仅处理 Spirit.Y < 360 (上) vs > 360 (下) 与水平偏移, 完全基于
|
||||
* 已知字段 (x/y/w/h). SizeCalcMode / CoordRelaX / CoordRelaY 等逆向未出的字段
|
||||
* 暂不支持 — 由 buildSpiritBlock 调用方保证父 group 已经处理 SizeCalcMode ≠ 0.
|
||||
*
|
||||
* 简化规则:
|
||||
* _alignFlags = 16 | 8 # 16=水平居中, 8=垂直居中
|
||||
* _horizontalCenter = x + w/2 - 640 # 像素偏移, 1280 坐标系水平中心
|
||||
* _verticalCenter = 360 - (y + h/2) # Y-up 翻转 + 720 坐标系垂直中心
|
||||
*
|
||||
* @param {{ x?: string, y?: string, w?: string, h?: string }} spirit
|
||||
* @returns {object} cc.Widget 字段 (除 __type__/node/__prefab/_id 外)
|
||||
*/
|
||||
export function computeWidgetAlignment(spirit) {
|
||||
const x = parseFloat(spirit.x || '0');
|
||||
const y = parseFloat(spirit.y || '0');
|
||||
const w = parseFloat(spirit.w || '0');
|
||||
const h = parseFloat(spirit.h || '0');
|
||||
return {
|
||||
_alignFlags: 16 | 8, // 水平居中 + 垂直居中
|
||||
_target: null,
|
||||
_left: 0, _right: 0, _top: 0, _bottom: 0,
|
||||
_horizontalCenter: x + w / 2 - 640, // 1280 体系半宽
|
||||
_verticalCenter: 360 - (y + h / 2), // Y-up + 720 体系半高
|
||||
_isAbsLeft: true, _isAbsRight: true, _isAbsTop: true, _isAbsBottom: true,
|
||||
_isAbsHorizontalCenter: true, _isAbsVerticalCenter: true,
|
||||
_originalWidth: 0, _originalHeight: 0,
|
||||
_alignMode: 2, _lockFlags: 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Spirit 记录按 BelongGroupID 归类, 生成 group-X 父节点集合 + Layer 根直挂子节点.
|
||||
*
|
||||
@@ -365,6 +398,25 @@ function makeWidget(nodeId, compPrefabId) {
|
||||
};
|
||||
}
|
||||
|
||||
// Spirit 专用的 Widget 工厂: 调用 computeWidgetAlignment 计算锚定参数.
|
||||
// 用法: buildSpiritBlock 在父节点是 group 时调用此工厂, 替代默认 makeWidget.
|
||||
// 注意: 此工厂只应在 parent 确实是 group 容器 (而非 Layer 根) 时调用 — 见
|
||||
// buildSpiritBlock 的入参语义. Layer 根与 group-X 末尾 envelope 仍用 makeWidget.
|
||||
function makeSpiritWidget(nodeId, compPrefabId, spirit) {
|
||||
const align = computeWidgetAlignment(spirit);
|
||||
return {
|
||||
__type__: 'cc.Widget',
|
||||
_name: '',
|
||||
_objFlags: 0,
|
||||
__editorExtras__: {},
|
||||
node: { __id__: nodeId },
|
||||
_enabled: true,
|
||||
__prefab: { __id__: compPrefabId },
|
||||
...align, // _alignFlags, _horizontal/verticalCenter...
|
||||
_id: '',
|
||||
};
|
||||
}
|
||||
|
||||
function makeSprite(nodeId, compPrefabId, spriteFrameUuid, type = 0) {
|
||||
return {
|
||||
__type__: 'cc.Sprite',
|
||||
@@ -574,7 +626,7 @@ export function emitPrefabJson(layer) {
|
||||
if (!spirit) {
|
||||
throw new Error(`emitPrefabJson: spirit id ${spiritId} referenced by ${gi.group.name} but not found in layer.spirits`);
|
||||
}
|
||||
const info = buildSpiritBlock(spirit, { __id__: gi.nodeId }, out);
|
||||
const info = buildSpiritBlock(spirit, { __id__: gi.nodeId }, out, { parentIsGroup: true });
|
||||
spiritInfo.set(spiritId, info);
|
||||
gi.node._children.push({ __id__: info.nodeId });
|
||||
}
|
||||
@@ -585,7 +637,7 @@ export function emitPrefabJson(layer) {
|
||||
if (!spirit) {
|
||||
throw new Error(`emitPrefabJson: root child spirit id ${spiritId} not found in layer.spirits`);
|
||||
}
|
||||
const info = buildSpiritBlock(spirit, { __id__: rootId }, out);
|
||||
const info = buildSpiritBlock(spirit, { __id__: rootId }, out, { parentIsGroup: false });
|
||||
spiritInfo.set(spiritId, info);
|
||||
rootNode._children.push({ __id__: info.nodeId });
|
||||
}
|
||||
@@ -605,8 +657,15 @@ export function emitPrefabJson(layer) {
|
||||
* 构造单个 Spirit 的所有对象 (Node + UITransform + CompPrefabInfo + 主组件 +
|
||||
* CompPrefabInfo + Widget + CompPrefabInfo + PrefabInfo), 按 schema 顺序 push
|
||||
* 到 out 数组, 返回关键 id 供外层 wiring.
|
||||
*
|
||||
* @param {object} spirit - Spirit 字段
|
||||
* @param {{ __id__: number }} parentRef - 父节点引用
|
||||
* @param {Array<object>} out - 输出 JSON 数组
|
||||
* @param {{ parentIsGroup: boolean }} [opts] - parentIsGroup=true 时 Widget
|
||||
* 走 computeWidgetAlignment (锚定 = 水平/垂直居中); false (Layer 根直挂)
|
||||
* 走默认 makeWidget (_alignFlags=45 全屏铺满).
|
||||
*/
|
||||
function buildSpiritBlock(spirit, parentRef, out) {
|
||||
function buildSpiritBlock(spirit, parentRef, out, opts = { parentIsGroup: false }) {
|
||||
const lpos = computeLpos(spirit);
|
||||
const size = computeContentSize(spirit);
|
||||
const componentName = mapSpiritTypeToComponent(spirit.type);
|
||||
@@ -656,7 +715,11 @@ function buildSpiritBlock(spirit, parentRef, out) {
|
||||
const widgetCompInfo = makeCompPrefabInfo();
|
||||
out.push(widgetCompInfo);
|
||||
const widgetCompInfoId = out.length - 1;
|
||||
const widget = makeWidget(nodeId, widgetCompInfoId);
|
||||
// parentIsGroup 时走 computeWidgetAlignment (水平+垂直居中); Layer 根直挂时
|
||||
// 用默认 _alignFlags=45 (全屏铺满占位, 后续 PoC 阶段再细化).
|
||||
const widget = opts.parentIsGroup
|
||||
? makeSpiritWidget(nodeId, widgetCompInfoId, spirit)
|
||||
: makeWidget(nodeId, widgetCompInfoId);
|
||||
out.push(widget);
|
||||
const widgetId = out.length - 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user