import { _decorator, Color, Component, Node, Sprite, tween, Vec3, view, } from "cc"; import { GlobalData } from "../config/GlobalData"; import { GameState } from "../config/Config"; import { EventDispatcher } from "../libs/EventDispatcher"; const { ccclass, property } = _decorator; @ccclass("NoteControl") export class NoteControl extends Component { // 音符下落的速度 private noteSpeed: number = 800; // 是否开始下落 private isEnableFall: boolean = false; start() { // 监听清除可视区域音符事件 EventDispatcher.getTarget().on( EventDispatcher.CLEAR_SCREEN_NOTE, this.clearScreenNote, this, ); // 监听游戏开始事件 EventDispatcher.getTarget().on( EventDispatcher.GAME_STAET, this.startFall, this, ); } // 开始下落 startFall() { this.isEnableFall = true; } // 当前音符被小恐龙吃到了 noteBeEaten() { // 删除当前音符 this.node.removeFromParent(); // 销毁当前音符 this.node.destroy(); } // 当前音符撞到线了 noteHitLine() { // 1. 获取文字提示节点 const noteHitLabel = this.node.getChildByName("tip_text"); // 2. 显示文字提示 noteHitLabel.active = true; // 3. 获取 node 节点下的 node_img 下的 Sprite 组件 const noteHitSprite = this.node .getChildByName("note_img") .getComponent(Sprite); // 4. 获取音符的颜色 const noteColor = new Color("ffffff"); // 5. 操作音符闪烁 tween(noteHitSprite) .repeat( 3, tween() .to(0.2, { color: new Color(noteColor.r, noteColor.g, noteColor.b, 0), }) .to(0.2, { color: noteColor, }), ) .call(() => { // 文字提示节点逐渐缩小并消失 tween(noteHitLabel) .to(0.5, { scale: new Vec3(0, 0, 0), }) .call(() => { // 完成闪烁之后的逻辑 // 判断游戏状态 if (GlobalData.gameState === GameState.GAME_OVER) { // 1. 游戏结束,删除当前界面内的音符节点 EventDispatcher.getTarget().emit(EventDispatcher.CLEAR_ALL_NOTE); // 2. 在0.1 s后操作小恐龙身体往上移动到线的位置 this.scheduleOnce(() => { EventDispatcher.getTarget().emit( EventDispatcher.MOVE_DINO_TO_LINE, ); }, 0.1); // 3. 弹出结束的弹窗 EventDispatcher.getTarget().emit( EventDispatcher.SHOW_RESULT_MODAL, ); } else if (GlobalData.gameState === GameState.PAUSED) { // 1. 显示继续游戏弹窗界面 EventDispatcher.getTarget().emit( EventDispatcher.SHOW_CONTINUE_MODAL, ); // 2. 清楚可视区域内的音符节点 EventDispatcher.getTarget().emit( EventDispatcher.CLEAR_SCREEN_NOTE, ); } }) .start(); }) .start(); } // 清除可视区域音符 private clearScreenNote() { // 判断是否在可视区域内 if (this.checkIsInScreen()) { // 清除所有音符节点 this.node.removeFromParent(); this.node.destroy(); } } // 检查是否在可视区域内 private checkIsInScreen() { // 获取屏幕可视区域的宽度和高度 const screenWidth = view.getVisibleSize().width; const screenHeight = view.getVisibleSize().height; // 获取当前节点的世界坐标 const worldPos = this.node.getWorldPosition(); // 判断音符是否在屏幕内 if ( worldPos.y >= 0 && worldPos.y <= screenHeight && worldPos.x >= 0 && worldPos.x <= screenWidth ) { return true; } return false; } update(deltaTime: number) { // 游戏未开始,不更新音符位置 if (!this.isEnableFall || GlobalData.gameState != GameState.PLAYING) { return; } this.node.setPosition( this.node.position.x, this.node.position.y - this.noteSpeed * GlobalData.speedRate * deltaTime, ); } }