useGameTimer.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import { ref, computed, watch } from 'vue'
  2. import {
  3. getBoostResidueTimes,
  4. getGoldCoinProductState,
  5. ProductionPlayIncreaseInterface,
  6. startCoinGame,
  7. UserCenter,
  8. } from '@/service/index/foo'
  9. const TWELVE_HOURS = 12 * 60 * 60 // 12 hours in seconds
  10. const REFRESH_INTERVAL = 10 // 10 seconds
  11. export const useGameTimer = () => {
  12. const currentLibaoData = ref<UserCenter>({} as UserCenter)
  13. const playData = ref<ProductionPlayIncreaseInterface>({} as ProductionPlayIncreaseInterface)
  14. const displayTime = ref('00h 00m 00s')
  15. const gamePlayTime = ref('00h 00m 00s')
  16. const percentage = ref(0)
  17. const isAnimating = ref(false)
  18. let countdownTimer: number | null = null
  19. let refreshTimer: number | null = null
  20. let playTimer: number | null = null
  21. const libaoShow = computed(() => {
  22. return currentLibaoData.value.status === 0 || currentLibaoData.value.status === 2
  23. })
  24. const formatDisplayTime = (seconds: number): string => {
  25. if (
  26. !seconds ||
  27. isNaN(seconds) ||
  28. seconds <= 0 ||
  29. currentLibaoData.value.status === 0 ||
  30. currentLibaoData.value.status === 2
  31. ) {
  32. return '00h 00m 00s'
  33. }
  34. seconds = Math.min(seconds, TWELVE_HOURS)
  35. const hours = Math.floor(seconds / 3600)
  36. const minutes = Math.floor((seconds % 3600) / 60)
  37. const remainingSecs = Math.round(seconds % 60)
  38. return `${hours.toString().padStart(2, '0')}h ${minutes.toString().padStart(2, '0')}m ${remainingSecs.toString().padStart(2, '0')}s`
  39. }
  40. const updateTimerAndProgress = () => {
  41. if (currentLibaoData.value.status === 1 && currentLibaoData.value.residueTimestamp > 0) {
  42. currentLibaoData.value.residueTimestamp--
  43. displayTime.value = formatDisplayTime(currentLibaoData.value.residueTimestamp)
  44. percentage.value =
  45. ((TWELVE_HOURS - currentLibaoData.value.residueTimestamp) / TWELVE_HOURS) * 100
  46. isAnimating.value = false
  47. } else if (currentLibaoData.value.status === 0 || currentLibaoData.value.status === 2) {
  48. displayTime.value = '00h 00m 00s'
  49. percentage.value = currentLibaoData.value.status === 2 ? 100 : 0
  50. isAnimating.value = true
  51. } else {
  52. stopTimers()
  53. refreshGameState()
  54. }
  55. }
  56. const updateGamePlayTime = async () => {
  57. if (!playData.value.temporaryRate) {
  58. gamePlayTime.value = '00h 00m 00s'
  59. }
  60. if (playData.value.boostResidueTimestamp > 0) {
  61. playData.value.boostResidueTimestamp--
  62. gamePlayTime.value = formatDisplayTime(playData.value.boostResidueTimestamp)
  63. } else {
  64. gamePlayTime.value = '00h 00m 00s'
  65. clearInterval(playTimer)
  66. }
  67. }
  68. const initPlayGame = async () => {
  69. const { data } = await getBoostResidueTimes()
  70. playData.value = data
  71. }
  72. const refreshGameState = async () => {
  73. try {
  74. const { data } = await getGoldCoinProductState()
  75. currentLibaoData.value = data
  76. if (currentLibaoData.value.status === 1) {
  77. startTimers()
  78. isAnimating.value = false
  79. } else if (currentLibaoData.value.status === 0 || currentLibaoData.value.status === 2) {
  80. displayTime.value = '00h 00m 00s'
  81. percentage.value = currentLibaoData.value.status === 2 ? 100 : 0
  82. isAnimating.value = true
  83. stopTimers()
  84. } else {
  85. stopTimers()
  86. percentage.value = 0
  87. isAnimating.value = false
  88. }
  89. await initPlayGame()
  90. } catch (error) {
  91. console.error('Failed to refresh game state:', error)
  92. }
  93. }
  94. const startTimers = () => {
  95. stopTimers() // Ensure any existing timers are stopped
  96. countdownTimer = setInterval(updateTimerAndProgress, 1000)
  97. refreshTimer = setInterval(refreshGameState, REFRESH_INTERVAL * 1000)
  98. playTimer = setInterval(updateGamePlayTime, 1000)
  99. }
  100. const stopTimers = () => {
  101. if (countdownTimer) {
  102. clearInterval(countdownTimer)
  103. countdownTimer = null
  104. }
  105. if (refreshTimer) {
  106. clearInterval(refreshTimer)
  107. refreshTimer = null
  108. }
  109. if (playTimer) {
  110. clearInterval(playTimer)
  111. playTimer = null
  112. }
  113. }
  114. const restartGame = async () => {
  115. try {
  116. // 调用后端 API 来重新开始游戏
  117. await startCoinGame()
  118. // 重新获取游戏状态
  119. await refreshGameState()
  120. } catch (error) {
  121. console.error('Failed to restart game:', error)
  122. // 这里可以添加错误处理逻辑,比如显示一个错误通知
  123. }
  124. }
  125. watch(
  126. () => currentLibaoData.value.status,
  127. (newStatus) => {
  128. if (newStatus === 1) {
  129. startTimers()
  130. isAnimating.value = false
  131. } else if (newStatus === 0 || newStatus === 2) {
  132. stopTimers()
  133. percentage.value = newStatus === 2 ? 100 : 0
  134. displayTime.value = '00h 00m 00s'
  135. isAnimating.value = true
  136. } else {
  137. stopTimers()
  138. percentage.value = 0
  139. isAnimating.value = false
  140. }
  141. },
  142. )
  143. return {
  144. currentLibaoData,
  145. displayTime,
  146. percentage,
  147. isAnimating,
  148. libaoShow,
  149. refreshGameState,
  150. stopTimers,
  151. restartGame,
  152. gamePlayTime,
  153. playData,
  154. }
  155. }