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.
488 lines
17 KiB
488 lines
17 KiB
|
1 week ago
|
import { _decorator, clamp01, Collider2D, Color, Component, Contact2DType, director, find, instantiate, IPhysics2DContact, Label, Node, Sprite, Tween, tween, v3, Vec3 } from 'cc';
|
||
|
|
import ZClips from 'db://assets/mx/components/ZClips';
|
||
|
|
import { SuDace } from './SuDace';
|
||
|
|
import { SuDaceBullet } from './SuDaceBullet';
|
||
|
|
import { SuDacePoint } from './SuDacePoint';
|
||
|
|
import { SuDaceBox } from './SuDaceBox';
|
||
|
|
|
||
|
|
/** 避免与 SuDaceMap 循环引用,仅声明格子查询 */
|
||
|
|
interface ISuDaceGridMap {
|
||
|
|
getGridCellAtWorld(worldPos: Readonly<Vec3>): Node | null;
|
||
|
|
getSuDacePointAtWorld(worldPos: Readonly<Vec3>): SuDacePoint | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
const { ccclass, property } = _decorator;
|
||
|
|
|
||
|
|
/** 移动方向(与 onMoveStatusChange / 动作表现一致,供摇杆等输入量化后复用) */
|
||
|
|
export enum MoveDirection {
|
||
|
|
NONE = 0,
|
||
|
|
RIGHT = 1,
|
||
|
|
LEFT = -1,
|
||
|
|
UP = 2,
|
||
|
|
DOWN = -2,
|
||
|
|
}
|
||
|
|
@ccclass('SuDacePlayer')
|
||
|
|
export class SuDacePlayer extends Component {
|
||
|
|
|
||
|
|
@property({ displayName: "移动速度" })
|
||
|
|
moveSpeed: number = 300;
|
||
|
|
|
||
|
|
@property({ displayName: "最大血量" })
|
||
|
|
maxHp = 100;
|
||
|
|
|
||
|
|
|
||
|
|
hp = 100;
|
||
|
|
|
||
|
|
/**玩家节点 */
|
||
|
|
skinNode: Node = null;
|
||
|
|
/**身体节点 */
|
||
|
|
bodyNode: Node = null;
|
||
|
|
/**倒地节点 */
|
||
|
|
dieNode: Node = null;
|
||
|
|
/**爬梯子 */
|
||
|
|
upMoveNode: Node = null;
|
||
|
|
/**头部节点 */
|
||
|
|
headNode: Node = null;
|
||
|
|
/**腿部节点 */
|
||
|
|
legNode: Node = null;
|
||
|
|
/**胳膊节点 */
|
||
|
|
armNode: Node = null;
|
||
|
|
|
||
|
|
/**血条 */
|
||
|
|
hpBar: Sprite = null;
|
||
|
|
|
||
|
|
/**子弹模版 */
|
||
|
|
bulletTemplate: Node = null;
|
||
|
|
|
||
|
|
/**是否正在爬楼梯 */
|
||
|
|
isClimbing: boolean = false;
|
||
|
|
/**描述文本 */
|
||
|
|
lbDesc: Label = null;
|
||
|
|
|
||
|
|
/**当前所在楼层(由脚下格子 SuDacePoint.floor 刷新) */
|
||
|
|
currentFloor: number = 0;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
private _dead = false;
|
||
|
|
_col: Collider2D | null = null;
|
||
|
|
|
||
|
|
atkAdd = 0;
|
||
|
|
speedAdd = 0;
|
||
|
|
atkIntervalAdd = 0;
|
||
|
|
|
||
|
|
addAttr(index: number, value: number) {
|
||
|
|
this.lbDesc.node.active = true;
|
||
|
|
switch (index) {
|
||
|
|
case 0:
|
||
|
|
this.atkAdd += value;
|
||
|
|
this.lbDesc.string = `攻击力+${Math.floor(value * 100)}%`;
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
this.speedAdd += value;
|
||
|
|
this.lbDesc.string = `速度+${Math.floor(value * 100)}%`;
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
this.atkIntervalAdd += value;
|
||
|
|
this.lbDesc.string = `攻击间隔+${Math.floor(value * 100)}%`;
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
this.hp += value;
|
||
|
|
if (this.hp > this.maxHp) this.hp = this.maxHp;
|
||
|
|
this.lbDesc.string = `血量+${Math.floor(value * 100)}%`;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
this.lbDesc.node.opacity = 255;
|
||
|
|
tween(this.lbDesc.node).delay(2).to(1, { opacity: 0 }).call(() => {
|
||
|
|
this.lbDesc.node.active = false;
|
||
|
|
}).start();
|
||
|
|
}
|
||
|
|
|
||
|
|
protected onLoad(): void {
|
||
|
|
this.skinNode = find("skin", this.node);
|
||
|
|
this.bodyNode = find("skin/射击", this.node);
|
||
|
|
this.dieNode = find("skin/倒地", this.node);
|
||
|
|
this.upMoveNode = find("skin/爬梯", this.node);
|
||
|
|
this.legNode = find("skin/射击/腿部", this.node);
|
||
|
|
this.headNode = find("skin/射击/头部", this.node);
|
||
|
|
this.armNode = find("skin/射击/胳膊", this.node);
|
||
|
|
this.bulletTemplate = find("bullet", this.armNode);
|
||
|
|
this.hpBar = find("b/bp", this.node).getComponent(Sprite);
|
||
|
|
this.lbDesc = find("lbDesc", this.node).getComponent(Label);
|
||
|
|
this.hp = Math.max(1, this.maxHp);
|
||
|
|
}
|
||
|
|
|
||
|
|
protected onEnable(): void {
|
||
|
|
this._col = this.node.getComponent(Collider2D);
|
||
|
|
this._col?.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
||
|
|
}
|
||
|
|
protected onDisable(): void {
|
||
|
|
this._col?.off(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
|
||
|
|
}
|
||
|
|
|
||
|
|
takeDamage(amount: number): void {
|
||
|
|
if (this._dead || amount <= 0) return;
|
||
|
|
this.hp -= amount;
|
||
|
|
if (this.hp <= 0) {
|
||
|
|
this.hp = 0;
|
||
|
|
this._dead = true;
|
||
|
|
SuDace.instance?.onPlayerDefeated();
|
||
|
|
}
|
||
|
|
this.hpBar.fillRange = clamp01(this.hp / this.maxHp);
|
||
|
|
|
||
|
|
let comp = this.node.getComponentsInChildren(Sprite);
|
||
|
|
comp.forEach(spr => {
|
||
|
|
if (spr.node.name != "bp") spr.color = Color.RED
|
||
|
|
});
|
||
|
|
this.scheduleOnce(() => {
|
||
|
|
comp.forEach(spr => {
|
||
|
|
spr.color = Color.WHITE
|
||
|
|
});
|
||
|
|
}, 0.3);
|
||
|
|
}
|
||
|
|
|
||
|
|
private onBeginContact(self: Collider2D, other: Collider2D, contact: IPhysics2DContact | null) {
|
||
|
|
if (!this.node.active || !other?.node?.active) return;
|
||
|
|
const otherName = other.node.name.toLowerCase();
|
||
|
|
if (otherName === "box" || otherName.includes("box")) {
|
||
|
|
let comp = other.node.getComponent(SuDaceBox);
|
||
|
|
if (comp) {
|
||
|
|
comp.openBox(this);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/** 关卡重开时由 SuDace 调用 */
|
||
|
|
resetForStage(): void {
|
||
|
|
this._dead = false;
|
||
|
|
this.hp = Math.max(1, this.maxHp);
|
||
|
|
this.hpBar.fillRange = clamp01(this.hp / this.maxHp);
|
||
|
|
this.isClimbing = false;
|
||
|
|
this._inputDir = MoveDirection.NONE;
|
||
|
|
this._lastInputDir = MoveDirection.NONE;
|
||
|
|
this._climbStartGrid = null;
|
||
|
|
this._leftStairStart = false;
|
||
|
|
this.onMoveStatusChange(MoveDirection.NONE);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 摇杆四向输入;NONE 表示无输入 */
|
||
|
|
private _inputDir: MoveDirection = MoveDirection.NONE;
|
||
|
|
/** 上一帧有效位移方向(含楼梯规则),用于边界时打断 tween、松手回待机 */
|
||
|
|
private _lastInputDir: MoveDirection = MoveDirection.NONE;
|
||
|
|
|
||
|
|
/** 开始攀爬时所在格子,用于判断是否离开起点 */
|
||
|
|
private _climbStartGrid: Node | null = null;
|
||
|
|
private readonly _climbStartWorld = new Vec3();
|
||
|
|
private _leftStairStart = false;
|
||
|
|
/** 离开楼梯起点判定:位移或换格超过该阈值视为已离开起点(像素,世界单位) */
|
||
|
|
private static readonly _STAIR_LEAVE_EPS = 22;
|
||
|
|
|
||
|
|
curentAtkInterval = 100;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 由 SuDaceJoystick 等输入组件每帧/每次触摸更新;仅改变位移,不改变 onMoveStatusChange 分支语义。
|
||
|
|
*/
|
||
|
|
setMoveInput(dir: MoveDirection): void {
|
||
|
|
this._inputDir = dir;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected update(dt: number): void {
|
||
|
|
if (this._dead) return;
|
||
|
|
if (!SuDace.instance) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (SuDace.instance.gameFailed || SuDace.instance.levelCleared) return;
|
||
|
|
this.curentAtkInterval = 30;
|
||
|
|
if (this.atkIntervalAdd > 0) {
|
||
|
|
this.curentAtkInterval = Math.max(30 - (this.atkIntervalAdd * 30), 10);
|
||
|
|
}
|
||
|
|
|
||
|
|
let grid = SuDace.instance.map.getGridCellAtWorld(this.node.worldPosition);
|
||
|
|
|
||
|
|
if (director.getTotalFrames() % this.curentAtkInterval == 0) {
|
||
|
|
this.atk();
|
||
|
|
|
||
|
|
SuDace.instance.playAtk();
|
||
|
|
if (grid) {
|
||
|
|
let p = grid.getComponent(SuDacePoint);
|
||
|
|
if (p && p.isTrap) {
|
||
|
|
let stone = SuDace.instance.map.generateStone();
|
||
|
|
stone.setWorldPosition(grid.worldPosition.clone().add(v3(0, -50, 0)));
|
||
|
|
stone.angle = 180;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
this.tickDirectionalInput(dt);
|
||
|
|
}
|
||
|
|
|
||
|
|
private tickDirectionalInput(dt: number): void {
|
||
|
|
const map = SuDace.instance?.map;
|
||
|
|
const point = map?.getSuDacePointAtWorld(this.node.worldPosition) ?? null;
|
||
|
|
const effective = this.resolveStairMoveDirection(this._inputDir, point);
|
||
|
|
|
||
|
|
if (effective === MoveDirection.NONE) {
|
||
|
|
if (this._lastInputDir !== MoveDirection.NONE) {
|
||
|
|
if (!this.isClimbing) {
|
||
|
|
this.onMoveStatusChange(MoveDirection.NONE);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this._lastInputDir = MoveDirection.NONE;
|
||
|
|
if (this.isClimbing) {
|
||
|
|
this.refreshStairLanding(map);
|
||
|
|
}
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!this.isClimbing) {
|
||
|
|
if (effective === MoveDirection.UP && point?.isUpStairs) {
|
||
|
|
this.beginStairClimb(map);
|
||
|
|
} else if (effective === MoveDirection.DOWN && point?.isDownStairs) {
|
||
|
|
this.beginStairClimb(map);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (this._lastInputDir === MoveDirection.NONE) {
|
||
|
|
Tween.stopAllByTarget(this.node);
|
||
|
|
}
|
||
|
|
this._lastInputDir = effective;
|
||
|
|
this.stepAxisLockedWorldMove(effective, dt);
|
||
|
|
this.onMoveStatusChange(effective);
|
||
|
|
if (this.isClimbing) {
|
||
|
|
this.refreshStairLanding(map);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private beginStairClimb(map: ISuDaceGridMap | null | undefined): void {
|
||
|
|
if (!map) return;
|
||
|
|
this.isClimbing = true;
|
||
|
|
this._climbStartGrid = map.getGridCellAtWorld(this.node.worldPosition);
|
||
|
|
this._leftStairStart = false;
|
||
|
|
Vec3.copy(this._climbStartWorld, this.node.worldPosition);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 楼梯规则:未攀爬时仅允许在对应楼梯口起垂直移动;攀爬中禁止水平移动;
|
||
|
|
* 离开起点后踩上带 isUpStairs/isDownStairs 的路点视为到达平台口,结束攀爬。
|
||
|
|
*/
|
||
|
|
private resolveStairMoveDirection(raw: MoveDirection, point: SuDacePoint | null): MoveDirection {
|
||
|
|
if (this.isClimbing) {
|
||
|
|
if (raw === MoveDirection.LEFT || raw === MoveDirection.RIGHT) {
|
||
|
|
return MoveDirection.NONE;
|
||
|
|
}
|
||
|
|
if (raw === MoveDirection.UP || raw === MoveDirection.DOWN) {
|
||
|
|
return raw;
|
||
|
|
}
|
||
|
|
return MoveDirection.NONE;
|
||
|
|
}
|
||
|
|
if (raw === MoveDirection.LEFT || raw === MoveDirection.RIGHT) {
|
||
|
|
return raw;
|
||
|
|
}
|
||
|
|
if (raw === MoveDirection.UP) {
|
||
|
|
return point?.isUpStairs ? MoveDirection.UP : MoveDirection.NONE;
|
||
|
|
}
|
||
|
|
if (raw === MoveDirection.DOWN) {
|
||
|
|
return point?.isDownStairs ? MoveDirection.DOWN : MoveDirection.NONE;
|
||
|
|
}
|
||
|
|
return MoveDirection.NONE;
|
||
|
|
}
|
||
|
|
|
||
|
|
private refreshStairLanding(map: ISuDaceGridMap | null | undefined): void {
|
||
|
|
if (!this.isClimbing || !map) return;
|
||
|
|
|
||
|
|
if (!this._leftStairStart && this._climbStartGrid) {
|
||
|
|
const cell = map.getGridCellAtWorld(this.node.worldPosition);
|
||
|
|
const dist = Vec3.distance(this.node.worldPosition, this._climbStartWorld);
|
||
|
|
if ((cell && cell !== this._climbStartGrid) || dist > SuDacePlayer._STAIR_LEAVE_EPS) {
|
||
|
|
this._leftStairStart = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!this._leftStairStart) return;
|
||
|
|
|
||
|
|
const p = map.getSuDacePointAtWorld(this.node.worldPosition);
|
||
|
|
if (p && (p.isUpStairs || p.isDownStairs)) {
|
||
|
|
this.finishStairClimbAtPoint(p);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 结束爬梯时把角色吸附到梯口路点,避免停在楼板里/悬空 */
|
||
|
|
private finishStairClimbAtPoint(point: SuDacePoint): void {
|
||
|
|
const z = this.node.worldPosition.z;
|
||
|
|
this.node.setWorldPosition(point.node.worldPosition.x, point.node.worldPosition.y, z);
|
||
|
|
this.isClimbing = false;
|
||
|
|
this._climbStartGrid = null;
|
||
|
|
this._leftStairStart = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 与 moveTo 一致:左右只动 X,上下只动 Y */
|
||
|
|
private stepAxisLockedWorldMove(dir: MoveDirection, dt: number): void {
|
||
|
|
const p = this.node.worldPosition;
|
||
|
|
const oldPos = this.node.worldPosition.clone();
|
||
|
|
const step = this.moveSpeed * dt * (1 + this.speedAdd);
|
||
|
|
switch (dir) {
|
||
|
|
case MoveDirection.RIGHT:
|
||
|
|
this.node.setWorldPosition(p.x + step, p.y, p.z);
|
||
|
|
break;
|
||
|
|
case MoveDirection.LEFT:
|
||
|
|
this.node.setWorldPosition(p.x - step, p.y, p.z);
|
||
|
|
break;
|
||
|
|
case MoveDirection.UP:
|
||
|
|
this.node.setWorldPosition(p.x, p.y + step, p.z);
|
||
|
|
break;
|
||
|
|
case MoveDirection.DOWN:
|
||
|
|
this.node.setWorldPosition(p.x, p.y - step, p.z);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
let grid = SuDace.instance.map.getGridCellAtWorld(this.node.worldPosition);
|
||
|
|
if (grid) {
|
||
|
|
let p = grid.getComponent(SuDacePoint);
|
||
|
|
if (p && p.isWall) {
|
||
|
|
this.node.setWorldPosition(oldPos);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (p && p.isCliff) {
|
||
|
|
tween(this.node).to(1, { position: v3(this.node.position.x, -641.689, 0) }).call(() => {
|
||
|
|
this.hp = 0;
|
||
|
|
this._dead = true;
|
||
|
|
SuDace.instance?.onPlayerDefeated();
|
||
|
|
}).start();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
moveTo(wordPos: Vec3, direction: MoveDirection = null) {
|
||
|
|
if (direction == null) {
|
||
|
|
direction = this.getMoveDirection(wordPos);
|
||
|
|
}
|
||
|
|
this.armNode.angle = 0;
|
||
|
|
let x = wordPos.x;
|
||
|
|
let y = wordPos.y;
|
||
|
|
let z = this.node.worldPosition.z;
|
||
|
|
if (direction == MoveDirection.RIGHT || direction == MoveDirection.LEFT) {
|
||
|
|
if (wordPos.y > this.node.worldPosition.y + 200) return;
|
||
|
|
if (wordPos.y < this.node.worldPosition.y) return;
|
||
|
|
y = this.node.worldPosition.y;
|
||
|
|
} else if (direction == MoveDirection.UP || direction == MoveDirection.DOWN) {
|
||
|
|
x = this.node.worldPosition.x;
|
||
|
|
}
|
||
|
|
Tween.stopAllByTarget(this.node);
|
||
|
|
this.onMoveStatusChange(direction);
|
||
|
|
this.targetPos.set(x, y, z);
|
||
|
|
let distance = Vec3.distance(this.node.worldPosition, this.targetPos);
|
||
|
|
let time = distance / this.moveSpeed;
|
||
|
|
tween(this.node).to(time, { worldPosition: this.targetPos }).call(() => {
|
||
|
|
this.onMoveStatusChange(MoveDirection.NONE);
|
||
|
|
}).start();
|
||
|
|
}
|
||
|
|
private targetPos: Vec3 = new Vec3();
|
||
|
|
|
||
|
|
atk() {
|
||
|
|
if (this._curentStatus == MoveDirection.UP || this._curentStatus == MoveDirection.DOWN) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
let bullet = SuDace.instance.map.generateBullet();
|
||
|
|
const muzzlePos = this.bulletTemplate?.worldPosition ?? this.armNode.worldPosition;
|
||
|
|
bullet.setWorldPosition(muzzlePos);
|
||
|
|
const bulletComp = bullet.getComponent(SuDaceBullet);
|
||
|
|
if (bulletComp) {
|
||
|
|
bulletComp.damage = SuDace.instance.weaponAttack * (1 + this.atkAdd);
|
||
|
|
}
|
||
|
|
|
||
|
|
let direction = new Vec3();
|
||
|
|
let monster = this.getAtkTarget();
|
||
|
|
if (monster) {
|
||
|
|
Vec3.subtract(direction, monster.worldPosition.clone().add(v3(0, 50, 0)), bullet.worldPosition);
|
||
|
|
} else {
|
||
|
|
// 无目标时按当前角色朝向发射
|
||
|
|
direction.set(this.node.scale.x >= 0 ? 1 : -1, 0, 0);
|
||
|
|
}
|
||
|
|
direction.normalize();
|
||
|
|
// 瞄准角(以 +X 方向为 0°):用于胳膊朝向
|
||
|
|
const aimAngle = Math.atan2(direction.y, direction.x) * 180 / Math.PI;
|
||
|
|
// SuDaceBullet 内部按 (node.angle + 90°) 计算朝向,这里要减 90° 修正
|
||
|
|
bullet.angle = aimAngle - 90;
|
||
|
|
// 同步胳膊角度(直接用瞄准角,避免与子弹修正角混用导致朝下)
|
||
|
|
this.syncArmAngleWithAim(aimAngle);
|
||
|
|
}
|
||
|
|
|
||
|
|
private syncArmAngleWithAim(aimAngle: number): void {
|
||
|
|
if (!this.armNode?.isValid) return;
|
||
|
|
// armNode 处在会左右翻转的父层级下,朝左(scale.x<0)时需要把世界瞄准角转换为局部角
|
||
|
|
const faceRight = this.node.scale.x >= 0;
|
||
|
|
const localAngle = faceRight ? aimAngle : 180 - aimAngle;
|
||
|
|
this.armNode.angle = this.normalizeDeg(localAngle);
|
||
|
|
}
|
||
|
|
|
||
|
|
private normalizeDeg(angle: number): number {
|
||
|
|
let a = angle % 360;
|
||
|
|
if (a > 180) a -= 360;
|
||
|
|
if (a < -180) a += 360;
|
||
|
|
return a;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
private getMoveDirection(targetPos: Vec3): MoveDirection {
|
||
|
|
let direction = MoveDirection.NONE;
|
||
|
|
if (targetPos.x > this.node.worldPosition.x) {
|
||
|
|
direction = MoveDirection.RIGHT;
|
||
|
|
} else if (targetPos.x < this.node.worldPosition.x) {
|
||
|
|
direction = MoveDirection.LEFT;
|
||
|
|
}
|
||
|
|
return direction;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**当移动状态发生变化时调用 */
|
||
|
|
onMoveStatusChange(status: MoveDirection) {
|
||
|
|
if (this._curentStatus === status) return;
|
||
|
|
this._curentStatus = status;
|
||
|
|
this.bodyNode.active = false;
|
||
|
|
this.upMoveNode.active = false;
|
||
|
|
let spe = 0.1 * (1 - this.atkIntervalAdd);
|
||
|
|
if (spe < 0.01) spe = 0.01;
|
||
|
|
if (spe > 0.1) spe = 0.1;
|
||
|
|
this.armNode.getComponent(ZClips).Duration = spe;
|
||
|
|
let moveClips = this.legNode.getComponent(ZClips);
|
||
|
|
moveClips.stop();
|
||
|
|
switch (status) {
|
||
|
|
case MoveDirection.NONE:
|
||
|
|
this.bodyNode.active = true;
|
||
|
|
moveClips.play(false);
|
||
|
|
break;
|
||
|
|
case MoveDirection.RIGHT:
|
||
|
|
this.bodyNode.active = true;
|
||
|
|
moveClips.play(true);
|
||
|
|
this.node.scale = v3(1, 1, 1);
|
||
|
|
this.hpBar.node.scale = v3(1, 1, 1);
|
||
|
|
this.lbDesc.node.scale = v3(1, 1, 1);
|
||
|
|
break;
|
||
|
|
case MoveDirection.LEFT:
|
||
|
|
this.bodyNode.active = true;
|
||
|
|
moveClips.play(true);
|
||
|
|
this.node.scale = v3(-1, 1, 1);
|
||
|
|
this.hpBar.node.scale = v3(-1, 1, 1);
|
||
|
|
this.lbDesc.node.scale = v3(-1, 1, 1);
|
||
|
|
break;
|
||
|
|
case MoveDirection.UP:
|
||
|
|
this.upMoveNode.active = true;
|
||
|
|
break;
|
||
|
|
case MoveDirection.DOWN:
|
||
|
|
this.upMoveNode.active = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
private _curentStatus: MoveDirection = MoveDirection.NONE;
|
||
|
|
|
||
|
|
private getAtkTarget() {
|
||
|
|
return SuDace.instance.getNearestMonster();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|