gameCtr.ts 30 KB

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