map.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import { MapEngine, type MapEngineStageRect, type MapEngineViewState } from '../../engine/map/mapEngine'
  2. import { loadRemoteMapConfig } from '../../utils/remoteMapConfig'
  3. type MapPageData = MapEngineViewState & {
  4. showDebugPanel: boolean
  5. }
  6. const INTERNAL_BUILD_VERSION = 'map-build-88'
  7. const REMOTE_GAME_CONFIG_URL = 'https://oss-mbh5.colormaprun.com/wxmini/test/qyds-001/game.json'
  8. let mapEngine: MapEngine | null = null
  9. function getFallbackStageRect(): MapEngineStageRect {
  10. const systemInfo = wx.getSystemInfoSync()
  11. const width = Math.max(320, systemInfo.windowWidth - 20)
  12. const height = Math.max(280, Math.floor(systemInfo.windowHeight * 0.66))
  13. return {
  14. width,
  15. height,
  16. left: 10,
  17. top: 0,
  18. }
  19. }
  20. Page({
  21. data: { showDebugPanel: false } as MapPageData,
  22. onLoad() {
  23. mapEngine = new MapEngine(INTERNAL_BUILD_VERSION, {
  24. onData: (patch) => {
  25. this.setData(patch)
  26. },
  27. })
  28. this.setData({ ...mapEngine.getInitialData(), showDebugPanel: false })
  29. },
  30. onReady() {
  31. this.measureStageAndCanvas()
  32. this.loadMapConfigFromRemote()
  33. },
  34. onUnload() {
  35. if (mapEngine) {
  36. mapEngine.destroy()
  37. mapEngine = null
  38. }
  39. },
  40. loadMapConfigFromRemote() {
  41. const currentEngine = mapEngine
  42. if (!currentEngine) {
  43. return
  44. }
  45. loadRemoteMapConfig(REMOTE_GAME_CONFIG_URL)
  46. .then((config) => {
  47. if (mapEngine !== currentEngine) {
  48. return
  49. }
  50. currentEngine.applyRemoteMapConfig(config)
  51. })
  52. .catch((error) => {
  53. if (mapEngine !== currentEngine) {
  54. return
  55. }
  56. const errorMessage = error && error.message ? error.message : '未知错误'
  57. this.setData({
  58. configStatusText: `载入失败: ${errorMessage}`,
  59. statusText: `远程地图配置载入失败: ${errorMessage} (${INTERNAL_BUILD_VERSION})`,
  60. })
  61. })
  62. },
  63. measureStageAndCanvas() {
  64. const page = this
  65. const applyStage = (rawRect?: Partial<WechatMiniprogram.BoundingClientRectCallbackResult>) => {
  66. const fallbackRect = getFallbackStageRect()
  67. const rect: MapEngineStageRect = {
  68. width: rawRect && typeof rawRect.width === 'number' ? rawRect.width : fallbackRect.width,
  69. height: rawRect && typeof rawRect.height === 'number' ? rawRect.height : fallbackRect.height,
  70. left: rawRect && typeof rawRect.left === 'number' ? rawRect.left : fallbackRect.left,
  71. top: rawRect && typeof rawRect.top === 'number' ? rawRect.top : fallbackRect.top,
  72. }
  73. const currentEngine = mapEngine
  74. if (!currentEngine) {
  75. return
  76. }
  77. currentEngine.setStage(rect)
  78. const canvasQuery = wx.createSelectorQuery().in(page)
  79. canvasQuery.select('#mapCanvas').fields({ node: true, size: true })
  80. canvasQuery.exec((canvasRes) => {
  81. const canvasRef = canvasRes[0] as any
  82. if (!canvasRef || !canvasRef.node) {
  83. page.setData({
  84. statusText: `WebGL 引擎初始化失败 (${INTERNAL_BUILD_VERSION})`,
  85. })
  86. return
  87. }
  88. const dpr = wx.getSystemInfoSync().pixelRatio || 1
  89. try {
  90. currentEngine.attachCanvas(canvasRef.node, rect.width, rect.height, dpr)
  91. } catch (error) {
  92. page.setData({
  93. statusText: `WebGL 初始化失败 (${INTERNAL_BUILD_VERSION})`,
  94. })
  95. }
  96. })
  97. }
  98. const query = wx.createSelectorQuery().in(page)
  99. query.select('.map-stage').boundingClientRect()
  100. query.exec((res) => {
  101. const rect = res[0] as WechatMiniprogram.BoundingClientRectCallbackResult | undefined
  102. applyStage(rect)
  103. })
  104. },
  105. handleTouchStart(event: WechatMiniprogram.TouchEvent) {
  106. if (mapEngine) {
  107. mapEngine.handleTouchStart(event)
  108. }
  109. },
  110. handleTouchMove(event: WechatMiniprogram.TouchEvent) {
  111. if (mapEngine) {
  112. mapEngine.handleTouchMove(event)
  113. }
  114. },
  115. handleTouchEnd(event: WechatMiniprogram.TouchEvent) {
  116. if (mapEngine) {
  117. mapEngine.handleTouchEnd(event)
  118. }
  119. },
  120. handleTouchCancel() {
  121. if (mapEngine) {
  122. mapEngine.handleTouchCancel()
  123. }
  124. },
  125. handleRecenter() {
  126. if (mapEngine) {
  127. mapEngine.handleRecenter()
  128. }
  129. },
  130. handleRotateStep() {
  131. if (mapEngine) {
  132. mapEngine.handleRotateStep()
  133. }
  134. },
  135. handleRotationReset() {
  136. if (mapEngine) {
  137. mapEngine.handleRotationReset()
  138. }
  139. },
  140. handleSetManualMode() {
  141. if (mapEngine) {
  142. mapEngine.handleSetManualMode()
  143. }
  144. },
  145. handleSetNorthUpMode() {
  146. if (mapEngine) {
  147. mapEngine.handleSetNorthUpMode()
  148. }
  149. },
  150. handleSetHeadingUpMode() {
  151. if (mapEngine) {
  152. mapEngine.handleSetHeadingUpMode()
  153. }
  154. },
  155. handleCycleNorthReferenceMode() {
  156. if (mapEngine) {
  157. mapEngine.handleCycleNorthReferenceMode()
  158. }
  159. },
  160. handleAutoRotateCalibrate() {
  161. if (mapEngine) {
  162. mapEngine.handleAutoRotateCalibrate()
  163. }
  164. },
  165. handleToggleGpsTracking() {
  166. if (mapEngine) {
  167. mapEngine.handleToggleGpsTracking()
  168. }
  169. },
  170. handleToggleDebugPanel() {
  171. this.setData({
  172. showDebugPanel: !this.data.showDebugPanel,
  173. })
  174. },
  175. })