消消方块阵换皮表情
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.

252 lines
9.1 KiB

1 week ago
import { _decorator, Component, Input, input, KeyCode, Vec2, Node, EventKeyboard, Vec3, EventTouch, v3, sp, UITransform, Prefab, instantiate, Label, tween } from 'cc';
import { GEvent } from 'db://assets/mx/module/event/GEvent';
import { GBundle } from '../../game/ConfigRes';
import { BattleType, ChapterDifficulty } from '../../manager/ChapterDataManager';
const { ccclass, property } = _decorator;
@ccclass('PlayerController')
export class PlayerController extends Component {
// 滑动控制区域节点
@property({
type: Node,
tooltip: "指定的滑动控制区域"
})
controlArea: Node = null;
@property({
type: Node,
tooltip: "可移动区域"
})
moveArea: Node = null;
// 玩家节点
@property({
type: Node,
tooltip: "需要控制的玩家节点"
})
playerNode: Node = null;
@property(sp.Skeleton)
playerSpine: sp.Skeleton = null;
@property(sp.Skeleton)
levelSpine: sp.Skeleton = null;
// 移动灵敏度
sensitivity: number = 1.1;
private gameModel: string = ''
// 记录触摸起点(勿用 Vec3.ZERO:引擎内为只读,引导未放开移动时 onTouchStart 可能未赋值,onTouchMove 里不能改 .x)
private startTouchPos: Vec3 = v3(0, 0, 0);
// 记录玩家初始X位置(用于锁定X轴)
private initialY: number = 0;
_dt: number = 0
private rightX: number = 150
private leftX: number = -150
private isStart: boolean = false
private isCanMove: boolean = false
private isTouchStart: boolean = false
private roleVisual: Node | null = null;
private roleBaseScaleX: number = 1;
private roleFacing: number = 0; // -1 left, +1 right, 0 unknown
protected onEnable(): void {
// 注册触摸事件
this.controlArea.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
this.controlArea.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.controlArea.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
GEvent.Ins.on(GEvent.ShowLevelSpine, this.showLevelSpine, this);
}
protected onDisable(): void {
// 移除输入事件监听
this.controlArea.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
this.controlArea.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.controlArea.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
GEvent.Ins.off(GEvent.ShowLevelSpine, this.showLevelSpine, this);
}
onLoad() {
let n = gg.res.getNode(`skin/${gg.skin.CurrentSkin}/`, `主角`, GBundle.Items);
this.playerNode.find("skin").addChild(n);
this.playerSpine = n.getComponent(sp.Skeleton);
// 缓存“角色”节点及初始朝向(只做左右翻转,不改大小)
this.roleVisual = this.playerNode.getChildByName('角色') || this.node.getChildByName('角色') || null;
if (this.roleVisual) {
const sx = this.roleVisual.scale.x;
this.roleBaseScaleX = Math.abs(sx) > 1e-6 ? Math.abs(sx) : 1;
this.roleFacing = sx >= 0 ? 1 : -1;
}
// 初始化玩家位置到屏幕左侧
this.setInitialPosition();
}
protected start(): void {
this.gameModel = gg.game.CurentSelectBattleType == BattleType.BoxMode ? 'baoxiang' : '不是宝箱副本'
// if (this.gameModel == 'baoxiang') {
// this.moveArea.getComponent(UITransform).height = 840
// this.moveArea.setPosition(0, -45)
// } else {
// this.moveArea.getComponent(UITransform).height = 742
// this.moveArea.setPosition(0, 15)
// }
// 记录玩家初始X位置,用于锁定X轴
this.initialY = this.playerNode.position.y;
this.rightX = this.moveArea.x + this.moveArea.getComponent(UITransform).width / 2
this.leftX = this.moveArea.x - this.moveArea.getComponent(UITransform).width / 2
this.playWait();
}
setIsReady(isStart: boolean) {
this.isStart = isStart
}
setPlayerIsCanMove(isCanMove: boolean) {
this.isCanMove = isCanMove
}
update(deltaTime: number) {
if (!gg.game.isBattleContextActive()) return;
if (!this.isStart) {
return
}
this._dt += deltaTime * gg.game.CurentBattle.TimeScale
//this._dt <= 1.6 || !this.isCanMove ||
// if (this._dt <= 1.6 || gg.game.CurentBattle.IsGamePause) {
// this.playWait()
// } else {
// this.playAtk()
// }
}
public setInitialPosition() {
// 将玩家设置在屏幕左侧中间位置
// const canvas = this.node.parent!;
// const canvasSize = canvas.getContentSize();
//this.playerNode.setPosition(0, -430);
}
/**
*
* @param event
*/
private onTouchStart(event: EventTouch) {
if (!gg.game.CurentBattle.canUpdateFrame()) return
if(!this.isCanMove && (gg.game.CurentBattle.ChapterId == 1 && gg.game.CurentBattle.Difficulty == ChapterDifficulty.Normal)){
return
}
// 获取触摸开始位置
event.preventSwallow = true;
event.propagationStopped = true;
const touchPos = event.getUILocation();
this.startTouchPos = v3(touchPos.x, touchPos.y, 0);
this.isTouchStart = true
}
/**
*
* @param event
*/
private onTouchMove(event: EventTouch) {
if (!gg.game.CurentBattle.canUpdateFrame()) return;
if(!this.isCanMove && (gg.game.CurentBattle.ChapterId == 1 && gg.game.CurentBattle.Difficulty == ChapterDifficulty.Normal)){
return
}
//BattleManager.Instance.hideMovePlayerGuide()
GEvent.Ins.emit(GEvent.onMovePlayer);
// 获取当前触摸位置
const currentPos = event.getUILocation();
// 计算Y方向的移动距离
const deltaX = currentPos.x - this.startTouchPos.x;
// 更新触摸起始参考点(整向量赋值,避免误改只读 Vec3)
this.startTouchPos.set(currentPos.x, currentPos.y, 0);
let posX = this.playerNode.position.x + deltaX * this.sensitivity
if (posX < this.leftX) posX = this.leftX
if (posX > this.rightX) posX = this.rightX
// 左右转向:根据手指滑动方向翻转“角色”节点
if (this.roleVisual && Math.abs(deltaX) > 0.01) {
const newFacing = deltaX > 0 ? 1 : -1;
if (newFacing !== this.roleFacing) {
this.roleFacing = newFacing;
const s = this.roleVisual.scale;
this.roleVisual.setScale(this.roleBaseScaleX * this.roleFacing, s.y, s.z);
}
}
// 计算新位置(只改变Y坐标,X坐标保持初始值不变)
// 应用新位置到玩家
this.playerNode.position = v3(posX, this.initialY, 0);
}
onTouchEnd(event: EventTouch) {
//穿透
event.preventSwallow = true;
event.propagationStopped = true;
this.isTouchStart = false
}
/**攻击动效 */
public playAtk() {
if (!this.playerSpine) return;
//if (this.playerSpine.animation == '攻击') return
this.playerSpine.setAnimation(0, '攻击', false);
this.playerSpine.setCompleteListener(() => {
this.playerSpine.setCompleteListener(null);
this.playWait();
})
}
/**待机动效 */
public playWait() {
if (!this.playerSpine) return;
if (this.playerSpine.animation == '待机') return
this.playerSpine.setAnimation(0, '待机', true);
}
/**显示升级特效 */
showLevelSpine(labstr: string) {
this.scheduleOnce(() => {
this.levelSpine.node.active = true
//播放音效
gg.audio.playEffect({ name: "强化" });
this.levelSpine.setAnimation(0, '升级', false);
this.levelSpine.setCompleteListener(() => {
this.levelSpine.node.active = false
})
if (labstr) {
let piaoLab = this.playerNode.find("piaoLab")
piaoLab.setPosition(0, 65)
if (piaoLab) {
piaoLab.active = true
piaoLab.getComponent(Label).string = labstr
tween(piaoLab)
.to(0.4, { position: v3(0, 120) })
.call(() => {
piaoLab.active = false
})
.start()
}
}
}, 0.2)
}
/**播放挥刀动画 */
public playFruitKnifeAtk(callback: Function) {
let n = this.node.find("水果刀");
if (n) {
n.active = true;
let anim = n.getComponent(sp.Skeleton);
anim.setAnimation(0, '挥刀', false);
anim.setCompleteListener(() => {
n.active = false;
anim.setCompleteListener(null);
if (callback) {
callback()
}
})
}
}
}