181404010226 пре 1 недеља
родитељ
комит
804c5229b8
2 измењених фајлова са 197 додато и 0 уклоњено
  1. 188 0
      assets/scripts/TimeBaseController.ts
  2. 9 0
      assets/scripts/TimeBaseController.ts.meta

+ 188 - 0
assets/scripts/TimeBaseController.ts

@@ -0,0 +1,188 @@
+import { _decorator, Component, Node, Label, Sprite, tween, Vec3 } from 'cc';
+const { ccclass, property } = _decorator;
+
+/**
+ * 时间底座动画控制器,负责处理时间相关的动画效果
+ */
+@ccclass('TimeBaseController')
+export class TimeBaseController extends Component {
+    @property({
+        type: Sprite,
+        tooltip: '时间灯1'
+    })
+    timeLight1: Sprite = null;
+
+    @property({
+        type: Sprite,
+        tooltip: '时间灯2'
+    })
+    timeLight2: Sprite = null;
+
+    @property({
+        type: Label,
+        tooltip: '时间标签'
+    })
+    timeLabel: Label = null;
+
+    // 倒计时总时间(秒)
+    private totalTime: number = 150; // 2分30秒
+    
+    // 当前剩余时间(秒)
+    private remainingTime: number = 150;
+    
+    // 上一分钟时间,用于检测分钟变化
+    private lastMinute: number = -1;
+    
+    // 灯光闪烁间隔(秒)
+    private urgentBlinkInterval: number = 0.5;
+    
+    // 当前是否在紧急状态(少于1分钟)
+    private isUrgent: boolean = false;
+    
+    // 灯光交替显示计时器
+    private blinkTimer: number = 0;
+    
+    // 当前激活的灯
+    private activeLightIndex: number = 0;
+
+    start() {
+        // 初始化灯光状态
+        this.resetLights();
+        
+        // 初始化时间显示
+        this.updateTimeDisplay();
+    }
+
+    update(dt: number) {
+        // 更新剩余时间
+        this.remainingTime = Math.max(0, this.remainingTime - dt);
+        
+        // 更新时间显示
+        this.updateTimeDisplay();
+        
+        // 计算分钟和秒
+        const minutes = Math.floor(this.remainingTime / 60);
+        const seconds = Math.floor(this.remainingTime % 60);
+        
+        // 检查是否进入紧急状态(剩余时间少于1分钟)
+        const isCurrentlyUrgent = minutes < 1;
+        
+        // 状态变化时重置
+        if (this.isUrgent !== isCurrentlyUrgent) {
+            this.isUrgent = isCurrentlyUrgent;
+            this.blinkTimer = 0;
+            this.resetLights();
+        }
+        
+        // 仅在紧急状态下处理灯光闪烁
+        if (this.isUrgent) {
+            this.handleLightBlink(dt);
+        }
+        
+        // 检查分钟变化,触发标签动画
+        if (minutes !== this.lastMinute) {
+            this.lastMinute = minutes;
+            this.playLabelPulseAnimation();
+        }
+    }
+    
+    /**
+     * 更新时间显示
+     */
+    private updateTimeDisplay() {
+        if (!this.timeLabel) return;
+        
+        // 计算分钟和秒
+        const minutes = Math.floor(this.remainingTime / 60);
+        const seconds = Math.floor(this.remainingTime % 60);
+        
+        // 格式化时间字符串 (mm:ss)
+        const timeString = `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
+        
+        // 更新标签文本
+        this.timeLabel.string = timeString;
+    }
+    
+    /**
+     * 重置倒计时时间
+     * @param time 设置的时间(秒)
+     */
+    public resetTime(time: number = 150) {
+        this.totalTime = time;
+        this.remainingTime = time;
+        this.lastMinute = Math.floor(time / 60);
+        this.updateTimeDisplay();
+        
+        // 重置状态
+        this.isUrgent = Math.floor(time / 60) < 1;
+        this.resetLights();
+    }
+    
+    /**
+     * 处理灯光闪烁逻辑
+     */
+    private handleLightBlink(dt: number) {
+        // 更新计时器
+        this.blinkTimer += dt;
+        
+        // 到达间隔时间则切换灯光
+        if (this.blinkTimer >= this.urgentBlinkInterval) {
+            this.blinkTimer = 0;
+            this.switchLights();
+        }
+    }
+    
+    /**
+     * 切换灯光显示
+     */
+    private switchLights() {
+        // 紧急状态时交替闪烁两个灯
+        this.activeLightIndex = 1 - this.activeLightIndex;
+        
+        if (this.timeLight1 && this.timeLight2) {
+            this.timeLight1.node.active = this.activeLightIndex === 0;
+            this.timeLight2.node.active = this.activeLightIndex === 1;
+        }
+    }
+    
+    /**
+     * 重置灯光状态
+     */
+    private resetLights() {
+        if (this.timeLight1 && this.timeLight2) {
+            if (this.isUrgent) {
+                // 紧急状态下初始只显示一个灯,准备交替闪烁
+                this.timeLight1.node.active = true;
+                this.timeLight2.node.active = false;
+                this.activeLightIndex = 0;
+            } else {
+                // 非紧急状态下只显示第一个灯,不闪烁
+                this.timeLight1.node.active = true;
+                this.timeLight2.node.active = false;
+            }
+        }
+    }
+    
+    /**
+     * 播放标签脉冲动画(在整数分钟时触发)
+     */
+    private playLabelPulseAnimation() {
+        if (!this.timeLabel) return;
+        
+        // 保存原始缩放
+        const originalScale = this.timeLabel.node.scale.clone();
+        const targetScale = new Vec3(originalScale.x * 1.3, originalScale.y * 1.3, originalScale.z);
+        
+        // 创建放大然后恢复的动画序列
+        tween(this.timeLabel.node)
+            .to(0.1, { scale: targetScale })
+            .to(0.1, { scale: originalScale })
+            // 添加轻微抖动
+            .to(0.05, { position: new Vec3(5, 0, 0) })
+            .to(0.05, { position: new Vec3(-5, 0, 0) })
+            .to(0.05, { position: new Vec3(3, 0, 0) })
+            .to(0.05, { position: new Vec3(-3, 0, 0) })
+            .to(0.05, { position: new Vec3(0, 0, 0) })
+            .start();
+    }
+} 

+ 9 - 0
assets/scripts/TimeBaseController.ts.meta

@@ -0,0 +1,9 @@
+{
+  "ver": "4.0.24",
+  "importer": "typescript",
+  "imported": true,
+  "uuid": "fa34dbfd-ff8d-4ff8-a20b-b9858d8db07a",
+  "files": [],
+  "subMetas": {},
+  "userData": {}
+}