| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- import { _decorator, Component, Node, Vec3, tween, find, Sprite, Color } from 'cc';
- const { ccclass, property } = _decorator;
- /**
- * SkillButtonAnimator
- * 负责技能按钮的缩放 / 移动动画和星星闪烁效果。
- * 提供 playShrink 接口供外部调用。
- */
- @ccclass('SkillButtonAnimator')
- export class SkillButtonAnimator extends Component {
- private _origScale: Vec3 = new Vec3();
- private _origPos: Vec3 = new Vec3();
- private _starNodes: Node[] = [];
- private _blinkTween: any = null;
-
- // 星星颜色配置
- private readonly STAR_ACTIVE_COLOR = new Color(255, 255, 255, 255); // 亮起的星星
- private readonly STAR_INACTIVE_COLOR = new Color(58, 37, 37, 255); // 未亮起的星星 (3A2525)
- onLoad() {
- // 记录初始位置、缩放,用于恢复
- this._origScale.set(this.node.scale);
- this._origPos.set(this.node.position);
-
- // 查找星星节点
- this.findStarNodes();
- }
- /**
- * 查找星星节点
- */
- private findStarNodes() {
- const starContainer = this.node.getChildByName('Star');
- if (starContainer) {
- // 查找所有星星节点 (xx-1, xx-2, xx-3, xx-4, xx-5)
- for (let i = 1; i <= 5; i++) {
- const starNode = starContainer.getChildByName(`xx-${i}`);
- if (starNode) {
- this._starNodes.push(starNode);
- }
- }
- }
- }
- /**
- * 设置技能等级并更新星星显示
- * @param currentLevel 当前等级 (0-5)
- */
- public setSkillLevel(currentLevel: number) {
- // 停止之前的闪烁动画
- this.stopBlinkAnimation();
-
- // 更新星星显示
- this._starNodes.forEach((starNode, index) => {
- const sprite = starNode.getComponent(Sprite);
- if (sprite) {
- if (index < currentLevel) {
- // 已亮起的星星
- sprite.color = this.STAR_ACTIVE_COLOR;
- } else {
- // 未亮起的星星
- sprite.color = this.STAR_INACTIVE_COLOR;
- }
- }
- });
-
- // 如果当前等级小于最大等级,开始闪烁下一颗星星
- if (currentLevel < 5) {
- this.startBlinkAnimation(currentLevel);
- }
- }
- /**
- * 开始星星闪烁动画
- * @param nextStarIndex 下一颗要闪烁的星星索引 (0-4)
- */
- private startBlinkAnimation(nextStarIndex: number) {
- if (nextStarIndex >= this._starNodes.length) return;
-
- const nextStar = this._starNodes[nextStarIndex];
- const sprite = nextStar.getComponent(Sprite);
- if (!sprite) return;
-
- // 创建闪烁动画:在亮起和未亮起之间切换
- this._blinkTween = tween(sprite)
- .to(0.5, { color: this.STAR_ACTIVE_COLOR })
- .to(0.5, { color: this.STAR_INACTIVE_COLOR })
- .union()
- .repeatForever()
- .start();
- }
- /**
- * 停止星星闪烁动画
- */
- private stopBlinkAnimation() {
- if (this._blinkTween) {
- this._blinkTween.stop();
- this._blinkTween = null;
- }
- }
- /**
- * 播放缩小并(可选)移动到指定目标位置的动画。
- * @param duration 动画时长(秒)
- * @param targetPos 目标位置(节点本地坐标系),不传则保持原位置
- * @param onComplete 完成回调
- */
- public playShrink(duration: number = 0.3, targetPos?: Vec3, onComplete?: () => void) {
- // 停止闪烁动画
- this.stopBlinkAnimation();
-
- // 若目标位置存在,则先 tween 到该位置;否则只缩放
- const props: any = { scale: new Vec3(0, 0, 0) };
- if (targetPos) {
- props.position = targetPos;
- }
- tween(this.node)
- .to(duration, props, { easing: 'quadIn' })
- .call(() => {
- // 动画结束后隐藏节点,但允许后续 resetState 恢复
- this.node.active = false;
- if (onComplete) onComplete();
- })
- .start();
- this.node.setPosition(this._origPos);
- }
- public resetState() {
- // 停止闪烁动画
- this.stopBlinkAnimation();
-
- // Reset scale, position, opacity, etc. as needed
- this.node.setScale(Vec3.ONE);
- this.node.active = true;
- this.node.setPosition(this._origPos);
-
- // 重置星星显示为0级状态
- this.setSkillLevel(0);
- }
- onDestroy() {
- // 清理闪烁动画
- this.stopBlinkAnimation();
- }
- }
- export default SkillButtonAnimator;
|