消消方块阵换皮表情
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

231 lines
8.5 KiB

import { _decorator, Component, find, Node, sp, Tween, tween, v3, Vec3 } from 'cc';
import { tetriWeaponCarrier } from '../tetriCard/tetriWeaponCarrier';
import { GEvent } from '../../mx/module/event/GEvent';
const { ccclass, property } = _decorator;
@ccclass('jiujiuwoMap')
export class jiujiuwoMap extends Component {
/**出怪口 */
public spawnPointParent: Node = null;
public _gameRoot: Node = null;
timeHit: number = 0;
/** 上次已切换到的喷泉档位 0~3(与血量分段一致),-1 表示尚未与城墙血量同步 */
private _lastFountainTier: number = -1;
meinvAnimState: string = '待机';
start() {
this._initNodes();
}
onEnable(){
GEvent.Ins.on(GEvent.playerHit, this._onPlayerHit, this);
}
onDisable(){
GEvent.Ins.off(GEvent.playerHit, this._onPlayerHit, this);
}
/**初始状态喷泉和美女*/
initState(){
const wallTarget1 = find('目标点/wallTarget1', this.node);
if (!wallTarget1 || !wallTarget1.isValid) {
return;
}
this._lastFountainTier = -1;
this.showMeinvIdleEffect();
this._updateWallFountainDisplay();
}
_initNodes(){
if (this._gameRoot) return;
this._gameRoot = find("GameRoot", this.node);
if (!this._gameRoot) return;
this.spawnPointParent = this.node.getChildByName('出怪口');
if (this.spawnPointParent.getChildByName('spawnPoint_4')) {
this.spawnPointParent.getChildByName('spawnPoint_4').x = 360;
this.spawnPointParent.getChildByName('spawnPoint_4').y = -356
}
if (this.spawnPointParent.getChildByName('spawnPoint_5')) {
this.spawnPointParent.getChildByName('spawnPoint_5').x = 360;
this.spawnPointParent.getChildByName('spawnPoint_5').y = -401
}
if (this.spawnPointParent.getChildByName('spawnPoint_6')) {
this.spawnPointParent.getChildByName('spawnPoint_6').x = 360;
this.spawnPointParent.getChildByName('spawnPoint_6').y = -401
}
}
/**获取目标点*/
public getPathShortestTarget(startPos: Vec3): Node {
const n1 = find('目标点/wallTarget1', this.node);
return n1;
}
/***获取_tetrisTable的子节点数量*/
getTetriNodeCount(){
return 0
}
//******美女胜利动画******/
showMeinvWinEffect(){
const wallTarget1 = find('目标点/wallTarget1', this.node);
if(!wallTarget1 || !wallTarget1.isValid){
return;
}
if(this.timeHit){
clearTimeout(this.timeHit);
}
let meinv = wallTarget1.getChildByName('美女');
if(meinv?.isValid){
this.meinvAnimState = '胜利';
meinv.getComponent(sp.Skeleton).setAnimation(0, '胜利', true)
}
}
/**遍历场上武器载体,找到对应 weaponId(救救我鸭为直挂角色,可能多个)*/
getTetriWeaponCarrier(weaponId: number): tetriWeaponCarrier[] {
const carriers = gg.game?.CurentBattle?.jiujiuwoyaWeaponCarriers ?? [];
return carriers.filter(c => c?.node?.isValid && c.getCurWeaponId() === weaponId);
}
//美女待机
showMeinvIdleEffect() {
if (this.meinvAnimState === '胜利') return;
const wallTarget1 = find('目标点/wallTarget1', this.node);
if(!wallTarget1 || !wallTarget1.isValid){
return;
}
let meinv = wallTarget1.getChildByName('美女');
if(meinv?.isValid){
this.meinvAnimState = '待机';
meinv.getComponent(sp.Skeleton).setAnimation(0, '待机', true)
}
}
showQiPaoEffect() {
const wallTarget1 = find('目标点/wallTarget1', this.node);
if(!wallTarget1 || !wallTarget1.isValid){
return;
}
let qipao = wallTarget1.getChildByName('气泡文字');
let meinv = wallTarget1.getChildByName('美女');
if (qipao?.isValid) {
if(this.timeHit){
clearTimeout(this.timeHit);
}
meinv.getComponent(sp.Skeleton).setAnimation(0, '说话', true)
this.meinvAnimState = '说话';
qipao.active = true;
qipao.scale = v3(0, 0, 0);
tween(qipao)
.to(0.5, { scale: v3(0.55, 0.55, 0.55) }, { easing: 'quadInOut' })
.delay(3.0)
.call(() => {
this.hideQiPaoEffect();
this.showMeinvIdleEffect();
})
.start();
}
}
hideQiPaoEffect() {
const wallTarget1 = find('目标点/wallTarget1', this.node);
let qipao = wallTarget1.getChildByName('气泡文字');
if (qipao?.isValid) {
qipao.active = false;
}
}
/**
* 100%~75%:喷泉;75%~50%:喷泉2;50%~25%:喷泉3;25%~0%:喷泉4。
* 档位切换时:将要显示的一层从透明淡入,原先显示的一层同时淡出至 0 再隐藏(交叉淡入淡出)。
*/
private _updateWallFountainDisplay() {
const battle = gg.game?.CurentBattle;
const wallTarget1 = find('目标点/wallTarget1', this.node);
if (!battle || !wallTarget1?.isValid) return;
const maxHp = Math.max(1, battle.WallMaxHp);
const ratio = battle.CurentWallHp / maxHp;
let tier = 3;
if (ratio >= 0.75) tier = 0;
else if (ratio >= 0.5) tier = 1;
else if (ratio >= 0.25) tier = 2;
const names = ['喷泉', '喷泉2', '喷泉3', '喷泉4'];
const newNode = find(names[tier], wallTarget1);
// 节点尚未挂好时不写 _lastFountainTier,避免「假同步」后永远不再刷新(偶现喷泉不显示)
if (!newNode?.isValid) return;
const duration = 2;
// 首次进入战斗 / 重置后:直接按档位点亮,避免与其它初始化时序竞态
if (this._lastFountainTier < 0 || this._lastFountainTier > 3) {
for (const name of names) {
const n = find(name, wallTarget1);
if (n?.isValid && n !== newNode) {
Tween.stopAllByTarget(n);
n.active = false;
n.opacity = 0;
}
}
Tween.stopAllByTarget(newNode);
newNode.active = true;
newNode.opacity = 255;
this._lastFountainTier = tier;
return;
}
// 档位不变:若当前档喷泉被误隐藏或透明度异常(tween 被 stop、异步回调顺序等),补一次淡入
if (tier === this._lastFountainTier) {
if (newNode.active && newNode.opacity >= 64) return;
newNode.active = true;
Tween.stopAllByTarget(newNode);
const from = newNode.opacity < 1 ? 0 : Math.min(newNode.opacity, 200);
newNode.opacity = from;
tween(newNode).to(0.35, { opacity: 255 }, { easing: 'quadOut' }).start();
return;
}
const oldNode = find(names[this._lastFountainTier], wallTarget1);
if (oldNode?.isValid) {
Tween.stopAllByTarget(oldNode);
tween(oldNode).to(duration, { opacity: 0 }, { easing: 'quadIn' }).call(() => {
if (oldNode?.isValid) oldNode.active = false;
}).start();
}
newNode.active = true;
newNode.opacity = 100;
Tween.stopAllByTarget(newNode);
tween(newNode).to(duration, { opacity: 255 }, { easing: 'quadOut' }).start();
this._lastFountainTier = tier;
}
//美女受击动画
showMeinvBeHitEffect() {
if (this.meinvAnimState === '胜利') return;
const wallTarget1 = find('目标点/wallTarget1', this.node);
if(!wallTarget1 || !wallTarget1.isValid){
return;
}
let meinv = wallTarget1.getChildByName('美女');
if(meinv?.isValid && this.meinvAnimState != '受击'){
this.meinvAnimState = '受击';
meinv.getComponent(sp.Skeleton).setAnimation(0, '受击', true)
}
}
_onPlayerHit(){
if (gg.game?.CurentBattle?.IsGameOver) return;
this.showMeinvBeHitEffect();
if(this.timeHit){
clearTimeout(this.timeHit);
}
// 喷泉状态:随城墙血量分档淡入淡出(受击时刷新)
this._updateWallFountainDisplay();
this.timeHit = setTimeout(() => {
this.showMeinvIdleEffect();
}, 2000);
}
}