feat: 支持游戏数值
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { _decorator, Component, Node, Vec3, input, Input, EventTouch, Camera, view, tween, Animation, Collider2D, Contact2DType } from 'cc';
|
||||
import { _decorator, Component, Node, Vec3, input, Input, EventTouch, Camera, view, tween, Animation, Collider2D, Contact2DType, Label, Color } from 'cc';
|
||||
import { TiledMapPathfinder } from './TiledMapPathfinder';
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
@@ -276,24 +276,146 @@ export class PlayerController extends Component {
|
||||
|
||||
onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D) {
|
||||
if (otherCollider.node.name.startsWith('guai_')) {
|
||||
this.isAttacking = true;
|
||||
// 怪物攻击
|
||||
const animation = otherCollider.node.getComponent(Animation);
|
||||
if (animation) {
|
||||
animation.play(`${otherCollider.node.name}_attack`);
|
||||
}
|
||||
|
||||
// player 攻击
|
||||
this.switchAnimation('attack');
|
||||
|
||||
|
||||
this.scheduleOnce(() => {
|
||||
animation.play(`${otherCollider.node.name}_stand`);
|
||||
|
||||
this.isAttacking = false;
|
||||
this.switchAnimation('die');
|
||||
|
||||
}, 3);
|
||||
this.handleAttack(otherCollider);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理攻击逻辑
|
||||
*/
|
||||
private handleAttack(otherCollider: Collider2D) {
|
||||
this.isAttacking = true;
|
||||
console.log('开始攻击,怪物名称:', otherCollider.node.name);
|
||||
|
||||
// 获取玩家和怪物的生命值
|
||||
const playerHpLabel = this.player.getChildByName('hp');
|
||||
const monsterHpLabel = otherCollider.node.getChildByName('hp');
|
||||
|
||||
if (!playerHpLabel || !monsterHpLabel) {
|
||||
console.warn('未找到生命值标签,玩家hp:', playerHpLabel, '怪物hp:', monsterHpLabel);
|
||||
this.isAttacking = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取生命值数值
|
||||
const playerLabel = playerHpLabel.getComponent(Label);
|
||||
const monsterLabel = monsterHpLabel.getComponent(Label);
|
||||
|
||||
if (!playerLabel || !monsterLabel) {
|
||||
console.warn('未找到Label组件');
|
||||
this.isAttacking = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const playerHp = parseInt(playerLabel.string) || 0;
|
||||
const monsterHp = parseInt(monsterLabel.string) || 0;
|
||||
console.log('玩家生命值:', playerHp, '怪物生命值:', monsterHp);
|
||||
|
||||
// 播放攻击动画
|
||||
const monsterAnimation = otherCollider.node.getComponent(Animation);
|
||||
if (monsterAnimation) {
|
||||
monsterAnimation.play(`${otherCollider.node.name}_attack`);
|
||||
}
|
||||
this.switchAnimation('attack');
|
||||
|
||||
// 2秒后判定攻击结果
|
||||
this.scheduleOnce(() => {
|
||||
// 比较生命值,判断输赢
|
||||
console.log('判定攻击结果,玩家HP:', playerHp, '怪物HP:', monsterHp);
|
||||
if (playerHp >= monsterHp) {
|
||||
// 玩家获胜
|
||||
console.log('玩家获胜!更新玩家生命值为:', playerHp + monsterHp);
|
||||
|
||||
// 玩家生命值增加怪物生命值
|
||||
const newPlayerHp = playerHp + monsterHp;
|
||||
playerLabel.string = newPlayerHp.toString();
|
||||
|
||||
// 播放生命值标签的强调动画
|
||||
this.playLabelEmphasisAnimation(playerLabel);
|
||||
|
||||
// 播放怪物死亡动画
|
||||
if (monsterAnimation) {
|
||||
monsterAnimation.play(`${otherCollider.node.name}_die`);
|
||||
}
|
||||
|
||||
// 1秒后怪物消失
|
||||
this.scheduleOnce(() => {
|
||||
otherCollider.node.destroy();
|
||||
console.log('怪物已消失');
|
||||
}, 1);
|
||||
|
||||
this.switchAnimation('stand'); // 玩家站立
|
||||
} else {
|
||||
// 怪物获胜
|
||||
console.log('怪物获胜!玩家生命值变为0');
|
||||
|
||||
// 玩家生命值变为0
|
||||
playerLabel.string = '0';
|
||||
|
||||
// 播放生命值标签的失败动画
|
||||
this.playLabelFailAnimation(playerLabel);
|
||||
|
||||
// 玩家死亡动画
|
||||
this.switchAnimation('die');
|
||||
|
||||
// 怪物站立动画
|
||||
if (monsterAnimation) {
|
||||
monsterAnimation.play(`${otherCollider.node.name}_stand`);
|
||||
}
|
||||
}
|
||||
|
||||
this.isAttacking = false;
|
||||
}, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放生命值标签强调动画(成功时)
|
||||
*/
|
||||
private playLabelEmphasisAnimation(label: Label) {
|
||||
if (!label) return;
|
||||
|
||||
const originalScale = label.node.scale.clone();
|
||||
const originalColor = label.color.clone();
|
||||
|
||||
// 创建强调动画序列
|
||||
tween(label.node)
|
||||
.to(0.1, { scale: new Vec3(originalScale.x * 1.2, originalScale.y * 1.2, originalScale.z) })
|
||||
.to(0.1, { scale: originalScale })
|
||||
.to(0.1, { scale: new Vec3(originalScale.x * 1.1, originalScale.y * 1.1, originalScale.z) })
|
||||
.to(0.1, { scale: originalScale })
|
||||
.start();
|
||||
|
||||
// 颜色闪烁效果
|
||||
tween(label)
|
||||
.to(0.1, { color: new Color(255, 255, 0) }) // 黄色
|
||||
.to(0.1, { color: new Color(0, 255, 0) }) // 绿色
|
||||
.to(0.1, { color: originalColor })
|
||||
.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* 播放生命值标签失败动画(失败时)
|
||||
*/
|
||||
private playLabelFailAnimation(label: Label) {
|
||||
if (!label) return;
|
||||
|
||||
const originalScale = label.node.scale.clone();
|
||||
const originalColor = label.color.clone();
|
||||
|
||||
// 创建失败动画序列 - 震动效果
|
||||
tween(label.node)
|
||||
.to(0.05, { position: new Vec3(label.node.position.x - 5, label.node.position.y, label.node.position.z) })
|
||||
.to(0.05, { position: new Vec3(label.node.position.x + 5, label.node.position.y, label.node.position.z) })
|
||||
.to(0.05, { position: new Vec3(label.node.position.x - 5, label.node.position.y, label.node.position.z) })
|
||||
.to(0.05, { position: new Vec3(label.node.position.x + 5, label.node.position.y, label.node.position.z) })
|
||||
.to(0.05, { position: label.node.position })
|
||||
.start();
|
||||
|
||||
// 颜色变红效果
|
||||
tween(label)
|
||||
.to(0.1, { color: new Color(255, 0, 0) }) // 红色
|
||||
.to(0.1, { color: new Color(128, 0, 0) }) // 暗红色
|
||||
.to(0.1, { color: originalColor })
|
||||
.start();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user