gameCtr.ts 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865
  1. import {
  2. _decorator,
  3. Animation,
  4. AnimationClip,
  5. AudioClip,
  6. AudioSource,
  7. CharacterController,
  8. Color,
  9. Component,
  10. director,
  11. EventMouse,
  12. EventTouch,
  13. Label,
  14. Node,
  15. NodeEventType,
  16. ParticleSystem2D,
  17. ProgressBar,
  18. Sprite,
  19. tween,
  20. Tween,
  21. UIOpacity,
  22. UITransform,
  23. v3,
  24. Vec2,
  25. Vec3
  26. } from "cc"
  27. import { noticePannelCtr } from "./noticePannelCtr"
  28. import { StoryPannelCtr } from "./StoryPannelCtr"
  29. import { OptionsCtr } from "./OptionsCtr"
  30. import { rankCtr } from "./rankCtr"
  31. import { RoleCtr } from "./RoleCtr"
  32. import { processCtr } from "./socket/processCtr"
  33. import { SocketClient } from "./socket/SocketClient"
  34. const { ccclass, property } = _decorator
  35. import flatObj from "./FloatObj"
  36. import floatObj from "./FloatObj"
  37. @ccclass("GameCtr")
  38. export class GameCtr extends Component {
  39. @property({ type: noticePannelCtr })
  40. public noticeCtr: noticePannelCtr | null = null
  41. @property({ type: SocketClient })
  42. public socketClient: SocketClient | null = null
  43. @property({ type: processCtr })
  44. public processCtr: processCtr | null = null
  45. @property({ type: RoleCtr })
  46. public roleCtr: RoleCtr | null = null
  47. @property({ type: StoryPannelCtr })
  48. public storyPannelCtr: StoryPannelCtr | null = null
  49. @property({ type: OptionsCtr })
  50. public optionsCtr: OptionsCtr | null = null
  51. @property({ type: rankCtr })
  52. public rankCtr: rankCtr | null = null
  53. @property({ type: Node })
  54. public titlePannel: Node = null
  55. @property({ type: Label })
  56. private dayLabel: Label | null = null
  57. @property(Animation)
  58. SunAnim: Animation = null
  59. @property(Animation)
  60. MoonAnim: Animation = null
  61. @property(Animation)
  62. BgAnim: Animation = null
  63. @property({ type: Node })
  64. BgNode: Node = null
  65. private sunIsUp: boolean = false
  66. private num: number = 1
  67. public roomId: number = 1
  68. public gameId: number = 1
  69. public resetNum: number = 1
  70. private gameInfo: any = null
  71. private historyInfo: any[] = []
  72. private initStoryPosition: Vec3 = null
  73. private initOptionsPosition: Vec3 = null
  74. //剧情布局变化状态:0:展示剧情 ,1:出现选项框 2:已选选项下方展示剧情,3:已选移除剧情上移出现选项框
  75. public storyActionStatus: number = 0
  76. //重启动画
  77. @property({ type: Label })
  78. public resetLabel: Label = null
  79. @property({ type: ProgressBar })
  80. public progressBar: ProgressBar = null
  81. @property({ type: Node })
  82. public resetNode: Node = null
  83. private _dotsCounter: number = 0
  84. private _dotsInterval: any = null
  85. //剧情选项相关
  86. private options: any[] = []
  87. private optionsLabel: string[] = []
  88. private storyHeight = 510
  89. private selectedOptionNum: number = 4
  90. //排名相关
  91. private rankInfo: any[] = []
  92. //角色信息
  93. private npc: any[] = null
  94. private player: any[] = null
  95. //简历角色名-node 字典
  96. private roleNodes = {}
  97. private modifyHp: any[]
  98. //确认正式同步后台数据正式开始标签
  99. private realStart: boolean = false
  100. //通知相关
  101. private noticeStr: string = ""
  102. @property(AudioClip)
  103. public moveClip: AudioClip = null!
  104. @property(AudioClip)
  105. public showOptionsClip: AudioClip = null!
  106. @property(AudioClip)
  107. public selectedOptionClip: AudioClip = null!
  108. public audioSource: AudioSource = null!
  109. @property(AudioSource)
  110. public bg1AudioSource: AudioSource = null!
  111. @property(AudioSource)
  112. public bg2AudioSource: AudioSource = null!
  113. private isPlayBgm1 = true
  114. public originUrl: string = null
  115. public hostName: string = null
  116. private globalUrl: string = "https://airpg1.izouma.com"
  117. private globalHostname: string = "airpg1.izouma.com"
  118. private moveNum: number = 1
  119. private lastVote: number[] = [0, 0, 0, 0]
  120. private currentDay: number = 0
  121. init() {
  122. //播放第一个背景音乐
  123. this.bg1AudioSource.play()
  124. console.log(location.href)
  125. if (location.hostname === "localhost") {
  126. this.originUrl = this.globalUrl
  127. this.hostName = this.globalHostname
  128. } else {
  129. this.originUrl = location.origin
  130. this.hostName = location.hostname
  131. }
  132. let roomId = new URLSearchParams(location.search).get("roomId")
  133. if (roomId != null) {
  134. this.roomId = Number(roomId)
  135. console.log("get roomId from URL:" + roomId)
  136. } else {
  137. console.log("use defult roomId")
  138. }
  139. const roomUrl = `${this.originUrl}/api/room/${this.roomId}`
  140. console.log(roomUrl)
  141. fetch(roomUrl)
  142. .then((response) => {
  143. if (!response.ok) {
  144. throw new Error("Network response was not ok")
  145. }
  146. return response.json()
  147. })
  148. .then((data) => {
  149. //获取游戏ID,房间信息
  150. console.log(data.currentGameId + " " + data.active)
  151. this.gameId = data.currentGameId
  152. this.noticeStr = data.notice
  153. if (this.socketClient.socket) {
  154. this.socketClient.socket.disconnect()
  155. } else {
  156. this.socketClient.gameId = this.gameId
  157. this.socketClient.initSocketConnection()
  158. }
  159. const gameUrl = `${this.originUrl}/api/game/${this.gameId}`
  160. fetch(gameUrl)
  161. .then((response) => {
  162. if (!response.ok) {
  163. throw new Error("Network response was not ok")
  164. }
  165. return response.json()
  166. })
  167. .then((data) => {
  168. console.log(data)
  169. const historyUrl = `${this.originUrl}/api/game/${this.gameId}/history`
  170. this.gameInfo = data
  171. this.resetNum = data.resetNum
  172. fetch(historyUrl)
  173. .then((response) => {
  174. if (!response.ok) {
  175. throw new Error("Network response was not ok")
  176. }
  177. return response.json()
  178. })
  179. .then((data) => {
  180. console.log("history")
  181. console.log(data)
  182. this.historyInfo = data
  183. //根据游戏信息与历史信息更新房间组件
  184. this.updateGame(this.gameInfo, this.historyInfo)
  185. })
  186. .catch((error) => {
  187. console.error("Fetch error:", error)
  188. })
  189. })
  190. .catch((error) => {
  191. console.error("Fetch error:", error)
  192. })
  193. })
  194. .catch((error) => {
  195. console.error("Fetch error:", error)
  196. })
  197. this.initRank(roomUrl + "/survivalRank")
  198. }
  199. initRank(url: string) {
  200. fetch(url)
  201. .then((response) => {
  202. if (!response.ok) {
  203. throw new Error("Network response was not ok")
  204. }
  205. return response.json()
  206. })
  207. .then((data) => {
  208. console.log("rank")
  209. console.log(data)
  210. this.rankInfo = data
  211. //根据游戏信息与历史信息更新房间组件
  212. this.rankCtr.updateRank(this.rankInfo)
  213. })
  214. .catch((error) => {
  215. console.error("Fetch error:", error)
  216. })
  217. }
  218. start() {
  219. //加载音频播放组件
  220. this.audioSource = this.node.getComponent(AudioSource)
  221. this.startResetAnimation()
  222. // this.scheduleOnce(() => { this.accessTargetComponent() }, 0.1)
  223. this.scheduleOnce(() => {
  224. this.init()
  225. }, 10)
  226. this.processCtr.init(this)
  227. this.schedule(this.chackGameInfo, 5 * 60)
  228. }
  229. chackGameInfo() {
  230. //轮询检查游戏信息
  231. const roomUrl = `${this.originUrl}/api/room/${this.roomId}`
  232. fetch(roomUrl)
  233. .then((response) => {
  234. if (!response.ok) {
  235. throw new Error("Network response was not ok")
  236. }
  237. return response.json()
  238. })
  239. .then((data) => {
  240. //获取游戏ID,房间信息
  241. console.log("轮询检查房间信息:" + data.currentGameId + " " + data.active)
  242. if (this.gameId == data.currentGameId) {
  243. if (this.noticeStr == data.notice) {
  244. return
  245. } else {
  246. this.noticeCtr.updateText(data.notice)
  247. this.noticeStr = data.notice
  248. }
  249. } else {
  250. director.loadScene("game")
  251. }
  252. })
  253. .catch((error) => {
  254. console.error("Fetch error:", error)
  255. })
  256. //查看历史记录,校验游戏是否还在同步中
  257. const historyUrl = `${this.originUrl}/api/game/${this.gameId}/history`
  258. fetch(historyUrl)
  259. .then((response) => {
  260. if (!response.ok) {
  261. throw new Error("Network response was not ok")
  262. }
  263. return response.json()
  264. })
  265. .then((data) => {
  266. const currentHistory: any[] = data
  267. // 计算日期差(结果单位为毫秒)
  268. const lastHistoryDate = new Date(currentHistory[currentHistory.length - 1].date)
  269. const firstHistoryDate = new Date(this.historyInfo[0].date)
  270. const differenceInMilliseconds = flatObj.subtract(lastHistoryDate.getTime(), firstHistoryDate.getTime())
  271. // 将毫秒转为天数
  272. const differenceInDays = flatObj.add(flatObj.divide(differenceInMilliseconds, 1000 * 60 * 60 * 24), 1)
  273. console.log("校验游戏进程是否同步:当前天数:" + this.currentDay + " 后台进行天数" + differenceInDays)
  274. //如果相差超过3天,则重置
  275. if (floatObj.subtract(differenceInDays, this.currentDay) > 2) {
  276. director.loadScene("game")
  277. }
  278. })
  279. .catch((error) => {
  280. console.error("Fetch error:", error)
  281. })
  282. }
  283. update(deltaTime: number) {}
  284. onButtonClick() {
  285. //director.loadScene(director.getScene().name);
  286. // this.exchangeTime()
  287. // this.noticeCtr.updateText(
  288. // "在 Cocos Creator 编辑器中,将富文本组件拖放到脚本的 richText 属性框中。运行游戏,现在你应该可以看到富文本的内容逐字出现。"
  289. // )
  290. //options初始化
  291. this.moveNum++
  292. // this.optionsCtr.showVotes(this.moveNum)
  293. // this.optionsCtr.selectOption(3)
  294. //重置测试
  295. //this.startResetAnimation()
  296. //测试排行切换
  297. // this.rankCtr.updateRankTop()
  298. //测试剧情Pannel移动
  299. // this.optionsAppearAction()
  300. //测试被攻击
  301. this.roleCtr.attack(this.roleCtr.node.getChildByName("role_icon_npc1"))
  302. // this.roleCtr.attack(this.roleCtr.node.getChildByName('role_icon_npc3'));
  303. this.roleCtr.treat(this.roleCtr.node.getChildByName("role_icon_npc2"))
  304. // this.roleCtr.newPlayer(this.roleCtr.node.getChildByName('role_icon_player1'));
  305. }
  306. //重启动画相关
  307. startResetAnimation() {
  308. // Fade in the black mask
  309. if (this._dotsInterval) {
  310. clearInterval(this._dotsInterval)
  311. this._dotsInterval = null
  312. }
  313. this.resetNode.getComponent(UIOpacity).opacity = 0
  314. this.progressBar.progress = 0
  315. this.resetNode.active = true
  316. this.BgNode.getComponent(UIOpacity).opacity = 0
  317. tween(this.resetNode.getComponent(UIOpacity))
  318. .to(1, { opacity: 255 })
  319. .call(() => this.showResetTextAndProgress())
  320. .start()
  321. }
  322. showResetTextAndProgress() {
  323. this.updateDots()
  324. this._dotsInterval = setInterval(() => this.updateDots(), 500)
  325. // Simulate progress
  326. let progress = 0
  327. const progressInterval = setInterval(() => {
  328. progress += 0.1
  329. this.progressBar.progress = progress
  330. if (progress >= 1) {
  331. clearInterval(progressInterval)
  332. this.endResetAnimation()
  333. }
  334. }, 1000)
  335. }
  336. updateDots() {
  337. const dots = ".".repeat((this._dotsCounter % 3) + 1)
  338. this.resetLabel.string = `世界重置中${dots}`
  339. this._dotsCounter++
  340. }
  341. endResetAnimation() {
  342. clearInterval(this._dotsInterval)
  343. // Fade out the black mask and reset
  344. tween(this.resetNode.getComponent(UIOpacity))
  345. .to(1, { opacity: 0 })
  346. .call(() => {
  347. this.progressBar.progress = 0
  348. this.resetNode.active = false
  349. this.BgNode.getComponent(UIOpacity).opacity = 255
  350. })
  351. .start()
  352. }
  353. handleStoryPannelMove(data: any) {
  354. this.storyPannelCtr.storyContent = data.data
  355. this.storyPannelCtr.isOnProcess = true
  356. //0:初始化后第一次收到剧情,直接展示剧情
  357. //3:接收到了最后一次剧情展示后清除队列
  358. if (this.storyActionStatus == 0 || this.storyActionStatus == 3) {
  359. if (this.storyPannelCtr) {
  360. this.storyPannelCtr.updateStory(data.data)
  361. } else {
  362. console.log("plot error")
  363. }
  364. this.realStart = true
  365. this.noticeCtr.updateText(this.noticeStr)
  366. } else if (this.storyActionStatus == 2) {
  367. this.optionsAppearAction()
  368. }
  369. }
  370. //处理收到选项事件
  371. handleOptions(data: any) {
  372. if (this.realStart) {
  373. this.options = data.data
  374. //更新optionsLabel
  375. for (let i = 0; i < 4; i++) {
  376. this.optionsLabel[i] = this.options[i].content
  377. }
  378. if (this.storyActionStatus === 0 || this.storyActionStatus === 3) {
  379. this.optionsAppearAction()
  380. //重置记票
  381. this.lastVote = [0, 0, 0, 0]
  382. } else {
  383. console.log("handleOptions处理失败" + " storyActionStatus" + this.storyActionStatus)
  384. this.processCtr.doneProcessing()
  385. }
  386. } else {
  387. console.log("handleOptions处理完成处理下一个")
  388. this.processCtr.doneProcessing()
  389. }
  390. }
  391. //处理投票进度
  392. handleVotes(data: any) {
  393. let vote: number[] = data.data
  394. if (this.realStart && Math.max(...vote) > 0 && JSON.stringify(this.lastVote) !== JSON.stringify(vote)) {
  395. // console.log("this22222"+this+" processCtr!!!!!"+this.processCtr)
  396. this.optionsCtr.showVotes(vote, this.lastVote, this.processCtr)
  397. this.lastVote = vote
  398. } else {
  399. console.log(
  400. "handle votes do nothing:" +
  401. this.realStart +
  402. " " +
  403. this.storyActionStatus +
  404. " " +
  405. Math.max(...(data.data as number[]))
  406. )
  407. this.processCtr.doneProcessing()
  408. }
  409. }
  410. //处理收到被选项事件
  411. handleVoteResul(data: any) {
  412. if (this.realStart) {
  413. this.modifyHp = data.data.modifyHp
  414. for (let i = 0; i < 4; i++) {
  415. if (this.options[i].content == data.data.content) {
  416. this.selectedOptionNum = i
  417. }
  418. }
  419. if (this.storyActionStatus === 1) {
  420. this.optionsAppearAction()
  421. } else {
  422. console.log("handleVoteResul处理失败" + " storyActionStatus" + this.storyActionStatus)
  423. }
  424. } else {
  425. console.log("handleVoteResul未处理")
  426. this.processCtr.doneProcessing()
  427. }
  428. }
  429. //处理新玩家加入
  430. handleNewPlayer(data: any) {
  431. this.player.push(data.data)
  432. let playerIndex = this.player.length - 1
  433. if (playerIndex === 8) {
  434. return
  435. }
  436. const rolePannelName: string = "role_icon_player" + (playerIndex + 1)
  437. const role: Node = this.roleCtr.node.getChildByName(rolePannelName)
  438. role.active = true
  439. console.log("new player@!!!!!!:" + data.data)
  440. this.roleCtr.newPlayer(role, this.player[playerIndex])
  441. this.roleNodes[data.data.name] = role
  442. console.log("handleNewPlayer处理完成处理下一个")
  443. this.processCtr.doneProcessing()
  444. }
  445. //单独处理死亡
  446. handleDeath(data: any) {
  447. this.roleCtr.deathNodes = data.data
  448. this.processCtr.doneProcessing()
  449. }
  450. //处理收到state时间:如果realStart == false ,则更新游戏初始状态
  451. handleStateResul(data: any) {
  452. if (!this.realStart) {
  453. console.log("处理开始前的status")
  454. this.historyInfo.push(data.data)
  455. this.updateGame(this.gameInfo, this.historyInfo)
  456. console.log("handleStateResul处理完成处理下一个")
  457. this.processCtr.doneProcessing()
  458. } else {
  459. console.log("处理开始后的status完成,处理下一个")
  460. this.processCtr.doneProcessing()
  461. }
  462. }
  463. //处理重置
  464. handleReset(data: any) {
  465. //director.reset()
  466. console.log("处理重置消息")
  467. this.roleCtr.dealDeath(this.roleNodes)
  468. this.scheduleOnce(() => {
  469. director.loadScene("game")
  470. }, 5)
  471. this.processCtr.doneProcessing()
  472. }
  473. //处理所有剧情、选项的移动逻辑
  474. optionsAppearAction() {
  475. console.log("storyActionStatus:" + this.storyActionStatus)
  476. //展示选项,折叠剧情,开启投票统计
  477. if (this.storyActionStatus == 0) {
  478. const storyNode = this.storyPannelCtr.node
  479. const storyUI = storyNode.getComponent(UITransform)
  480. if (storyUI.height > this.storyHeight) {
  481. this.initStoryPosition = storyNode.position.clone()
  482. tween(this.storyPannelCtr.node)
  483. .by(0.5, { position: new Vec3(0, storyUI.height - this.storyHeight, 0) })
  484. .call(() => {
  485. this.optionsCtr.setOptions(this.optionsLabel, this)
  486. //此处需要额外处理死亡,因为前一步有演示播放攻击动画,不排除死亡名单中有攻击后自然死亡角色,最后一个死亡的没啥用,暂没处理
  487. this.roleCtr.dealDeath(this.roleNodes)
  488. })
  489. .start()
  490. } else {
  491. this.optionsCtr.setOptions(this.optionsLabel, this)
  492. }
  493. this.playShowOptionsOneShot()
  494. } else if (this.storyActionStatus === 1) {
  495. //选中备选项
  496. this.optionsCtr.resetVotes()
  497. console.log("selectedOptionNum:" + this.selectedOptionNum)
  498. this.playSelectedOneShot()
  499. this.optionsCtr.selectOption(this.selectedOptionNum + 1, this)
  500. } else if (this.storyActionStatus === 2) {
  501. this.scheduleOnce(() => {
  502. // 隐藏未被选中选项
  503. for (let i = 0; i < 4; i++) {
  504. var optionNode: Node = this.optionsCtr.optionNodes[i]
  505. if (i !== this.selectedOptionNum) {
  506. const optionTween = tween(optionNode.getComponent(UIOpacity))
  507. optionTween.to(2.5, { opacity: 0 }).start()
  508. }
  509. }
  510. //播放移动声音
  511. this.playMoveOneShot()
  512. //隐藏上边剧情面板
  513. tween(this.storyPannelCtr.node.parent.getComponent(UIOpacity))
  514. .to(2.5, { opacity: 0 })
  515. .call(() => {
  516. this.storyPannelCtr.node.getComponent(Label).string = ""
  517. this.storyPannelCtr.node.position = new Vec3(0, 0, 0)
  518. this.initOptionsPosition = this.optionsCtr.node.position.clone()
  519. const storyY = this.storyPannelCtr.node.parent.position.y
  520. const optionsY = this.optionsCtr.node.position.y
  521. const selectedOption = this.optionsCtr.optionNodes[this.selectedOptionNum]
  522. const selectedOptionHeight = selectedOption.getComponent(UITransform).contentSize.height
  523. //选中选项上移
  524. tween(this.optionsCtr.node)
  525. .by(1.5, {
  526. position: new Vec3(
  527. 0,
  528. storyY - optionsY - selectedOption.position.y - selectedOptionHeight / 2,
  529. 0
  530. )
  531. })
  532. .call(() => {
  533. this.storyPannelCtr.node.parent.getComponent(UIOpacity).opacity = 255
  534. //剧情面板在下方出现并开始展示
  535. tween(this.storyPannelCtr.node)
  536. .by(0.01, { position: new Vec3(0, -selectedOptionHeight, 0) })
  537. .call(() => {
  538. this.storyPannelCtr.isOnProcess = true
  539. this.storyPannelCtr.updateStory(this.storyPannelCtr.storyContent)
  540. this.storyActionStatus = 3
  541. //延时触发扣血加血动画
  542. this.scheduleOnce(() => {
  543. this.updateHp()
  544. }, 2)
  545. })
  546. .start()
  547. })
  548. .start()
  549. })
  550. .start()
  551. }, 2)
  552. } else if (this.storyActionStatus == 3) {
  553. const selectedOption = this.optionsCtr.optionNodes[this.selectedOptionNum]
  554. //顶部备选项消失
  555. tween(selectedOption.getComponent(UIOpacity))
  556. .to(0.5, { opacity: 1 })
  557. .call(() => {
  558. //重置选项位置与透明度
  559. this.optionsCtr.node.position = this.initOptionsPosition
  560. // 这是被选中的选项
  561. selectedOption.getChildByName("text_option").getComponent(Label).color = Color.WHITE
  562. // 移除选中背景图
  563. const spriteComponent = selectedOption.getComponent(Sprite)
  564. if (spriteComponent) {
  565. spriteComponent.spriteFrame = this.optionsCtr.notSelectedSprite.spriteFrame
  566. }
  567. //剧情上移开始展示
  568. tween(this.storyPannelCtr.node)
  569. .to(0.2, { position: new Vec3(0, 0, 0) })
  570. .call(() => {
  571. this.storyActionStatus = 0
  572. this.optionsAppearAction()
  573. // console.log("剧情上移处理完成,处理下一个")
  574. // this.processCtr.doneProcessing()
  575. })
  576. .start()
  577. })
  578. .start()
  579. }
  580. }
  581. updateGame(gameInfo: any, historyInfo: any[]) {
  582. if (gameInfo && history) {
  583. this.updateDateByHistory(historyInfo[0], historyInfo[historyInfo.length - 1])
  584. const firstHistory = historyInfo[0]
  585. const lastHistory = historyInfo[historyInfo.length - 1]
  586. const charactors: any[] = lastHistory.charactors
  587. //初始化剧情!!!
  588. //触发剧情框文字
  589. if (this.storyPannelCtr) {
  590. this.storyPannelCtr.initStory(lastHistory.plot)
  591. } else {
  592. console.log("plot error")
  593. }
  594. //初始化角色!!!
  595. this.player = []
  596. this.npc = []
  597. this.roleNodes = {}
  598. for (let i = 0; i < charactors.length; i++) {
  599. if (charactors[i].danmuUserId) {
  600. this.player.push(charactors[i])
  601. } else {
  602. this.npc.push(charactors[i])
  603. }
  604. }
  605. for (let i = 0; i < this.npc.length; i++) {
  606. const rolePannelName: string = "role_icon_npc" + (i + 1)
  607. console.log(rolePannelName)
  608. const role: Node = this.roleCtr.node.getChildByName(rolePannelName)
  609. role.active = true
  610. this.roleCtr.newPlayer(role, this.npc[i])
  611. this.roleNodes[this.npc[i].name] = role
  612. }
  613. for (let i = 0; i < this.player.length; i++) {
  614. const rolePannelName: string = "role_icon_player" + (i + 1)
  615. const role: Node = this.roleCtr.node.getChildByName(rolePannelName)
  616. role.active = true
  617. this.roleCtr.newPlayer(role, this.player[i])
  618. this.roleNodes[this.player[i].name] = role
  619. }
  620. } else {
  621. throw new Error("gameInfo or historyInfo is null")
  622. }
  623. }
  624. //更新日期
  625. updateDateByHistory(firstHistory: any, lastHistory: any) {
  626. //初始化标题与天数!!!
  627. const time: string = lastHistory.time
  628. if (time === "evening") {
  629. this.sunIsUp = false
  630. this.exchangeTime()
  631. }
  632. this.titlePannel.getChildByName("text_title").getComponent(Label).string = this.gameInfo.name
  633. this.titlePannel.getChildByName("text_gameNo").getComponent(Label).string = "No." + (this.resetNum + 1)
  634. // 计算日期差(结果单位为毫秒)
  635. const lastHistoryDate = new Date(lastHistory.date)
  636. const firstHistoryDate = new Date(firstHistory.date)
  637. const differenceInMilliseconds = lastHistoryDate.getTime() - firstHistoryDate.getTime()
  638. // 将毫秒转为天数
  639. const differenceInDays = differenceInMilliseconds / (1000 * 60 * 60 * 24) + 1
  640. this.dayLabel.string = "第" + differenceInDays + "天"
  641. this.currentDay = differenceInDays
  642. }
  643. updateDateByWS(data: any) {
  644. const time: string = data.data.time
  645. if (time === "evening") {
  646. this.sunIsUp = false
  647. this.exchangeTime()
  648. } else {
  649. this.sunIsUp = true
  650. this.exchangeTime()
  651. }
  652. this.titlePannel.getChildByName("text_title").getComponent(Label).string = this.gameInfo.name
  653. this.titlePannel.getChildByName("text_gameNo").getComponent(Label).string = "No." + (this.resetNum + 1)
  654. // 计算日期差(结果单位为毫秒)
  655. const lastHistoryDate = new Date(data.data.date)
  656. const firstHistoryDate = new Date(this.historyInfo[0].date)
  657. const differenceInMilliseconds = lastHistoryDate.getTime() - firstHistoryDate.getTime()
  658. // 将毫秒转为天数
  659. const differenceInDays = differenceInMilliseconds / (1000 * 60 * 60 * 24) + 1
  660. this.dayLabel.string = "第" + differenceInDays + "天"
  661. this.currentDay = differenceInDays
  662. console.log("更新日期处理完成,处理下一个")
  663. this.processCtr.doneProcessing()
  664. }
  665. exchangeTime() {
  666. if (this.sunIsUp) {
  667. this.MoonAnim.play("moonUp")
  668. this.MoonAnim.on(Animation.EventType.FINISHED, () => {
  669. this.SunAnim.play("sunDown")
  670. this.MoonAnim.off(Animation.EventType.FINISHED)
  671. })
  672. this.sunIsUp = false
  673. } else {
  674. this.SunAnim.play("sunUp")
  675. this.SunAnim.on(
  676. Animation.EventType.FINISHED,
  677. () => {
  678. this.MoonAnim.play("moonDown")
  679. this.SunAnim.off(Animation.EventType.FINISHED)
  680. },
  681. this
  682. )
  683. this.sunIsUp = true
  684. }
  685. }
  686. updateHp() {
  687. if (this.modifyHp) {
  688. let changBgm2 = false
  689. for (let i = 0; i < this.modifyHp.length; i++) {
  690. const roleNode: Node = this.roleNodes[this.modifyHp[i].name]
  691. const pbNode: Node = roleNode.getChildByName("progressbar_hp")
  692. const orgHp = pbNode.getComponent(ProgressBar).progress
  693. //已死亡不触发
  694. if (orgHp == 0) {
  695. continue
  696. }
  697. let newHp = flatObj.add(orgHp, flatObj.divide(this.modifyHp[i].changeValue, 100))
  698. if (newHp <= 0) {
  699. newHp = 0
  700. } else if (newHp > 1) {
  701. newHp = 1
  702. }
  703. pbNode.getComponent(ProgressBar).progress = newHp
  704. console.log("updata HP: name:" + this.modifyHp[i].name + " orgHp:" + orgHp + " newHp:" + newHp)
  705. console.log(pbNode)
  706. if (this.modifyHp[i].changeValue > 0) {
  707. this.roleCtr.treat(roleNode)
  708. } else {
  709. this.roleCtr.attack(roleNode)
  710. //发生战斗,更换BGM
  711. changBgm2 = true
  712. }
  713. }
  714. if (changBgm2 && this.isPlayBgm1) {
  715. this.bg1AudioSource.pause()
  716. this.bg2AudioSource.play()
  717. this.isPlayBgm1 = false
  718. } else if (!changBgm2 && !this.isPlayBgm1) {
  719. this.bg2AudioSource.pause()
  720. this.bg1AudioSource.play()
  721. this.isPlayBgm1 = true
  722. }
  723. }
  724. }
  725. playMoveOneShot() {
  726. this.audioSource.playOneShot(this.moveClip, 0.2)
  727. }
  728. playSelectedOneShot() {
  729. this.audioSource.playOneShot(this.selectedOptionClip, 0.2)
  730. }
  731. playShowOptionsOneShot() {
  732. this.audioSource.playOneShot(this.showOptionsClip, 0.2)
  733. }
  734. }