Cocos Creator封裝自己的幀動(dòng)畫(huà)組件播放動(dòng)畫(huà)
前言
在Cocos Creator游戲開(kāi)發(fā)的過(guò)程中我們進(jìn)行需要使用動(dòng)畫(huà)效果,雖然可以通過(guò)動(dòng)畫(huà)編輯器編輯動(dòng)畫(huà)效果,但是有時(shí)候用戶想更靈活的控制幀動(dòng)畫(huà)的效果,就需要自己封裝幀動(dòng)畫(huà)組件。
一、幀動(dòng)畫(huà)播放組件
1: creator播放幀動(dòng)畫(huà)需要通過(guò)動(dòng)畫(huà)編輯器去制作;
2: 為了方便控制和使用加入幀動(dòng)畫(huà)代碼播放組件;
3: 屬性設(shè)置:
sprite_frames: 幀動(dòng)畫(huà)所用到的所有的幀;
duration: 每幀的時(shí)間間隔;
loop: 是否循環(huán)播放;
play_onload: 是否加載組件的時(shí)候播放;
4: 接口設(shè)置:
play_once(end_func); // 播放結(jié)束后的回掉函數(shù);
play_loop(); // 循環(huán)播放;
二、幀動(dòng)畫(huà)播放原理
1: 對(duì)的時(shí)間播放顯示對(duì)的圖片:
假設(shè)以三幀動(dòng)畫(huà)為例,時(shí)間間隔就是duration,

三、自己封裝幀動(dòng)畫(huà)組件
1. ?`const {ccclass, property} = cc._decorator;` 3. ?`@ccclass` 4. ?`export default class FrameAnim extends cc.Component {` 5. ?` ? ?@property({type: [cc.SpriteFrame], tooltip:"幀動(dòng)畫(huà)圖片數(shù)組"})` 6. ?`spriteFrames : Array<cc.SpriteFrame> = [];` 8. ?` ? ?@property({tooltip:"每一幀的時(shí)長(zhǎng)"})` 9. ?`duration : number = 0.1;` 11. ?` ? ?@property({tooltip:"是否循環(huán)播放"})` 12. ?` ? ?loop : boolean = false;` 14. ?` ? ?@property({tooltip:"是否在加載的時(shí)候就開(kāi)始播放"})` 15. ?`playOnload : boolean = false;` 17. ?` ? ?// 播放完后的回調(diào)函數(shù)`18. ?` ? ?private endFunc : any = null;` 19. ?` ? ?// 動(dòng)畫(huà)播放需要的精靈組件`20. ?` ? ?private sprite : cc.Sprite;` 21. ?` ? ?// 動(dòng)畫(huà)播放的狀態(tài),正在播放還是停止`22. ?` ? ?private isPlaying : boolean = false;` 23. ?` ? ?// 記錄已經(jīng)播放的時(shí)間`24. ?`private playTime : number = 0;` 26. ?` ? ?onLoad () {` 27. ?` ? ? ? ?// 獲取當(dāng)前動(dòng)畫(huà)組件掛載的節(jié)點(diǎn)上的Sprite組件,如果沒(méi)有則添加`28. ?` ? ? ? ?this.sprite = this.node.getComponent(cc.Sprite);` 29. ?` ? ? ? ?if(!this.sprite){` 30. ?` ? ? ? ? ? ?this.sprite = this.node.addComponent(cc.Sprite);` 31. ?` ? ? ? ?}` 33. ?` ? ? ? ?// 判斷是否是預(yù)加載播放`34. ?` ? ? ? ?if(this.playOnload){` 35. ?` ? ? ? ? ? ?if(this.loop){` 36. ?` ? ? ? ? ? ? ? ?this.playLoop(); ? ? ? ?// 循環(huán)播放`37. ?` ? ? ? ? ? ?}else{` 38. ?` ? ? ? ? ? ? ? ?this.playOnce(null); ? ?// 只播放一次`39. ?` ? ? ? ? ? ?}` 40. ?` ? ? ? ?}` 41. ?`}` 43. ?` ? ?public playLoop() : void {` 44. ?` ? ? ? ?this.initFrame(true, null);` 45. ?`} ? ` 47. ?` ? ?public playOnce(endf : any) : void {` 48. ?` ? ? ? ?this.initFrame(false, endf);` 49. ?`}` 51. ?` ? ?private initFrame(loop:boolean, endf : any) : void{` 52. ?` ? ? ? ?if(this.spriteFrames.length <= 0){` 53. ?` ? ? ? ? ? ?return;` 54. ?` ? ? ? ?}` 55. ?` ? ? ? ?this.isPlaying = true;` 56. ?` ? ? ? ?this.playTime = 0;` 57. ?` ? ? ? ?this.sprite.spriteFrame = this.spriteFrames[0];` 58. ?` ? ? ? ?this.loop = loop;` 59. ?` ? ? ? ?this.endFunc = endf;` 60. ?`}` 62. ?`start () {` 64. ?`}` 66. ?` ? ?update (dt) {` 67. ?` ? ? ? ?if(!this.isPlaying){` 68. ?` ? ? ? ? ? ?return;` 69. ?` ? ? ? ?}` 71. ?` ? ? ? ?// 累計(jì)時(shí)間,通過(guò)時(shí)間計(jì)算應(yīng)該取哪一張圖片展示`72. ?` ? ? ? ?this.playTime += dt;` 73. ?` ? ? ? ?let index : number = Math.floor(this.playTime / this.duration);` 75. ?` ? ? ? ?if(this.loop){ ?// 循環(huán)播放`76. ?` ? ? ? ? ? ?if(index >= this.spriteFrames.length){` 77. ?` ? ? ? ? ? ? ? ?index -= this.spriteFrames.length;` 78. ?` ? ? ? ? ? ? ? ?this.playTime -= (this.duration * this.spriteFrames.length);` 79. ?` ? ? ? ? ? ?}` 80. ?` ? ? ? ? ? ?this.sprite.spriteFrame = this.spriteFrames[index];` 81. ?` ? ? ? ?}else{ ? ? ? ? ?// 播放一次`82. ?` ? ? ? ? ? ?if(index >= this.spriteFrames.length){` 83. ?` ? ? ? ? ? ? ? ?this.isPlaying = false;` 84. ?` ? ? ? ? ? ? ? ?// 如果有回調(diào)函數(shù)的處理,則調(diào)用回調(diào)函數(shù)`85. ?` ? ? ? ? ? ? ? ?if(this.endFunc){` 86. ?` ? ? ? ? ? ? ? ? ? ?this.endFunc();` 87. ?` ? ? ? ? ? ? ? ?}` 88. ?` ? ? ? ? ? ?}else{` 89. ?` ? ? ? ? ? ? ? ?this.sprite.spriteFrame = this.spriteFrames[index];` 90. ?` ? ? ? ? ? ?}` 91. ?` ? ? ? ?}` 92. ?` ? ?}` 93. ?`}`
四、測(cè)試封裝的幀動(dòng)畫(huà)組件

