删除hook,框架改动
This commit is contained in:
@@ -241,7 +241,7 @@ var BaseComponent = (function() {
|
||||
this.isDestroyed = false;
|
||||
this.isInitialized = true;
|
||||
|
||||
console.log('🎨 BaseComponent: 初始化组件 "' + this.name + '" (图层: ' + this.layer + ')');
|
||||
// // console.log('🎨 BaseComponent: 初始化组件 "' + this.name + '" (图层: ' + this.layer + ')');
|
||||
|
||||
// 调用子类的init方法
|
||||
try {
|
||||
@@ -274,7 +274,7 @@ var BaseComponent = (function() {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" 的所有精灵 (数量: ' + this.sprites.length + ')');
|
||||
// console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" 的所有精灵 (数量: ' + this.sprites.length + ')');
|
||||
|
||||
for (var i = 0; i < this.sprites.length; i++) {
|
||||
var spriteId = this.sprites[i];
|
||||
@@ -293,7 +293,7 @@ var BaseComponent = (function() {
|
||||
*/
|
||||
init: function(config) {
|
||||
// 子类覆盖此方法
|
||||
console.log('📝 BaseComponent.init: 请在子类中覆盖此方法');
|
||||
// console.log('📝 BaseComponent.init: 请在子类中覆盖此方法');
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -312,11 +312,11 @@ var BaseComponent = (function() {
|
||||
}
|
||||
|
||||
if (this.isVisible) {
|
||||
console.log('ℹ️ BaseComponent.show: 组件已可见,跳过:', this.name);
|
||||
// console.log('ℹ️ BaseComponent.show: 组件已可见,跳过:', this.name);
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log('👁️ BaseComponent: 显示组件 "' + this.name + '" (图层: ' + this.layer + ')');
|
||||
// console.log('👁️ BaseComponent: 显示组件 "' + this.name + '" (图层: ' + this.layer + ')');
|
||||
|
||||
// 显示图层
|
||||
SpriteManager.showGroup(this.layer);
|
||||
@@ -344,11 +344,11 @@ var BaseComponent = (function() {
|
||||
}
|
||||
|
||||
if (!this.isVisible) {
|
||||
console.log('ℹ️ BaseComponent.hide: 组件已隐藏,跳过:', this.name);
|
||||
// console.log('ℹ️ BaseComponent.hide: 组件已隐藏,跳过:', this.name);
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" (图层: ' + this.layer + ')');
|
||||
// console.log('🙈 BaseComponent: 隐藏组件 "' + this.name + '" (图层: ' + this.layer + ')');
|
||||
|
||||
// 隐藏图层
|
||||
SpriteManager.hideGroup(this.layer);
|
||||
@@ -375,7 +375,7 @@ var BaseComponent = (function() {
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log('💥 BaseComponent: 销毁组件 "' + this.name + '"');
|
||||
// console.log('💥 BaseComponent: 销毁组件 "' + this.name + '"');
|
||||
|
||||
// 移除所有事件监听
|
||||
this._removeAllEventListeners();
|
||||
@@ -447,7 +447,7 @@ var BaseComponent = (function() {
|
||||
// 记录监听器
|
||||
this.eventListeners[eventName] = wrappedHandler;
|
||||
|
||||
console.log('📡 BaseComponent: 组件 "' + this.name + '" 注册事件:', eventName);
|
||||
// console.log('📡 BaseComponent: 组件 "' + this.name + '" 注册事件:', eventName);
|
||||
|
||||
return true;
|
||||
},
|
||||
@@ -467,7 +467,7 @@ var BaseComponent = (function() {
|
||||
EventBus.off(eventName, handler);
|
||||
delete this.eventListeners[eventName];
|
||||
|
||||
console.log('📴 BaseComponent: 组件 "' + this.name + '" 移除事件:', eventName);
|
||||
// console.log('📴 BaseComponent: 组件 "' + this.name + '" 移除事件:', eventName);
|
||||
|
||||
return true;
|
||||
},
|
||||
@@ -483,7 +483,7 @@ var BaseComponent = (function() {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('📤 BaseComponent: 组件 "' + this.name + '" 触发事件:', eventName);
|
||||
// console.log('📤 BaseComponent: 组件 "' + this.name + '" 触发事件:', eventName);
|
||||
EventBus.emit(eventName, data);
|
||||
},
|
||||
|
||||
@@ -511,7 +511,7 @@ var BaseComponent = (function() {
|
||||
}
|
||||
|
||||
this.sprites.push(spriteId);
|
||||
// console.log('➕ BaseComponent: 组件 "' + this.name + '" 添加精灵:', spriteId);
|
||||
// // console.log('➕ BaseComponent: 组件 "' + this.name + '" 添加精灵:', spriteId);
|
||||
|
||||
return true;
|
||||
},
|
||||
@@ -529,7 +529,7 @@ var BaseComponent = (function() {
|
||||
}
|
||||
|
||||
this.sprites.splice(index, 1);
|
||||
console.log('➖ BaseComponent: 组件 "' + this.name + '" 移除精灵:', spriteId);
|
||||
// console.log('➖ BaseComponent: 组件 "' + this.name + '" 移除精灵:', spriteId);
|
||||
|
||||
return true;
|
||||
},
|
||||
@@ -596,7 +596,7 @@ var BaseComponent = (function() {
|
||||
*/
|
||||
printState: function() {
|
||||
var state = this.getState();
|
||||
console.log('📊 组件状态:', JSON.stringify(state, null, 2));
|
||||
// console.log('📊 组件状态:', JSON.stringify(state, null, 2));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -84,7 +84,21 @@
|
||||
* scrollSensitivity: 5, // 移动5px以上才触发滚动
|
||||
* bounceSpeed: 1 // 回弹速度
|
||||
* });
|
||||
*
|
||||
*
|
||||
* 【横向列表(左右滑动)】
|
||||
* var themeList = new DynamicSpriteList({
|
||||
* containerId: sprites.LIST_CONTAINER,
|
||||
* clipArea: { x: 340, y: 240, width: 600, height: 160 },
|
||||
* orientation: 'horizontal', // 默认 'vertical'
|
||||
* itemWidth: 262, // 主轴步长(项宽 + 项间距),与纵向 rowHeight 对称
|
||||
* renderRow: function (ctx) {
|
||||
* // 横向下 ctx.addSprite 的 x 会叠加该项的主轴基准,y 原样
|
||||
* var sid = ctx.addSprite('preview', TPL_ID, 0, 0);
|
||||
* }
|
||||
* });
|
||||
* // 事件转发:横向传 offmovex(纵向传 offmovey)
|
||||
* themeList.handleMouseMove(event.spriteId, event.offset.x);
|
||||
*
|
||||
* 【设置数据(触发渲染)】
|
||||
* // 数据数组中每个元素对应一行
|
||||
* // setData 会清除旧行、重新创建新行
|
||||
@@ -176,6 +190,26 @@
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
/**
|
||||
* 主轴/交叉轴的引擎操作码与 clipArea 字段映射
|
||||
* 前缀 DSL_ 是必要的:友乐运行时所有 <script> 共享同一全局作用域,
|
||||
* 通用名(如 LIST_AXIS)会与其它文件互相覆盖。
|
||||
* 操作码:18=左右移动 19=上下移动 20=设宽 21=设高
|
||||
* (docs/important/client/精灵操作详细指南.md:38-41)
|
||||
*/
|
||||
var DSL_LIST_AXIS = {
|
||||
vertical: {
|
||||
posOp: 19, sizeOp: 21, crossPosOp: 18, crossSizeOp: 20,
|
||||
clipPos: 'y', clipSize: 'height', crossClipPos: 'x', crossClipSize: 'width',
|
||||
stepField: 'rowHeight'
|
||||
},
|
||||
horizontal: {
|
||||
posOp: 18, sizeOp: 20, crossPosOp: 19, crossSizeOp: 21,
|
||||
clipPos: 'x', clipSize: 'width', crossClipPos: 'y', crossClipSize: 'height',
|
||||
stepField: 'itemWidth'
|
||||
}
|
||||
};
|
||||
|
||||
function DynamicSpriteList(config) {
|
||||
// ========================================================================
|
||||
// 参数验证
|
||||
@@ -189,8 +223,11 @@ function DynamicSpriteList(config) {
|
||||
if (!config.clipArea) {
|
||||
throw new Error('DynamicSpriteList: clipArea is required');
|
||||
}
|
||||
if (typeof config.rowHeight !== 'number' || config.rowHeight <= 0) {
|
||||
throw new Error('DynamicSpriteList: rowHeight must be a positive number');
|
||||
var orientation = (config.orientation === 'horizontal') ? 'horizontal' : 'vertical';
|
||||
var axis = DSL_LIST_AXIS[orientation];
|
||||
var step = config[axis.stepField];
|
||||
if (typeof step !== 'number' || step <= 0) {
|
||||
throw new Error('DynamicSpriteList: ' + axis.stepField + ' must be a positive number');
|
||||
}
|
||||
var hasTemplates = config.templates && typeof config.templates === 'object';
|
||||
var hasRenderRow = typeof config.renderRow === 'function';
|
||||
@@ -220,11 +257,31 @@ function DynamicSpriteList(config) {
|
||||
};
|
||||
|
||||
/**
|
||||
* 每行高度
|
||||
* 排列方向:'vertical'(默认) | 'horizontal'
|
||||
* @type {string}
|
||||
*/
|
||||
this.orientation = orientation;
|
||||
|
||||
/**
|
||||
* 轴映射(操作码 + clipArea 取用字段),内部所有方向相关操作一律经此表
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
this._axis = axis;
|
||||
|
||||
/**
|
||||
* 主轴步长:纵向=行高(rowHeight),横向=项宽含间距(itemWidth)
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this._step = step;
|
||||
|
||||
/**
|
||||
* 每行高度(纵向语义保留字段;横向下等于主轴步长)
|
||||
* @type {number}
|
||||
*/
|
||||
this.rowHeight = config.rowHeight;
|
||||
|
||||
this.rowHeight = step;
|
||||
|
||||
/**
|
||||
* 模板精灵配置
|
||||
* @type {Object}
|
||||
@@ -431,31 +488,31 @@ DynamicSpriteList.prototype.destroy = function() {
|
||||
/**
|
||||
* 滚动到指定位置
|
||||
*
|
||||
* @param {number} y - 目标Y坐标
|
||||
* @param {number} offset - 目标主轴偏移量(纵向=Y方向,横向=X方向)
|
||||
* @param {boolean} [animated=true] - 是否使用动画
|
||||
* @returns {DynamicSpriteList} 返回自身,支持链式调用
|
||||
*/
|
||||
DynamicSpriteList.prototype.scrollTo = function(y, animated) {
|
||||
var currentY = get_self(this.containerId, 19, 0, 0, 0);
|
||||
var targetY = this.clipArea.y - y;
|
||||
|
||||
// 边界限制
|
||||
var contentHeight = this._data.length * this.rowHeight;
|
||||
var minY = this.clipArea.y + this.clipArea.height - contentHeight;
|
||||
if (targetY < minY) {
|
||||
targetY = minY;
|
||||
}
|
||||
if (targetY > this.clipArea.y) {
|
||||
targetY = this.clipArea.y;
|
||||
}
|
||||
|
||||
DynamicSpriteList.prototype.scrollTo = function(offset, animated) {
|
||||
var axis = this._axis;
|
||||
var clipStart = this.clipArea[axis.clipPos];
|
||||
var clipSize = this.clipArea[axis.clipSize];
|
||||
var current = get_self(this.containerId, axis.posOp, 0, 0, 0);
|
||||
var target = clipStart - offset;
|
||||
|
||||
// 边界钳制(双向):先钳末端,再钳起点。
|
||||
// 内容不足一屏时 min > clipStart,两条钳制叠加后恒为起点——这正是期望行为。
|
||||
var contentSize = this._data.length * this._step;
|
||||
var min = clipStart + clipSize - contentSize;
|
||||
if (target < min) { target = min; }
|
||||
if (target > clipStart) { target = clipStart; }
|
||||
|
||||
if (animated !== false) {
|
||||
play_ani(1, this.containerId, 19, currentY, targetY, 0,
|
||||
Math.abs(targetY - currentY), 0, 0, 0, this.bounceSpeed, 0, 0, 0);
|
||||
play_ani(1, this.containerId, axis.posOp, current, target, 0,
|
||||
Math.abs(target - current), 0, 0, 0, this.bounceSpeed, 0, 0, 0);
|
||||
} else {
|
||||
set_self(this.containerId, 19, targetY, 0, 0, 0);
|
||||
set_self(this.containerId, axis.posOp, target, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -476,8 +533,8 @@ DynamicSpriteList.prototype.scrollToTop = function(animated) {
|
||||
* @returns {DynamicSpriteList} 返回自身,支持链式调用
|
||||
*/
|
||||
DynamicSpriteList.prototype.scrollToBottom = function(animated) {
|
||||
var contentHeight = this._data.length * this.rowHeight;
|
||||
var maxScroll = contentHeight - this.clipArea.height;
|
||||
var contentSize = this._data.length * this._step;
|
||||
var maxScroll = contentSize - this.clipArea[this._axis.clipSize];
|
||||
if (maxScroll < 0) {
|
||||
maxScroll = 0;
|
||||
}
|
||||
@@ -492,7 +549,7 @@ DynamicSpriteList.prototype.scrollToBottom = function(animated) {
|
||||
* @returns {DynamicSpriteList} 返回自身,支持链式调用
|
||||
*/
|
||||
DynamicSpriteList.prototype.scrollToRow = function(rowIndex, animated) {
|
||||
var y = rowIndex * this.rowHeight;
|
||||
var y = rowIndex * this._step;
|
||||
return this.scrollTo(y, animated);
|
||||
};
|
||||
|
||||
@@ -531,36 +588,35 @@ DynamicSpriteList.prototype.handleMouseDown = function(spid, x, y) {
|
||||
* 需要在 utlmousemove 回调中调用
|
||||
*
|
||||
* @param {number} spid - 移动的精灵ID
|
||||
* @param {number} offsetY - Y方向移动偏移量
|
||||
* @param {number} offsetMain - 主轴方向移动偏移量(纵向传 Y 方向偏移,横向传 X 方向偏移)
|
||||
* @returns {boolean} 如果事件被处理返回 true
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* // 在 SpriteEventController 或 Game_Modify 中
|
||||
* // 在 SpriteEventController 或 Game_Modify 中(纵向列表传 offmovey,横向列表传 offmovex)
|
||||
* utlmousemove: function(gameid, spid, downx, downy, movex, movey, timelong, offmovex, offmovey) {
|
||||
* if (myList.handleMouseMove(spid, offmovey)) {
|
||||
* if (myList.handleMouseMove(spid, offmovey)) { // 横向列表改传 offmovex
|
||||
* return; // 事件已处理
|
||||
* }
|
||||
* // 其他处理...
|
||||
* }
|
||||
*/
|
||||
DynamicSpriteList.prototype.handleMouseMove = function(spid, offsetY) {
|
||||
DynamicSpriteList.prototype.handleMouseMove = function(spid, offsetMain) {
|
||||
if (!this.enableScroll) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (spid === this.containerId) {
|
||||
if (Math.abs(offsetY) > this.scrollSensitivity) {
|
||||
// 增量移动容器
|
||||
set_self(this.containerId, 19, offsetY, 1, 0, 0);
|
||||
if (Math.abs(offsetMain) > this.scrollSensitivity) {
|
||||
var axis = this._axis;
|
||||
// 增量移动容器(第4参 1 = 相对增量)
|
||||
set_self(this.containerId, axis.posOp, offsetMain, 1, 0, 0);
|
||||
this._isSliding = true;
|
||||
|
||||
// 触发滚动回调
|
||||
|
||||
if (typeof this.onScroll === 'function') {
|
||||
var currentY = get_self(this.containerId, 19, 0, 0, 0);
|
||||
var scrollY = this.clipArea.y - currentY;
|
||||
var contentHeight = this._data.length * this.rowHeight;
|
||||
var maxScrollY = contentHeight - this.clipArea.height;
|
||||
this.onScroll(scrollY, maxScrollY > 0 ? maxScrollY : 0);
|
||||
var current = get_self(this.containerId, axis.posOp, 0, 0, 0);
|
||||
var scrolled = this.clipArea[axis.clipPos] - current;
|
||||
var maxScroll = this._data.length * this._step - this.clipArea[axis.clipSize];
|
||||
this.onScroll(scrolled, maxScroll > 0 ? maxScroll : 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -661,29 +717,30 @@ DynamicSpriteList.prototype._addSpriteInternal = function (name, templateSpriteI
|
||||
* @private
|
||||
*/
|
||||
DynamicSpriteList.prototype._render = function() {
|
||||
set_self(this.containerId, 18, this.clipArea.x, 0, 0);
|
||||
set_self(this.containerId, 19, this.clipArea.y, 0, 0);
|
||||
var contentHeight = this._data.length * this.rowHeight;
|
||||
set_self(this.containerId, 21, contentHeight, 0, 0);
|
||||
var axis = this._axis;
|
||||
set_self(this.containerId, axis.posOp, this.clipArea[axis.clipPos], 0, 0);
|
||||
set_self(this.containerId, axis.crossPosOp, this.clipArea[axis.crossClipPos], 0, 0);
|
||||
var contentSize = this._data.length * this._step;
|
||||
set_self(this.containerId, axis.sizeOp, contentSize, 0, 0);
|
||||
|
||||
if (this.templates) {
|
||||
var tnames = Object.keys(this.templates);
|
||||
if (tnames.length > 0) {
|
||||
var w = get_self(this.templates[tnames[0]].spriteId, 20, 0, 0, 0);
|
||||
set_self(this.containerId, 20, w, 0, 0);
|
||||
// 交叉轴尺寸取首个模板的对应尺寸(纵向=宽 op20,横向=高 op21)
|
||||
var crossFromTpl = get_self(this.templates[tnames[0]].spriteId, axis.crossSizeOp, 0, 0, 0);
|
||||
set_self(this.containerId, axis.crossSizeOp, crossFromTpl, 0, 0);
|
||||
}
|
||||
} else {
|
||||
// renderRow 模式:容器宽度取裁剪区宽,保证整行可视宽都在容器 hit 区(点击/拖动检测)内。
|
||||
// 否则容器保持编辑器预置窄宽度,超出部分点击/拖动报的 spid≠containerId 而失效(对账 bak set_self(fSpid,20,bg宽))。
|
||||
set_self(this.containerId, 20, this.clipArea.width, 0, 0);
|
||||
// renderRow 模式:交叉轴尺寸取裁剪区对应边,保证整个可视区都在容器 hit 区(点击/拖动检测)内
|
||||
set_self(this.containerId, axis.crossSizeOp, this.clipArea[axis.crossClipSize], 0, 0);
|
||||
}
|
||||
|
||||
for (var rowIndex = 0; rowIndex < this._data.length; rowIndex++) {
|
||||
var rowData = this._data[rowIndex];
|
||||
var rowY = rowIndex * this.rowHeight;
|
||||
var rowBase = rowIndex * this._step;
|
||||
|
||||
if (this.renderRow) {
|
||||
this.renderRow(this._makeRowContext(rowIndex, rowData, rowY));
|
||||
this.renderRow(this._makeRowContext(rowIndex, rowData, rowBase));
|
||||
} else {
|
||||
var names = Object.keys(this.templates);
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
@@ -691,7 +748,9 @@ DynamicSpriteList.prototype._render = function() {
|
||||
var t = this.templates[name];
|
||||
var ox = (t.offset && t.offset.x) || 0;
|
||||
var oy = (t.offset && t.offset.y) || 0;
|
||||
var sid = this._addSpriteInternal(name, t.spriteId, ox, rowY + oy, rowIndex, t.clickable !== false);
|
||||
var px = (this.orientation === 'horizontal') ? (rowBase + ox) : ox;
|
||||
var py = (this.orientation === 'horizontal') ? oy : (rowBase + oy);
|
||||
var sid = this._addSpriteInternal(name, t.spriteId, px, py, rowIndex, t.clickable !== false);
|
||||
if (t.textProperty && rowData[t.textProperty] !== undefined) {
|
||||
set_self(sid, 7, rowData[t.textProperty], 0, 0);
|
||||
}
|
||||
@@ -708,19 +767,27 @@ DynamicSpriteList.prototype._render = function() {
|
||||
* 创建行上下文对象(传给 renderRow 回调)
|
||||
* @param {number} rowIndex - 行索引
|
||||
* @param {Object} rowData - 行数据
|
||||
* @param {number} rowBaseY - 行基准 Y 坐标
|
||||
* @param {number} rowBase - 行基准坐标(纵向=Y,横向=X)
|
||||
* @returns {Object} 行上下文
|
||||
* @private
|
||||
*/
|
||||
DynamicSpriteList.prototype._makeRowContext = function (rowIndex, rowData, rowBaseY) {
|
||||
DynamicSpriteList.prototype._makeRowContext = function (rowIndex, rowData, rowBase) {
|
||||
var self = this;
|
||||
var isH = (this.orientation === 'horizontal');
|
||||
return {
|
||||
rowIndex: rowIndex,
|
||||
rowData: rowData,
|
||||
rowBaseY: rowBaseY,
|
||||
rowBase: rowBase,
|
||||
// 保留 rowBaseY:renderRow 回调的既有字段协议,不得破坏。
|
||||
// 当前生产消费方为 RecordView.js(唯一使用本组件的调用方);
|
||||
// 回归测试 DynamicSpriteList.test.js 对该字段有硬断言。
|
||||
rowBaseY: rowBase,
|
||||
orientation: this.orientation,
|
||||
containerId: this.containerId,
|
||||
addSprite: function (name, templateSpriteId, x, y) {
|
||||
return self._addSpriteInternal(name, templateSpriteId, x, rowBaseY + y, rowIndex, true);
|
||||
var px = isH ? (rowBase + x) : x;
|
||||
var py = isH ? y : (rowBase + y);
|
||||
return self._addSpriteInternal(name, templateSpriteId, px, py, rowIndex, true);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -730,38 +797,39 @@ DynamicSpriteList.prototype._makeRowContext = function (rowIndex, rowData, rowBa
|
||||
* @private
|
||||
*/
|
||||
DynamicSpriteList.prototype._handleBounce = function() {
|
||||
var currentY = get_self(this.containerId, 19, 0, 0, 0);
|
||||
var contentHeight = get_self(this.containerId, 21, 0, 0, 0);
|
||||
var clipY = this.clipArea.y;
|
||||
var clipH = this.clipArea.height;
|
||||
|
||||
var targetY = currentY;
|
||||
var axis = this._axis;
|
||||
var current = get_self(this.containerId, axis.posOp, 0, 0, 0);
|
||||
var contentSize = get_self(this.containerId, axis.sizeOp, 0, 0, 0);
|
||||
var clipStart = this.clipArea[axis.clipPos];
|
||||
var clipSize = this.clipArea[axis.clipSize];
|
||||
|
||||
var target = current;
|
||||
var needBounce = false;
|
||||
|
||||
if (contentHeight <= clipH) {
|
||||
// 内容不足一屏,回弹到顶部
|
||||
if (currentY !== clipY) {
|
||||
targetY = clipY;
|
||||
|
||||
if (contentSize <= clipSize) {
|
||||
// 内容不足一屏,回弹到起点
|
||||
if (current !== clipStart) {
|
||||
target = clipStart;
|
||||
needBounce = true;
|
||||
}
|
||||
} else {
|
||||
if (currentY > clipY) {
|
||||
// 超出顶部
|
||||
targetY = clipY;
|
||||
if (current > clipStart) {
|
||||
// 越过起点
|
||||
target = clipStart;
|
||||
needBounce = true;
|
||||
} else {
|
||||
var minY = clipY + clipH - contentHeight;
|
||||
if (currentY < minY) {
|
||||
// 超出底部
|
||||
targetY = minY;
|
||||
var min = clipStart + clipSize - contentSize;
|
||||
if (current < min) {
|
||||
// 越过末端
|
||||
target = min;
|
||||
needBounce = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (needBounce) {
|
||||
play_ani(1, this.containerId, 19, currentY, targetY, 0,
|
||||
Math.abs(targetY - currentY), 0, 0, 0, this.bounceSpeed, 0, 0, 0);
|
||||
play_ani(1, this.containerId, axis.posOp, current, target, 0,
|
||||
Math.abs(target - current), 0, 0, 0, this.bounceSpeed, 0, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -772,6 +840,16 @@ DynamicSpriteList.prototype._handleBounce = function() {
|
||||
* @private
|
||||
*/
|
||||
DynamicSpriteList.prototype._handleClick = function(x, y) {
|
||||
// 裁剪区外的点击一律不算数。
|
||||
// 原因:引擎的 set_clip 只裁【绘制】、不裁【命中】,而 _render 会把容器的主轴尺寸
|
||||
// 撑到内容全长(远超可视区)。于是滑出可视区、屏幕上已经看不见的那些项,其矩形
|
||||
// 仍在容器内,ifast_check_add 照样判为命中 —— 用户点到列表旁的空白带,却选中了
|
||||
// 一个根本看不见的项。这里按 clipArea 兜住,横纵通用。
|
||||
var a = this.clipArea;
|
||||
if (x < a.x || x >= a.x + a.width || y < a.y || y >= a.y + a.height) {
|
||||
return;
|
||||
}
|
||||
|
||||
var clickedTag = ifast_check_add(this.containerId, x, y);
|
||||
if (clickedTag === -99999999) { return; }
|
||||
var rec = this._tagIndex[clickedTag];
|
||||
|
||||
@@ -63,6 +63,10 @@ var RecordView = {
|
||||
if (typeof gradeinfo[i].gameinfo1 === 'string') {
|
||||
gradeinfo[i].gameinfo1 = JSON.parse(gradeinfo[i].gameinfo1);
|
||||
}
|
||||
// roomtype 归一:平台战绩记录里 roomtype 可能被多做了一层 JSON 序列化,
|
||||
// 形如 '"11221000100003"'。下游权威 RoomConfigUtils.parse 严格要求 14 位裸字符串
|
||||
// (故意不做多格式兼容),故在此收包边界剥掉多余的 JSON 引号层。
|
||||
gradeinfo[i].roomtype = this._normalizeRoomtype(gradeinfo[i].roomtype);
|
||||
if (i === 0) { this._gradeIdx1 = gradeinfo[i].idx; }
|
||||
if (i === gradeinfo.length - 1) { this._gradeIdx2 = gradeinfo[i].idx; }
|
||||
}
|
||||
@@ -70,6 +74,17 @@ var RecordView = {
|
||||
this.open();
|
||||
},
|
||||
|
||||
// 剥掉 roomtype 上多余的 JSON 序列化层:'"11221000100003"' → '11221000100003'。
|
||||
// 多层引号(极端情况)循环剥;非字符串或无引号原样返回;JSON.parse 失败即停止不吞坏值。
|
||||
_normalizeRoomtype: function (rt) {
|
||||
var v = rt, guard = 0;
|
||||
while (typeof v === 'string' && v.length >= 2 && v.charAt(0) === '"' && guard < 5) {
|
||||
try { v = JSON.parse(v); } catch (e) { break; }
|
||||
guard++;
|
||||
}
|
||||
return v;
|
||||
},
|
||||
|
||||
// 翻页/类型 → 发获取战绩请求(平台通用协议)。类型切换 _requestGrade(type,null);翻页 _requestGrade(_,direction)。
|
||||
_requestGrade: function (arg1, direction) {
|
||||
var data = { agentid: GameData.AgentId, playerid: C_Player.playerid, gameid: GameData.GameId };
|
||||
@@ -77,9 +92,9 @@ var RecordView = {
|
||||
this._type = arg1; // 类型切换
|
||||
data.type = arg1;
|
||||
} else {
|
||||
data.type = this._type; // 翻页:type 用当前,direction + gradeidx
|
||||
data.type = this._type; // 翻页:type 用当前,direction + idx
|
||||
data.direction = direction;
|
||||
data.gradeidx = (direction === 1) ? this._gradeIdx1 : this._gradeIdx2;
|
||||
data.idx = (direction === 1) ? this._gradeIdx1 : this._gradeIdx2;
|
||||
}
|
||||
if (typeof Net !== 'undefined' && Net.Send_get_player_grade1) { Net.Send_get_player_grade1(data); }
|
||||
},
|
||||
@@ -89,7 +104,7 @@ var RecordView = {
|
||||
_requestReplayData: function (gameIndex) {
|
||||
var data = { agentid: GameData.AgentId, playerid: C_Player.playerid, gameid: GameData.GameId };
|
||||
if (this._gradeData && this._gradeData[gameIndex] && typeof this._gradeData[gameIndex].idx !== 'undefined') {
|
||||
data.gradeidx = this._gradeData[gameIndex].idx;
|
||||
data.idx = this._gradeData[gameIndex].idx;
|
||||
}
|
||||
if (typeof Net !== 'undefined' && Net.Send_get_player_grade2) { Net.Send_get_player_grade2(data); }
|
||||
},
|
||||
|
||||
@@ -145,7 +145,7 @@ var UIManager = (function () {
|
||||
SpriteManager.hide(LOADING_UI.SPRITES.LOADING_ICON);
|
||||
SpriteManager.hide(LOADING_UI.SPRITES.LOADING_TEXT);
|
||||
SpriteManager.hideGroup(LOADING_UI.GROUP_ID);
|
||||
console.log('[UIManager] Loading UI 初始化 (Layer ' + LOADING_UI.LAYER + ')');
|
||||
// console.log('[UIManager] Loading UI 初始化 (Layer ' + LOADING_UI.LAYER + ')');
|
||||
}
|
||||
|
||||
/** @private */
|
||||
@@ -153,7 +153,7 @@ var UIManager = (function () {
|
||||
SpriteManager.hide(MESSAGE_UI.SPRITES.BACKGROUND);
|
||||
SpriteManager.hide(MESSAGE_UI.SPRITES.TEXT);
|
||||
SpriteManager.hideGroup(MESSAGE_UI.GROUP_ID);
|
||||
console.log('[UIManager] Message UI 初始化 (Layer ' + MESSAGE_UI.LAYER + ')');
|
||||
// console.log('[UIManager] Message UI 初始化 (Layer ' + MESSAGE_UI.LAYER + ')');
|
||||
}
|
||||
|
||||
/** @private */
|
||||
@@ -164,7 +164,7 @@ var UIManager = (function () {
|
||||
SpriteManager.hide(CONFIRM_UI.SPRITES.BTN_CONFIRM);
|
||||
SpriteManager.hide(CONFIRM_UI.SPRITES.BTN_CANCEL);
|
||||
SpriteManager.hideGroup(CONFIRM_UI.GROUP_ID);
|
||||
console.log('[UIManager] Confirm UI 初始化 (Layer ' + CONFIRM_UI.LAYER + ')');
|
||||
// console.log('[UIManager] Confirm UI 初始化 (Layer ' + CONFIRM_UI.LAYER + ')');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,7 +227,7 @@ var UIManager = (function () {
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log('[UIManager] 初始化 (v1.0.0)');
|
||||
// console.log('[UIManager] 初始化 (v1.0.0)');
|
||||
|
||||
try {
|
||||
_components = {};
|
||||
@@ -239,7 +239,7 @@ var UIManager = (function () {
|
||||
|
||||
_isInitialized = true;
|
||||
this.initialized = true;
|
||||
console.log('[UIManager] 初始化完成');
|
||||
// console.log('[UIManager] 初始化完成');
|
||||
return true;
|
||||
} catch (err) {
|
||||
console.error('[UIManager] 初始化失败:', err);
|
||||
@@ -279,7 +279,7 @@ var UIManager = (function () {
|
||||
console.warn('[UIManager] registerComponent: 覆盖已存在组件:', name);
|
||||
}
|
||||
_components[name] = component;
|
||||
console.log('[UIManager] 注册组件 "' + name + '"');
|
||||
// console.log('[UIManager] 注册组件 "' + name + '"');
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -305,7 +305,7 @@ var UIManager = (function () {
|
||||
var c = _components[name];
|
||||
if (c.isVisible) { c.hide(); }
|
||||
delete _components[name];
|
||||
console.log('[UIManager] 注销组件 "' + name + '"');
|
||||
// console.log('[UIManager] 注销组件 "' + name + '"');
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -321,7 +321,7 @@ var UIManager = (function () {
|
||||
}
|
||||
_components[name].destroy();
|
||||
delete _components[name];
|
||||
console.log('[UIManager] 销毁组件 "' + name + '"');
|
||||
// console.log('[UIManager] 销毁组件 "' + name + '"');
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -371,7 +371,7 @@ var UIManager = (function () {
|
||||
}
|
||||
}
|
||||
_scenes[sceneName] = componentNames;
|
||||
console.log('[UIManager] 注册场景 "' + sceneName + '" (' + componentNames.length + ' 个组件)');
|
||||
// console.log('[UIManager] 注册场景 "' + sceneName + '" (' + componentNames.length + ' 个组件)');
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -390,7 +390,7 @@ var UIManager = (function () {
|
||||
return true;
|
||||
}
|
||||
|
||||
console.log('[UIManager] 切换场景 "' + (_currentScene || 'null') + '" → "' + sceneName + '"');
|
||||
// console.log('[UIManager] 切换场景 "' + (_currentScene || 'null') + '" → "' + sceneName + '"');
|
||||
_hideCurrentScene();
|
||||
_showScene(sceneName);
|
||||
|
||||
@@ -447,7 +447,7 @@ var UIManager = (function () {
|
||||
* @param {string} message
|
||||
*/
|
||||
showToast: function (message) {
|
||||
console.log('[UIManager] Toast:', message);
|
||||
// console.log('[UIManager] Toast:', message);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -458,7 +458,7 @@ var UIManager = (function () {
|
||||
*/
|
||||
showEffectToast: function (tag, title, description) {
|
||||
var msg = description ? (title + ':' + description) : title;
|
||||
console.log('[UIManager] EffectToast [' + tag + ']:', msg);
|
||||
// console.log('[UIManager] EffectToast [' + tag + ']:', msg);
|
||||
this.showToast(msg);
|
||||
},
|
||||
|
||||
@@ -575,14 +575,14 @@ var UIManager = (function () {
|
||||
* 打印状态(调试用)
|
||||
*/
|
||||
printState: function () {
|
||||
console.log('[UIManager] 状态:', JSON.stringify(this.getState(), null, 2));
|
||||
// console.log('[UIManager] 状态:', JSON.stringify(this.getState(), null, 2));
|
||||
},
|
||||
|
||||
/**
|
||||
* 销毁 UIManager(销毁所有组件并重置状态)
|
||||
*/
|
||||
destroy: function () {
|
||||
console.log('[UIManager] 开始销毁');
|
||||
// console.log('[UIManager] 开始销毁');
|
||||
for (var name in _components) {
|
||||
if (_components.hasOwnProperty(name)) { this.destroyComponent(name); }
|
||||
}
|
||||
@@ -594,7 +594,7 @@ var UIManager = (function () {
|
||||
_currentScene = null;
|
||||
_isInitialized = false;
|
||||
this.initialized = false;
|
||||
console.log('[UIManager] 销毁完成');
|
||||
// console.log('[UIManager] 销毁完成');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user