feat: 修改构建流程

This commit is contained in:
guanchao
2026-11-03 20:41:22 +08:00
7 changed files with 87 additions and 51 deletions
+6 -26
View File
@@ -30,17 +30,13 @@ export default class Reward extends cc.Component {
}
start() {
// ... 已有代码 ...
this.node.on(cc.Node.EventType.TOUCH_END, this.onNodeClick, this);
}
/**
* 节点点击事件处理函数
*/
onNodeClick() {
// console.log('Reward 节点被点击了', this.actionOver);
// 这里可以添加点击后的具体逻辑
if (this.actionOver == true) {
cc.fx.AudioManager._instance.playEffect("anniu_little", null);
this.actionOver = false;
@@ -51,10 +47,6 @@ export default class Reward extends cc.Component {
this.node.destroy();
});
}
else {
// 游戏整体加速
// this.speedUpGame();
}
}
@@ -151,7 +143,7 @@ export default class Reward extends cc.Component {
const rewardIcon = this.getOrCreateRewardIcon(iconNode,
rewardData.battlePass && rewardData.type === 'coin'
? { ...rewardData, spriteFrame: this.battlePassCoin } : rewardData);
if (rewardData.battlePass && rewardData.type !== 'coin' && rewardData.type !== 'infinite_health') {
if (rewardData.type !== 'coin' && rewardData.type !== 'infinite_health') {
const prefix = rewardNode.getChildByName('xnode');
prefix.getComponent(cc.Sprite).spriteFrame = NumberToImage.publicFont.getSpriteFrame('big_cheng');
}
@@ -162,16 +154,9 @@ export default class Reward extends cc.Component {
if (rewardData.type == 'coin')
NumberToImage.numberToImageNodesNumber(rewardData.count, 45, 5, "big_", label, true);
else if (rewardData.type == 'infinite_health') {
if (durationUnits || rewardData.battlePass) {
this.renderDuration(label, rewardData.count);
rewardNode.getChildByName('xnode').active = false;
} else {
NumberToImage.getTimeMargin2(rewardData.count, 45, "coins", label, true);
if (rewardData.count > 3600) label.x -= 10;
rewardNode.getChildByName('xnode').opacity = 1;
}
}
else {
this.renderDuration(label, rewardData.count);
rewardNode.getChildByName('xnode').active = false;
} else {
NumberToImage.numberToImageNodesNumber(rewardData.count, 50, 15, "big_", label, true);
const xnode = rewardNode.getChildByName('xnode');
xnode.opacity = 0;
@@ -189,8 +174,7 @@ export default class Reward extends cc.Component {
xnode.x = label.x + (firstDigit.x - firstDigit.width * firstDigit.anchorX) * label.scaleX
- 6 - xnode.width * (1 - xnode.anchorX) * xnode.scaleX;
}
if (rewardData.type !== 'infinite_health' || durationUnits || rewardData.battlePass)
this.alignAmount(rewardNode, rewardData.type !== 'coin' && rewardData.type !== 'infinite_health');
this.alignAmount(rewardNode, rewardData.type !== 'coin' && rewardData.type !== 'infinite_health');
rewardNode.getChildByName('label').active = false;
if (iconNode) {
cc.tween(iconNode)
@@ -202,8 +186,7 @@ export default class Reward extends cc.Component {
rewardNode.getChildByName('label').active = true;
if (rewardNode.getChildByName('xnode').opacity == 1) {
rewardNode.getChildByName('xnode').opacity = 0;
}
else if (rewardNode.getChildByName('xnode').opacity != 255) {
} else if (rewardNode.getChildByName('xnode').opacity != 255) {
rewardNode.getChildByName('xnode').active = true;
rewardNode.getChildByName('xnode').opacity = 255;
}
@@ -285,7 +268,4 @@ export default class Reward extends cc.Component {
rewardIcon.setScale(rewardData.type === "cat_skin" ? 1.1 : 1);
return rewardIcon;
}
}
+6 -6
View File
@@ -305,8 +305,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 84,
"height": 95
"width": 190,
"height": 147
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -358,7 +358,7 @@
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "d22678f9-a73b-4c94-af07-62a134fd2d30"
"__uuid__": "c331a597-3361-4765-8e44-9989c8e6648a"
},
"_type": 0,
"_sizeMode": 1,
@@ -1356,8 +1356,8 @@
},
"_contentSize": {
"__type__": "cc.Size",
"width": 36,
"height": 34
"width": 31,
"height": 32
},
"_anchorPoint": {
"__type__": "cc.Vec2",
@@ -1409,7 +1409,7 @@
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "fafa9ef2-f250-47c7-b198-49971d3a380d"
"__uuid__": "1d8908e8-0fc8-41b9-86b3-82c56da62633"
},
"_type": 0,
"_sizeMode": 1,
+1 -6
View File
@@ -36,7 +36,6 @@
"name": "cloud_rise_home",
"root": "subpackages/cloud_rise_home"
},
{
"name": "publicUI",
"root": "subpackages/publicUI"
@@ -61,10 +60,6 @@
"name": "jungle_treasure",
"root": "subpackages/jungle_treasure"
},
{
"name": "custom",
"root": "subpackages/custom"
},
{
"name": "action_bundle",
"root": "subpackages/action_bundle"
@@ -119,4 +114,4 @@
"iOSHighPerformance": true,
"iOSHighPerformance+": true,
"useNativePerformance": true
}
}
+2
View File
@@ -24,6 +24,8 @@ packages/level-resources/publication.json:
custom在微信配置为远程Bundle,抖音配置不变。Creator 2.4.15完整构建微信,填写HTTPS资源服务器地址。构建扩展自动生成levels-local内置目录、注入加载器、移除custom子包声明,并排除remote和subpackages/custom的微信上传。首次接入必须完整构建,单独运行资源发布命令不能更新客户端代码。
微信构建后处理统一由 `packages/activity-bundles/main.js` 注册:先生成活动资源,再执行关卡打包,任一步失败都会使构建失败。`level-resources/main.js` 不再单独注册写入钩子。更新构建扩展后须重启 Creator,让新的统一入口生效;构建成功时控制台应同时出现 `[activity-bundles]` 和 `[level-resources]` 日志。
## 生成资源(不上传、不部署)
```powershell
+7 -2
View File
@@ -1,10 +1,15 @@
'use strict';
const { pack } = require('./pack');
function onBuildFinished(options, callback) {
if ((options.actualPlatform || options.platform) !== 'wechatgame') return callback();
try {
const result = pack(options.dest);
// One hook owns both postprocessors so a successful build cannot omit levels.
// Reload implementations because Creator keeps extensions alive between builds.
for (const name of ['./pack', '../level-resources/pack', '../level-resources/validation'])
delete require.cache[require.resolve(name)];
const result = require('./pack').pack(options.dest);
Editor.log('[activity-bundles] ZIP 与公共清单已生成:' + result.publishDir);
const levels = require('../level-resources/pack').pack(options.dest);
Editor.log('[level-resources] ' + levels.publishDir);
callback();
} catch (error) { Editor.error(error); callback(error); }
}
+4 -11
View File
@@ -1,14 +1,7 @@
'use strict';
function finished(options, callback) {
if ((options.actualPlatform || options.platform) !== 'wechatgame') return callback();
try {
// Creator keeps extensions alive across builds; reload the publisher after source updates.
for (const name of ['./pack', './validation']) delete require.cache[require.resolve(name)];
Editor.log('[level-resources] ' + require('./pack').pack(options.dest).publishDir); callback();
}
catch (error) { Editor.error(error); callback(error); }
}
// activity-bundles owns the ordered WeChat build hook. Keep the CLI publisher
// available here, without registering a second writer for game.js/settings.js.
module.exports = {
load() { Editor.Builder.on('build-finished', finished); },
unload() { Editor.Builder.removeListener('build-finished', finished); }
load() {},
unload() {}
};
+61
View File
@@ -0,0 +1,61 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const vm = require('node:vm');
function fixture(failure) {
const events = [], errors = [], modules = {}, cache = {};
for (const name of ['./pack', '../level-resources/pack', '../level-resources/validation']) {
cache[name] = { stale: true };
modules[name] = { pack(dest) {
assert.equal(dest, 'output');
events.push(name);
if (name === failure) throw new Error('pack failed: ' + name);
return { publishDir: name };
} };
}
const requireModule = name => {
assert.equal(cache[name], undefined, 'postprocessor must be reloaded');
return modules[name];
};
requireModule.cache = cache;
requireModule.resolve = name => name;
let handler;
const Editor = { log() {}, error: error => errors.push(error), Builder: {
on(event, fn) { assert.equal(event, 'build-finished'); assert.equal(handler, undefined); handler = fn; },
removeListener(event, fn) { assert.equal(event, 'build-finished'); assert.equal(fn, handler); handler = undefined; },
} };
const module = { exports: {} };
vm.runInNewContext(fs.readFileSync('packages/activity-bundles/main.js', 'utf8'),
{ module, require: requireModule, Editor });
module.exports.load();
const legacy = { exports: {} };
vm.runInNewContext(fs.readFileSync('packages/level-resources/main.js', 'utf8'), { module: legacy, Editor });
legacy.exports.load(); // Must not install a second writer.
return { events, errors, extension: module.exports,
run(options) { const calls = []; handler(options, error => calls.push(error)); return calls; } };
}
for (const options of [{ platform: 'wechatgame' }, { platform: 'mini-game', actualPlatform: 'wechatgame' }])
test(`WeChat build runs both postprocessors in order (${JSON.stringify(options)})`, () => {
const f = fixture();
assert.deepEqual(f.run({ ...options, dest: 'output' }), [undefined]);
assert.deepEqual(f.events, ['./pack', '../level-resources/pack']);
assert.deepEqual(f.errors, []);
f.extension.unload();
});
test('other platforms do not run WeChat postprocessing', () => {
const f = fixture();
assert.deepEqual(f.run({ platform: 'mini-game', actualPlatform: 'bytedance' }), [undefined]);
assert.deepEqual(f.events, []);
});
for (const failure of ['./pack', '../level-resources/pack'])
test(`failure in ${failure} rejects the build exactly once`, () => {
const f = fixture(failure), calls = f.run({ platform: 'wechatgame', dest: 'output' });
assert.equal(calls.length, 1);
assert.match(calls[0].message, /pack failed/);
assert.equal(f.errors[0], calls[0]);
assert.deepEqual(f.events, failure === './pack' ? ['./pack'] : ['./pack', '../level-resources/pack']);
});