1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3 
  4  http://www.cocos2d-x.org
  5 
  6  Permission is hereby granted, free of charge, to any person obtaining a copy
  7  of this software and associated documentation files (the "Software"), to deal
  8  in the Software without restriction, including without limitation the rights
  9  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10  copies of the Software, and to permit persons to whom the Software is
 11  furnished to do so, subject to the following conditions:
 12 
 13  The above copyright notice and this permission notice shall be included in
 14  all copies or substantial portions of the Software.
 15 
 16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 22  THE SOFTWARE.
 23  ****************************************************************************/
 24 
 25 /**
 26  * Base class for ccs.ActionObject
 27  * @class
 28  * @extends ccs.Class
 29  */
 30 ccs.ActionObject = ccs.Class.extend({
 31     _actionNodeList: null,
 32     _name: "",
 33     _loop: false,
 34     _pause: false,
 35     _playing: false,
 36     _unitTime: 0,
 37     _currentTime: 0,
 38     _scheduler:null,
 39     ctor: function () {
 40         this._actionNodeList = [];
 41         this._name = "";
 42         this._loop = false;
 43         this._pause = false;
 44         this._playing = false;
 45         this._unitTime = 0.1;
 46         this._currentTime = 0;
 47         this._scheduler = new cc.Scheduler();
 48         cc.Director.getInstance().getScheduler().scheduleUpdateForTarget(this._scheduler, 0, false);
 49     },
 50 
 51     /**
 52      * Sets name for object
 53      * @param {string} name
 54      */
 55     setName: function (name) {
 56         this._name = name;
 57     },
 58 
 59     /**
 60      * Gets name for object
 61      * @returns {string}
 62      */
 63     getName: function () {
 64         return this._name;
 65     },
 66 
 67     /**
 68      * Sets if the action will loop play.
 69      * @param {boolean} loop
 70      */
 71     setLoop: function (loop) {
 72         this._loop = loop;
 73     },
 74 
 75     /**
 76      * Gets if the action will loop play.
 77      * @returns {boolean}
 78      */
 79     getLoop: function () {
 80         return this._loop;
 81     },
 82 
 83     /**
 84      * Sets the time interval of frame.
 85      * @param {number} time
 86      */
 87     setUnitTime: function (time) {
 88         this._unitTime = time;
 89         var frameNum = this._actionNodeList.length;
 90         for (var i = 0; i < frameNum; i++) {
 91             var locActionNode = this._actionNodeList[i];
 92             locActionNode.setUnitTime(this._unitTime);
 93         }
 94     },
 95 
 96     /**
 97      * Gets the time interval of frame.
 98      * @returns {number}
 99      */
100     getUnitTime: function () {
101         return this._unitTime;
102     },
103 
104     /**
105      * Gets the current time of frame.
106      * @returns {number}
107      */
108     getCurrentTime: function () {
109         return this._currentTime;
110     },
111 
112     /**
113      * Sets the current time of frame.
114      * @param time
115      */
116     setCurrentTime: function (time) {
117         this._currentTime = time;
118     },
119 
120     /**
121      * Return if the action is playing.
122      * @returns {boolean}
123      */
124     isPlaying: function () {
125         return this._playing;
126     },
127 
128     /**
129      * Init properties with a json dictionary
130      * @param {Object} dic
131      * @param {Object} root
132      */
133     initWithDictionary: function (dic, root) {
134         this.setName(dic["name"]);
135         this.setLoop(dic["loop"]);
136         this.setUnitTime(dic["unittime"]);
137         var actionNodeList = dic["actionnodelist"];
138         for (var i = 0; i < actionNodeList.length; i++) {
139             var locActionNode = new ccs.ActionNode();
140             var locActionNodeDic = actionNodeList[i];
141             locActionNode.initWithDictionary(locActionNodeDic, root);
142             locActionNode.setUnitTime(this.getUnitTime());
143             this._actionNodeList.push(locActionNode);
144             locActionNodeDic = null;
145         }
146     },
147 
148     /**
149      * Adds a ActionNode to play the action.
150      * @param {ccs.ActionNode} node
151      */
152     addActionNode: function (node) {
153         if (!node) {
154             return;
155         }
156         this._actionNodeList.push(node);
157         node.setUnitTime(this._unitTime);
158     },
159 
160     /**
161      * Removes a ActionNode which play the action.
162      * @param {ccs.ActionNode} node
163      */
164     removeActionNode: function (node) {
165         if (node == null) {
166             return;
167         }
168         cc.ArrayRemoveObject(this._actionNodeList, node);
169     },
170 
171     /**
172      * Play the action.
173      * @param {cc.CallFunc} fun
174      */
175     play: function (fun) {
176         this.stop();
177         this.updateToFrameByTime(0);
178         var frameNum = this._actionNodeList.length;
179         for (var i = 0; i < frameNum; i++) {
180             var locActionNode = this._actionNodeList[i];
181             locActionNode.playAction(fun);
182         }
183         if (this._loop) {
184             this._scheduler.scheduleCallbackForTarget(this, this.simulationActionUpdate, 0, cc.REPEAT_FOREVER, 0, false);
185     }
186     },
187 
188     /**
189      * pause the action.
190      */
191     pause: function () {
192         this._pause = true;
193     },
194 
195     /**
196      * stop the action.
197      */
198     stop: function () {
199         for (var i = 0; i < this._actionNodeList.length; i++) {
200             var locActionNode = this._actionNodeList[i];
201             locActionNode.stopAction();
202         }
203         this._scheduler.unscheduleCallbackForTarget(this, this.simulationActionUpdate);
204         this._pause = false;
205     },
206 
207     /**
208      * Method of update frame .
209      */
210     updateToFrameByTime: function (time) {
211         this._currentTime = time;
212         for (var i = 0; i < this._actionNodeList.length; i++) {
213             var locActionNode = this._actionNodeList[i];
214             locActionNode.updateActionToTimeLine(time);
215         }
216     },
217     simulationActionUpdate: function (dt) {
218         if (this._loop) {
219             var isEnd = true;
220             var actionNodeList = this._actionNodeList;
221             for (var i = 0; i < actionNodeList.length; i++) {
222                 var actionNode = actionNodeList[i];
223                 if (actionNode.isActionDoneOnce() == false) {
224                     isEnd = false;
225                     break;
226                 }
227             }
228             if (isEnd) {
229                 this.play();
230             }
231         }
232     }
233 });