DataManager.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. import { _decorator, Component, Node, JsonAsset, resources } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. // 问答对接口
  4. interface QAPair {
  5. question: string;
  6. answers: string[];
  7. }
  8. // 通行证信息
  9. interface PassInfo {
  10. name: string;
  11. room: string;
  12. identityId: string;
  13. reason: string;
  14. avatarPath: string;
  15. hasStamp: boolean;
  16. }
  17. // 个人信息
  18. interface PersonalInfo {
  19. id: string;
  20. info: string;
  21. avatarPath: string;
  22. hasRoommate: boolean;
  23. roommate: PersonalInfo | null;
  24. }
  25. // 错误信息
  26. interface ErrorInfo {
  27. errorTypes: number[];
  28. description: string;
  29. }
  30. // NPC接口
  31. interface NPC {
  32. type: 'real' | 'fake';
  33. characterId: number;
  34. characterName: string;
  35. skinId: number;
  36. skinName: string;
  37. qaPairs: QAPair[];
  38. pass: PassInfo;
  39. personal: PersonalInfo;
  40. error: ErrorInfo;
  41. }
  42. // 今日名单项
  43. export interface TodayListItem {
  44. name: string;
  45. avatarPath: string;
  46. }
  47. // 关卡数据接口
  48. interface LevelData {
  49. name: string;
  50. description: string;
  51. timeLimit: number;
  52. randomNpcCount: number;
  53. defaultQuestions: string[];
  54. npcs: NPC[];
  55. todayList: TodayListItem[];
  56. }
  57. @ccclass('DataManager')
  58. export class DataManager extends Component {
  59. // 允许策划将JSON资产拖放到此数组中
  60. @property({
  61. type: [JsonAsset],
  62. tooltip: '关卡JSON数据文件,顺序决定关卡顺序'
  63. })
  64. levelJsonAssets: JsonAsset[] = [];
  65. // 存储所有关卡数据
  66. private levels: LevelData[] = [];
  67. // 当前关卡索引
  68. private currentLevelIndex: number = 0;
  69. // 单例模式
  70. private static _instance: DataManager = null;
  71. public static get instance(): DataManager {
  72. return this._instance;
  73. }
  74. onLoad() {
  75. // 设置单例
  76. if (DataManager._instance === null) {
  77. DataManager._instance = this;
  78. } else {
  79. this.destroy();
  80. return;
  81. }
  82. // 加载所有关卡数据
  83. this.loadAllLevels();
  84. }
  85. /**
  86. * 加载所有关卡数据
  87. */
  88. private loadAllLevels(): void {
  89. this.levels = [];
  90. // 处理拖放到组件的JSON资产
  91. for (const jsonAsset of this.levelJsonAssets) {
  92. if (jsonAsset) {
  93. try {
  94. const levelData = jsonAsset.json as LevelData;
  95. this.levels.push(levelData);
  96. console.log(`成功加载关卡: ${levelData.name}`);
  97. } catch (error) {
  98. console.error(`加载关卡数据失败: ${jsonAsset.name}`, error);
  99. }
  100. }
  101. }
  102. console.log(`总共加载了 ${this.levels.length} 个关卡`);
  103. }
  104. /**
  105. * 获取当前关卡数据
  106. */
  107. public getCurrentLevel(): LevelData | null {
  108. if (this.levels.length === 0) {
  109. console.warn('没有加载任何关卡数据');
  110. return null;
  111. }
  112. if (this.currentLevelIndex < 0 || this.currentLevelIndex >= this.levels.length) {
  113. console.warn(`当前关卡索引 ${this.currentLevelIndex} 超出范围`);
  114. return null;
  115. }
  116. return this.levels[this.currentLevelIndex];
  117. }
  118. /**
  119. * 切换到下一个关卡
  120. * @returns 是否成功切换到下一关卡
  121. */
  122. public nextLevel(): boolean {
  123. if (this.currentLevelIndex < this.levels.length - 1) {
  124. this.currentLevelIndex++;
  125. console.log(`切换到关卡 ${this.currentLevelIndex + 1}: ${this.getCurrentLevel()?.name}`);
  126. return true;
  127. }
  128. console.log('已经是最后一个关卡');
  129. return false;
  130. }
  131. /**
  132. * 切换到上一个关卡
  133. * @returns 是否成功切换到上一关卡
  134. */
  135. public previousLevel(): boolean {
  136. if (this.currentLevelIndex > 0) {
  137. this.currentLevelIndex--;
  138. console.log(`切换到关卡 ${this.currentLevelIndex + 1}: ${this.getCurrentLevel()?.name}`);
  139. return true;
  140. }
  141. console.log('已经是第一个关卡');
  142. return false;
  143. }
  144. /**
  145. * 切换到指定索引的关卡
  146. * @param index 关卡索引
  147. * @returns 是否成功切换
  148. */
  149. public setLevel(index: number): boolean {
  150. if (index >= 0 && index < this.levels.length) {
  151. this.currentLevelIndex = index;
  152. console.log(`切换到关卡 ${index + 1}: ${this.getCurrentLevel()?.name}`);
  153. return true;
  154. }
  155. console.warn(`关卡索引 ${index} 超出范围`);
  156. return false;
  157. }
  158. /**
  159. * 获取当前关卡中的所有NPC
  160. */
  161. public getCurrentLevelNPCs(): NPC[] {
  162. const level = this.getCurrentLevel();
  163. return level ? level.npcs : [];
  164. }
  165. /**
  166. * 获取当前关卡中的真人NPC
  167. */
  168. public getRealNPCs(): NPC[] {
  169. const npcs = this.getCurrentLevelNPCs();
  170. return npcs.filter(npc => npc.type === 'real');
  171. }
  172. /**
  173. * 获取当前关卡中的伪人NPC
  174. */
  175. public getFakeNPCs(): NPC[] {
  176. const npcs = this.getCurrentLevelNPCs();
  177. return npcs.filter(npc => npc.type === 'fake');
  178. }
  179. /**
  180. * 根据角色ID获取NPC
  181. * @param characterId 角色ID
  182. */
  183. public getNPCById(characterId: number): NPC | null {
  184. const npcs = this.getCurrentLevelNPCs();
  185. return npcs.find(npc => npc.characterId === characterId) || null;
  186. }
  187. /**
  188. * 获取所有关卡数量
  189. */
  190. public getLevelCount(): number {
  191. return this.levels.length;
  192. }
  193. /**
  194. * 获取当前关卡索引
  195. */
  196. public getCurrentLevelIndex(): number {
  197. return this.currentLevelIndex;
  198. }
  199. /**
  200. * 重新加载所有关卡数据
  201. */
  202. public reloadAllLevels(): void {
  203. this.loadAllLevels();
  204. }
  205. /**
  206. * 获取当前关卡的时间限制(秒)
  207. */
  208. public getCurrentLevelTimeLimit(): number {
  209. const level = this.getCurrentLevel();
  210. return level ? level.timeLimit : 0;
  211. }
  212. /**
  213. * 获取当前关卡的随机NPC数量
  214. */
  215. public getRandomNpcCount(): number {
  216. const level = this.getCurrentLevel();
  217. return level ? level.randomNpcCount : 0;
  218. }
  219. /**
  220. * 获取当前关卡的默认问题列表
  221. */
  222. public getDefaultQuestions(): string[] {
  223. const level = this.getCurrentLevel();
  224. return level ? level.defaultQuestions : [];
  225. }
  226. /**
  227. * 获取当前关卡的今日名单
  228. */
  229. public getTodayList(): TodayListItem[] {
  230. const level = this.getCurrentLevel();
  231. return level ? level.todayList : [];
  232. }
  233. /**
  234. * 根据角色ID获取NPC的通行证信息
  235. * @param characterId 角色ID
  236. */
  237. public getNPCPassInfo(characterId: number): PassInfo | null {
  238. const npc = this.getNPCById(characterId);
  239. return npc ? npc.pass : null;
  240. }
  241. /**
  242. * 根据角色ID获取NPC的个人信息
  243. * @param characterId 角色ID
  244. */
  245. public getNPCPersonalInfo(characterId: number): PersonalInfo | null {
  246. const npc = this.getNPCById(characterId);
  247. return npc ? npc.personal : null;
  248. }
  249. /**
  250. * 根据角色ID获取NPC的错误信息
  251. * @param characterId 角色ID
  252. */
  253. public getNPCErrorInfo(characterId: number): ErrorInfo | null {
  254. const npc = this.getNPCById(characterId);
  255. return npc ? npc.error : null;
  256. }
  257. /**
  258. * 检查指定名称的人是否在今日名单上
  259. * @param name 人物名称
  260. */
  261. public isPersonInTodayList(name: string): boolean {
  262. const todayList = this.getTodayList();
  263. return todayList.some(item => item.name.trim() === name.trim());
  264. }
  265. }