actorManager.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  1. local actorManager = class("actorManager")
  2. local gameActorPlayer = require("actor/gameActorPlayer")
  3. local gameActorMonster = require("actor/gameActorMonster")
  4. local gameActorNpc = require("actor/gameActorNpc")
  5. local gameActorDropItem = require("actor/gameActorDropItem")
  6. local gameActorEffect = require("actor/gameActorEffect")
  7. local gameActorMonsterGate = require("actor/gameActorMonsterGate")
  8. local gameActorMonsterWall = require("actor/gameActorMonsterWall")
  9. local mAbs = math.abs
  10. local filterDis = 150
  11. local tsort = table.sort
  12. local INVALID_MAP_POS = 0xFFFF
  13. local function pickAble(actor)
  14. if actor:IsSEffect() then
  15. return false
  16. end
  17. return true
  18. end
  19. local function pickCmpFun(a1, a2)
  20. local dw1 = a1:IsDie() and 1 or 0
  21. local dw2 = a2:IsDie() and 1 or 0
  22. if dw1 ~= dw2 then
  23. return dw1 < dw2
  24. end
  25. local y1 = a1:GetMapY()
  26. local y2 = a2:GetMapY()
  27. return y1 > y2
  28. end
  29. local function filterActors(actors, ncount, pickPos)
  30. local newActors = {}
  31. local num = 0
  32. for i = 1, ncount do
  33. local actor = actors[i]
  34. if actor and pickAble(actor) and mAbs(actor:getPosition().x - pickPos.x) <= filterDis or mAbs(actor:getPosition().y - pickPos.y) <= filterDis then
  35. num = num + 1
  36. newActors[num] = actor
  37. end
  38. end
  39. tsort(newActors, pickCmpFun)
  40. return newActors, num
  41. end
  42. local function pickActors(actors, ncount, pickPos)
  43. local newActors, nums = filterActors(actors, ncount, pickPos)
  44. local boundBox = nil
  45. local pos = nil
  46. local actor = nil
  47. local mAnimate = nil
  48. local mIsAttack = false
  49. for i = 1, nums do
  50. actor = newActors[i]
  51. mAnimate = actor:GetAnimation()
  52. mIsAttack = actor:IsAttackType()
  53. if mIsAttack and mAnimate and actor:IsPlayerAttacked() then
  54. pos = actor:getPosition()
  55. if actor:IsMonster() and not actor:GetValueByKey(global.MMO.MONSTER_VISIBLE) then
  56. boundBox = cc.rect(0,0,0,0)
  57. boundBox.width = global.MMO.MapGridWidth -- 使用格子宽度
  58. boundBox.x = pos.x - boundBox.width * 0.5
  59. boundBox.height= global.MMO.HUD_OFFSET_1.y + global.MMO.MapGridHeight -- 血条位置高度
  60. boundBox.y = pos.y
  61. else
  62. boundBox = mAnimate:GetBoundingBox()
  63. boundBox.x = boundBox.x + pos.x
  64. boundBox.y = boundBox.y + pos.y
  65. end
  66. if cc.rectContainsPoint(boundBox, pickPos) then
  67. return actor
  68. end
  69. end
  70. end
  71. return nil
  72. end
  73. local function addMapXYActorID( mapTab,actorID,mapX,mapY )
  74. if mapX == INVALID_MAP_POS and mapY == INVALID_MAP_POS then
  75. return
  76. end
  77. local XYKey = KEY_MAP_XY( mapX,mapY )
  78. if not mapTab[XYKey] then
  79. mapTab[XYKey] = {}
  80. end
  81. mapTab[XYKey][actorID] = true
  82. end
  83. local function rmvMapXYActorID( mapTab,actorID,mapX,mapY )
  84. if mapX == INVALID_MAP_POS and mapY == INVALID_MAP_POS then
  85. return
  86. end
  87. local XYKey = KEY_MAP_XY( mapX,mapY )
  88. if not mapTab[XYKey] then
  89. return
  90. end
  91. mapTab[XYKey][actorID]=nil
  92. if not next( mapTab[XYKey] ) then
  93. mapTab[XYKey] = nil
  94. end
  95. end
  96. local function getAllMapXYActor( mapTab,mapX,mapY )
  97. local actors = {}
  98. if mapX == INVALID_MAP_POS and mapY == INVALID_MAP_POS then
  99. return actors
  100. end
  101. local XYKey = KEY_MAP_XY( mapX,mapY )
  102. if not mapTab[XYKey] then
  103. return actors
  104. end
  105. for k,v in pairs(mapTab[XYKey]) do
  106. local actor = global.actorManager:GetActor( k )
  107. if actor then
  108. table.insert( actors, actor )
  109. end
  110. end
  111. return actors
  112. end
  113. function actorManager:ctor()
  114. self.mGameActorsMap = {}
  115. self.mActorIndexMap = {}
  116. self.mGameActors = {}
  117. self.mActorsCount = 0
  118. self.mTicking = false
  119. self.mAddingActorsMap = {}
  120. self.mAddingActors = {}
  121. self.mAddingActorsCount = 0
  122. self.mAddingDirty = false
  123. self.mRmvingActors = {}
  124. self.mRmvingActorsCount = 0
  125. self.mRmvingDirty = false
  126. self.mNodeOfActorSprite = nil
  127. self.mNodeOfActorSpriteBehind = nil
  128. self.mMonsterAllocator = {}
  129. self.mPlayerAllocator = {}
  130. self.mMonsterMapXYActorID = {}
  131. self.mPlayerMapXYActorID = {}
  132. self.mNPCMapXYActorID = {}
  133. self.effect_root_node = {}
  134. self.effect_root_node_zorder = { 0, 4, 1, 2, 3, -1, 5 }
  135. self.mCurrLockT = 0
  136. self.mLockFrameT = 0 -- 非平滑模式锁帧时间,根据玩家的跑速度计算出来
  137. end
  138. function actorManager:destory()
  139. if actorManager.instance then
  140. actorManager.instance = nil
  141. end
  142. end
  143. function actorManager:Inst()
  144. if not actorManager.instance then
  145. local inst = actorManager.new()
  146. actorManager.instance = inst
  147. end
  148. return actorManager.instance
  149. end
  150. function actorManager:GetActors()
  151. return self.mGameActors, self.mActorsCount
  152. end
  153. function actorManager:IsMoveTime()
  154. return self.mCurrLockT <= 0
  155. end
  156. function actorManager:UpdateLockFrameT()
  157. local mainPlayer = global.gamePlayerController:GetMainPlayer()
  158. if not mainPlayer then
  159. return
  160. end
  161. self.mLockFrameT = mainPlayer:GetRunStepTime() / mainPlayer:GetRunSpeed() / 6 / 2
  162. end
  163. function actorManager:Tick(dt)
  164. self.mCurrLockT = self.mCurrLockT - dt
  165. if self.mAddingDirty then
  166. for i = 1, self.mAddingActorsCount do
  167. local d = self.mAddingActors[i]
  168. self:addActor(d.actorID, d.actor)
  169. end
  170. self.mAddingDirty = false
  171. self.mAddingActorsMap = {}
  172. self.mAddingActors = {}
  173. self.mAddingActorsCount = 0
  174. end
  175. if self.mRmvingDirty then
  176. for i = 1, self.mRmvingActorsCount do
  177. self:RemoveActor(self.mRmvingActors[i])
  178. end
  179. self.mRmvingDirty = false
  180. self.mRmvingActors = {}
  181. self.mRmvingActorsCount = 0
  182. end
  183. self.mTicking = true
  184. for i = 1, self.mActorsCount do
  185. local actor = self.mGameActors[i]
  186. if actor then
  187. actor:Tick(dt)
  188. end
  189. end
  190. self.mTicking = false
  191. -- 锁帧时间
  192. if self.mCurrLockT <= 0 then
  193. self.mCurrLockT = self.mLockFrameT
  194. end
  195. end
  196. function actorManager:Pick(pickPos, mainPlayer)
  197. local actors = nil
  198. local target = nil
  199. local ncount = 0
  200. -- npc
  201. if not target then
  202. actors, ncount = global.npcManager:GetNpcInCurrViewField()
  203. target = pickActors(actors, ncount, pickPos)
  204. end
  205. -- player
  206. if not target then
  207. local noMainPlayer = (not mainPlayer)
  208. actors, ncount = global.playerManager:FindPlayerInCurrViewField(noMainPlayer)
  209. target = pickActors(actors, ncount, pickPos)
  210. end
  211. -- monster
  212. if not target then
  213. actors, ncount = global.monsterManager:FindMonsterInCurrViewField(false, false)
  214. target = pickActors(actors, ncount, pickPos)
  215. end
  216. -- drop item
  217. if not target then
  218. actors, ncount = global.dropItemManager:FindDropItemInCurrViewField()
  219. target = pickActors(actors, ncount, pickPos)
  220. end
  221. return target
  222. end
  223. function actorManager:addActor(actorID, actor)
  224. if not actorID then
  225. return false
  226. end
  227. if not actor then
  228. return false
  229. end
  230. actor:SetID(actorID)
  231. if self.mTicking then
  232. self.mAddingDirty = true
  233. self.mAddingActorsMap[actorID] = actor
  234. self.mAddingActorsCount = self.mAddingActorsCount + 1
  235. local n = self.mAddingActorsCount
  236. self.mAddingActors[n] = {actor = actor, actorID = actorID}
  237. else
  238. self.mActorsCount = self.mActorsCount + 1
  239. local n = self.mActorsCount
  240. self.mActorIndexMap[actorID] = n
  241. self.mGameActors[n] = actor
  242. self.mGameActorsMap[actorID] = actor
  243. end
  244. end
  245. local actorNews = {
  246. [global.MMO.ACTOR_PLAYER] = function () return gameActorPlayer.new() end,
  247. [global.MMO.ACTOR_DROPITEM] = function () return gameActorDropItem.new() end,
  248. [global.MMO.ACTOR_NPC] = function () return gameActorNpc.new() end,
  249. [global.MMO.ACTOR_SEFFECT] = function () return gameActorEffect.new() end
  250. }
  251. local actorMonsterNews = {
  252. [900] = function () return gameActorMonsterGate.new() end,
  253. [901] = function () return gameActorMonsterWall.new() end,
  254. [902] = function () return gameActorMonsterWall.new() end,
  255. [903] = function () return gameActorMonsterWall.new() end,
  256. [904] = function () return gameActorMonsterWall.new() end,
  257. [905] = function () return gameActorMonsterWall.new() end,
  258. [906] = function () return gameActorMonsterWall.new() end,
  259. [-1] = function () return gameActorMonster.new() end
  260. }
  261. function actorManager:CreateActor(actorID, atype, params, isBehind, isFront)
  262. if self.mGameActorsMap[actorID] then
  263. return false
  264. end
  265. local actorfunc = nil
  266. if atype == global.MMO.ACTOR_MONSTER then
  267. actorfunc = actorMonsterNews[params.clothID] or actorMonsterNews[-1]
  268. else
  269. actorfunc = actorNews[atype]
  270. end
  271. local actor = actorfunc and actorfunc()
  272. if not actor then
  273. return false
  274. end
  275. actor:init()
  276. actor:InitParam(params)
  277. self:addActor(actorID, actor)
  278. -- Add to Actor Sprite Node.
  279. if isBehind then
  280. self:AddActorSfxInBehind(actor, atype, params.type)
  281. elseif isFront then
  282. self:AddActorSfxInFront(actor, atype, params.sfxId or 0)
  283. else
  284. self:AddActorSfx(actor)
  285. end
  286. return actor
  287. end
  288. ----------------------------------------------------------------------------
  289. -- actor 后面
  290. function actorManager:AddActorSfxInBehind(actor, type, effectType)
  291. if global.MMO.ACTOR_SEFFECT == type then
  292. if self.effect_root_node[effectType] then
  293. self.effect_root_node[effectType]:addChild(actor:GetNode())
  294. else
  295. self.mNodeOfActorSpriteBehind:addChild(actor:GetNode())
  296. end
  297. else
  298. self.mNodeOfActorSpriteBehind:addChild(actor:GetNode())
  299. end
  300. end
  301. -- actor 前面
  302. function actorManager:AddActorSfxInFront(actor, type, order)
  303. local IsSfx = global.MMO.ACTOR_SEFFECT == type
  304. local zOrder = IsSfx and order or 0
  305. self.mNodeOfActorSpriteFront:addChild(actor:GetNode(), zOrder)
  306. end
  307. function actorManager:AddActorSfx(actor)
  308. self.mNodeOfActorSprite:addChild(actor:GetNode())
  309. end
  310. function actorManager:GetActor(actorID)
  311. return self.mGameActorsMap[actorID] or self.mAddingActorsMap[actorID]
  312. end
  313. function actorManager:GetActorNum()
  314. return self.mActorsCount
  315. end
  316. function actorManager:RemoveActor(actorID)
  317. if not actorID then
  318. return false
  319. end
  320. local actor = self.mGameActorsMap[actorID]
  321. if not actor then
  322. return false
  323. end
  324. if self.mTicking then
  325. self.mRmvingDirty = true
  326. self.mRmvingActorsCount = self.mRmvingActorsCount + 1
  327. local n = self.mRmvingActorsCount
  328. self.mRmvingActors[n] = actorID
  329. else
  330. self:deleteActor(actor)
  331. self.mGameActorsMap[actorID] = nil
  332. -- remove index
  333. local index = self.mActorIndexMap[actorID]
  334. if index == self.mActorsCount then
  335. self.mGameActors[index] = nil
  336. else
  337. -- last index --> index
  338. local lastActor = self.mGameActors[self.mActorsCount]
  339. self.mGameActors[index] = lastActor
  340. self.mActorIndexMap[lastActor:GetID()] = index
  341. -- reset last value
  342. self.mGameActors[self.mActorsCount] = nil
  343. end
  344. self.mActorIndexMap[actorID] = nil
  345. self.mActorsCount = self.mActorsCount - 1
  346. end
  347. end
  348. function actorManager:RemoveAllActor(excludeID)
  349. local excludeActor = nil
  350. if excludeID and excludeID ~= 0 then
  351. excludeActor = self.mGameActorsMap[excludeID]
  352. end
  353. for i = 1, self.mActorsCount do
  354. local actor = self.mGameActors[i]
  355. if actor and actor:GetID() ~= excludeID then
  356. self:deleteActor(actor)
  357. end
  358. end
  359. if excludeActor then
  360. local actorID = excludeActor:GetID()
  361. self.mGameActorsMap = {[actorID] = excludeActor}
  362. self.mActorIndexMap = {[actorID] = 1}
  363. self.mGameActors = {excludeActor}
  364. self.mActorsCount = 1
  365. else
  366. self.mGameActorsMap = {}
  367. self.mActorIndexMap = {}
  368. self.mGameActors = {}
  369. self.mActorsCount = 0
  370. end
  371. end
  372. function actorManager:Cleanup()
  373. self:RemoveAllActor()
  374. self:cleanupActorRootNode()
  375. end
  376. function actorManager:RefreshActorID(actorID, newActorID)
  377. local actor = self.mGameActorsMap[actorID]
  378. if not actor then
  379. return false
  380. end
  381. if actor:IsPlayer() then
  382. actor:SetID(newActorID)
  383. end
  384. local n = self.mActorIndexMap[actorID]
  385. self.mActorIndexMap[newActorID] = n
  386. self.mGameActors[n] = actor
  387. self.mGameActorsMap[newActorID] = actor
  388. self.mGameActorsMap[actorID] = nil
  389. self.mActorIndexMap[actorID] = nil
  390. end
  391. function actorManager:deleteActor(actor)
  392. local actorNode = actor:GetNode()
  393. if actorNode and not tolua.isnull(actorNode) then
  394. actorNode:removeFromParent()
  395. end
  396. self:RmvMapXYActor( actor,actor:GetMapX(),actor:GetMapY() )
  397. actor:destory()
  398. end
  399. function actorManager:cleanupActorRootNode()
  400. if self.mNodeOfActorSpriteFront then
  401. self.mNodeOfActorSpriteFront:autorelease()
  402. self.mNodeOfActorSpriteFront = nil
  403. end
  404. if self.mNodeOfActorSprite then
  405. self.mNodeOfActorSprite:autorelease()
  406. self.mNodeOfActorSprite = nil
  407. end
  408. if self.mNodeOfActorSpriteBehind then
  409. self.mNodeOfActorSpriteBehind:autorelease()
  410. self.mNodeOfActorSpriteBehind = nil
  411. end
  412. for i = 1, global.MMO.EFFECT_TYPE_MAX do
  413. if self.effect_root_node[i] then
  414. self.effect_root_node[i]:removeFromParent()
  415. self.effect_root_node[i] = nil
  416. end
  417. end
  418. self.effect_root_node = {}
  419. end
  420. function actorManager:InitOnEnterWorld()
  421. self.mNodeOfActorSprite = global.sceneGraphCtl:GetActorSpriteNode()
  422. self.mNodeOfActorSprite:retain()
  423. GUI._actorRootNode = self.mNodeOfActorSprite
  424. self.mNodeOfActorSpriteBehind = global.sceneGraphCtl:GetSceneNode(global.MMO.NODE_ACTOR_SFX_BEHIND)
  425. self.mNodeOfActorSpriteBehind:retain()
  426. if #self.effect_root_node == 0 then
  427. for i = 1, global.MMO.EFFECT_TYPE_MAX do
  428. self.effect_root_node[i] = cc.Node:create()
  429. if self.mNodeOfActorSpriteBehind then
  430. self.mNodeOfActorSpriteBehind:addChild(self.effect_root_node[i], self.effect_root_node_zorder[i])
  431. end
  432. end
  433. end
  434. if not self.mNodeOfActorSpriteFront then
  435. self.mNodeOfActorSpriteFront = global.sceneGraphCtl:GetSceneNode(global.MMO.NODE_ACTOR_SFX_FRONT)
  436. self.mNodeOfActorSpriteFront:retain()
  437. end
  438. end
  439. ----------------- MapXY begin ---------------------
  440. function actorManager:AddMapXYActor( actor,mapX,mapY )
  441. if not actor then
  442. return
  443. end
  444. if actor:IsMonster() then
  445. addMapXYActorID( self.mMonsterMapXYActorID, actor:GetID(), mapX, mapY )
  446. elseif actor:IsPlayer() then
  447. addMapXYActorID( self.mPlayerMapXYActorID, actor:GetID(), mapX, mapY )
  448. elseif actor:IsNPC() then
  449. addMapXYActorID( self.mNPCMapXYActorID, actor:GetID(), mapX, mapY )
  450. end
  451. end
  452. function actorManager:RmvMapXYActor( actor,mapX,mapY )
  453. if not actor then
  454. return
  455. end
  456. if actor:IsMonster() then
  457. rmvMapXYActorID( self.mMonsterMapXYActorID, actor:GetID(), mapX, mapY )
  458. elseif actor:IsPlayer() then
  459. rmvMapXYActorID( self.mPlayerMapXYActorID, actor:GetID(), mapX, mapY )
  460. elseif actor:IsNPC() then
  461. rmvMapXYActorID( self.mNPCMapXYActorID, actor:GetID(), mapX, mapY )
  462. end
  463. end
  464. function actorManager:GetMonsterActorByMapXY( mapX,mapY,isAll )
  465. if isAll then
  466. return getAllMapXYActor( self.mMonsterMapXYActorID,mapX,mapY )
  467. end
  468. local XYKey = KEY_MAP_XY( mapX,mapY )
  469. local actorID = self.mMonsterMapXYActorID[XYKey] and next(self.mMonsterMapXYActorID[XYKey]) or nil
  470. if not actorID then
  471. return nil
  472. end
  473. return self:GetActor( actorID )
  474. end
  475. function actorManager:GetPlayerActorByMapXY( mapX,mapY,isAll )
  476. if isAll then
  477. return getAllMapXYActor( self.mPlayerMapXYActorID,mapX,mapY )
  478. end
  479. local XYKey = KEY_MAP_XY( mapX,mapY )
  480. local actorID = self.mPlayerMapXYActorID[XYKey] and next(self.mPlayerMapXYActorID[XYKey]) or nil
  481. if not actorID then
  482. return nil
  483. end
  484. return self:GetActor( actorID )
  485. end
  486. function actorManager:GetNPCActorByMapXY( mapX,mapY,isAll )
  487. if isAll then
  488. return getAllMapXYActor( self.mNPCMapXYActorID,mapX,mapY )
  489. end
  490. local XYKey = KEY_MAP_XY( mapX,mapY )
  491. local actorID = self.mNPCMapXYActorID[XYKey] and next(self.mNPCMapXYActorID[XYKey]) or nil
  492. if not actorID then
  493. return nil
  494. end
  495. return self:GetActor(actorID)
  496. end
  497. ----------------- MapXY end ---------------------
  498. function actorManager:SetActorMapXY( actor, mapX, mapY )
  499. actor:SetMapX( mapX )
  500. actor:SetMapY( mapY )
  501. if actor:IsMonster() then
  502. self:RmvMapXYActor( actor,actor:GetLastMapX(),actor:GetLastMapY() )
  503. self:AddMapXYActor( actor,mapX,mapY )
  504. global.netMonsterController:handle_ActorMapXYChange( actor, mapX, mapY )
  505. elseif actor:IsPlayer() then
  506. if not actor:IsMainPlayer() then
  507. self:RmvMapXYActor( actor,actor:GetLastMapX(),actor:GetLastMapY() )
  508. self:AddMapXYActor( actor,mapX,mapY )
  509. global.netPlayerController:handle_ActorMapXYChange( actor, mapX, mapY )
  510. end
  511. elseif actor:IsNPC() then
  512. self:RmvMapXYActor( actor,actor:GetLastMapX(),actor:GetLastMapY() )
  513. self:AddMapXYActor( actor,mapX,mapY )
  514. end
  515. end
  516. return actorManager