优化0827-2

main
chenanghui 5 days ago
parent 47835bb8f4
commit 756e09a89c
  1. 6
      assets/bundles/first/config/Chapter.json
  2. 2
      assets/bundles/first/config/Const_weight.json
  3. 340
      assets/bundles/first/config/Monster2.json
  4. 1
      assets/script/game/Physics2DGate.ts
  5. 14
      assets/script/interface/AutoTable.ts
  6. 1
      assets/script/sdk/SDKManager.ts
  7. 20
      assets/script/tetriCard/role.ts
  8. 7
      assets/script/tetriCard/tetriAbility.ts
  9. 20
      assets/script/tetriCard/tetriFloorNode.ts
  10. 51
      assets/script/tetriCard/tetriNode.ts
  11. 62
      assets/script/tetriCard/tetriWeaponCarrier.ts
  12. 159
      assets/script/tetriMap/tetriMap.ts
  13. 17
      assets/script/ui/BattleGame/BattleCore.ts
  14. 20
      assets/script/ui/BattleGame/MonsterSpawner.ts
  15. 3
      assets/script/ui/tetriGame/UItetriGame.ts
  16. 2
      bin/tt_bknsb1.0.1.bin
  17. BIN
      tetriWeaponCarrier.patch
  18. BIN
      配置表/excelList/常量表.xlsx
  19. BIN
      配置表/excelList/怪物表.xlsx
  20. BIN
      配置表/excelList/章节表.xlsx
  21. BIN
      配置表/策划配置/俄罗斯方块战斗武器12波.xlsx

@ -6406,8 +6406,8 @@
"box_reward3": "", "box_reward3": "",
"barrier": "火车站锥形桶", "barrier": "火车站锥形桶",
"box_time": "", "box_time": "",
"monster1": "301,10,1|301,10,2|301,10,3|301,10,4|301,5,5;305,5,5|301,10,6|301,10,7|301,10,8|301,10,9|301,10,10;306,1,10|301,15,11|301,15,12|301,15,13|301,15,14|301,10,15;305,5,15|301,15,16|301,15,17|301,15,18|301,15,19|301,15,20;306,1,20|301,20,21|301,20,22|301,20,23|301,20,24|301,15,25;305,5,25|301,20,26|301,20,27|301,20,28|301,20,29|301,20,30;306,1,30", "monster1": "501,10,1|501,10,2|501,10,3|501,10,4|502,5,5;505,5,5|502,10,6|502,10,7|502,10,8|502,10,9|502,10,10;506,1,10|503,15,11|503,15,12|503,15,13|503,15,14|503,10,15;505,5,15|503,15,16|503,15,17|503,15,18|503,15,19|503,15,20;506,1,20",
"monster2_1": "301,10,1|301,10,2|301,10,3|301,10,4|301,5,5;305,5,5|301,10,6|301,10,7|301,10,8|301,10,9|301,10,10;306,1,10|301,15,11|301,15,12|301,15,13|301,15,14|301,10,15;305,5,15|301,15,16|301,15,17|301,15,18|301,15,19|301,15,20;306,1,20|301,20,21|301,20,22|301,20,23|301,20,24|301,15,25;305,5,25|301,20,26|301,20,27|301,20,28|301,20,29|301,20,30;306,1,30", "monster2_1": "501,10,1|501,10,2|501,10,3|501,10,4|502,5,5;505,5,5|502,10,6|502,10,7|502,10,8|502,10,9|502,10,10;506,1,10|503,15,11|503,15,12|503,15,13|503,15,14|503,10,15;505,5,15|503,15,16|503,15,17|503,15,18|503,15,19|503,15,20;506,1,20",
"monster2_2": "", "monster2_2": "",
"monster2_3": "", "monster2_3": "",
"monster2_4": "", "monster2_4": "",
@ -6651,7 +6651,7 @@
"difficult": 1, "difficult": 1,
"power": 0, "power": 0,
"base_coin": 100, "base_coin": 100,
"monster_group": 30, "monster_group": 13,
"hp_multiple": 19, "hp_multiple": 19,
"atk_group": 1, "atk_group": 1,
"atk_multiple": 1, "atk_multiple": 1,

