174 lines
4.7 KiB
TypeScript
174 lines
4.7 KiB
TypeScript
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() {
|
|
// 设置小恐龙脖子颜色
|
|
this.setDinoNeckColor();
|
|
// 监听清除可视区域音符事件
|
|
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: new Color(GlobalData.currentDinoInfo.dinoColor),
|
|
}),
|
|
)
|
|
.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;
|
|
}
|
|
|
|
// 设置小恐龙脖子颜色
|
|
private setDinoNeckColor() {
|
|
// 获取当前小恐龙信息
|
|
const dinoInfo = GlobalData.currentDinoInfo;
|
|
// 获取小恐龙脖子节点
|
|
const dinoNeckNode = this.node.getChildByName("note_img");
|
|
// 获取小恐龙脖子节点下的 Sprite 组件
|
|
const dinoNeckSprite = dinoNeckNode.getComponent(Sprite);
|
|
// 设置小恐龙脖子颜色
|
|
dinoNeckSprite.color = new Color(dinoInfo.dinoColor);
|
|
}
|
|
|
|
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,
|
|
);
|
|
}
|
|
}
|