main
chenanghui 1 week ago
parent 0423f441b9
commit f227e8ec38
  1. 9
      assets/bundles/tetriCards/350.meta
  2. 9
      assets/bundles/tetriCards/350/247.meta
  3. 9
      assets/bundles/tetriCards/350/247/222.meta
  4. 9
      assets/bundles/tetriCards/350/247/222/350.meta
  5. 9
      assets/bundles/tetriCards/350/247/222/350/211.meta
  6. 9
      assets/bundles/tetriCards/350/247/222/350/211/262.meta
  7. 9
      assets/bundles/tetriCards/350/247/222/350/211/262/350.meta
  8. 9
      assets/bundles/tetriCards/350/247/222/350/211/262/350/247.meta
  9. 9
      assets/bundles/tetriCards/350/247/222/350/211/262/350/247/222.meta
  10. 9
      assets/bundles/tetriCards/350/247/222/350/211/262/350/247/222/350.meta
  11. 9
      assets/bundles/tetriCards/350/247/222/350/211/262/350/247/222/350/211.meta
  12. 9
      assets/bundles/tetriCards/prefab/Tetris_att_.meta
  13. 9
      assets/bundles/tetriCards/prefab/Tetris_att_/345.meta
  14. 9
      assets/bundles/tetriCards/prefab/Tetris_att_/345/207.meta
  15. 2
      assets/bundles/tetriCards/prefab/Tetris_att_凸_2.prefab
  16. 38
      assets/script/interface/AutoTable.ts
  17. 1
      assets/script/tetriCard/roleHand.ts
  18. 316
      assets/script/tetriCard/tetriWeaponCarrier.ts
  19. 2
      settings/v2/packages/builder.json

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "89ba5527-a4bc-4f98-ae19-3481f1826cde",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "c59b5b7e-8124-41d7-99c5-0969b1add3f5",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "73b68213-4cf6-475e-8af6-968f2ba09ee6",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "37070032-98df-45ee-9d01-ba2ae312ceeb",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "32fdb07e-4eb0-4554-96d4-97f4d091d20d",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "36e9edf0-83e5-4fe2-9ceb-f560b5f29872",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "6648ada5-6888-413e-8a1f-fbe9e656b61c",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "779b37b5-3343-4832-b159-ce92093e9c57",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "8d5cc47d-eed7-45bb-9068-654989fe43b5",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "9f9e53df-8358-4def-b1a6-9c5aee425e6b",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "68aba59a-bced-47c3-8469-9af98a71aff5",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "e37a83f0-fae9-4ddc-8aa9-bb2d501431eb",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "8aeca904-16b7-49bd-b956-89452d06bbd3",
"files": [],
"subMetas": {},
"userData": {}
}

@ -1,9 +0,0 @@
{
"ver": "1.2.0",
"importer": "directory",
"imported": true,
"uuid": "f6e568b9-a1e6-48af-9543-c53fbbc035c1",
"files": [],
"subMetas": {},
"userData": {}
}

@ -198,7 +198,7 @@
"__expectedType__": "sp.SkeletonData" "__expectedType__": "sp.SkeletonData"
}, },
"defaultSkin": "default", "defaultSkin": "default",
"defaultAnimation": "", "defaultAnimation": "<None>",
"_premultipliedAlpha": true, "_premultipliedAlpha": true,
"_timeScale": 1, "_timeScale": 1,
"_preCacheMode": 0, "_preCacheMode": 0,