勾選PlayOnLoad和去掉的區(qū)別,勾選Loop和去掉的區(qū)別,可以發(fā)現(xiàn)預(yù)加載和循環(huán)播放。如何在代碼中控制?
新建GameMgr.ts掛載到Canvas節(jié)點(diǎn)上****。
1. ?`import FrameAnim from "./FrameAnim";` 3. ?`const {ccclass, property} = cc._decorator;` 4. ?`@ccclass` 5. ?`export default class GameMgr extends cc.Component {` 7. ?` ? ?@property({type: [FrameAnim], tooltip:"幀動(dòng)畫(huà)數(shù)組"})` 8. ?` ? ?anim : Array<FrameAnim> = [];` 9. ?`// onLoad () {}`11. ?` ? ?endPlay(){` 12. ?` ? ? ? ?console.log("動(dòng)畫(huà)播放完畢??!");` 13. ?` ? ?}` 14. ?` ? ?start () {` 15. ?` ? ? ? ?//this.anim[0].playOnce(this.endPlay);`16. ?` ? ? ? ?//this.anim[1].playOnce(this.endPlay);`17. ?` ? ? ? ?//this.anim[0].playOnce(null);`18. ?` ? ? ? ?//this.anim[1].playOnce(null);`19. ?` ? ? ? ?//this.anim[0].playLoop();`20. ?` ? ? ? ?//this.anim[1].playLoop();`21. ?` ? ? ? ?if(this.anim.length > 1){` 22. ?` ? ? ? ? ? ?this.anim[1].duration = 0.5;` 23. ?` ? ? ? ? ? ?this.anim[1].playOnce(this.endPlay);` 24. ?` ? ? ? ?}` 25. ?` ? ? ? ?if(this.anim.length > 0){` 26. ?` ? ? ? ? ? ?this.anim[0].playLoop();` 27. ?` ? ? ? ?}` 28. ?` ? ?}` 29. ?`}`

