actorSequenceFrameAnim.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. local actorSequenceFrameAnim = class("actorSequenceFrameAnim", function ()
  2. return LuaSprite:create()
  3. end)
  4. local action_tag = 1
  5. local default_bound_box = cc.rect( 0, 0, 48, 64 )
  6. local player_bound_box = cc.rect( 0, -16, 48, 80 )
  7. local monster_bound_box = cc.rect( 0, -16, 60, 100 )
  8. local npc_bound_box = cc.rect( 0, -16, 60, 100 )
  9. function actorSequenceFrameAnim:ctor()
  10. self._animAct = -1
  11. self._animDir = -1
  12. self._animSpeed = 1
  13. self._animIsLoop = false
  14. self._isSequence = true
  15. self._endAnimListener = nil
  16. self._isPlaying = false
  17. self._stopFrameIndex = nil
  18. self._animDataDesc = nil
  19. self._animation = nil
  20. self._animateAction = nil
  21. self._sequenceAction = nil
  22. self._repeatAction = nil
  23. self._callfunc = nil
  24. self._syncElapsed = nil
  25. self._globalElapseEnable = nil
  26. self._turePosition = cc.p(0, 0)
  27. self:RegisterLuaHandler(handler( self, self.onDestory))
  28. end
  29. function actorSequenceFrameAnim:setPosition(px, py)
  30. self._turePosition = cc.p(px, py)
  31. local p = self._turePosition
  32. local offset = self:GetOffset()
  33. getmetatable(getmetatable(getmetatable(self))).setPosition(self, cc.pAdd(p, offset))
  34. end
  35. function actorSequenceFrameAnim:setPositionX(px)
  36. self._turePosition.x = px
  37. local offset = self:GetOffset()
  38. getmetatable(getmetatable(getmetatable(self))).setPositionX(self, px + offset.x)
  39. end
  40. function actorSequenceFrameAnim:setPositionY(py)
  41. self._turePosition.y = py
  42. local offset = self:GetOffset()
  43. getmetatable(getmetatable(getmetatable(self))).setPositionY(self, py + offset.y)
  44. end
  45. function actorSequenceFrameAnim:getTurePosition()
  46. return self._turePosition
  47. end
  48. function actorSequenceFrameAnim:setScaleX(sx)
  49. local enlarge = self:GetEnlarge()
  50. getmetatable(getmetatable(getmetatable(self))).setScaleX(self, enlarge * sx)
  51. end
  52. function actorSequenceFrameAnim:setScaleY(sy)
  53. local enlarge = self:GetEnlarge()
  54. getmetatable(getmetatable(getmetatable(self))).setScaleY(self, enlarge * sy)
  55. end
  56. function actorSequenceFrameAnim:onDestory()
  57. self:Stop()
  58. self:Cleanup()
  59. global.FrameAnimManager:RemoveSequAnim( self )
  60. end
  61. function actorSequenceFrameAnim:Cleanup()
  62. if self._animation then
  63. self._animation:release()
  64. self._animation = nil
  65. end
  66. if self._animateAction then
  67. self._animateAction:release()
  68. self._animateAction = nil
  69. end
  70. if self._callfunc then
  71. self._callfunc:release()
  72. self._callfunc = nil
  73. end
  74. if self._sequenceAction then
  75. self._sequenceAction:release()
  76. self._sequenceAction = nil
  77. end
  78. if self._repeatAction then
  79. self._repeatAction:release()
  80. self._repeatAction = nil
  81. end
  82. self:CleanupLuaHandler()
  83. end
  84. -----------------------------------------------------------------------------
  85. function actorSequenceFrameAnim:GetID()
  86. if self._animDataDesc then
  87. return self._animDataDesc.animID
  88. end
  89. return 0
  90. end
  91. -----------------------------------------------------------------------------
  92. function actorSequenceFrameAnim:GetAnimDataDesc()
  93. return self._animDataDesc
  94. end
  95. function actorSequenceFrameAnim:SetAnimDataDesc(animDataDesc)
  96. self._animDataDesc = animDataDesc
  97. end
  98. -----------------------------------------------------------------------------
  99. function actorSequenceFrameAnim:Play( act, dir, isLoop, speed, isSequence )
  100. act = (not act or act < global.MMO.ANIM_DEFAULT or global.MMO.ANIM_COUNT <= act) and global.MMO.ANIM_DEFAULT or act
  101. dir = (dir == nil or dir < global.MMO.ORIENT_U or global.MMO.ORIENT_COUNT <= dir) and global.MMO.ORIENT_U or dir
  102. speed = nil == speed and 1 or speed
  103. isSequence = isSequence ~= false
  104. if self._isPlaying and self._animSpeed == speed and self._animAct == act and self._animDir == dir then
  105. return false
  106. end
  107. -- stop
  108. self:Stop()
  109. -- Mark something.
  110. self._isPlaying = true
  111. self._animAct = act
  112. self._animDir = dir
  113. self._animIsLoop = isLoop
  114. self._animSpeed = speed
  115. self._isSequence = isSequence
  116. -- check and load res
  117. self:CheckAndLoadRes( act, dir )
  118. local index = GetFrameAnimIndex( act, dir )
  119. local animFrameVec = self._animDataDesc.animFrameVecs[index]
  120. local frameInterval = self._animDataDesc.animDelays[index] or global.MMO.ANIM_DEFAULT_INTERVAL
  121. -- use empty anim frame
  122. if not animFrameVec then
  123. animFrameVec = global.FrameAnimManager:getAnimFrameVecEmpty()
  124. end
  125. if not isSequence then
  126. local newAnimFrameVec = {}
  127. for i=1,#animFrameVec do
  128. newAnimFrameVec[i] = animFrameVec[#animFrameVec-i+1]
  129. end
  130. animFrameVec = newAnimFrameVec
  131. end
  132. -- check cc.Animation
  133. if not self._animation then
  134. self._animation = cc.Animation:create( animFrameVec, frameInterval / speed, 1 )
  135. self._animation:retain()
  136. else
  137. self._animation:initWithAnimationFrames( animFrameVec, frameInterval / speed, 1 )
  138. end
  139. -- check cc.Animate
  140. if not self._animateAction then
  141. self._animateAction = cc.Animate:create( self._animation )
  142. self._animateAction:retain()
  143. else
  144. self._animateAction:initWithAnimation( self._animation )
  145. end
  146. -- check cc.CallFunc
  147. if not self._callfunc then
  148. self._callfunc = cc.CallFunc:create( handler( self, self.onAnimationEnd ) )
  149. self._callfunc:retain()
  150. end
  151. -- check sequence action
  152. if not self._sequenceAction then
  153. self._sequenceAction = cc.Sequence:create( self._animateAction, self._callfunc )
  154. self._sequenceAction:retain()
  155. else
  156. self._sequenceAction:initWithTwoActions( self._animateAction, self._callfunc )
  157. end
  158. local action = nil
  159. if isLoop then
  160. -- check repeat action
  161. if not self._repeatAction then
  162. self._repeatAction = cc.RepeatForever:create( self._sequenceAction )
  163. self._repeatAction:retain()
  164. else
  165. self._repeatAction:initWithAction( self._sequenceAction )
  166. end
  167. action = self._repeatAction
  168. else
  169. -- non-loop
  170. action = self._sequenceAction
  171. end
  172. action:setTag( action_tag )
  173. -- Play it!
  174. self:runAction( action )
  175. -- sync elapsed
  176. if self._syncElapsed and self._syncElapsed > 0 then
  177. self._sequenceAction:setElapsed( self._syncElapsed )
  178. self._syncElapsed = nil
  179. end
  180. -- sync global elapsed
  181. if self._globalElapseEnable then
  182. self._sequenceAction:setElapsed( global.FrameAnimManager:getGlobalElapsed() )
  183. end
  184. return true
  185. end
  186. function actorSequenceFrameAnim:Replay()
  187. self:Stop()
  188. self:Play( self._animAct, self._animDir, self._animIsLoop, self._animSpeed, self._isSequence )
  189. end
  190. function actorSequenceFrameAnim:Stop( frameIndex, act, dir, isForceLastFrame )
  191. if isForceLastFrame then
  192. local frameCount = self:GetAnimActFrameCount(act or self._animAct, dir or self._animDir)
  193. frameIndex = frameCount > 0 and frameCount or frameIndex
  194. end
  195. self:SetStopFrameIndex( frameIndex, act, dir )
  196. if not self._isPlaying then
  197. return
  198. end
  199. self:stopAllActionsByTag( action_tag )
  200. self._isPlaying = false
  201. if self._sequenceAction then
  202. self._sequenceAction:setElapsed(0)
  203. end
  204. end
  205. function actorSequenceFrameAnim:SetStopFrameIndex( frameIndex, act, dir )
  206. self._stopFrameIndex = frameIndex
  207. if not self._stopFrameIndex then
  208. return
  209. end
  210. local checkRes = false
  211. if act and act ~= self._animAct then
  212. self._animAct = act
  213. checkRes = true
  214. end
  215. if dir and dir ~= self._animDir then
  216. self._animDir = dir
  217. checkRes = true
  218. end
  219. -- check and load res
  220. if checkRes then
  221. self:CheckAndLoadRes( self._animAct, self._animDir )
  222. end
  223. local animIndex = GetFrameAnimIndex( self._animAct, self._animDir )
  224. local animFrameVec = self._animDataDesc.animFrameVecs[animIndex]
  225. if not animFrameVec then
  226. return nil
  227. end
  228. -- end frame
  229. if frameIndex == -1 then
  230. frameIndex = #animFrameVec
  231. end
  232. local animFrame = animFrameVec[frameIndex]
  233. if animFrame then
  234. self:setSpriteFrame( animFrame:getSpriteFrame() )
  235. end
  236. end
  237. function actorSequenceFrameAnim:SetSpeed( speed )
  238. speed = nil == speed and 1 or speed
  239. if speed ~= self._animSpeed then
  240. self:Play( self._animAct, self._animDir, self._animIsLoop, self._animSpeed, self._isSequence )
  241. end
  242. end
  243. function actorSequenceFrameAnim:SetAnimEventCallback( listener )
  244. self._endAnimListener = listener
  245. end
  246. function actorSequenceFrameAnim:GetHUDTop()
  247. if not self._animDataDesc then
  248. return 20
  249. end
  250. return self._animDataDesc.hudTop or 20
  251. end
  252. function actorSequenceFrameAnim:GetOffset()
  253. if not self._animDataDesc then
  254. return cc.p(0,0)
  255. end
  256. return self._animDataDesc.offset or cc.p(0, 0)
  257. end
  258. function actorSequenceFrameAnim:GetEnlarge()
  259. if not self._animDataDesc then
  260. return 1
  261. end
  262. return self._animDataDesc.enlarge or 1
  263. end
  264. function actorSequenceFrameAnim:GetStandPoint()
  265. if not self._animDataDesc then
  266. return cc.p(0.5, 0.5)
  267. end
  268. return self._animDataDesc.standPoint
  269. end
  270. function actorSequenceFrameAnim:GetBlendMode()
  271. if not self._animDataDesc then
  272. return 0
  273. end
  274. return self._animDataDesc.blendMode or 0
  275. end
  276. function actorSequenceFrameAnim:GetHasShadow()
  277. if not self._animDataDesc then
  278. return true
  279. end
  280. return self._animDataDesc.hasShadow
  281. end
  282. function actorSequenceFrameAnim:GetBoundingBox()
  283. if not self._animDataDesc then
  284. return default_bound_box
  285. end
  286. local animType = self._animDataDesc.animType
  287. if global.MMO.SFANIM_TYPE_MONSTER == animType then
  288. local enlarge = self:GetEnlarge()
  289. local isShadow = self:GetHasShadow()
  290. local ret = self:GetFrameBox()
  291. local anchorPoint = self:getAnchorPoint()
  292. ret.x = monster_bound_box.x--ret.x - ret.width * anchorPoint.x + global.MMO.PLAYER_AVATAR_OFFSET.x
  293. ret.y = monster_bound_box.y--ret.y - ret.height * anchorPoint.y + global.MMO.PLAYER_AVATAR_OFFSET.y
  294. local widthRatio = isShadow and 0.6 or 1
  295. ret.width = ret.width * widthRatio * enlarge
  296. ret.height = ret.height * enlarge
  297. ret.x = ret.x - ret.width * 0.5
  298. return ret
  299. end
  300. local box = default_bound_box
  301. if global.MMO.SFANIM_TYPE_PLAYER == animType then
  302. box = player_bound_box
  303. elseif global.MMO.SFANIM_TYPE_NPC == animType then
  304. box = npc_bound_box
  305. else
  306. if self._animDataDesc.boxWidth and self._animDataDesc.boxHeight then
  307. local boxWidth = self._animDataDesc.boxWidth
  308. local boxHeight = self._animDataDesc.boxHeight
  309. local ret = cc.rect(-boxWidth * 0.5, npc_bound_box.y, boxWidth, boxHeight)
  310. return ret
  311. end
  312. end
  313. local height = box.height
  314. local hudTop = self:GetHUDTop()
  315. if hudTop and hudTop > height then
  316. height = hudTop
  317. end
  318. local ret = cc.rect(box.x, box.y, box.width, height)
  319. ret.x = ret.x - ret.width * 0.5
  320. return ret
  321. end
  322. function actorSequenceFrameAnim:GetFrameBox()
  323. local spriteFrame = self:getSpriteFrame()
  324. if not spriteFrame then
  325. local index = 1
  326. local animIndex = GetFrameAnimIndex( global.MMO.ANIM_IDLE, global.MMO.ORIENT_U )
  327. local animFrameVec = self._animDataDesc.animFrameVecs[animIndex]
  328. if animFrameVec and animFrameVec[index] then
  329. spriteFrame = animFrameVec[index]:getSpriteFrame()
  330. end
  331. end
  332. if not spriteFrame then
  333. return default_bound_box
  334. end
  335. local bbox = spriteFrame:getRectInPixels()
  336. local offset = spriteFrame:getOffset()
  337. bbox.x = offset.x
  338. bbox.y = offset.y
  339. return bbox
  340. end
  341. function actorSequenceFrameAnim:Sync( anim )
  342. if nil == anim then return end
  343. if nil == self._animDataDesc then return end
  344. self._endAnimListener = anim._endAnimListener
  345. if anim._sequenceAction and not self._animDataDesc.ignoreSync then
  346. self._syncElapsed = anim._sequenceAction:getElapsed()
  347. else
  348. self._syncElapsed = nil
  349. end
  350. self._animAct = anim._animAct
  351. self._animDir = anim._animDir
  352. -- sync stop frame
  353. if anim._stopFrameIndex then
  354. self:SetStopFrameIndex( anim._stopFrameIndex, anim._animAct, anim._animDir )
  355. end
  356. -- sync color
  357. self:setColor( anim:getColor() )
  358. -- sync shader
  359. self:setGLProgram( anim:getGLProgram() )
  360. end
  361. function actorSequenceFrameAnim:GetElapsed()
  362. if self._sequenceAction then
  363. return self._sequenceAction:getElapsed()
  364. end
  365. return nil
  366. end
  367. function actorSequenceFrameAnim:SyncElapsed( elapsed )
  368. self._syncElapsed = elapsed
  369. end
  370. function actorSequenceFrameAnim:resetAnimPlay( unitID )
  371. if not self._isPlaying then
  372. if self._stopFrameIndex then
  373. self:SetStopFrameIndex( self._stopFrameIndex )
  374. else
  375. self:SetStopFrameIndex( -1 )
  376. end
  377. return
  378. end
  379. local checkUnitID = self._animAct
  380. if global.MMO.SFANIM_TYPE_SKILL == self._animDataDesc.animType then
  381. checkUnitID = self._animDir
  382. end
  383. -- load act res callback, but act ~= currentAct
  384. if unitID and unitID ~= checkUnitID then return end
  385. self:Sync( self )
  386. self:Stop()
  387. self:Play( self._animAct, self._animDir, self._animIsLoop, self._animSpeed, self._isSequence )
  388. end
  389. function actorSequenceFrameAnim:onAnimationEnd()
  390. if not self._animIsLoop then
  391. self._isPlaying = false
  392. end
  393. if nil ~= self._endAnimListener then
  394. local isLoaded = self:CheckResIsLoaded(self._animAct, self._animDir)
  395. local loadCode = isLoaded and 1 or 0
  396. self._endAnimListener( self, 1, loadCode )
  397. end
  398. end
  399. function actorSequenceFrameAnim:onAnimationLoadError()
  400. if nil ~= self._endAnimListener then
  401. local loadCode = -1
  402. self._endAnimListener( self, 1, loadCode )
  403. end
  404. end
  405. function actorSequenceFrameAnim:CheckResIsLoaded( act, dir )
  406. if not self._animDataDesc then
  407. return false
  408. end
  409. local animID = self._animDataDesc.animID
  410. local animType = self._animDataDesc.animType
  411. local frameLoaded = self._animDataDesc.frameLoaded
  412. local unitID = act
  413. if global.MMO.SFANIM_TYPE_SKILL == animType then
  414. unitID = dir
  415. end
  416. return frameLoaded[unitID] == true
  417. end
  418. function actorSequenceFrameAnim:CheckAndLoadRes( act, dir )
  419. if not self._animDataDesc then
  420. return false
  421. end
  422. local animID = self._animDataDesc.animID
  423. local animType = self._animDataDesc.animType
  424. local frameLoaded = self._animDataDesc.frameLoaded
  425. local unitID = act
  426. if global.MMO.SFANIM_TYPE_SKILL == animType then
  427. unitID = dir
  428. end
  429. if true ~= frameLoaded[unitID] then
  430. global.FrameAnimManager:LoadAnimUnit( animID, animType, unitID )
  431. end
  432. return true
  433. end
  434. -- unitID(act or dir)
  435. function actorSequenceFrameAnim:CheckCurrUnit( unitID )
  436. if not self._animDataDesc then
  437. return false
  438. end
  439. local animType = self._animDataDesc.animType
  440. if global.MMO.SFANIM_TYPE_SKILL == animType then
  441. return unitID == self._animDir
  442. else
  443. return unitID == self._animAct
  444. end
  445. end
  446. function actorSequenceFrameAnim:SetGlobalElapseEnable(enable)
  447. self._globalElapseEnable = enable
  448. end
  449. function actorSequenceFrameAnim:GetCurrAnimAct()
  450. return self._animAct
  451. end
  452. function actorSequenceFrameAnim:GetCurrAnimDir()
  453. return self._animDir
  454. end
  455. function actorSequenceFrameAnim:CheckAnimActIsLoaded()
  456. if not self._animDataDesc then
  457. return false
  458. end
  459. local animType = self._animDataDesc.animType
  460. local frameLoaded = self._animDataDesc.frameLoaded
  461. local unitID = self._animAct
  462. if global.MMO.SFANIM_TYPE_SKILL == animType then
  463. unitID = self._animDir
  464. end
  465. return frameLoaded[unitID]
  466. end
  467. function actorSequenceFrameAnim:GetAnimActFrameCount(act, dir)
  468. if not self._animDataDesc then
  469. return 0
  470. end
  471. local index = GetFrameAnimIndex( act, dir )
  472. local animFrameVec = self._animDataDesc.animFrameVecs[index]
  473. -- use empty anim frame
  474. if not animFrameVec then
  475. return 0
  476. end
  477. return #animFrameVec
  478. end
  479. return actorSequenceFrameAnim