@ -107,6 +107,7 @@ declare global {
/** 奖励 */ /** 奖励 */
readonly reward: string; readonly reward: string;
} }
/** /**
* Box * Box
*/ */
@ -130,6 +131,7 @@ declare global {
id, */ id, */
readonly fragment: string; readonly fragment: string;
} }
/** /**
* Shop * Shop
*/ */
@ -153,6 +155,7 @@ declare global {
/** 权重 */ /** 权重 */
readonly weight: number; readonly weight: number;
} }
/** /**
* Const * Const
*/ */
@ -168,6 +171,7 @@ declare global {
/** 组 */ /** 组 */
readonly constString: string; readonly constString: string;
} }
/** /**
* Monster * Monster
*/ */
@ -269,6 +273,7 @@ declare global {
/** 难度28 */ /** 难度28 */
readonly attr28: number; readonly attr28: number;
} }
/** /**
* Skill * Skill
*/ */
@ -470,6 +475,7 @@ declare global {
*/ */
readonly fall_effect: string; readonly fall_effect: string;
} }
/** /**
* NewYearSign * NewYearSign
*/ */
@ -483,6 +489,7 @@ declare global {
/** 道具id,数量 */ /** 道具id,数量 */
readonly reward: string; readonly reward: string;
} }
/** /**
* Weapon2 * Weapon2
*/ */
@ -628,6 +635,7 @@ declare global {
/** 升级道具数 */ /** 升级道具数 */
readonly item_num4: number; readonly item_num4: number;
} }
/** /**
* Task * Task
*/ */
@ -661,6 +669,7 @@ declare global {
4 */ 4 */
readonly location: string; readonly location: string;
} }
/** /**
* TaskReward * TaskReward
*/ */
@ -681,6 +690,7 @@ declare global {
/** 数量 */ /** 数量 */
readonly quantity: number; readonly quantity: number;
} }
/** /**
* Chapter * Chapter
*/ */
@ -903,6 +913,7 @@ declare global {
/** 出现权重 */ /** 出现权重 */
readonly weight: number; readonly weight: number;
} }
/** /**
* Sign * Sign
*/ */
@ -912,6 +923,7 @@ declare global {
/** 类型,道具id,数量 */ /** 类型,道具id,数量 */
readonly reward: string; readonly reward: string;
} }
/** /**
* Role * Role
*/ */
@ -955,6 +967,7 @@ declare global {
/** 金币消耗系数3 */ /** 金币消耗系数3 */
readonly coefficient_coin3: number; readonly coefficient_coin3: number;
} }
/** /**
* Character * Character
*/ */
@ -976,6 +989,7 @@ declare global {
/** 数量 */ /** 数量 */
readonly num: number; readonly num: number;
} }
/** /**
* lang_cn * lang_cn
*/ */
@ -998,6 +1012,7 @@ declare global {
/** 英文 */ /** 英文 */
readonly en: string; readonly en: string;
} }
/** /**
* Lottery * Lottery
*/ */
@ -1033,6 +1048,7 @@ declare global {
/** 首次权重 */ /** 首次权重 */
readonly weight: string; readonly weight: string;
} }
/** /**
* Item * Item
*/ */
@ -1093,6 +1109,7 @@ declare global {
/** 字段说明 */ /** 字段说明 */
readonly reward: string; readonly reward: string;
} }
/** /**
* LimitActivity * LimitActivity
*/ */
@ -1118,6 +1135,7 @@ declare global {
/** 活动未开始的提示文字 */ /** 活动未开始的提示文字 */
readonly tips: string; readonly tips: string;
} }
/** /**
* Obstacle * Obstacle
*/ */
@ -1844,6 +1862,9 @@ declare global {
@ -2050,7 +2071,6 @@ declare global {
/** 解锁弹出描述 */ /** 解锁弹出描述 */
readonly popDesc: string; readonly popDesc: string;
} }
/** /**
* Replica * Replica
*/ */
@ -2105,6 +2125,7 @@ declare global {
/** 排序 */ /** 排序 */
readonly sort: number; readonly sort: number;
} }
/** /**
* Playmode * Playmode
*/ */
@ -2140,6 +2161,7 @@ declare global {
/** 参数2 */ /** 参数2 */
readonly par2: string; readonly par2: string;
} }
/** /**
* TarTask * TarTask
*/ */
@ -2162,6 +2184,7 @@ declare global {
/** 跳转 */ /** 跳转 */
readonly jumpto: number; readonly jumpto: number;
} }
/** /**
* Skin * Skin
*/ */
@ -2207,7 +2230,6 @@ declare global {
/** 升级属性 */ /** 升级属性 */
readonly upattr: string; readonly upattr: string;
} }
/** /**
* Pet * Pet
*/ */
@ -2307,7 +2329,6 @@ declare global {
/** 权重 */ /** 权重 */
readonly hight: number; readonly hight: number;
} }
/** /**
* StoryComic * StoryComic
*/ */
@ -2331,6 +2352,7 @@ declare global {
/** 引导 */ /** 引导 */
readonly guide: number; readonly guide: number;
} }
/** /**
* Guide * Guide
*/ */
@ -2352,7 +2374,6 @@ declare global {
/** 描述(部分引导需要展示的文字提示内容) */ /** 描述(部分引导需要展示的文字提示内容) */
readonly desc: string; readonly desc: string;
} }
/** /**
* Skill_pool * Skill_pool
*/ */
@ -2426,7 +2447,6 @@ declare global {
/** 181-240 */ /** 181-240 */
readonly refresh_game_time4: string; readonly refresh_game_time4: string;
} }
/** /**
* Const_weight * Const_weight
*/ */
@ -2440,6 +2460,7 @@ declare global {
/** 组 */ /** 组 */
readonly constString: string; readonly constString: string;
} }
/** /**
* chapter_reward * chapter_reward
*/ */
@ -2450,7 +2471,6 @@ declare global {
id, */ id, */
readonly reward: string; readonly reward: string;
} }
/** /**
* zombie * zombie
*/ */
@ -2482,6 +2502,7 @@ declare global {
/** 升级奖励 */ /** 升级奖励 */
readonly levelRewardNum: string; readonly levelRewardNum: string;
} }
/** /**
* Gift * Gift
*/ */
@ -2491,7 +2512,6 @@ declare global {
/** 类型,道具id,数量 */ /** 类型,道具id,数量 */
readonly reward: string; readonly reward: string;
} }
/** /**
* BattleCube * BattleCube
*/ */
@ -2540,7 +2560,6 @@ declare global {
/** 权重 */ /** 权重 */
readonly typeweight4: string; readonly typeweight4: string;
} }
/** /**
* ReplicaLevel * ReplicaLevel
*/ */
@ -2593,6 +2612,9 @@ declare global {

@ -65,7 +65,6 @@ export function applyRoleHand(hostNode: Node | null, handName?: string): void {
hideRoleAnim(hostNode); hideRoleAnim(hostNode);
const handNode = hostNode.getChildByName('hand'); const handNode = hostNode.getChildByName('hand');
if (!handNode?.isValid) { if (!handNode?.isValid) {
console.warn('[roleHand] 方块缺少 hand 子节点');
return; return;
} }

@ -1,5 +1,4 @@
import { _decorator, Component, find, isValid, Layers, Node, sp, UITransform, v3, Vec3 } from 'cc'; import { _decorator, Component, find, isValid, Layers, Node, sp, UITransform, v3, Vec3 } from 'cc';
import { SpriteLoad } from '../../mx/components/SpriteLoad';
import { GBundle, GPath } from '../game/ConfigRes'; import { GBundle, GPath } from '../game/ConfigRes';
import { shootPoint } from './shootPoint'; import { shootPoint } from './shootPoint';
import { GEvent } from '../../mx/module/event/GEvent'; import { GEvent } from '../../mx/module/event/GEvent';
@ -8,7 +7,8 @@ import { IWeaponProperty, SpecialSkillType } from '../ui/BattleGame/BattleDataMa
import { Skill } from '../ui/BattleGame/WeaponSkill/Skill'; import { Skill } from '../ui/BattleGame/WeaponSkill/Skill';
import { LaserLine } from '../ui/BattleGame/WeaponSkill/LaserLine'; import { LaserLine } from '../ui/BattleGame/WeaponSkill/LaserLine';
import { tetriNode } from './tetriNode'; import { tetriNode } from './tetriNode';
import { role } from './role'; import { applyRoleHand } from './roleHand';
import MTools from '../../mx/tools/MTools';
import { WeaponType } from '../manager/WeaponDataManager'; import { WeaponType } from '../manager/WeaponDataManager';
import { BattleType } from '../manager/ChapterDataManager'; import { BattleType } from '../manager/ChapterDataManager';
import { UILayer } from '../../mx/module/ui/UIManager'; import { UILayer } from '../../mx/module/ui/UIManager';
@ -28,30 +28,26 @@ export class tetriWeaponCarrier extends Component {
private static readonly ATK_ANIM_LEAD_SEC = 0.4; private static readonly ATK_ANIM_LEAD_SEC = 0.4;
private static readonly ATK_ANIM_LEAD_SEC2 = 0.1; private static readonly ATK_ANIM_LEAD_SEC2 = 0.1;
/** 方块 prefab 名 → 武器/hand 缩放与 hand 贴图(与原「角色」节点 scale 一致) */
roleConfig = [ roleConfig = [
{ id: 1, name: "Tetris_att_I", mainPosi: { x: -0.308, y: -10.809 }, animSkin: '小紫', scalex: -0.25, scaley: 0.25 }, { id: 1, name: "Tetris_att_I", mainPosi: { x: 0, y: 0 }, handName: '3格横手', scalex: -0.25, scaley: 0.25 },
{ id: 2, name: "Tetris_att_1_1", mainPosi: { x: -1.484, y: -12.331 }, animSkin: '小紫', scalex: -0.25, scaley: 0.25 }, { id: 2, name: "Tetris_att_1_1", mainPosi: { x: 0, y: 0 }, handName: '3格横手', scalex: -0.25, scaley: 0.25 },
{ id: 3, name: "Tetris_att_J1", mainPosi: { x: -28.877, y: -25.077 }, animSkin: '小蓝', scalex: -0.25, scaley: 0.25 }, { id: 3, name: "Tetris_att_J1", mainPosi: { x: -12.214, y: -17.434 }, handName: '左L手', scalex: -0.25, scaley: 0.25 },
{ id: 4, name: "Tetris_att_J2", mainPosi: { x: -13.884, y: 23.864 }, animSkin: '小蓝', scalex: -0.25, scaley: 0.25 }, { id: 4, name: "Tetris_att_J2", mainPosi: { x: -18.862, y: 10.235 }, handName: '左L手', scalex: -0.25, scaley: 0.25 },
{ id: 5, name: "Tetris_att_J3", mainPosi: { x: 33.67, y: 5.42 }, animSkin: '小蓝', scalex: -0.25, scaley: 0.25 }, { id: 5, name: "Tetris_att_J3", mainPosi: { x: 11.196, y: 18.98 }, handName: '左L手', scalex: -0.25, scaley: 0.25 },
{ id: 6, name: "Tetris_att_J", mainPosi: { x: 16.683, y: -43.542 }, animSkin: '小蓝', scalex: -0.25, scaley: 0.25 }, { id: 6, name: "Tetris_att_J", mainPosi: { x: 18.079, y: -8.477 }, handName: '左L手', scalex: -0.25, scaley: 0.25 },
{ id: 7, name: "Tetris_att_L1", mainPosi: { x: -19, y: 15 }, handName: '右L手', scalex: -0.25, scaley: 0.25 },
{ id: 7, name: "Tetris_att_L1", mainPosi: { x: -29.799, y: 4.73 }, animSkin: '小橙', scalex: -0.25, scaley: 0.25 }, { id: 8, name: "Tetris_att_L2", mainPosi: { x: 17, y: 18 }, handName: '右L手', scalex: -0.25, scaley: 0.25 },
{ id: 8, name: "Tetris_att_L2", mainPosi: { x: 15.513, y: 21.501 }, animSkin: '小橙', scalex: -0.25, scaley: 0.25 }, { id: 9, name: "Tetris_att_L3", mainPosi: { x: 19, y: -15 }, handName: '右L手', scalex: -0.25, scaley: 0.25 },
{ id: 9, name: "Tetris_att_L3", mainPosi: { x: 33.276, y: -29.162 }, animSkin: '小橙', scalex: -0.25, scaley: 0.25 }, { id: 10, name: "Tetris_att_L", mainPosi: { x: -25, y: -22 }, handName: '右L手', scalex: -0.25, scaley: 0.25 },
{ id: 10, name: "Tetris_att_L", mainPosi: { x: -14.952, y: -44.351 }, animSkin: '小橙', scalex: -0.25, scaley: 0.25 }, { id: 11, name: "Tetris_att_Z1_1", mainPosi: { x: 4.018, y: -2.712 }, handName: '右z手', scalex: -0.25, scaley: 0.25 },
{ id: 12, name: "Tetris_att_Z1", mainPosi: { x: -6.197, y: -4.563 }, handName: '右z手', scalex: -0.2, scaley: 0.2 },
{ id: 11, name: "Tetris_att_Z1_1", mainPosi: { x: 2.397, y: -12.412 }, animSkin: '小憨', scalex: -0.25, scaley: 0.25 }, { id: 13, name: "Tetris_att_Z2_1", mainPosi: { x: 2.81, y: 1.751 }, handName: '左z手', scalex: -0.25, scaley: 0.25 },
{ id: 12, name: "Tetris_att_Z1", mainPosi: { x: -0.035, y: -9.153 }, animSkin: '小憨', scalex: -0.2, scaley: 0.2 }, { id: 14, name: "Tetris_att_Z2", mainPosi: { x: 4.65, y: -1.475 }, handName: '左z手', scalex: -0.25, scaley: 0.25 },
{ id: 15, name: "Tetris_att_凸_1", mainPosi: { x: 20.727, y: 0 }, handName: 'T手', scalex: -0.25, scaley: 0.25 },
{ id: 13, name: "Tetris_att_Z2_1", mainPosi: { x: 16.189, y: -10.274 }, animSkin: '小红', scalex: -0.25, scaley: 0.25 }, { id: 16, name: "Tetris_att_凸_2", mainPosi: { x: 0, y: -19.624 }, handName: 'T手', scalex: -0.25, scaley: 0.25 },
{ id: 14, name: "Tetris_att_Z2", mainPosi: { x: -0.057, y: -12.142 }, animSkin: '小红', scalex: -0.25, scaley: 0.25 }, { id: 17, name: "Tetris_att_凸_3", mainPosi: { x: -16.394, y: 0 }, handName: 'T手', scalex: -0.25, scaley: 0.25 },
{ id: 18, name: "Tetris_att_凸", mainPosi: { x: 0, y: 17.555 }, handName: 'T手', scalex: -0.25, scaley: 0.25 },
{ id: 15, name: "Tetris_att_凸_1", mainPosi: { x: -14.41, y: -10.235 }, animSkin: '小贱', scalex: -0.25, scaley: 0.25 },
{ id: 16, name: "Tetris_att_凸_2", mainPosi: { x: 0.131, y: 1.91 }, animSkin: '小贱', scalex: -0.25, scaley: 0.25 },
{ id: 17, name: "Tetris_att_凸_3", mainPosi: { x: 15.166, y: -13.766 }, animSkin: '小贱', scalex: -0.25, scaley: 0.25 },
{ id: 18, name: "Tetris_att_凸", mainPosi: { x: -0.001, y: -25.291 }, animSkin: '小贱', scalex: -0.25, scaley: 0.25 },
] ]
@ -61,10 +57,9 @@ export class tetriWeaponCarrier extends Component {
timeoutIndex: number = 0 timeoutIndex: number = 0
animState: string; animState: string;
/**初始角色朝向*/ /** 武器挂点初始朝向(scale.x 符号) */
initRoleFacing: number = 0; initRoleFacing: number = 0;
initRoleFacingFix: number = 0; initRoleFacingFix: number = 0;
private roleNode: Node | null = null;
private roleBaseAbsScaleX: number = 1; private roleBaseAbsScaleX: number = 1;
_isBattleScene = false //是否是战斗场景相机 _isBattleScene = false //是否是战斗场景相机
_isCanShoot = true //是否可以射击 _isCanShoot = true //是否可以射击
@ -106,10 +101,7 @@ export class tetriWeaponCarrier extends Component {
const block = this.findCarrierTetriNode()?.node ?? this.node; const block = this.findCarrierTetriNode()?.node ?? this.node;
gg.game?.CurentBattle?.pruneDetachedBattleLayers?.(block); gg.game?.CurentBattle?.pruneDetachedBattleLayers?.(block);
const weapon = this.weaponNode; const weapon = this.weaponNode;
const role = this.roleNode;
this.weaponNode = null; this.weaponNode = null;
this.roleNode = null;
// 武器挂在「角色/武器」下,先回收武器再回收角色,避免子随父一起进半销毁态
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)
@ -123,7 +115,6 @@ export class tetriWeaponCarrier extends Component {
GEvent.Ins.off(GEvent.StraightTargetDamage, this.StraightTargetDamage, this) GEvent.Ins.off(GEvent.StraightTargetDamage, this.StraightTargetDamage, this)
GEvent.Ins.off(GEvent.LightningElectricity, this.LightningElectricity, this) GEvent.Ins.off(GEvent.LightningElectricity, this.LightningElectricity, this)
this.safePutPoolNode(weapon); this.safePutPoolNode(weapon);
this.safePutPoolNode(role);
} }
@ -142,140 +133,104 @@ export class tetriWeaponCarrier extends Component {
GEvent.Ins.on(GEvent.StraightTargetDamage, this.StraightTargetDamage, this)//直线目标持续伤害 GEvent.Ins.on(GEvent.StraightTargetDamage, this.StraightTargetDamage, this)//直线目标持续伤害
GEvent.Ins.on(GEvent.LightningElectricity, this.LightningElectricity, this)//雷电电击攻击单体 GEvent.Ins.on(GEvent.LightningElectricity, this.LightningElectricity, this)//雷电电击攻击单体
if(gg.game.CurentBattle.BattleType == BattleType.OrangeWeaponMode_Ya){ this.scheduleOnce(() => this.initCarrier(), 0.02);
//已经有角色了直接修改皮肤
this.scheduleOnce(() => {
//this.addWeapon()
this.createRoleNode2()
}, 0.02)
}else{
this.scheduleOnce(() => {
this.createRoleNode()
}, 0.02)
}
} }
createRoleNode2(){ /** 方块 prefab 上的武器挂点 */
if (!this._config) { private getWeaponMountNode(): Node | null {
console.error('[tetriWeaponCarrier] createRoleNode: _config 为空,请保证 setConfig 在 start 之前已调用'); return find('武器', this.node);
return; }
}
this.roleNode = this.node /** 武器预制体 Spine(动画在子节点 spine 上) */
const conf = this.roleConfig.find(item => item.name == this._config.cubename); private getWeaponSkeleton(weaponNode: Node | null): sp.Skeleton | null {
// console.log('conf',conf); if (!weaponNode?.isValid) return null;
if (conf) { const spineNode = weaponNode.getChildByName('spine');
// this.roleNode.setPosition(conf.mainPosi.x, conf.mainPosi.y); if (spineNode?.isValid) {
this.roleNode.setScale(conf.scalex, conf.scaley); return spineNode.getComponent(sp.Skeleton);
const anim = this.roleNode.getChildByName('anim')?.getComponent(sp.Skeleton);
if (anim) {
anim.setAnimation(0, '待机', true);
anim.setSkin(conf.animSkin);
} else {
console.warn('[tetriWeaponCarrier] createRoleNode: 角色 prefab 缺少 anim 子节点', this._config.cubename);
}
} }
return weaponNode.getComponent(sp.Skeleton);
}
this.scheduleOnce(() => { private playWeaponAnim(weaponNode: Node | null, animName: string, loop: boolean): void {
if (!isValid(this.node)) return; this.getWeaponSkeleton(weaponNode)?.setAnimation(0, animName, loop);
this.setView();
}, 0.1);
this.initRoleFacing = this.roleNode.scale.x;
this.initRoleFacingFix = this.roleNode.scale.x;
const abs = Math.abs(this.initRoleFacingFix);
this.roleBaseAbsScaleX = abs > 1e-6 ? abs : 1;
} }
createRoleNode() {
// 先挂角色节点,再 setView -> addWeapon(依赖子路径 角色/anim、角色/武器) /** 清理旧版动态挂上的「角色」子节点 */
if (!this._config) { private removeLegacyRoleNodes(): void {
console.error('[tetriWeaponCarrier] createRoleNode: _config 为空,请保证 setConfig 在 start 之前已调用');
return;
}
// instantiate(整块) / 参考方块拷贝会带上已有「角色」;若再从池里取会叠两个
const dupDestroy: Node[] = []; const dupDestroy: Node[] = [];
let existingRole: Node | null = null;
for (let i = 0; i < this.node.children.length; i++) { for (let i = 0; i < this.node.children.length; i++) {
const c = this.node.children[i]; const c = this.node.children[i];
if (c.name === '角色') { if (c?.name === '角色') dupDestroy.push(c);
if (!existingRole) existingRole = c;
else dupDestroy.push(c);
}
} }
for (const d of dupDestroy) { for (const d of dupDestroy) {
if (d?.isValid) d.destroy(); if (d?.isValid) d.destroy();
} }
}
let roleNode: Node | null = existingRole?.isValid ? existingRole : null; /** 按 roleConfig 设置武器挂点 / hand 的缩放与朝向基准(等同原角色节点 setScale) */
if (!roleNode) { private applyBlockWeaponVisual(conf: { scalex: number; scaley: number }): void {
void gg.res.getNodeAsync('角色/', '角色', GBundle.tetriCards).then((loaded) => { const mount = this.getWeaponMountNode();
if (!loaded?.isValid || !this.node?.isValid) return; if (mount?.isValid) {
this._setupRoleNode(loaded); mount.setScale(conf.scalex, conf.scaley);
});
return;
} }
this._setupRoleNode(roleNode); const hand = this.node.getChildByName('hand');
if (hand?.isValid) {
hand.setScale(conf.scalex, conf.scaley);
}
this.initRoleFacing = conf.scalex;
this.initRoleFacingFix = conf.scalex;
const abs = Math.abs(conf.scalex);
this.roleBaseAbsScaleX = abs > 1e-6 ? abs : 1;
} }
private _setupRoleNode(roleNode: Node) { /** 初始化方块载体:hand 贴图 + 武器(挂方块「武器」节点,local 0,0) */
roleNode.setParent(this.node); private initCarrier(): void {
this.roleNode = roleNode; if (!this._config) {
roleNode.active = true; console.error('[tetriWeaponCarrier] initCarrier: _config 为空,请保证 setConfig 在 start 之前已调用');
return;
const roleComp = roleNode.getComponent(role); }
roleComp?.setFollowTarget(this.findCarrierTetriNode()?.node ?? this.node); this.removeLegacyRoleNodes();
const conf = this.roleConfig.find(item => item.name == this._config.cubename); const conf = this.roleConfig.find(item => item.name === this._config.cubename);
// console.log('conf',conf);
if (conf) { if (conf) {
roleNode.setPosition(conf.mainPosi.x, conf.mainPosi.y); if (conf.handName) {
roleNode.setScale(conf.scalex, conf.scaley); applyRoleHand(this.node, conf.handName);
const anim = roleNode.getChildByName('anim')?.getComponent(sp.Skeleton);
if (anim) {
anim.setAnimation(0, '待机', true);
anim.setSkin(conf.animSkin);
} else {
console.warn('[tetriWeaponCarrier] createRoleNode: 角色 prefab 缺少 anim 子节点', this._config.cubename);
} }
this.applyBlockWeaponVisual(conf);
} }
if (this._isBattleScene) {
console.log('我是在战斗场景相机下创建角色', this.node.layer)
this.setLayerMask(roleNode, this.node.layer)
}
this.scheduleOnce(() => { this.scheduleOnce(() => {
if (!isValid(this.node)) return; if (!isValid(this.node)) return;
const conf2 = this.roleConfig.find(item => item.name === this._config?.cubename);
if (conf2) {
if (conf2.handName) applyRoleHand(this.node, conf2.handName);
this.applyBlockWeaponVisual(conf2);
}
this.setView(); this.setView();
}, 0.1); }, 0.1);
this.initRoleFacing = this.roleNode.scale.x;
this.initRoleFacingFix = this.roleNode.scale.x;
const abs = Math.abs(this.initRoleFacingFix);
this.roleBaseAbsScaleX = abs > 1e-6 ? abs : 1;
} }
/** 翻转武器挂点 / hand 面向目标 x(只改 scale.x) */
/**将“角色”翻转到面向目标 x(只改 scale.x,不改大小) */
private faceRoleToWorldX(targetWorldX: number) { private faceRoleToWorldX(targetWorldX: number) {
if (!this.roleNode || !isValid(this.roleNode)) return; const mount = this.getWeaponMountNode();
// 用载体方块作为参考坐标,更稳定(避免“角色”子节点有额外偏移) if (!mount?.isValid) return;
const selfX = this.node.worldPosition.x; const selfX = this.node.worldPosition.x;
const dx = targetWorldX - selfX; const dx = targetWorldX - selfX;
if (Math.abs(dx) < 0.01) return; if (Math.abs(dx) < 0.01) return;
// 你给的基准:初始一定是“脸朝右”,但 scale.x 可能正/负
// 所以把初始符号视为“朝右符号”,朝左时取反即可
const rightSign = this.initRoleFacingFix >= 0 ? 1 : -1; const rightSign = this.initRoleFacingFix >= 0 ? 1 : -1;
const dir = dx >= 0 ? rightSign : -rightSign; const dir = dx >= 0 ? rightSign : -rightSign;
const s = this.roleNode.scale;
const newX = this.roleBaseAbsScaleX * dir; const newX = this.roleBaseAbsScaleX * dir;
if (Math.abs(s.x - newX) > 1e-6) {
this.roleNode.setScale(newX, s.y, s.z); const applyFlip = (n: Node) => {
} const s = n.scale;
if (Math.abs(s.x - newX) > 1e-6) {
n.setScale(newX, s.y, s.z);
}
};
applyFlip(mount);
const hand = this.node.getChildByName('hand');
if (hand?.isValid) applyFlip(hand);
} }
private faceRoleToMonster(monsterNode: Node | null) { private faceRoleToMonster(monsterNode: Node | null) {
@ -334,13 +289,13 @@ export class tetriWeaponCarrier extends Component {
* @param isUpLevel true false * @param isUpLevel true false
*/ */
showSkillSelectCompleteEffect(isUpLevel = true, delay = 0) { showSkillSelectCompleteEffect(isUpLevel = true, delay = 0) {
const host = this.roleNode?.isValid ? this.roleNode : this.node; const host = this.node;
if (!host?.isValid) return; if (!host?.isValid) return;
this.scheduleOnce(() => { this.scheduleOnce(() => {
if (!host?.isValid) return; if (!host?.isValid) return;
void gg.res.getNodeAsync(GPath.Prefab, '三选一完成格子效果', GBundle.tetriGame).then((eff) => { void gg.res.getNodeAsync(GPath.Prefab, '三选一完成格子效果', GBundle.tetriGame).then((eff) => {
if (!eff?.isValid) return; if (!eff?.isValid) return;
const battle = gg.game?.CurentBattle; const battle = gg.game?.CurentBattle;
const ya = battle?.BattleType === BattleType.OrangeWeaponMode_Ya; const ya = battle?.BattleType === BattleType.OrangeWeaponMode_Ya;
@ -393,25 +348,31 @@ export class tetriWeaponCarrier extends Component {
this.addWeapon(weaponani) this.addWeapon(weaponani)
} }
//增加武器和修改icon图片 // 武器挂到方块 prefab 的「武器」节点(local 0,0,偏移在 prefab 挂点配置)
addWeapon(weaponani) { addWeapon(weaponani) {
const anim = find('anim', this.roleNode); const wuqiNode = this.getWeaponMountNode();
const wuqiNode = find('武器', this.roleNode); if (!wuqiNode) {
if (!anim || !wuqiNode) { console.error('[tetriWeaponCarrier] addWeapon: 未找到方块/武器', this._config?.cubename);
console.error('[tetriWeaponCarrier] addWeapon: 未找到 角色/anim 或 角色/武器', this._config?.cubename);
return; return;
} }
void gg.res.getNodeAsync('prefab/', weaponani, GBundle.tetriWeapon).then((weaponNode) => { void gg.res.getNodeAsync('prefab/', weaponani, GBundle.tetriWeapon).then((weaponNode) => {
if (!weaponNode?.isValid || !wuqiNode?.isValid) return; if (!weaponNode?.isValid || !wuqiNode?.isValid) {
if (!weaponNode) {
console.error('[tetriWeaponCarrier] addWeapon: 武器预制未取到', weaponani, this._config?.cubename);
}
return;
}
this.setLayerMask(weaponNode, wuqiNode.layer); this.setLayerMask(weaponNode, wuqiNode.layer);
this.weaponNode = weaponNode; this.weaponNode = weaponNode;
weaponNode.setParent(wuqiNode); weaponNode.setParent(wuqiNode);
anim.getComponent(sp.Skeleton)?.setAnimation(0, '待机', true); weaponNode.setPosition(0, 0, 0);
weaponNode.getComponent(sp.Skeleton)?.setAnimation(0, '待机', true);
this.playWeaponAnim(weaponNode, '待机', true);
}); });
} }
setLayerMask(n: Node, layerMask: number) { setLayerMask(n: Node, layerMask: number) {
if (n.name === 'hand') return;
n.layer = layerMask; n.layer = layerMask;
for (let i = 0; i < n.children.length; i++) { for (let i = 0; i < n.children.length; i++) {
if (n.children[i].isValid) { if (n.children[i].isValid) {
@ -428,23 +389,13 @@ export class tetriWeaponCarrier extends Component {
//播放攻击动画 //播放攻击动画
playAtkAnim() { playAtkAnim() {
clearTimeout(this.timeoutIndex as unknown as number); clearTimeout(this.timeoutIndex as unknown as number);
if (!this.roleNode?.isValid) { const weaponSk = this.getWeaponSkeleton(this.weaponNode);
if (!weaponSk) {
return; return;
} }
const animNode = find('anim', this.roleNode); weaponSk.setAnimation(0, '攻击', false);
const animSk = animNode?.getComponent(sp.Skeleton);
const weaponSk = this.weaponNode?.getComponent(sp.Skeleton);
if (animSk) {
animSk.setAnimation(0, '攻击', false);
}
if (weaponSk) {
weaponSk.setAnimation(0, '攻击', false);
}
this.timeoutIndex = setTimeout(() => { this.timeoutIndex = setTimeout(() => {
if (animSk?.isValid) {
animSk.setAnimation(0, '待机', true);
}
if (weaponSk?.isValid) { if (weaponSk?.isValid) {
weaponSk.setAnimation(0, '待机', true); weaponSk.setAnimation(0, '待机', true);
} }
@ -456,14 +407,13 @@ export class tetriWeaponCarrier extends Component {
//获取武器的发射节点和原点 //获取武器的发射节点和原点
getWeaponLaunchNode(): Node { getWeaponLaunchNode(): Node {
if (!this.roleNode?.isValid) { const wuqiNode = this.getWeaponMountNode();
return this.node;
}
const wuqiNode = find('武器', this.roleNode);
if (!wuqiNode?.isValid) { if (!wuqiNode?.isValid) {
return this.roleNode; return this.node;
} }
const shoot = wuqiNode.getComponentInChildren(shootPoint)?.node; const shoot =
this.weaponNode?.getComponentInChildren(shootPoint)?.node
?? wuqiNode.getComponentInChildren(shootPoint)?.node;
if (shoot?.isValid) { if (shoot?.isValid) {
return shoot; return shoot;
} }
@ -557,8 +507,9 @@ export class tetriWeaponCarrier extends Component {
this.scheduleWeaponFire(t1, () => { this.scheduleWeaponFire(t1, () => {
// 面向最近怪物(角色不移动也需要左右转向) // 面向最近怪物(角色不移动也需要左右转向)
this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode)); this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode));
// 音效节流交给 SoundManager.shouldPlayWeaponSfx(按音效名);勿共用 audio_timeStamp if (!MTools.beforeTimes(100, "audio_timeStamp")) {
this.playEffectStraight(weaponId); this.playEffectStraight(weaponId);
}
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
let addPos = v3(j * posX - (launchCount - 1) * posX / 2, 0, 0) let addPos = v3(j * posX - (launchCount - 1) * posX / 2, 0, 0)
void battle.SkillController.instantiateSingleWeapon(weaponId, volume, addPos, 0, launchNodeSnap).then((weaponNode) => { void battle.SkillController.instantiateSingleWeapon(weaponId, volume, addPos, 0, launchNodeSnap).then((weaponNode) => {
@ -615,7 +566,9 @@ export class tetriWeaponCarrier extends Component {
this.scheduleWeaponFire(t1, () => { this.scheduleWeaponFire(t1, () => {
// 面向最近怪物(角色不移动也需要左右转向) // 面向最近怪物(角色不移动也需要左右转向)
this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode)); this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode));
this.playEffectStraightLaunch(weaponId); if (!MTools.beforeTimes(100, "audio_timeStamp2")) {
this.playEffectStraightLaunch(weaponId);
}
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
let addPos = v3(j * posX - (launchCount - 1) * posX / 2, 0, 0) let addPos = v3(j * posX - (launchCount - 1) * posX / 2, 0, 0)
void battle.SkillController.instantiateSingleWeapon(weaponId, volume, addPos, 0, launchNodeSnap).then((weaponNode) => { void battle.SkillController.instantiateSingleWeapon(weaponId, volume, addPos, 0, launchNodeSnap).then((weaponNode) => {
@ -670,7 +623,9 @@ export class tetriWeaponCarrier extends Component {
// 面向最近怪物(角色不移动也需要左右转向) // 面向最近怪物(角色不移动也需要左右转向)
this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode)); this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode));
this.playEffectStraightNum(weaponId); if (!MTools.beforeTimes(100, "audio_timeStamp3")) {
this.playEffectStraightNum(weaponId);
}
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
//多个子弹并排开 //多个子弹并排开
@ -727,7 +682,9 @@ export class tetriWeaponCarrier extends Component {
// 面向最近怪物(角色不移动也需要左右转向) // 面向最近怪物(角色不移动也需要左右转向)
this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode)); this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode));
this.playEffectStraight(weaponId); if (!MTools.beforeTimes(100, "audio_timeStamp3")) {
this.playEffectStraight(weaponId);
}
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
//多个子弹并排开 //多个子弹并排开
@ -784,7 +741,9 @@ export class tetriWeaponCarrier extends Component {
// 面向最近怪物(角色不移动也需要左右转向) // 面向最近怪物(角色不移动也需要左右转向)
this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode)); this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode));
this.playEffectStraight(weaponId); if (!MTools.beforeTimes(100, "audio_timeStamp3")) {
this.playEffectStraight(weaponId);
}
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
//多个子弹并排开 //多个子弹并排开
@ -854,7 +813,9 @@ export class tetriWeaponCarrier extends Component {
let singleLaunchCall = () => { let singleLaunchCall = () => {
//单次发射数量 //单次发射数量
this.playEffectParabolaCollide(weaponId); if (!MTools.beforeTimes(100, "audio_timeStamp4")) {
this.playEffectParabolaCollide(weaponId);
}
let selectMonster = []; let selectMonster = [];
selectMonster = gg.game.CurentBattle.MonsterSpawner.getMonsterNearestCountPar(this.node, throwCount); selectMonster = gg.game.CurentBattle.MonsterSpawner.getMonsterNearestCountPar(this.node, throwCount);
if (selectMonster.length == 0) { if (selectMonster.length == 0) {
@ -890,8 +851,8 @@ export class tetriWeaponCarrier extends Component {
if (isBurst) { if (isBurst) {
for (let j = 0; j < burstCount; j++) { for (let j = 0; j < burstCount; j++) {
this.scheduleWeaponFire(lead + xTime * j, () => { this.scheduleWeaponFire(lead + xTime * j, () => {
singleLaunchCall(); singleLaunchCall()
}); })
} }
//单发 //单发
} else { } else {
@ -972,7 +933,9 @@ export class tetriWeaponCarrier extends Component {
let singleLaunchCall = () => { let singleLaunchCall = () => {
//单次发射数量 //单次发射数量
this.playEffectParabolaNoCollide(weaponId); if (!MTools.beforeTimes(100, "audio_timeStamp5")) {
this.playEffectParabolaNoCollide(weaponId);
}
let selectMonster = []; let selectMonster = [];
selectMonster = gg.game.CurentBattle.MonsterSpawner.getMonsterParabolaPos(throwCount, this.node); selectMonster = gg.game.CurentBattle.MonsterSpawner.getMonsterParabolaPos(throwCount, this.node);
if (selectMonster.length == 0) { if (selectMonster.length == 0) {
@ -1011,8 +974,8 @@ export class tetriWeaponCarrier extends Component {
if (isBurst) { if (isBurst) {
for (let j = 0; j < burstCount; j++) { for (let j = 0; j < burstCount; j++) {
this.scheduleWeaponFire(lead + xTime * j, () => { this.scheduleWeaponFire(lead + xTime * j, () => {
singleLaunchCall(); singleLaunchCall()
}); })
} }
//单发 //单发
} else { } else {
@ -1074,6 +1037,10 @@ export class tetriWeaponCarrier extends Component {
carrier.playAtkAnim(); carrier.playAtkAnim();
const lead = tetriWeaponCarrier.ATK_ANIM_LEAD_SEC2 / battle.TimeScale; const lead = tetriWeaponCarrier.ATK_ANIM_LEAD_SEC2 / battle.TimeScale;
this.scheduleWeaponFire(lead, () => { this.scheduleWeaponFire(lead, () => {
const b = gg.game.CurentBattle;
if (b?.IsWarnTimeActive && b?.IsGamePause) {
return;
}
for (let i = 0; i < burstCount; i++) { for (let i = 0; i < burstCount; i++) {
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
const laserIndex = i * launchCount + j; const laserIndex = i * launchCount + j;
@ -1131,8 +1098,9 @@ export class tetriWeaponCarrier extends Component {
this.scheduleWeaponFire(t1, () => { this.scheduleWeaponFire(t1, () => {
// 面向最近怪物(角色不移动也需要左右转向) // 面向最近怪物(角色不移动也需要左右转向)
this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode)); this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode));
// 音效节流交给 SoundManager.shouldPlayWeaponSfx(按音效名);勿共用 audio_timeStamp if (!MTools.beforeTimes(100, "audio_timeStamp")) {
this.playEffectStraight(weaponId); this.playEffectStraight(weaponId);
}
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
let addPos = v3(j * posX - (launchCount - 1) * posX / 2, 0, 0) let addPos = v3(j * posX - (launchCount - 1) * posX / 2, 0, 0)
void battle.SkillController.instantiateSingleWeapon(weaponId, volume, addPos, 0, launchNodeSnap).then((weaponNode) => { void battle.SkillController.instantiateSingleWeapon(weaponId, volume, addPos, 0, launchNodeSnap).then((weaponNode) => {
@ -1192,7 +1160,9 @@ export class tetriWeaponCarrier extends Component {
// 面向最近怪物(角色不移动也需要左右转向) // 面向最近怪物(角色不移动也需要左右转向)
this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode)); this.faceRoleToMonster(battle.MonsterSpawner?.getAllPathDisMinMonster?.(carrierNode));
this.playEffectStraightNum(weaponId); if (!MTools.beforeTimes(100, "audio_timeStamp3")) {
this.playEffectStraightNum(weaponId);
}
for (let j = 0; j < launchCount; j++) { for (let j = 0; j < launchCount; j++) {
//多个子弹并排开 //多个子弹并排开

@ -252,7 +252,7 @@
}, },
"splash-setting": { "splash-setting": {
"logo": { "logo": {
"image": "project://settings/ICON.png", "image": "project://settings/icon.jpg",
"type": "custom" "type": "custom"
}, },
"background": { "background": {

Loading…
Cancel
Save