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

@@ -14,6 +14,7 @@ import {
Prefab,
instantiate,
director,
Color,
} from "cc";
import { NoteControl } from "./NoteControl";
import { BombEffect } from "../effects/BombEffectControl";
@@ -43,6 +44,8 @@ export class DinoControl extends Component {
lineNode: Node = null;
onLoad() {
// 设置小恐龙颜色
this.setDinoColor();
// 监听继续游戏事件
EventDispatcher.getTarget().on(
EventDispatcher.GAME_RESUME,
@@ -130,6 +133,10 @@ export class DinoControl extends Component {
// 设置这个空节点的父节点
neckChild.parent = this.node.getChildByName("dino_neck_box");
// 设置脖子的颜色
neckChild.getComponent(Sprite).color = new Color(
GlobalData.currentDinoInfo.dinoColor,
);
// 获取小恐龙身体
const bodyNode = this.node.getChildByName("dino_body");
@@ -216,5 +223,19 @@ export class DinoControl extends Component {
}
}
// 设置小恐龙颜色
setDinoColor() {
// 获取当前小恐龙信息
const dinoInfo = GlobalData.currentDinoInfo;
// 获取小恐龙颜色
const dinoColor = new Color(dinoInfo.dinoColor);
// 设置小恐龙身体颜色
this.node.getChildByName("dino_body").getComponent(Sprite).color =
dinoColor;
// 设置小恐龙头部颜色
this.node.getChildByName("dino_head").getComponent(Sprite).color =
dinoColor;
}
update(deltaTime: number) {}
}

View File

@@ -21,6 +21,8 @@ export class NoteControl extends Component {
// 是否开始下落
private isEnableFall: boolean = false;
start() {
// 设置小恐龙脖子颜色
this.setDinoNeckColor();
// 监听清除可视区域音符事件
EventDispatcher.getTarget().on(
EventDispatcher.CLEAR_SCREEN_NOTE,
@@ -59,6 +61,7 @@ export class NoteControl extends Component {
const noteHitSprite = this.node
.getChildByName("note_img")
.getComponent(Sprite);
// 4. 获取音符的颜色
const noteColor = new Color("ffffff");
// 5. 操作音符闪烁
@@ -70,7 +73,7 @@ export class NoteControl extends Component {
color: new Color(noteColor.r, noteColor.g, noteColor.b, 0),
})
.to(0.2, {
color: noteColor,
color: new Color(GlobalData.currentDinoInfo.dinoColor),
}),
)
.call(() => {
@@ -144,6 +147,18 @@ export class NoteControl extends Component {
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) {

View File

@@ -18,6 +18,24 @@ export class GlobalData {
public static speedRate: number = 1;
// 每次闯关增加的速率
public static speedRateAdd: number = 0.2;
//获取当前选择的音乐的信息
public static get currentMusicInfo(): any {
//从本地缓存中获取(默认)
return (
Utils.getCache(GameStorageKeyConfig.CurrentMusicInfo) || {
id: 1,
title: "Like A Dino!",
bestScore: 0,
isLocked: 0,
unlockGold: 0,
}
);
}
//设置当前选择的音乐的信息
public static set currentMusicInfo(value) {
//存储到本地缓存中
Utils.setCache(GameStorageKeyConfig.CurrentMusicInfo, value);
}
// 获取当前选择的音乐 id
public static get selectedMusicID(): number {
return Utils.getCache(GameStorageKeyConfig.SelectedMusicID) || 1;
@@ -27,6 +45,55 @@ export class GlobalData {
//存储到本地缓存中
Utils.setCache(GameStorageKeyConfig.SelectedMusicID, value);
}
//获取当前选择的小恐龙ID(默认是1)
public static get selectedDinoID() {
return parseInt(Utils.getCache(GameStorageKeyConfig.SelectedDinoID)) || 1;
}
//设置当前选择的小恐龙ID
public static set selectedDinoID(value) {
//存储到本地缓存中
Utils.setCache(GameStorageKeyConfig.SelectedDinoID, value);
}
//获取解锁了哪些音乐的ID列表
public static get unlockMusicIDList() {
//从本地缓存中获取(默认)
return Utils.getCache(GameStorageKeyConfig.UnlockMusicIDList) || [];
}
//存储解锁了哪些音乐的ID列表
public static set unlockMusicIDList(value) {
//存储到本地缓存中
Utils.setCache(GameStorageKeyConfig.UnlockMusicIDList, value);
}
//获取当前选择的小恐龙的信息
public static get currentDinoInfo(): any {
//从本地缓存中获取(默认)
return (
Utils.getCache(GameStorageKeyConfig.CurrentDinoInfo) || {
id: 1,
name: "小恐龙1",
desc: "Dino:Will you marry me?",
isLocked: 0,
unlockGold: 0,
dinoColor: "#ffffff",
bgColor: "#cce5cd",
}
);
}
//设置当前选择的小恐龙的信息
public static set currentDinoInfo(value) {
//存储到本地缓存中
Utils.setCache(GameStorageKeyConfig.CurrentDinoInfo, value);
}
//获取解锁了哪些小恐龙的ID列表
public static get unlockDinoIDList() {
//从本地缓存中获取(默认)
return Utils.getCache(GameStorageKeyConfig.UnlockDinoIDList) || [];
}
//存储解锁了哪些小恐龙的ID列表
public static set unlockDinoIDList(value) {
//存储到本地缓存中
Utils.setCache(GameStorageKeyConfig.UnlockDinoIDList, value);
}
//获取玩家累计的总得分(总的金币数)
public static get totalScore() {
//从本地缓存中获取

View File

@@ -0,0 +1,92 @@
/**
* 游戏开发者:程序员加菲猫
* 游戏名称Like A Dino!
*/
import { Color, Node, Sprite } from "cc";
import { GlobalData } from "../config/GlobalData";
import { DataManager } from "./DataManager";
//公共业务方法类
export default class Common {
/**
* 加载对应的音乐音符数据
* @param musicID 音乐ID
* @returns 音乐音符数据对象
*/
public static async loadMusicNoteData(musicID: number): Promise<any | null> {
return await DataManager.loadJson<any>(`data/music_${musicID}`);
}
/**
* 检查是否解锁了指定的音乐
* @param musicID 音乐ID
* @returns 是否解锁了指定的音乐
*/
public static isMusicUnlocked(musicID: number): boolean {
return GlobalData.unlockMusicIDList?.includes(musicID);
}
/**
* 解锁指定的音乐
* @param musicID 音乐ID
*/
public static unlockMusic(musicID: number) {
//如果已经解锁了,则直接返回
if (Common.isMusicUnlocked(musicID)) {
return;
}
let unlockMusicIDList = GlobalData.unlockMusicIDList || [];
//解锁音乐,并存储到本地缓存中
unlockMusicIDList?.push(musicID);
//更新本地缓存
GlobalData.unlockMusicIDList = unlockMusicIDList;
}
/**
* 检查是否解锁了指定的小恐龙
* @param dinoID 小恐龙ID
* @returns 是否解锁了指定的小恐龙
*/
public static isDinoUnlocked(dinoID: number): boolean {
return GlobalData.unlockDinoIDList?.includes(dinoID);
}
/**
* 解锁指定的小恐龙
* @param dinoID 小恐龙ID
*/
public static unlockDino(dinoID: number) {
//如果已经解锁了,则直接返回
if (Common.isDinoUnlocked(dinoID)) {
return;
}
let unlockDinoIDList = GlobalData.unlockDinoIDList || [];
//解锁小恐龙,并存储到本地缓存中
unlockDinoIDList?.push(dinoID);
//更新本地缓存
GlobalData.unlockDinoIDList = unlockDinoIDList;
}
/**
* 设置页面背景色
* @param node 页面节点
* @param color 背景色
*/
public static setPageBackgroundColor(node: Node, color: Color) {
node.getComponent(Sprite).color = color;
}
/**
* 设置页面背景色和小恐龙背景色相同
* @param node 页面节点
*/
public static setPageBackgroundColorAsDino(node: Node) {
// 获取当前小恐龙信息
const dinoInfo = GlobalData.currentDinoInfo;
// 获取背景色
const backgroundColor = new Color(dinoInfo.bgColor);
// 设置页面的背景颜色
this.setPageBackgroundColor(node.getChildByName("bg"), backgroundColor);
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "b80b50f7-99b8-4174-9ee1-e3a0b698d4ea",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -0,0 +1,22 @@
import { _decorator, JsonAsset, resources } from "cc";
const { ccclass, property } = _decorator;
@ccclass("DataManager")
export class DataManager {
/**
* 从resources目录读取JSON文件
* @param path 文件路径(不包含扩展名)
*/
public static async loadJson<T>(path: string): Promise<T | null> {
return new Promise((resolve) => {
resources.load(path, JsonAsset, (err, asset) => {
if (err) {
console.error(`加载JSON文件失败: ${path}`, err);
resolve(null);
return;
}
resolve(asset.json as T);
});
});
}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "de375e5e-601f-472d-bbe7-e9ada0277697",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -34,6 +34,12 @@ export class EventDispatcher {
public static readonly SHOW_PAUSE_MODAL = "show_pause_modal";
// 显示继续游戏弹窗事件
public static readonly SHOW_CONTINUE_MODAL = "show_continue_modal";
// 提示消息事件
public static readonly TIP_MSG = "tip_msg";
// 选中音乐列表某一个 item 事件
public static readonly SELECT_MOOD_ITEM = "select_mood_item";
// 解锁音乐列表某一个 item 事件
public static readonly UNLOCK_MOOD_ITEM = "unlock_mood_item";
static getTarget() {
if (EventDispatcher.data == null) {

File diff suppressed because it is too large Load Diff

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": {}
}

View File

@@ -1,7 +1,17 @@
import { _decorator, Component, Node, tween, UITransform, Vec3 } from "cc";
import {
_decorator,
Color,
Component,
Node,
Sprite,
tween,
UITransform,
Vec3,
} from "cc";
import { EventDispatcher } from "../libs/EventDispatcher";
import { GlobalData } from "../config/GlobalData";
import { GameState } from "../config/Config";
import Common from "../libs/Common";
const { ccclass, property } = _decorator;
@ccclass("ContonueModal")
@@ -37,6 +47,8 @@ export class ContonueModal extends Component {
showModal() {
// 游戏暂停
GlobalData.gameState = GameState.PAUSED;
// 设置 页面 背景色
Common.setPageBackgroundColorAsDino(this.node);
// 显示继续游戏弹窗
this.node.active = true;
// 操作提示动画
@@ -76,6 +88,11 @@ export class ContonueModal extends Component {
// 播放提示1的动画
playTipAnimation(tNode: Node) {
// 设置小恐龙颜色
tNode.getChildByName("dino").getComponent(Sprite).color = new Color(
GlobalData.currentDinoInfo.dinoColor,
);
// 显示提示1
tNode.active = true;
// 获取提示节点的位置

View File

@@ -0,0 +1,163 @@
import {
_decorator,
Color,
Component,
Label,
Node,
Sprite,
tween,
UIOpacity,
Vec3,
} from "cc";
import { GlobalData } from "../config/GlobalData";
import AudioEffect from "../libs/AudioEffect";
import { EventDispatcher } from "../libs/EventDispatcher";
import Common from "../libs/Common";
const { ccclass, property } = _decorator;
interface MoodItem {
id: number;
title: string;
bestScore: number;
isLocked: number;
unlockGold: number;
}
@ccclass("MoodListItem")
export class MoodListItem extends Component {
// 保存当前列表项数据对象
private itemObj: MoodItem = null;
start() {
// 监听当前节点的点击事件
this.node.on(Node.EventType.TOUCH_END, this.onClickMusicItem, this);
// 监听选中音乐列表某一个 item 事件
EventDispatcher.getTarget().on(
EventDispatcher.SELECT_MOOD_ITEM,
this.onSelectMusicItem,
this,
);
// 监听解锁音乐列表某一个 item 事件
EventDispatcher.getTarget().on(
EventDispatcher.UNLOCK_MOOD_ITEM,
this.onUnlockMusicItem,
this,
);
// 设置小恐龙颜色
this.setDionColor();
}
onClickMusicItem() {
// 播放点击音效
AudioEffect.playClickAudio();
// 选中当前列表项
this.setSelected();
// 设置动画 先缩小到 0.9 再还原到 1
tween(this.node)
.to(0.1, { scale: new Vec3(0.9, 0.9, 1) })
.to(0.1, { scale: new Vec3(1, 1, 1) })
.start();
}
onUnlockMusicItem(id: number) {
// 如果当前列表项的 id 与不是解锁的音乐 id 不处理
if (this.itemObj?.id != id) return;
// 设置当前音乐项未解锁状态
this.itemObj.isLocked = 0;
// 刷新有无锁定状态显示
this.setLockState(this.itemObj);
// 设置选中状态
this.setSelected();
// 存储解锁状态
Common.unlockMusic(id);
}
// 选中音乐列表某一个 item 事件
onSelectMusicItem(id: number) {
if (this.itemObj.id == id) return;
// 设置未选中状态
this.setUnSelected();
}
// 初始化列表项节点
init(item: MoodItem) {
// 保存当前列表项数据对象
this.itemObj = item;
// 设置列表项的标题
this.node.getChildByName("music_title").getComponent(Label).string =
item.title;
// 设置有无锁定状态显示
this.setLockState(item);
// 如果当前列表项是默认选中项 则设置选中状态
if (item.id == GlobalData.selectedMusicID) {
this.setSelected();
}
// // 设置列表项的金币数;
// this.node.getChildByName("gold").getComponent(Label).string =
// this.itemObj.unlockGold.toString();
// 监听点击事件
// moodItem.on(Node.EventType.TOUCH_END, this.onClickMusicItem, this);
}
// 设置有无锁定状态显示
setLockState(item: MoodItem) {
if (item.isLocked == 0) {
// 解锁状态
this.node.getChildByName("best_score").active = true;
this.node.getChildByName("locked").active = false;
this.node
.getChildByName("best_score")
.getChildByName("score_num")
.getComponent(Label).string = this.itemObj.bestScore.toString();
} else {
// 锁定状态
this.node.getChildByName("best_score").active = false;
this.node.getChildByName("locked").active = true;
}
}
// 设置选中状态
setSelected() {
// 获取透明度组件
const opacity = this.node
.getChildByName("list_item_bg")
.getComponent(UIOpacity);
// 设置透明度为255
opacity.opacity = 200;
// 获取选中图标节点
const selectNode = this.node.getChildByName("dino");
selectNode.active = true;
// 派发选中某一个 item 事件
EventDispatcher.getTarget().emit(
EventDispatcher.SELECT_MOOD_ITEM,
this.itemObj.id,
);
}
// 设置未选中状态
setUnSelected() {
// 获取透明度组件
const opacity = this.node
.getChildByName("list_item_bg")
.getComponent(UIOpacity);
// 设置透明度为255
opacity.opacity = 255;
// 获取选中图标节点
const selectNode = this.node.getChildByName("dino");
selectNode.active = false;
}
// 设置小恐龙颜色
setDionColor() {
// 获取选中图标节点
const selectNode = this.node.getChildByName("dino");
// 设置选中图标节点的颜色为小恐龙颜色
selectNode.getComponent(Sprite).color = new Color(
GlobalData.currentDinoInfo.dinoColor,
);
}
update(deltaTime: number) {}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "bca91580-94ca-4df5-9706-eb1184b1846d",
"files": [],
"subMetas": {},
"userData": {}
}

View File

@@ -1,5 +1,6 @@
import { _decorator, Component, director, Node } from "cc";
import { EventDispatcher } from "../libs/EventDispatcher";
import Common from "../libs/Common";
const { ccclass, property } = _decorator;
@ccclass("PauseModal")
@@ -20,6 +21,8 @@ export class PauseModal extends Component {
// 显示弹窗
showModal() {
this.node.active = true;
// 设置暂停游戏背景色
Common.setPageBackgroundColorAsDino(this.node);
// 暂停游戏
director.pause();
// 发送暂停游戏事件

View File

@@ -1,9 +1,11 @@
import {
_decorator,
Color,
Component,
director,
Label,
Node,
Sprite,
tween,
UITransform,
Vec3,
@@ -157,6 +159,12 @@ export class ResultModal extends Component {
// 执行提示动画
playTipAni() {
// 设置提示 dino 颜色
const dinoInfo = GlobalData.currentDinoInfo;
const dinoColor = new Color(dinoInfo.dinoColor);
// 设置提示 dino 颜色
this.tipNode.getChildByName("dino").getComponent(Sprite).color = dinoColor;
// 开启提示
this.tipNode.active = true;
// 获取提示的位置

View File

@@ -0,0 +1,35 @@
import { _decorator, Component, Label, Node, tween, Vec3 } from "cc";
import { EventDispatcher } from "../libs/EventDispatcher";
const { ccclass, property } = _decorator;
@ccclass("TipControl")
export class TipControl extends Component {
//提示标签
@property(Label)
tipLabel: Label | null = null;
start() {
//默认位置,屏幕外
this.node.setPosition(0, -1000);
//监听tips msg事件
EventDispatcher.getTarget().on(
EventDispatcher.TIP_MSG,
this.showTips,
this,
);
}
//显示提示
showTips(msg: string) {
this.tipLabel.string = msg;
tween(this.node)
.to(0.2, { position: new Vec3(0, 0, 0) })
.delay(1)
.to(0.2, { position: new Vec3(0, 1000, 0) })
.call(() => {
this.node.setPosition(0, -1000);
})
.start();
}
update(deltaTime: number) {}
}

View File

@@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "2e7b5643-5827-4d57-b89e-580c05c3e847",
"files": [],
"subMetas": {},
"userData": {}
}