优化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": "",
"barrier": "火车站锥形桶",
"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",
"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",
"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": "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_3": "",
"monster2_4": "",
@ -6651,7 +6651,7 @@
"difficult": 1,
"power": 0,
"base_coin": 100,
"monster_group": 30,
"monster_group": 13,
"hp_multiple": 19,
"atk_group": 1,
"atk_multiple": 1,

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

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

@ -12,6 +12,7 @@ export class Physics2DGate {
private static _reasons = new Set<string>();
static readonly VideoAd = 'videoAd';
static readonly ViewportResize = 'viewportResize';
static suspend(reason: string): void {
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);
this.query = res.query;
this._show_time = new Date().getTime();
gg.game?.CurentBattle?.TetraMap?.stabilizeAfterViewportChange?.();
//this._restoreVideoAdRuntimeOnForeground();
if (this._onShare) {
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 {
if (isValid(this.node)) this.node.destroy();
}

@ -36,6 +36,13 @@ export class tetriAbility extends Component {
this.setView()
}
/** 放置到战场:无独立角色节点,补一次清理与数值刷新 */
ensureBattleReady(): void {
if (!this._config) return;
this._removeLegacyRoleNodes();
this.setView();
}
start() {
this._removeLegacyRoleNodes()
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 的触摸控制配合) */
public applySimTouchPush(dir: number, deltaVelX: number, maxVelX: number): void {
if (!this.isSimFalling) return;

@ -1305,6 +1305,57 @@ export class tetriNode extends Component {
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 {
const a = this._unionWorldAabb(this._getAllColliders2D(this.node));

@ -61,6 +61,10 @@ export class tetriWeaponCarrier extends Component {
initRoleFacing: number = 0;
initRoleFacingFix: number = 0;
private roleBaseAbsScaleX: number = 1;
/** 武器异步加载序号,丢弃过期回调 */
private _weaponLoadSeq = 0;
/** 武器异步加载中,避免 initCarrier / ensureBattleReady 并发重复挂载 */
private _weaponLoading = false;
_isBattleScene = false //是否是战斗场景相机
_isCanShoot = true //是否可以射击
@ -94,7 +98,8 @@ export class tetriWeaponCarrier extends Component {
this.applyBlockWeaponVisual(conf);
}
this._isCanShoot = true;
if (!this.weaponNode?.isValid) {
this._syncWeaponNodeFromMount();
if (!this.weaponNode?.isValid && !this._weaponLoading) {
this.setView();
}
}
@ -117,6 +122,8 @@ export class tetriWeaponCarrier extends Component {
gg.game?.CurentBattle?.pruneDetachedBattleLayers?.(block);
const weapon = this.weaponNode;
this.weaponNode = null;
this._weaponLoadSeq++;
this._weaponLoading = false;
if (this.timeoutIndex) clearTimeout(this.timeoutIndex as unknown as number);
GEvent.Ins.off(GEvent.ChangeCubeWeaponConfig, this.ChangeCubeWeapon, this)
GEvent.Ins.off(GEvent.StraightWeaponShoot, this.StraightWeaponShoot, this)
@ -156,6 +163,38 @@ export class tetriWeaponCarrier extends Component {
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 上) */
private getWeaponSkeleton(weaponNode: Node | null): sp.Skeleton | null {
if (!weaponNode?.isValid) return null;
@ -221,6 +260,10 @@ export class tetriWeaponCarrier extends Component {
if (conf2.handName) applyRoleHand(this.node, conf2.handName);
this.applyBlockWeaponVisual(conf2);
}
this._syncWeaponNodeFromMount();
if (this.weaponNode?.isValid || this._weaponLoading) return;
// 战场方块由 ensureBattleReady 负责补武器,避免与 initCarrier 重复加载
if (this._isBattleScene) return;
this.setView();
}, 0.1);
}
@ -279,6 +322,8 @@ export class tetriWeaponCarrier extends Component {
console.error('[tetriWeaponCarrier] setView: 武器表无数据 weaponId=', this._curentWeaponId, this._config?.cubename);
return;
}
this._syncWeaponNodeFromMount();
if (this.weaponNode?.isValid || this._weaponLoading) return;
this.addWeapon(conf.weaponani);
//this.changeIcon(conf.typeicon);
}
@ -357,9 +402,9 @@ export class tetriWeaponCarrier extends Component {
}
changeWeapon(weaponani) {
const old = this.weaponNode;
this.weaponNode = null;
this.safePutPoolNode(old);
this._weaponLoadSeq++;
this._weaponLoading = false;
this._clearWeaponMountChildren();
this.addWeapon(weaponani)
}
@ -370,13 +415,22 @@ export class tetriWeaponCarrier extends Component {
console.error('[tetriWeaponCarrier] addWeapon: 未找到方块/武器', this._config?.cubename);
return;
}
if (this._weaponLoading) return;
this._weaponLoading = true;
const loadSeq = ++this._weaponLoadSeq;
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) {
console.error('[tetriWeaponCarrier] addWeapon: 武器预制未取到', weaponani, this._config?.cubename);
}
return;
}
this._clearWeaponMountChildren();
this.setLayerMask(weaponNode, wuqiNode.layer);
this.weaponNode = weaponNode;
weaponNode.setParent(wuqiNode);

@ -2,6 +2,7 @@ import { _decorator, Camera, Collider2D, Component, Contact2DType, Director, ERi
import { tetriNode } from '../tetriCard/tetriNode';
import { tetriFloorNode } from '../tetriCard/tetriFloorNode';
import { tetriWeaponCarrier } from '../tetriCard/tetriWeaponCarrier';
import { role } from '../tetriCard/role';
import { TetriType } from '../game/ConfigProjectData';
import { GEvent } from '../../mx/module/event/GEvent';
import { StatusType } from '../game/GameData';
@ -132,7 +133,7 @@ export class tetriMap extends Component {
highLineFollowSpeed: number = 10;
/**缩放目标(镜头拉远;背景/地面 Sprite 用 1/scale 补偿铺满视口) */
private _scaleTarget: number = 1;
/** 设计分辨率高度变化时短暂停物理 */
/** 设计分辨率高度变化后等待布局再同步刚体 */
private _physicsStabilizeScheduled = false;
private _lastDesignHeight = 0;
/** 游戏相机(通过 UIManager 注入) */
@ -366,6 +367,7 @@ export class tetriMap extends Component {
this._cameraTargetOrthoHeight = this._designHalfHeight;
this._cameraTargetY = cam.node.position.y;
this._cameraTargetZ = cam.node.position.z;
this._syncGameCameraToUiCamera(true);
}
if (gg.data.doc.chapter == 1 && gg.data.getStatus(StatusType.IsShowPlayGuidePop) == 0) {
@ -1230,9 +1232,11 @@ export class tetriMap extends Component {
}
/**
* B 750x1334750x1600
* setResolutionPolicy / syncSceneToPhysics 2
* A + designHalfHeight
* B
* - 750×1334 750×1600
* - /
* - GameCamera ortho UICamera
* - Canvas syncPositionToPhysics / rb.enabled
*/
private _bindViewportResize(): void {
this._unbindViewportResize();
@ -1245,43 +1249,137 @@ export class tetriMap extends Component {
screen.off('window-resize', this._onViewportResize, this);
}
public stabilizeAfterViewportChange(): void {
this._onViewportResize();
}
private _onViewportResize(): void {
if (!gg.game?.isBattleContextActive?.()) return;
const designH = view.getDesignResolutionSize().height;
if (!(designH > 0) || Math.abs(designH - this._lastDesignHeight) < 1) {
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._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;
this._physicsStabilizeScheduled = true;
// 不要开关全局 PhysicsSystem2D.enable:与激励视频等其它挂起互相覆盖,
// 会导致 enable 永久为 false → 子弹碰撞失效、怪不掉血。此处只刹速度即可。
// 等 Canvas/Widget 布局稳定后再对齐刚体
this.scheduleOnce(() => {
this._physicsStabilizeScheduled = false;
if (this._tetrisTable?.isValid) {
const rbs = this._tetrisTable.getComponentsInChildren(RigidBody2D) ?? [];
for (let i = 0; i < rbs.length; i++) {
const rb = rbs[i];
if (!rb?.isValid || rb.type !== ERigidBody2DType.Dynamic) continue;
const t = this._findInParents(rb.node, (n) => n.getComponent(tetriNode)).comp;
if (!t?.isSettled) continue;
rb.linearVelocity = new Vec2(0, 0);
rb.angularVelocity = 0;
this.scheduleOnce(() => {
this._physicsStabilizeScheduled = false;
this._resyncAllTetriRigidBodiesFromNodes();
this._syncGameCameraToUiCamera(true);
role.refreshFollowOffsetsAfterViewportChange();
}, 0);
}, 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) {
this._gameCamera.orthoHeight = this._cameraTargetOrthoHeight;
const camPos = this._gameCamera.node.position;
this._gameCamera.node.setPosition(camPos.x, this._cameraTargetY, this._cameraTargetZ);
const tn = n.getComponent(tetriNode);
const rb = n.getComponent(RigidBody2D) ?? n.getComponentInChildren(RigidBody2D);
if (rb?.isValid) {
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 {
@ -1734,7 +1832,10 @@ export class tetriMap extends Component {
}
if (this._gameCamera?.isValid && this._cameraBaseOrthoHeight > 0) {
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._cameraTargetZ = 1000;
}

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

@ -101,8 +101,8 @@ export class MonsterSpawner extends Component {
*/
public initMonsterConfigs() {
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){
// 解析monster1配置 (1-3出怪口随机)
@ -116,7 +116,23 @@ export class MonsterSpawner extends Component {
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 */

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

File diff suppressed because one or more lines are too long

Binary file not shown.
Loading…
Cancel
Save