212 lines
6.2 KiB
TypeScript
212 lines
6.2 KiB
TypeScript
import { _decorator, Component, Node, SkeletalAnimation, Input, EventTouch, input, Label } from 'cc';
|
||
const { ccclass, property } = _decorator;
|
||
|
||
/** 玩家状态 */
|
||
enum EPlayerState {
|
||
IDLE,
|
||
WALK,
|
||
RUN,
|
||
DIE,
|
||
VICTORY
|
||
}
|
||
|
||
@ccclass('WoodenManPlayer')
|
||
export class WoodenManPlayer extends Component {
|
||
|
||
private id: number = 0;
|
||
private alive: boolean = true;
|
||
private passed: boolean = false;
|
||
private isLocalPlayer: boolean = false;
|
||
private animator: SkeletalAnimation = null;
|
||
public isMoving: boolean = false;
|
||
private hasPlayedDieAnimation: boolean = false;
|
||
private moveTimer: number = 0; // 添加移动计时器
|
||
private readonly WALK_SPEED = 3; // 走路速度
|
||
private readonly RUN_SPEED = 6; // 跑步速度
|
||
private isStoppingMove: boolean = false; // 添加在类的开头
|
||
private _playerState: EPlayerState = EPlayerState.IDLE;
|
||
|
||
|
||
@property(Node)
|
||
moveButton: Node = null; // 新增移动按钮引用
|
||
|
||
@property(Label)
|
||
buttonLabel: Label = null; // 新增按钮文字组件引用
|
||
|
||
private isMovingByButton: boolean = false; // 按钮触发移动状态
|
||
|
||
init(id: number, isLocal: boolean) {
|
||
this.id = id;
|
||
this.isLocalPlayer = isLocal;
|
||
this.animator = this.getComponentInChildren(SkeletalAnimation);
|
||
if (!this.animator) {
|
||
console.error(`Player ${id} 缺少 SkeletalAnimation 组件`);
|
||
} else {
|
||
const idleState = this.animator.getState('player_idle1');
|
||
if (idleState && this._playerState === EPlayerState.IDLE) {
|
||
this.animator.crossFade('player_idle1', 0.1);
|
||
}
|
||
}
|
||
}
|
||
|
||
getId(): number {
|
||
return this.id;
|
||
}
|
||
|
||
isAlive(): boolean {
|
||
return this.alive;
|
||
}
|
||
|
||
isPassed(): boolean {
|
||
return this.passed;
|
||
}
|
||
|
||
setAlive(alive: boolean) {
|
||
this.alive = alive;
|
||
if (!alive) {
|
||
// 死亡时停止所有动画和移动
|
||
this.isMoving = false;
|
||
this._playerState = EPlayerState.DIE;
|
||
if (this._getAnimator()) {
|
||
this.animator.stop(); // 停止当前动画
|
||
}
|
||
}
|
||
}
|
||
|
||
setPassed(value: boolean) {
|
||
this.passed = value;
|
||
}
|
||
|
||
// 播放死亡动画
|
||
playDieAnimation(callback?: () => void) {
|
||
if (this.hasPlayedDieAnimation) return;
|
||
|
||
// 先停止当前动画
|
||
if (this._getAnimator()) {
|
||
this.animator.stop();
|
||
const state = this.animator.getState('player_die');
|
||
if (state) {
|
||
state.wrapMode = 1; // 1 表示只播放一次
|
||
this.animator.crossFade('player_die', 0.5);
|
||
if (callback) {
|
||
state.once(SkeletalAnimation.EventType.FINISHED, callback);
|
||
}
|
||
this.hasPlayedDieAnimation = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 播放胜利动画
|
||
playVictoryAnimation() {
|
||
// if (this.animator) {
|
||
// // 胜利动画带过渡
|
||
// this.animator.crossFade('victory', 0.5);
|
||
// }
|
||
}
|
||
|
||
// 播放行走动画
|
||
playWalkAnimation() {
|
||
if (this._getAnimator()) {
|
||
const state = this.animator.getState('player_walk');
|
||
if (state) {
|
||
this._playerState = EPlayerState.WALK;
|
||
state.wrapMode = 2; // 2 表示循环模式
|
||
this.animator.play('player_walk');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 播放跑步动画
|
||
playRunAnimation() {
|
||
if (this._getAnimator()) {
|
||
const state = this.animator.getState('player_run');
|
||
if (state) {
|
||
this._playerState = EPlayerState.RUN;
|
||
state.wrapMode = 2; // 2 表示循环模式
|
||
this.animator.play('player_run');
|
||
}
|
||
}
|
||
}
|
||
|
||
// 停止移动c
|
||
stopMoving() {
|
||
if (!this.isMoving || this.isStoppingMove) return;
|
||
|
||
this.isStoppingMove = true; // 设置标志
|
||
this.isMoving = false;
|
||
this.moveTimer = 0;
|
||
this._playerState = EPlayerState.IDLE;
|
||
if (this._getAnimator()) {
|
||
this.animator.crossFade('player_idle1', 0.3);
|
||
}
|
||
// 同步按钮状态
|
||
if (this.isMovingByButton && this.buttonLabel) {
|
||
this.buttonLabel.string = 'GO';
|
||
this.isMovingByButton = false;
|
||
}
|
||
|
||
this.isStoppingMove = false; // 重置标志
|
||
}
|
||
|
||
// 修改按钮点击处理
|
||
onButtonClick() {
|
||
if (!this.isAlive()) return;
|
||
|
||
if (!this.isMovingByButton) {
|
||
this.startMoving();
|
||
if (this.buttonLabel) {
|
||
this.buttonLabel.string = 'STOP';
|
||
}
|
||
this.isMovingByButton = true;
|
||
} else {
|
||
this.stopMoving();
|
||
if (this.buttonLabel) {
|
||
this.buttonLabel.string = 'GO';
|
||
}
|
||
this.isMovingByButton = false;
|
||
}
|
||
}
|
||
|
||
private _getAnimator() {
|
||
if (!this.animator) {
|
||
this.animator = this.getComponentInChildren(SkeletalAnimation);
|
||
if (!this.animator) {
|
||
console.error(`Player ${this.id} 缺少 SkeletalAnimation 组件`);
|
||
}
|
||
}
|
||
return this.animator;
|
||
|
||
}
|
||
|
||
|
||
public startMoving() {
|
||
if (!this.isAlive() || this.isMoving) return;
|
||
|
||
this.isMoving = true;
|
||
this.moveTimer = 0; // 重置计时器
|
||
if (this._getAnimator()) {
|
||
this.playWalkAnimation();
|
||
}
|
||
}
|
||
|
||
update(dt: number) {
|
||
if (this.isMoving) {
|
||
this.moveTimer += dt;
|
||
|
||
// 根据移动时间切换动画
|
||
if (this.moveTimer >= 1 && this._getAnimator() && this._playerState !== EPlayerState.RUN) {
|
||
this._playerState = EPlayerState.RUN;
|
||
this.animator.getState('player_run').wrapMode = 2;
|
||
this.animator.crossFade('player_run', 0.3);
|
||
}
|
||
|
||
// 计算移动速度
|
||
const currentSpeed = this.moveTimer >= 1 ? this.RUN_SPEED : this.WALK_SPEED;
|
||
|
||
// 向-Z方向移动(假设角色朝向正确)
|
||
const newPos = this.node.position.clone();
|
||
newPos.z -= currentSpeed * dt;
|
||
this.node.setPosition(newPos);
|
||
}
|
||
}
|
||
}
|