@ -236,7 +236,7 @@
{ {
"id": 1210, "id": 1210,
"desc": "波次预警提前时间15s(大于1关)", "desc": "波次预警提前时间15s(大于1关)",
"constValue": 20, "constValue": 18,
"constString": "" "constString": ""
}, },
{ {

@ -72,23 +72,23 @@
"attr0": 94, "attr0": 94,
"attr1": 88, "attr1": 88,
"attr2": 35, "attr2": 35,
"attr3": 61, "attr3": 70,
"attr4": 62, "attr4": 71,
"attr5": 63, "attr5": 71,
"attr6": 64, "attr6": 72,
"attr7": 65, "attr7": 72,
"attr8": 66, "attr8": 73,
"attr9": 67, "attr9": 73,
"attr10": 68, "attr10": 74,
"attr11": 69, "attr11": 74,
"attr12": 70, "attr12": 75,
"attr13": 71, "attr13": 75,
"attr14": 72, "attr14": 76,
"attr15": 73, "attr15": 76,
"attr16": 74, "attr16": 77,
"attr17": 75, "attr17": 77,
"attr18": 77, "attr18": 78,
"attr19": 78, "attr19": 79,
"attr20": 79, "attr20": 79,
"attr21": 63, "attr21": 63,
"attr22": 63, "attr22": 63,
@ -105,7 +105,7 @@
"id": 4, "id": 4,
"attr0": 113, "attr0": 113,
"attr1": 58, "attr1": 58,
"attr2": 56, "attr2": 51,
"attr3": 47, "attr3": 47,
"attr4": 49, "attr4": 49,
"attr5": 50, "attr5": 50,
@ -139,25 +139,25 @@
"id": 5, "id": 5,
"attr0": 225, "attr0": 225,
"attr1": 140, "attr1": 140,
"attr2": 65, "attr2": 61,
"attr3": 168, "attr3": 182,
"attr4": 170, "attr4": 184,
"attr5": 172, "attr5": 185,
"attr6": 175, "attr6": 187,
"attr7": 177, "attr7": 189,
"attr8": 179, "attr8": 191,
"attr9": 182, "attr9": 192,
"attr10": 184, "attr10": 194,
"attr11": 187, "attr11": 196,
"attr12": 189, "attr12": 198,
"attr13": 192, "attr13": 199,
"attr14": 194, "attr14": 201,
"attr15": 197, "attr15": 203,
"attr16": 199, "attr16": 205,
"attr17": 202, "attr17": 207,
"attr18": 205, "attr18": 209,
"attr19": 207, "attr19": 211,
"attr20": 210, "attr20": 228,
"attr21": 53, "attr21": 53,
"attr22": 53, "attr22": 53,
"attr23": 53, "attr23": 53,
@ -173,25 +173,25 @@
"id": 6, "id": 6,
"attr0": 281, "attr0": 281,
"attr1": 198, "attr1": 198,
"attr2": 119, "attr2": 105,
"attr3": 245, "attr3": 261,
"attr4": 250, "attr4": 274,
"attr5": 255, "attr5": 288,
"attr6": 259, "attr6": 302,
"attr7": 264, "attr7": 317,
"attr8": 270, "attr8": 333,
"attr9": 275, "attr9": 350,
"attr10": 280, "attr10": 367,
"attr11": 285, "attr11": 386,
"attr12": 291, "attr12": 405,
"attr13": 297, "attr13": 425,
"attr14": 302, "attr14": 446,
"attr15": 308, "attr15": 469,
"attr16": 314, "attr16": 492,
"attr17": 320, "attr17": 517,
"attr18": 326, "attr18": 543,
"attr19": 333, "attr19": 570,
"attr20": 340, "attr20": 570,
"attr21": 130, "attr21": 130,
"attr22": 130, "attr22": 130,
"attr23": 130, "attr23": 130,
@ -207,25 +207,25 @@
"id": 7, "id": 7,
"attr0": 375, "attr0": 375,
"attr1": 236, "attr1": 236,
"attr2": 180, "attr2": 162,
"attr3": 344, "attr3": 364,
"attr4": 352, "attr4": 393,
"attr5": 360, "attr5": 425,
"attr6": 368, "attr6": 459,
"attr7": 377, "attr7": 495,
"attr8": 385, "attr8": 535,
"attr9": 394, "attr9": 578,
"attr10": 403, "attr10": 624,
"attr11": 412, "attr11": 674,
"attr12": 422, "attr12": 728,
"attr13": 431, "attr13": 786,
"attr14": 441, "attr14": 849,
"attr15": 451, "attr15": 917,
"attr16": 461, "attr16": 990,
"attr17": 472, "attr17": 1069,
"attr18": 483, "attr18": 1155,
"attr19": 494, "attr19": 1247,
"attr20": 505, "attr20": 1425,
"attr21": 154, "attr21": 154,
"attr22": 154, "attr22": 154,
"attr23": 154, "attr23": 154,
@ -241,25 +241,25 @@
"id": 8, "id": 8,
"attr0": 450, "attr0": 450,
"attr1": 236, "attr1": 236,
"attr2": 329, "attr2": 274,
"attr3": 244, "attr3": 270,
"attr4": 252, "attr4": 317,
"attr5": 261, "attr5": 373,
"attr6": 270, "attr6": 438,
"attr7": 279, "attr7": 515,
"attr8": 288, "attr8": 605,
"attr9": 298, "attr9": 711,
"attr10": 308, "attr10": 835,
"attr11": 319, "attr11": 981,
"attr12": 330, "attr12": 1153,
"attr13": 341, "attr13": 1354,
"attr14": 353, "attr14": 1591,
"attr15": 365, "attr15": 1870,
"attr16": 377, "attr16": 2197,
"attr17": 390, "attr17": 2582,
"attr18": 403, "attr18": 3033,
"attr19": 417, "attr19": 3564,
"attr20": 431, "attr20": 4275,
"attr21": 165, "attr21": 165,
"attr22": 165, "attr22": 165,
"attr23": 165, "attr23": 165,
@ -275,25 +275,25 @@
"id": 9, "id": 9,
"attr0": 656, "attr0": 656,
"attr1": 236, "attr1": 236,
"attr2": 515, "attr2": 438,
"attr3": 449, "attr3": 470,
"attr4": 477, "attr4": 564,
"attr5": 506, "attr5": 677,
"attr6": 537, "attr6": 812,
"attr7": 570, "attr7": 975,
"attr8": 605, "attr8": 1170,
"attr9": 642, "attr9": 1403,
"attr10": 682, "attr10": 1684,
"attr11": 723, "attr11": 2021,
"attr12": 768, "attr12": 2425,
"attr13": 815, "attr13": 2910,
"attr14": 865, "attr14": 3492,
"attr15": 918, "attr15": 4191,
"attr16": 975, "attr16": 5029,
"attr17": 1034, "attr17": 6034,
"attr18": 1098, "attr18": 7241,
"attr19": 1165, "attr19": 8690,
"attr20": 1237, "attr20": 12825,
"attr21": 189, "attr21": 189,
"attr22": 189, "attr22": 189,
"attr23": 189, "attr23": 189,
@ -309,25 +309,25 @@
"id": 10, "id": 10,
"attr0": 938, "attr0": 938,
"attr1": 236, "attr1": 236,
"attr2": 755, "attr2": 629,
"attr3": 665, "attr3": 720,
"attr4": 723, "attr4": 900,
"attr5": 785, "attr5": 1125,
"attr6": 853, "attr6": 1406,
"attr7": 927, "attr7": 1758,
"attr8": 1007, "attr8": 2197,
"attr9": 1095, "attr9": 2747,
"attr10": 1190, "attr10": 3433,
"attr11": 1293, "attr11": 4292,
"attr12": 1405, "attr12": 5364,
"attr13": 1526, "attr13": 6706,
"attr14": 1658, "attr14": 8382,
"attr15": 1802, "attr15": 10477,
"attr16": 1958, "attr16": 13097,
"attr17": 2128, "attr17": 16371,
"attr18": 2312, "attr18": 20464,
"attr19": 2512, "attr19": 25580,
"attr20": 2730, "attr20": 38475,
"attr21": 118, "attr21": 118,
"attr22": 118, "attr22": 118,
"attr23": 118, "attr23": 118,
@ -343,25 +343,25 @@
"id": 11, "id": 11,
"attr0": 1296, "attr0": 1296,
"attr1": 236, "attr1": 236,
"attr2": 755, "attr2": 629,
"attr3": 891, "attr3": 960,
"attr4": 1007, "attr4": 1268,
"attr5": 1138, "attr5": 1674,
"attr6": 1286, "attr6": 2210,
"attr7": 1453, "attr7": 2918,
"attr8": 1642, "attr8": 3853,
"attr9": 1855, "attr9": 5088,
"attr10": 2097, "attr10": 6718,
"attr11": 2369, "attr11": 8870,
"attr12": 2677, "attr12": 11713,
"attr13": 3026, "attr13": 15465,
"attr14": 3419, "attr14": 20421,
"attr15": 3864, "attr15": 26964,
"attr16": 4366, "attr16": 35603,
"attr17": 4934, "attr17": 47011,
"attr18": 5576, "attr18": 62074,
"attr19": 6301, "attr19": 81963,
"attr20": 7120, "attr20": 115425,
"attr21": 175, "attr21": 175,
"attr22": 184, "attr22": 184,
"attr23": 184, "attr23": 184,
@ -377,25 +377,25 @@
"id": 12, "id": 12,
"attr0": 1620, "attr0": 1620,
"attr1": 236, "attr1": 236,
"attr2": 755, "attr2": 629,
"attr3": 996, "attr3": 1068,
"attr4": 1178, "attr4": 1407,
"attr5": 1394, "attr5": 1854,
"attr6": 1649, "attr6": 2443,
"attr7": 1951, "attr7": 3219,
"attr8": 2308, "attr8": 4241,
"attr9": 2731, "attr9": 5588,
"attr10": 3231, "attr10": 7363,
"attr11": 3823, "attr11": 9702,
"attr12": 4522, "attr12": 12783,
"attr13": 5350, "attr13": 16843,
"attr14": 6330, "attr14": 22193,
"attr15": 7489, "attr15": 29241,
"attr16": 8860, "attr16": 38529,
"attr17": 10482, "attr17": 50766,
"attr18": 12401, "attr18": 66889,
"attr19": 14671, "attr19": 88133,
"attr20": 17357, "attr20": 112219,
"attr21": 212, "attr21": 212,
"attr22": 221, "attr22": 221,
"attr23": 221, "attr23": 221,

@ -12,6 +12,7 @@ export class Physics2DGate {
private static _reasons = new Set<string>(); private static _reasons = new Set<string>();
static readonly VideoAd = 'videoAd'; static readonly VideoAd = 'videoAd';
static readonly ViewportResize = 'viewportResize';
static suspend(reason: string): void { static suspend(reason: string): void {
if (!reason) return; if (!reason) return;

@ -1849,6 +1849,13 @@ declare global {
@ -2603,6 +2610,13 @@ declare global {

@ -343,6 +343,7 @@ export class SDKManager extends Singleton {
console.log("onPfShow", res); console.log("onPfShow", res);
this.query = res.query; this.query = res.query;
this._show_time = new Date().getTime(); this._show_time = new Date().getTime();
gg.game?.CurentBattle?.TetraMap?.stabilizeAfterViewportChange?.();
//this._restoreVideoAdRuntimeOnForeground(); //this._restoreVideoAdRuntimeOnForeground();
if (this._onShare) { if (this._onShare) {
let t = new Date().getTime() - this._share_time; let t = new Date().getTime() - this._share_time;

@ -183,6 +183,26 @@ export class role extends Component {
} }
} }
/**
* ui_roleLayer PiP
*/
public static refreshFollowOffsetsAfterViewportChange(): void {
const layer = gg?.game?.CurentBattle?.ui_roleLayer;
if (!layer?.isValid) return;
const list = layer.getComponentsInChildren(role);
for (let i = 0; i < list.length; i++) {
list[i].refreshFollowOffset();
}
}
/** 重算已挂到 roleLayer 的跟随偏移 */
public refreshFollowOffset(): void {
const target = this.followTarget;
if (!target?.isValid || !this._movedToRoleLayer) return;
Mat4.invert(this._matInv, target.worldMatrix);
Vec3.transformMat4(this._offsetInTargetSpace, this.node.worldPosition, this._matInv);
}
private _destroySelf(): void { private _destroySelf(): void {
if (isValid(this.node)) this.node.destroy(); if (isValid(this.node)) this.node.destroy();
} }

@ -36,6 +36,13 @@ export class tetriAbility extends Component {
this.setView() this.setView()
} }
/** 放置到战场:无独立角色节点,补一次清理与数值刷新 */
ensureBattleReady(): void {
if (!this._config) return;
this._removeLegacyRoleNodes();
this.setView();
}
start() { start() {
this._removeLegacyRoleNodes() this._removeLegacyRoleNodes()
if (this._config) { if (this._config) {

@ -202,6 +202,26 @@ export class tetriFloorNode extends Component {
} }
} }
/**
* Canvas/floor RigidBody2D PolygonCollider2D Dynamic
* 姿 Box2D穿
*/
public refreshPhysicsCollidersAfterViewportChange(): void {
if (!this.node?.isValid || !this._settled) return;
this._ensureFloorCollidersSolidNoBounce();
const cols = this.node.getComponentsInChildren(PolygonCollider2D) ?? [];
for (let i = 0; i < cols.length; i++) {
const c = cols[i];
if (!c?.isValid) continue;
const was = c.enabled;
c.enabled = false;
c.enabled = was;
if (typeof c.apply === 'function') c.apply();
}
const p = this.node.position;
this.node.setPosition(p.x, p.y, p.z);
}
/**触摸推动:仅在脚本下落期生效(与 tetriMap 的触摸控制配合) */ /**触摸推动:仅在脚本下落期生效(与 tetriMap 的触摸控制配合) */
public applySimTouchPush(dir: number, deltaVelX: number, maxVelX: number): void { public applySimTouchPush(dir: number, deltaVelX: number, maxVelX: number): void {
if (!this.isSimFalling) return; if (!this.isSimFalling) return;

@ -1305,6 +1305,57 @@ export class tetriNode extends Component {
return this.node.getComponent(RigidBody2D) ?? this.node.getComponentInChildren(RigidBody2D); return this.node.getComponent(RigidBody2D) ?? this.node.getComponentInChildren(RigidBody2D);
} }
/**
* /Canvas Box2D
* rb.enabled /
*/
public syncRigidBodyPoseFromNode(zeroLinearVel = true): void {
const rb = this._getMainRigidBody();
if (!rb?.isValid || !this.node?.isValid) return;
const savedVy = rb.linearVelocity.y;
const savedVx = rb.linearVelocity.x;
this._pushNodeTransformToPhysics(rb);
if (this._physicsFrozen) {
rb.type = ERigidBody2DType.Static;
rb.gravityScale = 0;
rb.fixedRotation = true;
rb.allowSleep = true;
}
rb.angularVelocity = 0;
if (zeroLinearVel) {
rb.linearVelocity = new Vec2(0, 0);
} else {
rb.linearVelocity = new Vec2(savedVx, savedVy);
}
this._coldRefreshCollidersOnNode(this.node);
}
private _coldRefreshCollidersOnNode(root: Node): void {
const cols = root.getComponentsInChildren(PolygonCollider2D) ?? [];
for (let i = 0; i < cols.length; i++) {
const col = cols[i];
if (!col?.isValid) continue;
const was = col.enabled;
col.enabled = false;
col.enabled = was;
if (typeof col.apply === 'function') col.apply();
}
}
/** 把当前节点世界姿态写入 Box2D(不移动节点) */
private _pushNodeTransformToPhysics(rb: RigidBody2D): void {
const body = (rb as { _body?: { syncPositionToPhysics?: (resetVel?: boolean) => void } })._body;
if (body?.syncPositionToPhysics) {
body.syncPositionToPhysics(false);
return;
}
const p = this.node.position;
this.node.setPosition(p.x, p.y, p.z);
}
/** 两方块碰撞体是否有真实重叠(可选贴边小间隙兜底) */ /** 两方块碰撞体是否有真实重叠(可选贴边小间隙兜底) */
private _hasPhysicalOverlapWith(otherRoot: Node): boolean { private _hasPhysicalOverlapWith(otherRoot: Node): boolean {
const a = this._unionWorldAabb(this._getAllColliders2D(this.node)); const a = this._unionWorldAabb(this._getAllColliders2D(this.node));

@ -61,6 +61,10 @@ export class tetriWeaponCarrier extends Component {
initRoleFacing: number = 0; initRoleFacing: number = 0;
initRoleFacingFix: number = 0; initRoleFacingFix: number = 0;
private roleBaseAbsScaleX: number = 1; private roleBaseAbsScaleX: number = 1;
/** 武器异步加载序号,丢弃过期回调 */
private _weaponLoadSeq = 0;
/** 武器异步加载中,避免 initCarrier / ensureBattleReady 并发重复挂载 */
private _weaponLoading = false;
_isBattleScene = false //是否是战斗场景相机 _isBattleScene = false //是否是战斗场景相机
_isCanShoot = true //是否可以射击 _isCanShoot = true //是否可以射击
@ -94,7 +98,8 @@ export class tetriWeaponCarrier extends Component {
this.applyBlockWeaponVisual(conf); this.applyBlockWeaponVisual(conf);
} }
this._isCanShoot = true; this._isCanShoot = true;
if (!this.weaponNode?.isValid) { this._syncWeaponNodeFromMount();
if (!this.weaponNode?.isValid && !this._weaponLoading) {
this.setView(); this.setView();
} }
} }
@ -117,6 +122,8 @@ export class tetriWeaponCarrier extends Component {
gg.game?.CurentBattle?.pruneDetachedBattleLayers?.(block); gg.game?.CurentBattle?.pruneDetachedBattleLayers?.(block);
const weapon = this.weaponNode; const weapon = this.weaponNode;
this.weaponNode = null; this.weaponNode = null;
this._weaponLoadSeq++;
this._weaponLoading = false;
if (this.timeoutIndex) clearTimeout(this.timeoutIndex as unknown as number); if (this.timeoutIndex) clearTimeout(this.timeoutIndex as unknown as number);
GEvent.Ins.off(GEvent.ChangeCubeWeaponConfig, this.ChangeCubeWeapon, this) GEvent.Ins.off(GEvent.ChangeCubeWeaponConfig, this.ChangeCubeWeapon, this)
GEvent.Ins.off(GEvent.StraightWeaponShoot, this.StraightWeaponShoot, this) GEvent.Ins.off(GEvent.StraightWeaponShoot, this.StraightWeaponShoot, this)
@ -156,6 +163,38 @@ export class tetriWeaponCarrier extends Component {
return find('武器', this.node); return find('武器', this.node);
} }
/** 挂点上已有武器但 weaponNode 未同步(instantiate 克隆常见)时对齐引用并去掉多余实例 */
private _syncWeaponNodeFromMount(): void {
const mount = this.getWeaponMountNode();
if (!mount?.isValid) return;
const kids = mount.children.filter((c) => c?.isValid);
if (kids.length === 0) {
if (!this.weaponNode?.isValid) this.weaponNode = null;
return;
}
if (this.weaponNode?.isValid && kids.indexOf(this.weaponNode) >= 0) {
for (let i = 0; i < kids.length; i++) {
if (kids[i] !== this.weaponNode) this.safePutPoolNode(kids[i]);
}
return;
}
this.weaponNode = kids[0];
for (let i = 1; i < kids.length; i++) {
this.safePutPoolNode(kids[i]);
}
}
/** 清空挂点上动态加载的武器(保留挂点节点本身) */
private _clearWeaponMountChildren(): void {
const mount = this.getWeaponMountNode();
if (!mount?.isValid) return;
const kids = mount.children.slice();
for (let i = 0; i < kids.length; i++) {
this.safePutPoolNode(kids[i]);
}
this.weaponNode = null;
}
/** 武器预制体 Spine(动画在子节点 spine 上) */ /** 武器预制体 Spine(动画在子节点 spine 上) */
private getWeaponSkeleton(weaponNode: Node | null): sp.Skeleton | null { private getWeaponSkeleton(weaponNode: Node | null): sp.Skeleton | null {
if (!weaponNode?.isValid) return null; if (!weaponNode?.isValid) return null;
@ -221,6 +260,10 @@ export class tetriWeaponCarrier extends Component {
if (conf2.handName) applyRoleHand(this.node, conf2.handName); if (conf2.handName) applyRoleHand(this.node, conf2.handName);
this.applyBlockWeaponVisual(conf2); this.applyBlockWeaponVisual(conf2);
} }
this._syncWeaponNodeFromMount();
if (this.weaponNode?.isValid || this._weaponLoading) return;
// 战场方块由 ensureBattleReady 负责补武器,避免与 initCarrier 重复加载
if (this._isBattleScene) return;
this.setView(); this.setView();
}, 0.1); }, 0.1);
} }
@ -279,6 +322,8 @@ export class tetriWeaponCarrier extends Component {
console.error('[tetriWeaponCarrier] setView: 武器表无数据 weaponId=', this._curentWeaponId, this._config?.cubename); console.error('[tetriWeaponCarrier] setView: 武器表无数据 weaponId=', this._curentWeaponId, this._config?.cubename);
return; return;
} }
this._syncWeaponNodeFromMount();
if (this.weaponNode?.isValid || this._weaponLoading) return;
this.addWeapon(conf.weaponani); this.addWeapon(conf.weaponani);
//this.changeIcon(conf.typeicon); //this.changeIcon(conf.typeicon);
} }
@ -357,9 +402,9 @@ export class tetriWeaponCarrier extends Component {
} }
changeWeapon(weaponani) { changeWeapon(weaponani) {
const old = this.weaponNode; this._weaponLoadSeq++;
this.weaponNode = null; this._weaponLoading = false;
this.safePutPoolNode(old); this._clearWeaponMountChildren();
this.addWeapon(weaponani) this.addWeapon(weaponani)
} }
@ -370,13 +415,22 @@ export class tetriWeaponCarrier extends Component {
console.error('[tetriWeaponCarrier] addWeapon: 未找到方块/武器', this._config?.cubename); console.error('[tetriWeaponCarrier] addWeapon: 未找到方块/武器', this._config?.cubename);
return; return;
} }
if (this._weaponLoading) return;
this._weaponLoading = true;
const loadSeq = ++this._weaponLoadSeq;
void gg.res.getNodeAsync('prefab/', weaponani, GBundle.tetriWeapon).then((weaponNode) => { void gg.res.getNodeAsync('prefab/', weaponani, GBundle.tetriWeapon).then((weaponNode) => {
this._weaponLoading = false;
if (loadSeq !== this._weaponLoadSeq) {
this.safePutPoolNode(weaponNode);
return;
}
if (!weaponNode?.isValid || !wuqiNode?.isValid) { if (!weaponNode?.isValid || !wuqiNode?.isValid) {
if (!weaponNode) { if (!weaponNode) {
console.error('[tetriWeaponCarrier] addWeapon: 武器预制未取到', weaponani, this._config?.cubename); console.error('[tetriWeaponCarrier] addWeapon: 武器预制未取到', weaponani, this._config?.cubename);
} }
return; return;
} }
this._clearWeaponMountChildren();
this.setLayerMask(weaponNode, wuqiNode.layer); this.setLayerMask(weaponNode, wuqiNode.layer);
this.weaponNode = weaponNode; this.weaponNode = weaponNode;
weaponNode.setParent(wuqiNode); weaponNode.setParent(wuqiNode);

@ -2,6 +2,7 @@ import { _decorator, Camera, Collider2D, Component, Contact2DType, Director, ERi
import { tetriNode } from '../tetriCard/tetriNode'; import { tetriNode } from '../tetriCard/tetriNode';
import { tetriFloorNode } from '../tetriCard/tetriFloorNode'; import { tetriFloorNode } from '../tetriCard/tetriFloorNode';
import { tetriWeaponCarrier } from '../tetriCard/tetriWeaponCarrier'; import { tetriWeaponCarrier } from '../tetriCard/tetriWeaponCarrier';
import { role } from '../tetriCard/role';
import { TetriType } from '../game/ConfigProjectData'; import { TetriType } from '../game/ConfigProjectData';
import { GEvent } from '../../mx/module/event/GEvent'; import { GEvent } from '../../mx/module/event/GEvent';
import { StatusType } from '../game/GameData'; import { StatusType } from '../game/GameData';
@ -132,7 +133,7 @@ export class tetriMap extends Component {
highLineFollowSpeed: number = 10; highLineFollowSpeed: number = 10;
/**缩放目标(镜头拉远;背景/地面 Sprite 用 1/scale 补偿铺满视口) */ /**缩放目标(镜头拉远;背景/地面 Sprite 用 1/scale 补偿铺满视口) */
private _scaleTarget: number = 1; private _scaleTarget: number = 1;
/** 设计分辨率高度变化时短暂停物理 */ /** 设计分辨率高度变化后等待布局再同步刚体 */
private _physicsStabilizeScheduled = false; private _physicsStabilizeScheduled = false;
private _lastDesignHeight = 0; private _lastDesignHeight = 0;
/** 游戏相机(通过 UIManager 注入) */ /** 游戏相机(通过 UIManager 注入) */
@ -366,6 +367,7 @@ export class tetriMap extends Component {
this._cameraTargetOrthoHeight = this._designHalfHeight; this._cameraTargetOrthoHeight = this._designHalfHeight;
this._cameraTargetY = cam.node.position.y; this._cameraTargetY = cam.node.position.y;
this._cameraTargetZ = cam.node.position.z; this._cameraTargetZ = cam.node.position.z;
this._syncGameCameraToUiCamera(true);
} }
if (gg.data.doc.chapter == 1 && gg.data.getStatus(StatusType.IsShowPlayGuidePop) == 0) { if (gg.data.doc.chapter == 1 && gg.data.getStatus(StatusType.IsShowPlayGuidePop) == 0) {
@ -1230,9 +1232,11 @@ export class tetriMap extends Component {
} }
/** /**
* B 750x1334750x1600 * B
* setResolutionPolicy / syncSceneToPhysics 2 * - 750×1334 750×1600
* A + designHalfHeight * - /
* - GameCamera ortho UICamera
* - Canvas syncPositionToPhysics / rb.enabled
*/ */
private _bindViewportResize(): void { private _bindViewportResize(): void {
this._unbindViewportResize(); this._unbindViewportResize();
@ -1245,43 +1249,137 @@ export class tetriMap extends Component {
screen.off('window-resize', this._onViewportResize, this); screen.off('window-resize', this._onViewportResize, this);
} }
public stabilizeAfterViewportChange(): void {
this._onViewportResize();
}
private _onViewportResize(): void { private _onViewportResize(): void {
if (!gg.game?.isBattleContextActive?.()) return;
const designH = view.getDesignResolutionSize().height; const designH = view.getDesignResolutionSize().height;
if (!(designH > 0) || Math.abs(designH - this._lastDesignHeight) < 1) { if (!(designH > 0) || Math.abs(designH - this._lastDesignHeight) < 1) {
return; return;
} }
const oldHalf = this._designHalfHeight > 0 ? this._designHalfHeight : (this._lastDesignHeight * 0.5);
const newHalf = designH * 0.5;
if (oldHalf > 0 && this._cameraBaseOrthoHeight > 0) {
this._cameraBaseOrthoHeight *= newHalf / oldHalf;
}
this._designHalfHeight = newHalf;
this._lastDesignHeight = designH; this._lastDesignHeight = designH;
this._syncGameCameraToUiCamera(true);
this._scheduleViewportStabilize();
}
/** 设计高度变化后:GameCamera 与 UICamera 保持同一缩放比例,避免 GameRoot 横向偏移 */
private _syncGameCameraToUiCamera(snapNow = false): void {
const uiCam = gg.ui?.UICamera;
const gameCam = this._gameCamera?.isValid ? this._gameCamera : (gg.ui?.GameCamera ?? null);
if (!uiCam?.isValid || !gameCam?.isValid) return;
const uiOrtho = uiCam.orthoHeight;
const lockedHalf = this._designHalfHeight;
if (!(uiOrtho > 0) || !(lockedHalf > 0) || !(this._cameraBaseOrthoHeight > 0)) return;
const zoom = Math.max(0.05, this._scaleTarget || 1);
const gameToUi = this._cameraBaseOrthoHeight / lockedHalf;
this._cameraTargetOrthoHeight = (uiOrtho * gameToUi) / zoom;
this._cameraTargetY = (this._cameraTargetOrthoHeight - lockedHalf) / 2;
if (snapNow) {
gameCam.orthoHeight = this._cameraTargetOrthoHeight;
const p = gameCam.node.position;
gameCam.node.setPosition(p.x, this._cameraTargetY, this._cameraTargetZ);
}
}
private _scheduleViewportStabilize(): void {
if (this._physicsStabilizeScheduled) return; if (this._physicsStabilizeScheduled) return;
this._physicsStabilizeScheduled = true; this._physicsStabilizeScheduled = true;
// 不要开关全局 PhysicsSystem2D.enable:与激励视频等其它挂起互相覆盖, // 等 Canvas/Widget 布局稳定后再对齐刚体
// 会导致 enable 永久为 false → 子弹碰撞失效、怪不掉血。此处只刹速度即可。
this.scheduleOnce(() => { this.scheduleOnce(() => {
this._physicsStabilizeScheduled = false; this.scheduleOnce(() => {
if (this._tetrisTable?.isValid) { this._physicsStabilizeScheduled = false;
const rbs = this._tetrisTable.getComponentsInChildren(RigidBody2D) ?? []; this._resyncAllTetriRigidBodiesFromNodes();
for (let i = 0; i < rbs.length; i++) { this._syncGameCameraToUiCamera(true);
const rb = rbs[i]; role.refreshFollowOffsetsAfterViewportChange();
if (!rb?.isValid || rb.type !== ERigidBody2DType.Dynamic) continue; }, 0);
const t = this._findInParents(rb.node, (n) => n.getComponent(tetriNode)).comp; }, 0);
if (!t?.isSettled) continue; }
rb.linearVelocity = new Vec2(0, 0);
rb.angularVelocity = 0; /**
*
* floor RigidBody2D PolygonCollider2D
*/
private _resyncAllTetriRigidBodiesFromNodes(): void {
const visited = new Set<Node>();
const pushRb = (rb: RigidBody2D) => {
const body = (rb as { _body?: { syncPositionToPhysics?: (resetVel?: boolean) => void } })._body;
body?.syncPositionToPhysics?.(false);
};
const visit = (n: Node) => {
if (!n?.isValid || visited.has(n)) return;
visited.add(n);
const floor = n.getComponent(tetriFloorNode);
if (floor) {
if (floor.isSettled) {
floor.refreshPhysicsCollidersAfterViewportChange();
} }
return;
} }
this._updateHighLine();
if (this._gameCamera?.isValid && this._cameraTargetOrthoHeight > 0) { const tn = n.getComponent(tetriNode);
this._gameCamera.orthoHeight = this._cameraTargetOrthoHeight; const rb = n.getComponent(RigidBody2D) ?? n.getComponentInChildren(RigidBody2D);
const camPos = this._gameCamera.node.position; if (rb?.isValid) {
this._gameCamera.node.setPosition(camPos.x, this._cameraTargetY, this._cameraTargetZ); if (tn) {
const falling = !tn.isSettled && !tn.isPhysicsFrozen;
tn.syncRigidBodyPoseFromNode(!falling);
} else {
pushRb(rb);
rb.angularVelocity = 0;
if (rb.type === ERigidBody2DType.Static || rb.type === ERigidBody2DType.Kinematic) {
rb.linearVelocity = new Vec2(0, 0);
}
const cols = n.getComponentsInChildren(PolygonCollider2D) ?? [];
for (let i = 0; i < cols.length; i++) {
this._coldRefreshCollider2D(cols[i]);
}
}
} else {
const cols = n.getComponentsInChildren(PolygonCollider2D) ?? [];
for (let i = 0; i < cols.length; i++) {
this._coldRefreshCollider2D(cols[i]);
}
} }
}, 0);
const ch = n.children;
for (let i = 0; i < ch.length; i++) visit(ch[i]);
};
if (this._tetrisTable?.isValid) {
for (const child of this._tetrisTable.children) visit(child);
}
if (this.latestFallingNode?.isValid) visit(this.latestFallingNode);
if (this._floorTaizi?.isValid) visit(this._floorTaizi);
if (this._groundTable?.isValid) visit(this._groundTable);
this._refreshAllPinnedFloorsAfterViewport();
}
private _coldRefreshCollider2D(col: PolygonCollider2D): void {
if (!col?.isValid) return;
const was = col.enabled;
col.enabled = false;
col.enabled = was;
if (typeof col.apply === 'function') col.apply();
}
/** 无重力板钉住后再冷启碰撞体,并消邻域竖直冲量,避免穿透/炸塔 */
private _refreshAllPinnedFloorsAfterViewport(): void {
if (!this._tetrisTable?.isValid) return;
const floors = this._tetrisTable.getComponentsInChildren(tetriFloorNode) ?? [];
for (let i = 0; i < floors.length; i++) {
const f = floors[i];
if (!f?.isSettled || !f.node?.isValid) continue;
f.refreshPhysicsCollidersAfterViewportChange();
this._dampDynamicsNearFloorRegionImpl(f.node, 3, false);
}
} }
private _resizeUIForScale(curScale: number): void { private _resizeUIForScale(curScale: number): void {
@ -1734,7 +1832,10 @@ export class tetriMap extends Component {
} }
if (this._gameCamera?.isValid && this._cameraBaseOrthoHeight > 0) { if (this._gameCamera?.isValid && this._cameraBaseOrthoHeight > 0) {
const halfH = this._designHalfHeight > 0 ? this._designHalfHeight : (gg.ui.height / 2); const halfH = this._designHalfHeight > 0 ? this._designHalfHeight : (gg.ui.height / 2);
this._cameraTargetOrthoHeight = this._cameraBaseOrthoHeight / this._scaleTarget; const zoom = Math.max(0.05, this._scaleTarget || 1);
const uiOrtho = gg.ui?.UICamera?.orthoHeight;
const gameToUi = this._cameraBaseOrthoHeight / Math.max(1, halfH);
this._cameraTargetOrthoHeight = (uiOrtho > 0 ? uiOrtho * gameToUi : this._cameraBaseOrthoHeight) / zoom;
this._cameraTargetY = (this._cameraTargetOrthoHeight - halfH) / 2; this._cameraTargetY = (this._cameraTargetOrthoHeight - halfH) / 2;
this._cameraTargetZ = 1000; this._cameraTargetZ = 1000;
} }

@ -784,7 +784,7 @@ export class BattleCore {
void BattleResLoader.preloadBossSkillAssets(); void BattleResLoader.preloadBossSkillAssets();
} }
//如果是副本模式,并且需要随机章节地图的话,随机一个章节地图id // 副本 mapID:随机章节(地图、血量系数、机制等);出怪单独走 getMonsterSpawnChapterConfig()
if (this.CurentConfigReplica && this.CurentConfigReplica.mapID.length > 0) { if (this.CurentConfigReplica && this.CurentConfigReplica.mapID.length > 0) {
let idRange = this.CurentConfigReplica.mapID; let idRange = this.CurentConfigReplica.mapID;
let minID = idRange[0]; let minID = idRange[0];
@ -910,7 +910,7 @@ export class BattleCore {
this.CurentCoinNum = this.CurentChapterBaseCoin; this.CurentCoinNum = this.CurentChapterBaseCoin;
//确定波次 //确定波次
let monsterStr = this.CurentConfigChapter2 || this.CurentConfigChapter; let monsterStr = this.getMonsterSpawnChapterConfig();
let monster1 = monsterStr.monster1.split('|') let monster1 = monsterStr.monster1.split('|')
let monster2_1 = monsterStr.monster2_1.split('|') let monster2_1 = monsterStr.monster2_1.split('|')
//选择长度最长的 //选择长度最长的
@ -922,7 +922,6 @@ export class BattleCore {
// } // }
this.TotalWaveNum = num; this.TotalWaveNum = num;
console.log('TotalWaveNum++++++++===', this.TotalWaveNum)
// if (this.BattleType == BattleType.GachaMode) { // if (this.BattleType == BattleType.GachaMode) {
// this.WaveRefreshTime = 60 // this.WaveRefreshTime = 60
@ -990,14 +989,20 @@ export class BattleCore {
this.addCurHaveSkillArr(skillArr); this.addCurHaveSkillArr(skillArr);
} }
/** 出怪/波次用章节:无尽副本用副本 chapterID,其余优先随机章节 */
getMonsterSpawnChapterConfig(): ITableChapter {
if (this.BattleType === BattleType.InfiniteMode && this.CurentConfigChapter) {
return this.CurentConfigChapter;
}
return this.CurentConfigChapter2 || this.CurentConfigChapter;
}
/**初始化当前章节怪物总数 */ /**初始化当前章节怪物总数 */
private initTotalMonsterNum() { private initTotalMonsterNum() {
this.PerWaveSpawnNumCumulative = [] this.PerWaveSpawnNumCumulative = []
let config = this.CurentConfigChapter; let config = this.getMonsterSpawnChapterConfig();
if (this.CurentConfigChapter2)
config = this.CurentConfigChapter2;
const monsterNumScale = gg.game.monsterNumScale > 0 ? gg.game.monsterNumScale : 1 const monsterNumScale = gg.game.monsterNumScale > 0 ? gg.game.monsterNumScale : 1
let getMonster1_2Num = (monster) => { let getMonster1_2Num = (monster) => {

@ -101,8 +101,8 @@ export class MonsterSpawner extends Component {
*/ */
public initMonsterConfigs() { public initMonsterConfigs() {
this.createMonsterTimeInterval = gg.data.table.getConst(ConstNumType.DefaultMonsterInterval); this.createMonsterTimeInterval = gg.data.table.getConst(ConstNumType.DefaultMonsterInterval);
// 章节配置 // 章节配置(出怪)
let config: ITableChapter = gg.game.CurentBattle.CurentConfigChapter2 || gg.game.CurentBattle.CurentConfigChapter; let config: ITableChapter = gg.game.CurentBattle.getMonsterSpawnChapterConfig();
if(gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya){ if(gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya){
// 解析monster1配置 (1-3出怪口随机) // 解析monster1配置 (1-3出怪口随机)
@ -116,7 +116,23 @@ export class MonsterSpawner extends Component {
this.parseSpawnPointConfig(config.monster2_1, [4, 6]); this.parseSpawnPointConfig(config.monster2_1, [4, 6]);
} }
this.logSpawnConfigSummary(config);
}
/** 打印章节出怪 id 与总波次(调试用) */
private logSpawnConfigSummary(config: ITableChapter) {
const battle = gg.game.CurentBattle;
const totalWaves = battle?.TotalWaveNum ?? this.pendingByWave.length;
const randomChapterId = battle?.CurentConfigChapter2?.id ?? '-';
const waveParts: string[] = [];
for (let i = 0; i < totalWaves; i++) {
const ids = this.getMonsterIdsForWave(i);
waveParts.push(`${i + 1}[${ids.length ? ids.join(',') : '-'}]`);
}
console.log(
`[出怪配置] 随机章节=${randomChapterId} 出怪章节=${config?.id} 总波次=${totalWaves}`,
waveParts.join(' ')
);
} }
/** 指定波次(0-based)涉及的怪物 id */ /** 指定波次(0-based)涉及的怪物 id */

@ -709,6 +709,9 @@ export class UItetraGame extends Auto_tetriGame {
for (const wc of preview.getComponentsInChildren(tetriWeaponCarrier)) { for (const wc of preview.getComponentsInChildren(tetriWeaponCarrier)) {
wc.ensureBattleReady() wc.ensureBattleReady()
} }
for (const ab of preview.getComponentsInChildren(tetriAbility)) {
ab.ensureBattleReady()
}
for (const t of preview.getComponentsInChildren(tetriNode)) { for (const t of preview.getComponentsInChildren(tetriNode)) {
t.playBlockSpine(TetriBlockSpineState.Falling); t.playBlockSpine(TetriBlockSpineState.Falling);
} }

File diff suppressed because one or more lines are too long

Binary file not shown.
Loading…
Cancel
Save