2026-05-12 06:46:31 +08:00
|
|
|
import {
|
|
|
|
|
_decorator,
|
|
|
|
|
Color,
|
|
|
|
|
Component,
|
|
|
|
|
google,
|
|
|
|
|
Label,
|
|
|
|
|
Node,
|
|
|
|
|
Sprite,
|
|
|
|
|
tween,
|
|
|
|
|
UITransform,
|
|
|
|
|
Vec3,
|
|
|
|
|
} from "cc";
|
2026-04-30 00:13:37 +08:00
|
|
|
import { GlobalData } from "../config/GlobalData";
|
|
|
|
|
import { EventDispatcher } from "../libs/EventDispatcher";
|
|
|
|
|
import { GameState } from "../config/Config";
|
|
|
|
|
import { MusicManager } from "../managers/MusicManager";
|
2026-05-12 06:46:31 +08:00
|
|
|
import Common from "../libs/Common";
|
2026-04-30 00:13:37 +08:00
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
|
|
|
|
|
|
@ccclass("GameSceneControl")
|
|
|
|
|
export class GameSceneControl extends Component {
|
|
|
|
|
// 当前这一局得分label
|
|
|
|
|
@property(Label)
|
|
|
|
|
curRoundScoreLabel: Label = null;
|
|
|
|
|
|
|
|
|
|
// 当前这句剩余生命值label
|
|
|
|
|
@property(Label)
|
|
|
|
|
lifeNumLabel: Label = null;
|
|
|
|
|
|
2026-05-12 06:46:31 +08:00
|
|
|
// 开始游戏提示label
|
|
|
|
|
@property(Node)
|
|
|
|
|
startGameNode: Node = null;
|
|
|
|
|
|
|
|
|
|
// 速度提升游戏节点
|
|
|
|
|
@property(Node)
|
|
|
|
|
speedUpNode: Node = null;
|
|
|
|
|
|
2026-04-30 00:13:37 +08:00
|
|
|
// ui 节点
|
|
|
|
|
@property(Node)
|
|
|
|
|
uiNode: Node = null;
|
|
|
|
|
|
|
|
|
|
// 音频管理器
|
|
|
|
|
musicManager: MusicManager = null;
|
|
|
|
|
|
2026-05-12 06:46:31 +08:00
|
|
|
// 屏幕宽度
|
|
|
|
|
screenWidth: number = 0;
|
|
|
|
|
|
2026-04-30 00:13:37 +08:00
|
|
|
onLoad() {
|
2026-05-12 06:46:31 +08:00
|
|
|
// 设置游戏背景和界面小恐龙头颜色
|
|
|
|
|
this.setPageBackgroundColor();
|
|
|
|
|
// 获取屏幕宽度
|
|
|
|
|
this.screenWidth = this.node.getComponent(UITransform).width;
|
2026-04-30 00:13:37 +08:00
|
|
|
// 获取音频管理器
|
|
|
|
|
this.musicManager = this.node.getComponent(MusicManager);
|
|
|
|
|
|
|
|
|
|
// 监听小恐龙吃到音符事件
|
|
|
|
|
EventDispatcher.getTarget().on(
|
|
|
|
|
EventDispatcher.DINO_EAT_NOTE,
|
|
|
|
|
this.updateCurRoundScoreLabel,
|
|
|
|
|
this,
|
|
|
|
|
);
|
|
|
|
|
// 监听音符碰到线事件
|
|
|
|
|
EventDispatcher.getTarget().on(
|
|
|
|
|
EventDispatcher.UPDATE_LIFE,
|
|
|
|
|
this.updateLifeNumLabel,
|
|
|
|
|
this,
|
|
|
|
|
);
|
|
|
|
|
// 监听游戏结束事件
|
|
|
|
|
EventDispatcher.getTarget().on(
|
|
|
|
|
EventDispatcher.GAME_OVER,
|
|
|
|
|
this.handleEndGame,
|
|
|
|
|
this,
|
|
|
|
|
);
|
|
|
|
|
// 监听过关事件
|
|
|
|
|
EventDispatcher.getTarget().on(
|
|
|
|
|
EventDispatcher.PASS_LEVLE,
|
|
|
|
|
this.handlePassLevel,
|
|
|
|
|
this,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start() {
|
|
|
|
|
// 重置游戏数据
|
|
|
|
|
GlobalData.resetGameData();
|
|
|
|
|
this.startGame();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startGame() {
|
|
|
|
|
// 开始游戏
|
|
|
|
|
this.uiNode.active = true;
|
|
|
|
|
// 更新 ui 节点相关数据
|
|
|
|
|
this.updateUi();
|
|
|
|
|
// 设置游戏状态为进行中
|
|
|
|
|
GlobalData.gameState = GameState.PLAYING;
|
|
|
|
|
// 开始游戏提示动画
|
2026-05-12 06:46:31 +08:00
|
|
|
this.showStartGameTip();
|
2026-04-30 00:13:37 +08:00
|
|
|
|
|
|
|
|
// 1 s 后正式开始游戏
|
|
|
|
|
this.scheduleOnce(() => {
|
|
|
|
|
// 开始播放背景音乐
|
|
|
|
|
this.playMusic();
|
|
|
|
|
// 发送开始游戏事件
|
|
|
|
|
EventDispatcher.getTarget().emit(EventDispatcher.GAME_STAET);
|
|
|
|
|
}, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新 ui
|
|
|
|
|
updateUi() {
|
|
|
|
|
// 更新本局总得分
|
|
|
|
|
this.updateCurRoundScoreLabel();
|
|
|
|
|
// 更新生命值
|
|
|
|
|
this.updateLifeNumLabel();
|
|
|
|
|
// 更新当前速度的显示
|
|
|
|
|
this.updateSpeed();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新当前这一局得分
|
|
|
|
|
updateCurRoundScoreLabel() {
|
|
|
|
|
this.curRoundScoreLabel.string = GlobalData.curRoundTotalScore.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新当前这句剩余生命值
|
|
|
|
|
updateLifeNumLabel() {
|
|
|
|
|
this.lifeNumLabel.string = "x" + GlobalData.lifeNumPerRound.toString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 更新速度显示
|
2026-05-12 06:46:31 +08:00
|
|
|
updateSpeed() {
|
|
|
|
|
this.uiNode
|
|
|
|
|
.getChildByName("note_info")
|
|
|
|
|
.getChildByName("speed")
|
|
|
|
|
.getComponent(Label).string = "速度: x" + GlobalData.speedRate;
|
|
|
|
|
}
|
2026-04-30 00:13:37 +08:00
|
|
|
|
|
|
|
|
// 暂停游戏
|
|
|
|
|
pauseGame() {
|
|
|
|
|
EventDispatcher.getTarget().emit(EventDispatcher.SHOW_PAUSE_MODAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 处理游戏结束时
|
|
|
|
|
handleEndGame() {
|
|
|
|
|
// 游戏结束,弹出游戏界面
|
|
|
|
|
this.uiNode.active = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 闯过当前关卡时 重新开始下一轮
|
|
|
|
|
handlePassLevel() {
|
|
|
|
|
// 增加速率
|
|
|
|
|
GlobalData.speedRate += GlobalData.speedRateAdd;
|
|
|
|
|
// 继续开始游戏
|
|
|
|
|
this.startGame();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 播放音乐
|
|
|
|
|
playMusic() {
|
|
|
|
|
this.musicManager.play();
|
|
|
|
|
}
|
2026-05-12 06:46:31 +08:00
|
|
|
|
|
|
|
|
// 显示开始游戏提示
|
|
|
|
|
showStartGameTip() {
|
|
|
|
|
if (GlobalData.speedRate > 1) {
|
|
|
|
|
// 显示速度提升提示
|
|
|
|
|
this.speedUpTipAnim();
|
|
|
|
|
} else {
|
|
|
|
|
// 首次开始游戏动画
|
|
|
|
|
this.firstStartGameAnim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示速度提升提示
|
|
|
|
|
speedUpTipAnim() {
|
|
|
|
|
// 设置速度提升提示文字
|
|
|
|
|
this.speedUpNode.getComponent(Label).string =
|
|
|
|
|
`速度提升: (x ${GlobalData.speedRate})`;
|
|
|
|
|
|
|
|
|
|
// 首先显示节点
|
|
|
|
|
this.speedUpNode.active = true;
|
|
|
|
|
|
|
|
|
|
// 获取原有位置
|
|
|
|
|
const oriPos = this.speedUpNode.getPosition().clone();
|
|
|
|
|
// tween 向右移动半屏距离 然后停留 0.5 s 消失
|
|
|
|
|
tween(this.speedUpNode)
|
|
|
|
|
.to(0.3, {
|
|
|
|
|
position: new Vec3(oriPos.x + this.screenWidth / 2 + 200, oriPos.y, 0),
|
|
|
|
|
})
|
|
|
|
|
.delay(0.5)
|
|
|
|
|
.to(0.3, {
|
|
|
|
|
position: new Vec3(oriPos.x + this.screenWidth + 200, oriPos.y, 0),
|
|
|
|
|
})
|
|
|
|
|
.call(() => {
|
|
|
|
|
// 消失节点
|
|
|
|
|
this.speedUpNode.active = false;
|
|
|
|
|
// 重置当前节点的位置
|
|
|
|
|
this.speedUpNode.setPosition(oriPos);
|
|
|
|
|
})
|
|
|
|
|
.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 首次开始游戏动画
|
|
|
|
|
firstStartGameAnim() {
|
|
|
|
|
// 首先显示节点
|
|
|
|
|
this.startGameNode.active = true;
|
|
|
|
|
// 获取原有位置
|
|
|
|
|
const oriPos = this.startGameNode.getPosition().clone();
|
|
|
|
|
// tween 向右移动半屏距离 然后停留 0.5 s 消失
|
|
|
|
|
tween(this.startGameNode)
|
|
|
|
|
.to(0.3, {
|
|
|
|
|
position: new Vec3(oriPos.x + this.screenWidth / 2 + 200, oriPos.y, 0),
|
|
|
|
|
})
|
|
|
|
|
.delay(0.5)
|
|
|
|
|
.to(0.3, {
|
|
|
|
|
position: new Vec3(oriPos.x + this.screenWidth + 200, oriPos.y, 0),
|
|
|
|
|
})
|
|
|
|
|
.call(() => {
|
|
|
|
|
// 消失节点
|
|
|
|
|
this.startGameNode.active = false;
|
|
|
|
|
// 重置当前节点的位置
|
|
|
|
|
this.startGameNode.setPosition(oriPos);
|
|
|
|
|
})
|
|
|
|
|
.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 设置页面的背景颜色
|
|
|
|
|
setPageBackgroundColor() {
|
|
|
|
|
// 获取当前小恐龙信息
|
|
|
|
|
const dinoInfo = GlobalData.currentDinoInfo;
|
|
|
|
|
// 获取背景色
|
|
|
|
|
const backgroundColor = new Color(dinoInfo.bgColor);
|
|
|
|
|
// 获取小恐龙颜色
|
|
|
|
|
const dinoColor = new Color(dinoInfo.dinoColor);
|
|
|
|
|
|
|
|
|
|
// 获取小恐龙 ui 头节点
|
|
|
|
|
const dinoHeadNode = this.uiNode
|
|
|
|
|
.getChildByName("life")
|
|
|
|
|
.getChildByName("dino_head");
|
|
|
|
|
// 设置小恐龙 ui 头节点的颜色
|
|
|
|
|
dinoHeadNode.getComponent(Sprite).color = dinoColor;
|
|
|
|
|
// 设置页面的背景颜色
|
|
|
|
|
Common.setPageBackgroundColor(
|
|
|
|
|
this.node.getChildByName("bg"),
|
|
|
|
|
backgroundColor,
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-04-30 00:13:37 +08:00
|
|
|
}
|