05_OPhone平臺2D游戲引擎實現(xiàn)——時間動畫.docx_第1頁
05_OPhone平臺2D游戲引擎實現(xiàn)——時間動畫.docx_第2頁
05_OPhone平臺2D游戲引擎實現(xiàn)——時間動畫.docx_第3頁
05_OPhone平臺2D游戲引擎實現(xiàn)——時間動畫.docx_第4頁
05_OPhone平臺2D游戲引擎實現(xiàn)——時間動畫.docx_第5頁
已閱讀5頁,還剩20頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

經(jīng)過幾篇文章的介紹,我們的引擎基本上已經(jīng)開始慢慢成形了,上一節(jié)我們雖然我們實現(xiàn)了各種組件,但是這些組件和節(jié)點(Node)都處于靜止狀態(tài),很顯然既然是游戲,就不可能沒有動畫,那么這一片文章我們就將給大家介紹引擎的動畫系統(tǒng),這里我們將動畫系統(tǒng)分為兩個大類,其一是一些基本的動畫,包括位置的移動,縮放、旋轉,透明度變化等,其二是幀動畫,即由許多幀構成的動畫,在實現(xiàn)這些動畫之前,我們都需要對一些基礎類進行封裝,以方便我們對各種動畫的實現(xiàn)。動作(Action)這里我們說的動作類便是所有動畫的基類,該類封裝一個特定行為,在運行時賦予動作一個目標,于是這個目標將會執(zhí)行該動作。同時需要注意只有節(jié)點(Node)的子類才能執(zhí)行一個動作。有些動作只有特定的節(jié)點類型才能運行,但是大部分動作都不限制節(jié)點具體類型。由于是所有動畫的基類,所以我們只需要實現(xiàn)動畫的路框架,包括動畫結束的回調函數(shù)等,具體的動畫效果實現(xiàn)將在其子類來實現(xiàn),如代碼清單5-1所示。代碼清單5-1:Action實現(xiàn)view plaincopy to clipboardprint?1. publicabstractclassActionimplementsYFSCopyable 2. /非法的標記,為-1 3. publicstaticfinalintINVALID_TAG=-1; 4. /源目標 5. privateNodemOriginalTarget; 6. /目標節(jié)點 7. publicNodemTarget; 8. /動畫標記 9. privateintmTag; 10. /回調 11. privateCallbackmCallback; 12. /得到源節(jié)點 13. publicNodegetOriginalTarget() 14. returnthis.mOriginalTarget; 15. 16. /設置源節(jié)點 17. publicvoidsetOriginalTarget(Nodevalue) 18. this.mOriginalTarget=value; 19. 20. /得到目標 21. publicNodegetTarget() 22. returnthis.mTarget; 23. 24. /設置目標 25. publicvoidsetTarget(Nodevalue) 26. this.mTarget=value; 27. 28. /設置回調 29. publicvoidsetCallback(Callbackcallback) 30. this.mCallback=callback; 31. 32. /得到回調 33. publicCallbackgetCallback() 34. returnthis.mCallback; 35. 36. /得到,設置tag 37. publicintgetTag() 38. returnthis.mTag; 39. 40. publicvoidsetTag(intvalue) 41. this.mTag=value; 42. 43. /構建動作 44. protectedAction() 45. this.mTarget=(this.mOriginalTarget=null); 46. this.mTag=INVALID_TAG; 47. 48. /拷貝動作 49. publicabstractActioncopy(); 50. /生成反響動作 51. publicabstractActionreverse(); 52. /開始在指定節(jié)點上執(zhí)行動作 53. publicvoidstart(Nodetarger) 54. this.mOriginalTarget=(this.mTarget=targer); 55. 56. /停止 57. publicvoidstop() 58. this.mTarget=null; 59. 60. /是否完成 61. publicbooleanisDone() 62. returntrue; 63. 64. /單步執(zhí)行 65. publicabstractvoidstep(floatparamFloat); 66. /更新 67. publicabstractvoidupdate(floatparamFloat); 68. /回調接口,動作完成之后進入 69. publicstaticabstractinterfaceCallback 70. publicabstractvoidonDone(ActionparamAction); 71. 72. public abstract class Action implements YFSCopyable /非法的標記,為-1 public static final int INVALID_TAG = -1; /源目標 private Node mOriginalTarget; /目標節(jié)點 public Node mTarget; /動畫標記 private int mTag; /回調 private Callback mCallback; /得到源節(jié)點 public Node getOriginalTarget() return this.mOriginalTarget; /設置源節(jié)點 public void setOriginalTarget(Node value) this.mOriginalTarget = value; /得到目標 public Node getTarget() return this.mTarget; /設置目標 public void setTarget(Node value) this.mTarget = value; /設置回調 public void setCallback(Callback callback) this.mCallback = callback; /得到回調 public Callback getCallback() return this.mCallback; /得到,設置tag public int getTag() return this.mTag; public void setTag(int value) this.mTag = value; /構建動作 protected Action() this.mTarget = (this.mOriginalTarget = null); this.mTag = INVALID_TAG; /拷貝動作 public abstract Action copy(); /生成反響動作 public abstract Action reverse(); /開始在指定節(jié)點上執(zhí)行動作 public void start(Node targer) this.mOriginalTarget = (this.mTarget = targer); /停止 public void stop() this.mTarget = null; /是否完成 public boolean isDone() return true; /單步執(zhí)行 public abstract void step(float paramFloat); /更新 public abstract void update(float paramFloat); /回調接口,動作完成之后進入 public static abstract interface Callback public abstract void onDone(Action paramAction); 從代碼中我們可以看到,我們構建了兩個Node對象,mOriginalTarget和mTarget分別是源目標和當前的目標,源目標主要用于處理特定的動畫,比如:屏幕的翻轉效果等,當前目標表示當前動畫在其目標上執(zhí)行,同時我們還為每個動畫都分配了一個標記(mTag),這樣方便管理,這里特別需要說明的是我們的回調接口Callback,用于處理動畫執(zhí)行完畢之后觸發(fā)其接口中的onDone函數(shù),同時還提供了生成反向動畫的函數(shù)reverse,當然這并不是每個動畫都能生成反向動畫,需要在子類進行實現(xiàn),后面我們會有實例介紹。動作管理器(ActionManager)動作管理器則是用來管理整個引擎中的動畫,我們知道由于一個節(jié)點可以包含很多個動畫,因此我們就構建了一個HashElement來表示一個節(jié)點的動畫情況,HashElement中包括了一個目標節(jié)點和該節(jié)點的動畫序列以及是否暫停,線面我們看ActionManager的具體實現(xiàn),如代碼清單5-2所示。代碼清單5-2:ActionManager實現(xiàn)view plaincopy to clipboardprint?1. publicclassActionManager 2. /所有的動作列表,包括每個節(jié)點的動畫 3. privateConcurrentHashMaptargets; 4. privatestaticActionManagersInstance; 5. static 6. sInstance=null; 7. 8. /取得本類實例對象 9. publicstaticActionManagergetInstance() 10. synchronized(ActionManager.class) 11. if(sInstance=null) 12. sInstance=newActionManager(); 13. 14. returnsInstance; 15. 16. 17. /構建動作管理器對象 18. privateActionManager() 19. synchronized(ActionManager.class) 20. /構建一個計時器 21. /指定更新函數(shù)為tick 22. Scheduler.getInstance().schedule(newScheduler.Timer(this,tick); 23. this.targets=newConcurrentHashMap(131); 24. 25. 26. /清楚動作 27. privatevoiddeleteHashElement(HashElementelement) 28. element.actions.clear(); 29. this.targets.remove(element.target); 30. 31. /動作列表 32. privatevoidactionAlloc(HashElementelement) 33. if(element.actions=null) 34. element.actions=newCopyOnWriteArrayList(); 35. 36. /移除指定動作 37. privatevoidremoveAction(intindex,HashElementelement) 38. element.actions.remove(index); 39. 40. if(element.actions.size()=0) 41. deleteHashElement(element); 42. 43. /暫停所有動作 44. publicvoidpauseAllActions(Nodetarget) 45. HashElementelement=(HashElement)this.targets.get(target); 46. if(element!=null) 47. element.paused=true; 48. 49. /重新開始所有動作 50. publicvoidresumeAllActions(Nodetarget) 51. HashElementelement=(HashElement)this.targets.get(target); 52. if(element!=null) 53. element.paused=false; 54. 55. /添加動作 56. publicvoidaddAction(Actionaction,Nodetarget,booleanpaused) 57. assert(action!=null):Argumentactionmustbenon-null; 58. assert(target!=null):Argumenttargetmustbenon-null; 59. 60. HashElementelement=(HashElement)this.targets.get(target); 61. if(element=null) 62. element=newHashElement(target,paused); 63. this.targets.put(target,element); 64. 65. 66. actionAlloc(element); 67. 68. assert(!element.actions.contains(action):runAction:Actionalreadyrunning; 69. 70. element.actions.add(action); 71. /開始動作 72. action.start(target); 73. 74. /移除所有動作 75. publicvoidremoveAllActions() 76. for(HashElementelement:this.targets.values() 77. removeAllActions(element.target); 78. 79. /移除指定節(jié)點的所有動作 80. publicvoidremoveAllActions(Nodetarget) 81. if(target=null) 82. return; 83. 84. /先找到指定節(jié)點 85. HashElementelement=(HashElement)this.targets.get(target); 86. if(element!=null) 87. element.actions.clear(); 88. deleteHashElement(element); 89. 90. 91. /移除指定動作 92. publicvoidremoveAction(Actionaction) 93. /先找到動作的源目標 94. HashElementelement=(HashElement)this.targets.get(action 95. .getOriginalTarget(); 96. if(element!=null) 97. inti=element.actions.indexOf(action); 98. if(i!=Action.INVALID_TAG) 99. removeAction(i,element); 100. 101. 102. /移除指定 103. publicvoidremoveAction(inttag,Nodetarget) 104. assert(tag!=Action.INVALID_TAG):Invalidtag; 105. HashElementelement=(HashElement)this.targets.get(target); 106. if(element=null)|(element.actions=null) 107. return; 108. intlimit=element.actions.size(); 109. for(inti=0;ilimit;+i) 110. Actiona=(Action)element.actions.get(i); 111. if(a.getTag()=tag)&(a.getOriginalTarget()=target) 112. removeAction(i,element); 113. 114. 115. /得到指定目標的指定動作 116. publicActiongetAction(inttag,Nodetarget) 117. assert(tag!=Action.INVALID_TAG):Invalidtag; 118. HashElementelement=(HashElement)this.targets.get(target); 119. if(element!=null)&(element.actions!=null) 120. intlimit=element.actions.size(); 121. for(inti=0;ilimit;+i) 122. Actiona=(Action)element.actions.get(i); 123. if(a.getTag()=tag) 124. returna; 125. 126. 127. 128. returnnull; 129. 130. /得到運行中的動作的數(shù)量 131. publicintgetRunningActionCount(Nodetarget) 132. HashElementelement=(HashElement)this.targets.get(target); 133. if(element!=null) 134. return(element.actions!=null)?element.actions.size():0; 135. 136. return0; 137. 138. /計時 139. publicvoidtick(floatdt) 140. for(HashElementcurrentTarget:this.targets.values() 141. if(!currentTarget.paused) 142. for(intactionIndex=0;actionIndexcurrentTarget.actions.size();+actionIndex) 143. /取得動作 144. ActioncurrentAction=(Action)currentTarget.actions 145. .get(actionIndex); 146. /設置單步執(zhí)行 147. currentAction.step(dt); 148. /如果動作完成則調用所指定的回調函數(shù) 149. if(currentAction.isDone() 150. currentAction.stop(); 151. if(currentAction.getCallback()!=null) 152. currentAction.getCallback().onDone(currentAction); 153. 154. removeAction(currentAction); 155. 156. 157. 158. /沒有動作就清楚 159. if(currentTarget.actions.size()=0) 160. deleteHashElement(currentTarget); 161. 162. 163. 164. staticclassHashElement 165. /動作列表 166. CopyOnWriteArrayListactions; 167. /目標節(jié)點 168. Nodetarget; 169. /是否暫停 170. booleanpaused; 171. HashElement(Nodet,booleanp) 172. this.target=t; 173. this.paused=p; 174. 175. publicStringtoString() 176. Strings=target=+this.target+,paused=+this.paused 177. +,actions=+this.actions+n; 178. for(Actiona:this.actions) 179. s=s+a.toString()+n; 180. 181. returns; 182. 183. 184. public class ActionManager /所有的動作列表,包括每個節(jié)點的動畫 private ConcurrentHashMap targets; private static ActionManager sInstance; static sInstance = null; /取得本類實例對象 public static ActionManager getInstance() synchronized (ActionManager.class) if (sInstance = null) sInstance = new ActionManager(); return sInstance; /構建動作管理器對象 private ActionManager() synchronized (ActionManager.class) /構建一個計時器 /指定更新函數(shù)為tick Scheduler.getInstance().schedule(new Scheduler.Timer(this, tick); this.targets = new ConcurrentHashMap(131); /清楚動作 private void deleteHashElement(HashElement element) element.actions.clear(); this.targets.remove(element.target); /動作列表 private void actionAlloc(HashElement element) if (element.actions = null) element.actions = new CopyOnWriteArrayList(); /移除指定動作 private void removeAction(int index, HashElement element) element.actions.remove(index); if (element.actions.size() = 0) deleteHashElement(element); /暫停所有動作 public void pauseAllActions(Node target) HashElement element = (HashElement) this.targets.get(target); if (element != null) element.paused = true; /重新開始所有動作 public void resumeAllActions(Node target) HashElement element = (HashElement) this.targets.get(target); if (element != null) element.paused = false; /添加動作 public void addAction(Action action, Node target, boolean paused) assert (action != null) : Argument action must be non-null; assert (target != null) : Argument target must be non-null; HashElement element = (HashElement) this.targets.get(target); if (element = null) element = new HashElement(target, paused); this.targets.put(target, element); actionAlloc(element); assert (!element.actions.contains(action) : runAction: Action already running; element.actions.add(action); /開始動作 action.start(target); /移除所有動作 public void removeAllActions() for (HashElement element : this.targets.values() removeAllActions(element.target); /移除指定節(jié)點的所有動作 public void removeAllActions(Node target) if (target = null) return; /先找到指定節(jié)點 HashElement element = (HashElement) this.targets.get(target); if (element != null) element.actions.clear(); deleteHashElement(element); /移除指定動作 public void removeAction(Action action) /先找到動作的源目標 HashElement element = (HashElement) this.targets.get(action .getOriginalTarget(); if (element != null) int i = element.actions.indexOf(action); if (i != Action.INVALID_TAG) removeAction(i, element); /移除指定 public void removeAction(int tag, Node target) assert (tag != Action.INVALID_TAG) : Invalid tag; HashElement element = (HashElement) this.targets.get(target); if (element = null) | (element.actions = null) return; int limit = element.actions.size(); for (int i = 0; i limit; +i) Action a = (Action) element.actions.get(i); if (a.getTag() = tag) & (a.getOriginalTarget() = target) removeAction(i, element); /得到指定目標的指定動作 public Action getAction(int tag, Node target) assert (tag != Action.INVALID_TAG) : Invalid tag; HashElement element = (HashElement) this.targets.get(target); if (element != null) & (element.actions != null) int limit = element.actions.size(); for (int i = 0; i limit; +i) Action a = (Action) element.actions.get(i); if (a.getTag() = tag) return a; return null; /得到運行中的動作的數(shù)量 public int getRunningActionCount(Node target) HashElement element = (HashElement) this.targets.get(target); if (element != null) return (element.actions != null) ? element.actions.size() : 0; return 0; /計時 public void tick(float dt) for (HashElement currentTarget : this.targets.values() if (!currentTarget.paused) for (int actionIndex = 0; actionIndex currentTarget.actions.size(); +actionIndex) /取得動作 Action currentAction = (Action) currentTarget.actions .get(actionIndex); /設置單步執(zhí)行 currentAction.step(dt); /如果動作完成則調用所指定的回調函數(shù) if (currentAction.isDone() currentAction.stop(); if (currentAction.getCallback() != null) currentAction.getCallback().onDone(currentAction); removeAction(currentAction); /沒有動作就清楚 if (currentTarget.actions.size() = 0) deleteHashElement(currentTarget); static class HashElement /動作列表 CopyOnWriteArrayList actions; /目標節(jié)點 Node target; /是否暫停 boolean paused; HashElement(Node t, boolean p) this.target = t; this.paused = p; public String toString() String s = target= + this.target + , paused= + this.paused + , actions= + this.actions + n; for (Action a : this.actions) s = s + a.toString() + n; return s; 大家可以看到HashElement的定義正如我們所說,包含一個節(jié)點的所有動畫序列,然后整個ActionManager就應該包含每一個節(jié)點,因此使用了ConcurrentHashMap來表示這所有節(jié)點的所有動畫。大家可以看到我們在構建動作管理器對象時創(chuàng)建了一個計時器,該計時器會不停的調用tick函數(shù),因此我們在tick函數(shù)中就需要先去的當前執(zhí)行動畫的節(jié)點,但后在找到該節(jié)點正在執(zhí)行的動畫(一個節(jié)點可以同時執(zhí)行多個動畫,或者后面即將介紹的組合動畫),最后通過step函數(shù)來設置動畫的單步執(zhí)行,同時我們在tick函數(shù)中就可以時刻檢查當前動畫是否結束,如果結束就調用動作類(Action)中的回調接口中的函數(shù)onDone。另外的一些操作就比較簡單了,就是從動畫管理器中添加、刪除動畫,當添加一個動畫時,我們就將對該動畫調用start函數(shù)來觸發(fā)開始動畫操作。時間動畫(FiniteTimeAction)“時間動畫”這個標題或許概括得并不完善,實際上該類用于表示在有限時間內可以完成的動作,即有限時間動畫,當然也就對應會有無限時間動畫了,比如后面我們要給大家介紹的永久不停的動畫就屬于無限時間動畫。首先我們分析該類屬于動作范圍,所以它將繼承自Action類,在因為他有一段有限的時間限制,所以我們需要一個表示動畫時間的變量,另外:同樣還有很多動畫都需要在制定時間內完成,所以它還是我們封裝的一個基類,有了這些條件下面來看我們的具體實現(xiàn),如代碼清單5-3所示。代碼清單5-3:FiniteTimeAction實現(xiàn)view plaincopy to clipboardprint?1. /用于表示在有限時間內可以完成的動作。 2. publicabstractclassFiniteTimeActionextendsAction 3. /執(zhí)行動畫的時間限制 4. protectedfloatmDuration; 5. protectedFiniteTimeAction(floatduration) 6. this.mDuration=duration; 7. 8. publicfloatgetDuration() 9. returnthis.mDuration; 10. 11. publicvoidsetDuration(floatduration) 12. this.mDuration=duration; 13. 14. /用于表示在有限時間內可以完成的動作。 public abstract class FiniteTimeAction extends Action /執(zhí)行動畫的時間限制 protected float mDuration; protected FiniteTimeAction(float duration) this.mDuration = duration; public float getD

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論