feat: group 1.0.0

This commit is contained in:
zzc
2026-05-12 06:46:31 +08:00
parent 493b4709bc
commit 2fc90c1219
55 changed files with 23561 additions and 1767 deletions

View File

@@ -1,8 +1,20 @@
import { _decorator, Component, google, Label, Node } from "cc";
import {
_decorator,
Color,
Component,
google,
Label,
Node,
Sprite,
tween,
UITransform,
Vec3,
} from "cc";
import { GlobalData } from "../config/GlobalData";
import { EventDispatcher } from "../libs/EventDispatcher";
import { GameState } from "../config/Config";
import { MusicManager } from "../managers/MusicManager";
import Common from "../libs/Common";
const { ccclass, property } = _decorator;
@ccclass("GameSceneControl")
@@ -15,6 +27,14 @@ export class GameSceneControl extends Component {
@property(Label)
lifeNumLabel: Label = null;
// 开始游戏提示label
@property(Node)
startGameNode: Node = null;
// 速度提升游戏节点
@property(Node)
speedUpNode: Node = null;
// ui 节点
@property(Node)
uiNode: Node = null;
@@ -22,7 +42,14 @@ export class GameSceneControl extends Component {
// 音频管理器
musicManager: MusicManager = null;
// 屏幕宽度
screenWidth: number = 0;
onLoad() {
// 设置游戏背景和界面小恐龙头颜色
this.setPageBackgroundColor();
// 获取屏幕宽度
this.screenWidth = this.node.getComponent(UITransform).width;
// 获取音频管理器
this.musicManager = this.node.getComponent(MusicManager);
@@ -66,6 +93,7 @@ export class GameSceneControl extends Component {
// 设置游戏状态为进行中
GlobalData.gameState = GameState.PLAYING;
// 开始游戏提示动画
this.showStartGameTip();
// 1 s 后正式开始游戏
this.scheduleOnce(() => {
@@ -97,7 +125,12 @@ export class GameSceneControl extends Component {
}
// 更新速度显示
updateSpeed() {}
updateSpeed() {
this.uiNode
.getChildByName("note_info")
.getChildByName("speed")
.getComponent(Label).string = "速度: x" + GlobalData.speedRate;
}
// 暂停游戏
pauseGame() {
@@ -122,4 +155,90 @@ export class GameSceneControl extends Component {
playMusic() {
this.musicManager.play();
}
// 显示开始游戏提示
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,
);
}
}

View File

@@ -1,5 +1,7 @@
import { _decorator, Component, director, Node } from "cc";
import { _decorator, Color, Component, director, Node } from "cc";
import AudioEffect from "../libs/AudioEffect";
import { GlobalData } from "../config/GlobalData";
import Common from "../libs/Common";
const { ccclass, property } = _decorator;
@ccclass("HomeSceneCon")
@@ -11,6 +13,8 @@ export class HomeSceneCon extends Component {
start() {
// 监听滑动区域事件
this.swipeNode.on(Node.EventType.TOUCH_START, this.goToGameScene, this);
// 设置页面的背景颜色
this.setPageBackgroundColor();
}
// 跳转到游戏场景
@@ -44,5 +48,18 @@ export class HomeSceneCon extends Component {
});
}
// 设置页面的背景颜色
setPageBackgroundColor() {
// 获取当前小恐龙信息
const dinoInfo = GlobalData.currentDinoInfo;
// 获取背景色
const backgroundColor = new Color(dinoInfo.bgColor);
// 设置页面的背景颜色
Common.setPageBackgroundColor(
this.node.getChildByName("bg"),
backgroundColor,
);
}
update(deltaTime: number) {}
}

View File

@@ -0,0 +1,176 @@
import {
_decorator,
AudioClip,
Color,
Component,
director,
Label,
Node,
resources,
Sprite,
tween,
Vec3,
} from "cc";
import Common from "../libs/Common";
import { GlobalData } from "../config/GlobalData";
import AudioEffect from "../libs/AudioEffect";
const { ccclass, property } = _decorator;
@ccclass("LoadingSceneControl")
export class LoadingSceneControl extends Component {
// 小恐龙节点
@property(Node)
dinoNode: Node = null;
// 加载文案 Label
@property(Label)
loadingLabel: Label = null;
// 开始按钮节点
@property(Node)
startButtonNode: Node = null;
// 资源目录(图片资源和预制体资源)
private resourceDir = ["images", "prefabs"];
// 定义总的需要加载资源的数量
private totalResourceCount: number = 5;
// 标记加载进度
private loadingProgress: number = 0;
// 标记是否完成加载
private isFinished: boolean = false;
start() {
// 设置当前页面的背景颜色
Common.setPageBackgroundColorAsDino(this.node);
// 设置小恐龙颜色
this.setDinoColor();
// 播放小恐龙动画
this.playDinoAnimation();
// 播放加载文案动画
this.playLoadingAnimation();
// 预加载资源
this.preloadResources();
}
setDinoColor() {
this.dinoNode.getComponent(Sprite).color = new Color(
GlobalData.currentDinoInfo.dinoColor,
);
}
playDinoAnimation() {
// 获取小恐龙当前的位置
const position = this.dinoNode.getPosition();
// 执行小恐龙动画
//执行缓动动画
tween(this.dinoNode)
.repeatForever(
tween()
.set({ scale: new Vec3(-1, 1, 1) })
.to(1, {
position: new Vec3(150, position.y, position.z),
})
.set({ scale: new Vec3(1, 1, 1) })
.to(1, {
position: new Vec3(-150, position.y, position.z),
}),
) //无限循环
.start();
}
playLoadingAnimation() {
//每隔1秒修改一次loading...文案,主要是修改后面的三个点
tween(this.loadingLabel)
.repeatForever(
tween()
.set({ string: "加载中." })
.delay(0.5)
.set({ string: "加载中.." })
.delay(0.5)
.set({ string: "加载中..." })
.delay(0.5),
) //无限循环
.start();
}
preloadResources() {
// 1. 预加载首页场景
director.preloadScene("home", (err) => {
// 修改进度
this.loadingProgress += 1;
});
// 2. 预加载游戏场景
director.preloadScene("game", (err) => {
// 修改进度
this.loadingProgress += 1;
});
// 3. 预加载图片和预制体资源
this.preloadImageResources();
// 4. 预加载音频资源
this.preloadAudioResources();
}
// 预加载图片和预制体资源
preloadImageResources() {
// 预加载图片资源
this.resourceDir.forEach((dir) => {
resources.loadDir(dir, (err, assets) => {
// 修改进度
this.loadingProgress += 1;
});
});
}
// 预加载音频资源
preloadAudioResources() {
// 只加载当前选择的音乐
// 获取当前选择的音乐 id
const musicId = GlobalData.selectedMusicID;
// 获取音乐文件的路径
const musicPath = `audios/music/music_${musicId}`;
resources.load(musicPath, AudioClip, (err, asset) => {
// 修改进度
this.loadingProgress += 1;
});
}
// 跳转到首页
onStartGame() {
// 播放点击音效
AudioEffect.playClickAudio();
// 跳转到首页场景
this.scheduleOnce(() => {
director.loadScene("home");
}, 0.2);
}
// 开放开始按钮
openStartButton() {
// 隐藏加载文案节点
this.loadingLabel.node.active = false;
// 开始按钮显示
this.startButtonNode.active = true;
// 设置按钮动画
tween(this.startButtonNode)
.repeatForever(
tween()
.to(0.5, { scale: new Vec3(1.1, 1.1, 1.1) })
.to(0.5, { scale: new Vec3(1, 1, 1) }),
) //无限循环
.start();
}
update(deltaTime: number) {
// 如果已经完成加载
if (this.isFinished) return;
// 如果加载进度等于预定的数量 就是完成了
if (this.loadingProgress >= this.totalResourceCount) {
this.isFinished = true;
// 开放开始按钮
this.openStartButton();
}
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "7a7f50a5-1539-45b6-aea3-5d73d073b046",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,243 @@
import {
_decorator,
Color,
Component,
director,
Label,
Node,
PageView,
Sprite,
} from "cc";
import { GlobalData } from "../config/GlobalData";
import Common from "../libs/Common";
import AudioEffect from "../libs/AudioEffect";
import { EventDispatcher } from "../libs/EventDispatcher";
const { ccclass, property } = _decorator;
@ccclass("LoveStorySceneControl")
export class LoveStorySceneControl extends Component {
// 总金币的标签
@property(Label)
totalScoreLabel: Label = null;
// 故事简介的标签
@property(Label)
storyDescLabel: Label = null;
// pageview 组件
@property(PageView)
pageviewComp: PageView = null;
// 按钮组节点
@property(Node)
buttonGroupNode: Node = null;
// 临时保存当前小恐龙的 id
private selectDinoID: number = 0;
//恐龙列表
dinoList: any[] = [
{
id: 1,
name: "小恐龙1",
desc: "爱你",
isLocked: 0,
unlockGold: 0,
dinoColor: "#ffffff",
bgColor: "#cce5cd",
},
{
id: 2,
name: "小恐龙2",
desc: "我的宝",
isLocked: 1,
unlockGold: 1000,
dinoColor: "#FFE064",
bgColor: "#f3ffc8",
},
{
id: 3,
name: "小恐龙3",
desc: "哎萌萌",
isLocked: 1,
unlockGold: 2000,
dinoColor: "#FD6445",
bgColor: "#ffaf6d",
},
{
id: 4,
name: "小恐龙4",
desc: "嘻嘻",
isLocked: 1,
unlockGold: 3000,
dinoColor: "#9164FF",
bgColor: "#a4a2ff",
},
{
id: 5,
name: "小恐龙5",
desc: "cccc",
isLocked: 1,
unlockGold: 4000,
dinoColor: "#FD64F2",
bgColor: "#f19dff",
},
];
onLoad() {
// 设置页面背景色
this.setBackgroundColor();
// 初始化小恐龙列表的解锁状态
this.initDinoListLockStatus();
}
start() {
// 设置总的金币数标签
this.setTotalScoreLabel();
// 初始刷pageView
this.initPageView();
}
private setTotalScoreLabel() {
this.totalScoreLabel.string = GlobalData.totalScore.toString();
}
// 初始化小恐龙列表的解锁状态
private initDinoListLockStatus() {
// 默认解锁小恐龙id为1的小恐龙
Common.unlockDino(1);
// 遍历小恐龙列表设置哪几个小恐龙解锁了
this.dinoList.forEach((item) => {
item.isLocked = Common.isDinoUnlocked(item.id) ? 0 : 1;
});
}
// 设置当前页面的背景色
private setBackgroundColor() {
// 获取当前小恐龙信息
const dionInfo = GlobalData.currentDinoInfo;
const bgColor = dionInfo.bgColor;
Common.setPageBackgroundColor(
this.node.getChildByName("bg"),
new Color(bgColor),
);
}
// 三个按钮方法
// 回到首页
onBackToHome() {
// 播放点击音效
AudioEffect.playClickAudio();
// 加载首页
director.loadScene("home");
}
// 购买小恐龙
onBuyDino() {
// 播放点击音效
AudioEffect.playClickAudio();
// 获取当前选择的小恐龙信息
const dionInfo = this.dinoList.find(
(item) => item.id === this.selectDinoID,
);
if (!dionInfo) {
return;
}
// 当前金币数如果大于所需要的金币数
if (GlobalData.totalScore >= dionInfo.unlockGold) {
// 扣除所需要的金币数
GlobalData.totalScore -= dionInfo.unlockGold;
// 更新总的金币数标签
this.setTotalScoreLabel();
// 解锁当前小恐龙
Common.unlockDino(dionInfo.id);
// 获取当前选中小恐龙索引
const currentIndex = this.selectDinoID - 1;
// 设置当前选中的小恐龙信息为解锁状态
this.dinoList[currentIndex].isLocked = 0;
// 刷新按钮显示
this.refreshButtonDisplay(currentIndex);
} else {
// 发送提示消息
EventDispatcher.getTarget().emit(EventDispatcher.TIP_MSG, "金币不足");
}
}
// 确认购买
onConfirmBuyDino() {
// 播放点击音效
AudioEffect.playClickAudio();
// 设置当前选择小恐龙的 id
if (this.selectDinoID > 0) {
GlobalData.selectedDinoID = this.selectDinoID;
// 设置小恐龙信息
GlobalData.currentDinoInfo = this.dinoList[this.selectDinoID - 1];
}
// 回到首页
this.scheduleOnce(() => {
director.loadScene("home");
}, 0.4);
}
// 轮播滑动事件
onSlideEvent(event: any) {
// 获取当前的索引
const currentIndex = parseInt(event.curPageIdx);
// 获取选中小恐龙信息
const dionInfo = this.dinoList[currentIndex];
// 更新当前临时选择的小恐龙 id
this.selectDinoID = dionInfo.id || 1;
// 设置故事简介
this.storyDescLabel.string = dionInfo.desc;
// 设置页面的背景颜色
Common.setPageBackgroundColor(
this.node.getChildByName("bg"),
new Color(dionInfo.bgColor),
);
// 刷新按钮显示
this.refreshButtonDisplay(currentIndex);
}
// 刷新按钮显示
private refreshButtonDisplay(currentIndex: number) {
// 保存当前临时保存的小恐龙 id
this.selectDinoID = this.dinoList[currentIndex].id || 1;
// 获取当前选中的小恐龙信息
const dionInfo = this.dinoList[currentIndex];
// 如果当前小恐龙未解锁
if (dionInfo.isLocked) {
this.buttonGroupNode.getChildByName("button_buy").active = true;
this.buttonGroupNode.getChildByName("button_cancel").active = true;
this.buttonGroupNode.getChildByName("button_ok").active = false;
// 设置购买的金额
this.buttonGroupNode
.getChildByName("button_buy")
.getChildByName("gold_num")
.getComponent(Label).string = dionInfo.unlockGold.toString() ?? "0";
} else {
this.buttonGroupNode.getChildByName("button_buy").active = false;
this.buttonGroupNode.getChildByName("button_cancel").active = false;
this.buttonGroupNode.getChildByName("button_ok").active = true;
}
}
// 初始化 pageview 组件
private initPageView() {
// 设置默认显示第几个小恐龙 index
const index = this.dinoList.findIndex(
(item) => item.id === GlobalData.selectedDinoID,
);
if (index !== -1) {
this.pageviewComp.setCurrentPageIndex(index);
// 获取小恐龙信息
const dionInfo = this.dinoList[index];
// 设置故事简介
this.storyDescLabel.string = dionInfo.desc;
// 刷新按钮显示
this.refreshButtonDisplay(index);
}
}
update(deltaTime: number) {}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "bc8722c5-dfec-4bca-b4c2-747bb434fd54",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,282 @@
import {
_decorator,
AudioClip,
AudioSource,
Component,
director,
instantiate,
Label,
Node,
Prefab,
resources,
} from "cc";
import Common from "../libs/Common";
import Utils from "../libs/Utils";
import { GameStorageKeyConfig } from "../config/Config";
import { GlobalData } from "../config/GlobalData";
import { MoodListItem } from "../ui/MoodListItem";
import AudioEffect from "../libs/AudioEffect";
import { EventDispatcher } from "../libs/EventDispatcher";
const { ccclass, property } = _decorator;
@ccclass("MoodSceneControl")
export class MoodSceneControl extends Component {
// 列表项预制体
@property(Prefab)
moodItemPrefab: Prefab = null;
// 内容列表父节点(挂载点)
@property(Node)
contentNode: Node = null;
// 总的金币数标签 Label
@property(Label)
totalScoreLabel: Label = null;
// 按钮组节点
@property(Node)
buttonGroupNode: Node = null;
// 保存当前用户临时选择的音乐 id
selectedMusicId: number = 0;
// 音频播放器
private audioSource: AudioSource = null;
// 标记有没有点击过按钮
private isClickedButton: boolean = false;
//歌曲列表
musicList: any[] = [
{
id: 1,
title: "Like A Dino!",
bestScore: 0,
isLocked: 0,
unlockGold: 0,
},
{
id: 2,
title: "It's Ok,Not To Be Ok!",
bestScore: 0,
isLocked: 1,
unlockGold: 1000,
},
{
id: 3,
title: "Good Luck Today!",
bestScore: 0,
isLocked: 1,
unlockGold: 2000,
},
{
id: 4,
title: "A Piece Of Cake!",
bestScore: 0,
isLocked: 1,
unlockGold: 3000,
},
{
id: 5,
title: "Im So Excited!",
bestScore: 0,
isLocked: 1,
unlockGold: 4000,
},
{
id: 6,
title: "It Is What It Is!",
bestScore: 0,
isLocked: 1,
unlockGold: 5000,
},
{
id: 7,
title: "A Silver Lining!",
bestScore: 0,
isLocked: 1,
unlockGold: 6000,
},
{
id: 8,
title: "So Suβ!",
bestScore: 0,
isLocked: 1,
unlockGold: 7000,
},
{
id: 9,
title: "You Made My Day!",
bestScore: 0,
isLocked: 1,
unlockGold: 8000,
},
];
onLoad() {
// 初始化音频播放器
this.audioSource = this.getComponent(AudioSource);
// 初始化音乐了列表解锁状态
this.initMusicListLockStatus();
}
start() {
// 监听选中音乐列表某一个 item 事件
EventDispatcher.getTarget().on(
EventDispatcher.SELECT_MOOD_ITEM,
this.refedButtonDisplay,
this,
);
// 设置页面的背景颜色
Common.setPageBackgroundColorAsDino(this.node);
// 设置总的金币数标签
this.setTotalScoreLabel();
// 初始化音乐列表
this.addMoodListItems();
}
// 设置总的金币数标签
setTotalScoreLabel() {
this.totalScoreLabel.string = GlobalData.totalScore.toString();
}
initMusicListLockStatus() {
// 获取每个歌曲的最佳成绩
const bestScoreMap: any =
Utils.getCache(GameStorageKeyConfig.BestScore) || {};
// 默认解锁第一条音乐
Common.unlockMusic(1);
// 遍历音乐列表
this.musicList.forEach((item) => {
// 更新解锁信息
item.isLocked = Common.isMusicUnlocked(item.id) ? 0 : 1;
// 更新最佳成绩
item.bestScore = bestScoreMap[item.id] || 0;
});
}
// 初始化音乐列表
addMoodListItems() {
// 遍历音乐列表
this.musicList.forEach((item) => {
// 实例化列表项
const moodItem = instantiate(this.moodItemPrefab);
// 初始化列表项节点
moodItem.getComponent(MoodListItem).init(item);
// 挂载到内容列表父节点
moodItem.parent = this.contentNode;
});
}
refedButtonDisplay(musicId: number) {
this.selectedMusicId = musicId;
// 找到当前选中的音乐
const musicItem = this.musicList.find((item) => item.id == musicId);
if (!musicItem) return;
// 判断音乐是否解锁
if (musicItem.isLocked) {
// 未解锁
this.buttonGroupNode.getChildByName("button_buy").active = true;
this.buttonGroupNode.getChildByName("button_cancel").active = true;
this.buttonGroupNode.getChildByName("button_ok").active = false;
// 设置购买的金额
this.buttonGroupNode
.getChildByName("button_buy")
.getChildByName("gold_num")
.getComponent(Label).string = musicItem.unlockGold.toString() ?? "0";
} else {
// 已解锁
this.buttonGroupNode.getChildByName("button_buy").active = false;
this.buttonGroupNode.getChildByName("button_cancel").active = false;
this.buttonGroupNode.getChildByName("button_ok").active = true;
}
// 播放音乐
this.playMusic();
}
// 播放音乐
playMusic() {
// 判断有没有临时选择的音乐 id
if (!this.selectedMusicId) return;
// 获取音乐文件路径
const musicPath = "audios/music/music_" + this.selectedMusicId;
// 播放音乐
if (this.audioSource) {
resources.load(musicPath, (err, clip: AudioClip) => {
if (err) {
console.error("加载音乐失败", err, musicPath);
return;
}
// 停止播放 防止其他音乐在播放
this.audioSource.stop();
this.audioSource.clip = clip;
this.audioSource.play();
// 设置声音高度
this.audioSource.volume = 1;
});
}
}
// 三个按钮方法
// 回到首页
onBackToHome() {
// 播放点击音效
AudioEffect.playClickAudio();
// 加载首页
director.loadScene("home");
}
// 购买音乐
onBuyMusic() {
// 判断有没有点击过按钮
if (this.isClickedButton) return;
this.isClickedButton = true;
this.scheduleOnce(() => {
this.isClickedButton = false;
}, 0.2);
// 获取当前选择的音乐
const musicInfo = this.musicList.find(
(item) => item.id === this.selectedMusicId,
);
if (!musicInfo) {
return;
}
// 当前金币数如果大于所需要的金币数
if (GlobalData.totalScore >= musicInfo.unlockGold) {
// 扣除所需要的金币数
GlobalData.totalScore -= musicInfo.unlockGold;
// 更新总的金币数标签
this.setTotalScoreLabel();
// 解锁当前音乐
EventDispatcher.getTarget().emit(
EventDispatcher.UNLOCK_MOOD_ITEM,
this.selectedMusicId,
);
} else {
// 发送提示消息
EventDispatcher.getTarget().emit(EventDispatcher.TIP_MSG, "金币不足");
}
}
// 确认购买
onConfirmBuyMusic() {
// 播放点击音效
AudioEffect.playClickAudio();
// 设置当前选择音乐的 id
if (this.selectedMusicId > 0) {
GlobalData.selectedMusicID = this.selectedMusicId;
// 设置音乐信息
GlobalData.currentMusicInfo = this.musicList[this.selectedMusicId - 1];
}
// 回到首页
this.scheduleOnce(() => {
director.loadScene("home");
}, 0.4);
}
update(deltaTime: number) {}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "035f9fa4-604d-4bd2-9c33-b13438b287be",
"files": [],
"subMetas": {},
"userData": {}
}