darkNodeManager.lua 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. ------------
  2. local lightNode = class("lightNode")
  3. local darkNodeManager = class("darkNodeManager")
  4. local MAXNODE = 200 -- 最多有多少个圈
  5. function darkNodeManager:ctor()
  6. self._nodeInfo = {}
  7. self._nodeNum = 0
  8. self._mapLight = {}
  9. end
  10. function darkNodeManager:destory()
  11. if darkNodeManager.instance then
  12. darkNodeManager.instance = nil
  13. end
  14. end
  15. function darkNodeManager:Inst()
  16. if not darkNodeManager.instance then
  17. darkNodeManager.instance = darkNodeManager.new()
  18. end
  19. return darkNodeManager.instance
  20. end
  21. -----------------------------------------------------------------------------
  22. function darkNodeManager:Cleanup()
  23. if SL:GetMetaValue("GAME_DATA", "dark") ~= 1 then
  24. return
  25. end
  26. self._nodeInfo = {}
  27. self._nodeNum = 0
  28. end
  29. -----------------------------------------------------------------------------
  30. ---MapGridWidth = 48, -- 地图格子宽度
  31. -- MapGridHeight = 32, -- 地图格子高度
  32. local MapGridWidth = global.MMO.MapGridWidth
  33. --- data { pos , t} -> {x,y,r,w}
  34. function darkNodeManager:createNode(data)-- 光圈数据 {x,y,r,w} --x,y世界坐标 r光圈半径 w 渐变宽度
  35. if SL:GetMetaValue("GAME_DATA", "dark") ~= 1 then
  36. return
  37. end
  38. -- return
  39. local index
  40. --最多两百个圈
  41. for i = 1, MAXNODE do
  42. if not self._nodeInfo[i .. ""] then
  43. index = i .. ""
  44. break
  45. end
  46. end
  47. if _DEBUG and not index then
  48. dump("200个圈了!!!")
  49. end
  50. if index then
  51. local offset = data.offset or cc.p(0, 0)
  52. self._nodeInfo[index] = { x = data.x + offset.x, y = data.y + offset.y, r = data.r * MapGridWidth , w = data.w * MapGridWidth}
  53. self._nodeNum = self._nodeNum + 1
  54. end
  55. return index
  56. end
  57. function darkNodeManager:updateNode(index, data) --
  58. if SL:GetMetaValue("GAME_DATA", "dark") ~= 1 then
  59. return
  60. end
  61. if not index then
  62. return false
  63. end
  64. local light = self._nodeInfo[index]
  65. if not light then
  66. return false
  67. end
  68. if data.isLast and light.r ~= data.r then
  69. light.last_r = light.r / MapGridWidth
  70. end
  71. if data.isLast and light.w ~= data.w then
  72. light.last_w = light.w / MapGridWidth
  73. end
  74. if data.r then
  75. light.r = data.r * MapGridWidth
  76. end
  77. if data.w then
  78. light.w = data.w * MapGridWidth
  79. end
  80. local offset = cc.p(0, 0)
  81. if data.offset then
  82. offset = data.offset
  83. end
  84. if data.x then
  85. light.x = data.x + offset.x
  86. end
  87. if data.y then
  88. light.y = data.y + offset.y
  89. end
  90. return true
  91. end
  92. function darkNodeManager:removeNode(index) --
  93. if SL:GetMetaValue("GAME_DATA", "dark") ~= 1 then
  94. return
  95. end
  96. if not index then
  97. return false
  98. end
  99. local light = self._nodeInfo[index]
  100. if not light then
  101. return false
  102. end
  103. self._nodeInfo[index] = nil
  104. self._nodeNum = self._nodeNum - 1
  105. return true
  106. end
  107. --b 是否保留自己的灯光
  108. function darkNodeManager:clearAllNodes(b) --
  109. if SL:GetMetaValue("GAME_DATA", "dark") ~= 1 then
  110. return
  111. end
  112. if b then
  113. local mainPlayer = global.gamePlayerController:GetMainPlayer()
  114. local id
  115. if mainPlayer then
  116. id = mainPlayer:GetLightID()
  117. end
  118. local light = self._nodeInfo[id]
  119. self._nodeInfo = {}
  120. self._nodeNum = 0
  121. if light then
  122. self._nodeInfo[id] = light
  123. self._nodeNum = 1
  124. end
  125. else
  126. self._nodeInfo = {}
  127. self._nodeNum = 0
  128. end
  129. self._mapLight = {}
  130. end
  131. function darkNodeManager:getAllNodes()
  132. return self._nodeInfo
  133. end
  134. function darkNodeManager:getNodeByLightID(lightID)
  135. if not lightID then
  136. return nil
  137. end
  138. return self._nodeInfo[lightID]
  139. end
  140. function darkNodeManager:getNodeNums()
  141. return self._nodeNum
  142. end
  143. ------------------
  144. --地图数据相关
  145. function darkNodeManager:InitmapInfo()
  146. local mapData = global.sceneManager:GetMapData2DPtr()
  147. local needLoadLight = false
  148. repeat
  149. if not mapData then
  150. break
  151. end
  152. if not mapData.GetLight then
  153. break
  154. end
  155. if SL:GetMetaValue("GAME_DATA", "dark") ~= 1 then
  156. break
  157. end
  158. needLoadLight = true
  159. until true
  160. self._mapRows = mapData:getMapDataRows()
  161. self._mapCols = mapData:getMapDataCols()
  162. self._needLoadLight = needLoadLight
  163. self._lastTilesArea = cc.rect(0,0,0,0)
  164. self._tilesArea = cc.rect(0,0,0,0)
  165. self._screenArea = cc.rect(0,0,0,0)
  166. end
  167. function darkNodeManager:followPlayer(pos)
  168. self:calcScreenAreaRect(pos)
  169. self:calcScreenLight()
  170. self:loadScreenTile()
  171. end
  172. function darkNodeManager:calcScreenAreaRect(pos)
  173. if not self._needLoadLight then
  174. return
  175. end
  176. local viewSize = global.gameMapController:GetViewSize()
  177. local centerOffset = global.gameMapController:GetViewCenterOffset()
  178. local centerOfView = cc.size(viewSize.width/2 + centerOffset.x, viewSize.height/2 + centerOffset.y)
  179. local x = pos.x;
  180. local y = -pos.y;
  181. self._screenArea = cc.rect(x - centerOfView.width, y - centerOfView.height, viewSize.width, viewSize.height)
  182. end
  183. function darkNodeManager:calcScreenLight()
  184. if not self._needLoadLight then
  185. return
  186. end
  187. local queryRect = self._screenArea
  188. local minX, minY;
  189. local maxX, maxY;
  190. local sliceW = global.MMO.MapGridWidth;
  191. local sliceH = global.MMO.MapGridHeight;
  192. local offset = global.gameMapController:GetViewCenterOffset()
  193. minX = queryRect.x / sliceW;
  194. minX = (minX > 0) and minX or 0;
  195. minY = queryRect.y
  196. minY = minY / sliceH;
  197. minY = (minY > 0) and minY or 0;
  198. maxX = cc.rectGetMaxX(queryRect)
  199. maxX = maxX / sliceW;
  200. maxX = (maxX % sliceW > 0 and maxX < self._mapCols) and maxX + 1 or maxX
  201. maxY = cc.rectGetMaxY(queryRect)
  202. maxY = maxY / sliceH;
  203. maxY = (maxY % sliceH > 0 and maxY < self._mapRows) and maxY + 1 or maxY
  204. minX = math.max(0, minX - 4);
  205. minY = math.max(0, minY - 3);
  206. maxX = math.min(maxX + 3, self._mapCols - 1);
  207. maxY = math.min(maxY + 3, self._mapRows - 1);
  208. self._lastTilesArea = self._tilesArea;
  209. self._tilesArea =cc.rect(minX, minY, maxX - minX, maxY - minY);
  210. end
  211. local rectIntersection = function (rect1, rect2)
  212. local x = math.max(rect1.x, rect2.x)
  213. local y = math.max(rect1.y, rect2.y)
  214. local width = math.min(rect1.x + rect1.width, rect2.x + rect2.width) - x;
  215. local height = math.min(rect1.y + rect1.height, rect2.y + rect2.height) - y;
  216. local rect = cc.rect(x, y, width, height)
  217. return rect
  218. end
  219. function darkNodeManager:loadScreenTile()
  220. if not self._needLoadLight then
  221. return
  222. end
  223. local isInter = cc.rectIntersectsRect( self._tilesArea, self._lastTilesArea )
  224. if not isInter then
  225. self:UnloadAllLight();
  226. self:LoadLightInRect(self._tilesArea);
  227. else
  228. local interRect = rectIntersection(self._lastTilesArea, self._tilesArea);
  229. local unLoadTileArray = self:GetDiffRect(self._lastTilesArea, interRect);
  230. local loadTileArray = self:GetDiffRect(self._tilesArea, interRect);
  231. for i, rect in ipairs(unLoadTileArray) do
  232. self:UnLoadLightInRect(rect);
  233. end
  234. for i, rect in ipairs(loadTileArray) do
  235. self:LoadLightInRect(rect);
  236. end
  237. end
  238. end
  239. function darkNodeManager:GetDiffRect(originRect, interRect)
  240. local t = {}
  241. local dx = interRect.x - originRect.x;
  242. if dx ~= 0 or interRect.width ~= originRect.width then
  243. local beginX = originRect.x;
  244. local endX = beginX + dx - 1;
  245. if dx == 0 then
  246. beginX = cc.rectGetMaxX(interRect) + 1;
  247. endX = cc.rectGetMaxX(originRect);
  248. end
  249. local beginY = originRect.y;
  250. local endY = beginY + originRect.height;
  251. table.insert(t, cc.rect(beginX, beginY, endX - beginX, endY - beginY));
  252. end
  253. local dy = interRect.y - originRect.y;
  254. if dy ~= 0 or interRect.height ~= originRect.height then
  255. local beginX = math.max(interRect.x, originRect.x);
  256. if dx == 0 then
  257. beginX = interRect.x;
  258. end
  259. local endX = beginX + interRect.width;
  260. local beginY = originRect.y;
  261. local endY = beginY + dy - 1;
  262. if dy == 0 then
  263. beginY = cc.rectGetMaxY(interRect) + 1;
  264. endY = cc.rectGetMaxY(originRect)
  265. end
  266. table.insert(t, cc.rect(beginX, beginY, endX - beginX, endY - beginY));
  267. end
  268. return t
  269. end
  270. function darkNodeManager:UnloadAllLight()
  271. for k, v in pairs(self._mapLight) do
  272. self:removeNode(v)
  273. end
  274. self._mapLight = {}
  275. end
  276. function darkNodeManager:UnLoadLightInRect(rect)
  277. local minX = math.ceil(rect.x);
  278. local minY = math.ceil(rect.y);
  279. local maxX = math.ceil(cc.rectGetMaxX(rect));
  280. local maxY = math.ceil(cc.rectGetMaxY(rect));
  281. for y = minY, maxY do
  282. for x = minX, maxX do
  283. self:UnLoadOneLight(x,y)
  284. end
  285. end
  286. end
  287. function darkNodeManager:LoadLightInRect(rect)
  288. local minX = math.floor(rect.x);
  289. local minY = math.floor(rect.y);
  290. local maxX = math.floor(cc.rectGetMaxX(rect));
  291. local maxY = math.floor(cc.rectGetMaxY(rect));
  292. for y = minY, maxY do
  293. for x = minX, maxX do
  294. self:LoadOneLight(x,y)
  295. end
  296. end
  297. end
  298. function darkNodeManager:LoadOneLight(x,y)
  299. if not self._needLoadLight then
  300. return
  301. end
  302. local mapData = global.sceneManager:GetMapData2DPtr()
  303. if not mapData then
  304. return
  305. end
  306. local light = mapData:GetLight(x, y)
  307. local DarkLayerProxy = global.Facade:retrieveProxy(global.ProxyTable.DarkLayerProxy)
  308. if light > 0 then
  309. local index = string.format("%s_%s",x,y)
  310. local pos = global.sceneManager:MapPos2WorldPos(x, y, true)
  311. local param = DarkLayerProxy.LIGHT_TYPE.Two_Skill
  312. self._mapLight[index] = self:createNode({x = pos.x, y = pos.y, r = param.r ,w = param.w})
  313. end
  314. end
  315. function darkNodeManager:UnLoadOneLight(x,y)
  316. if not self._needLoadLight then
  317. return
  318. end
  319. local index = string.format("%s_%s",x,y)
  320. if self._mapLight[index] then
  321. self:removeNode(self._mapLight[index])
  322. self._mapLight[index] = nil
  323. end
  324. end
  325. ------------------
  326. return darkNodeManager