topical media & game development

talk show tell print

lib-flex-animation-code-10-org-as3lib-kitchensync-action-KSSimultaneousEndGroup.ax

lib-flex-animation-code-10-org-as3lib-kitchensync-action-KSSimultaneousEndGroup.ax (swf ) [ flash ] flex


  package org.as3lib.kitchensync.action
  {
          import flash.utils.Dictionary;
          import flash.utils.getQualifiedClassName;
          
          import org.as3lib.kitchensync.core.KitchenSyncEvent;
          import org.as3lib.kitchensync.core.Timestamp;
          import org.as3lib.kitchensync.utils.TimestampUtil;
          
          
A parallel group where all children END at the same time instead of starting at the same time. Instantaneous items will play at the end.
author: Mims Wright @since 1.6

  
          public class @ax-lib-flex-animation-code-10-org-as3lib-kitchensync-action-KSSimultaneousEndGroup extends KSParallelGroup {
                  private var _longestItemsTotalDuration:int;
                  private var _childStartTimes:Dictionary;
                  
                  
Constructor.

  
                  public function @ax-lib-flex-animation-code-10-org-as3lib-kitchensync-action-KSSimultaneousEndGroup (... children) {
                          super();
                          for (var i:int = 0; i < children.length; i++) {
                                  if (children[i] is IAction) {
                                          var action:IAction = IAction(children[i]);
                                          addAction(action); 
                                  } else {
                                          throw new TypeError ("All children must be of type IAction. Make sure you are not calling start() on the objects you've added to the group. Found " + getQualifiedClassName(children[i]) + " where IAction was expected.");
                                  }
                          }
                  }
                  
                  override public function update(currentTimestamp:Timestamp):void {
                          if (startTimeHasElapsed) {
                                  var childAction:IAction;
                                  // if the group isn't already running...
                                  if (!childrenAreRunning) {
                                          // reset the number of running children.
                                          _runningChildren = 0;                                
                                          // cache the longest duration
                                          _longestItemsTotalDuration = getLongestItemsTotalDuration();
                                          // reset the dictionary.
                                          _childStartTimes = new Dictionary(true);
                                          
                                          // for all child actions
                                          childAction = null;
                                          for each (childAction in childActions) {
                                                  // add the start time to a dictionary.
                                                  _childStartTimes[childAction] = calculateStartTime(childAction, _longestItemsTotalDuration);
                                                  
                                                  // add a listener to each action so that the completion of the entire group can be tracked.
                                                  childAction.addEventListener(KitchenSyncEvent.START, onChildStart);
                                                  childAction.addEventListener(KitchenSyncEvent.COMPLETE, onChildFinished);
                                                  
                                                  //trace("final start time: " + _childStartTimes[childAction]);
                                          }
                                          // once this has started, it doesn't need updates anymore.
                                          //unregister();
                                  }
                                  
                                  childAction = null;
                                  // Once it's running, for all child actions
                                  for each (childAction in childActions) {
                                          // check to see if start time has elapsed for the child.
                                          if (isChildStartTimeElapsed(childAction, currentTimestamp)) {
                                                  // if so, start the child.
                                                  childAction.start();
                                                  // add one running child.
                                                  _runningChildren++;
                                          }
                                  }
                                  // if all children are running, unregister the group.
                                  if (_runningChildren >= _childActions.length) { unregister(); }
                          }
                  }
                  
                  
Determines if the child should start yet.

  
                   private function isChildStartTimeElapsed(childAction:IAction, currentTimestamp:Timestamp):Boolean {
                           if (childAction.isRunning) { return false; }
                           var startTime:int = _childStartTimes[childAction];
                           //trace(startTime, "<=", currentTimestamp.currentTime);
                          if (sync) {
                                  if (startTime <= currentTimestamp.currentTime) { return true; }
                          } else {
                                  if (TimestampUtil.millisecondsToFrames(startTime) <= currentTimestamp.currentFrame) { return true; }
                          }
                          return false;
                   }
                  
                  
Calculates the start time for an action using the following formula: S: start time for item. G: start time for the group. L: longest item's delay and duration. O: item's offset D: item's duration S = G + L - O - D
parameter: action The action to get the start time for.
parameter: longestItemsTotalDuration The delay + duration of the longest item.

  
                   private function calculateStartTime(action:IAction, longestItemsTotalDuration:int):int {
                           return _startTime.currentTime + longestItemsTotalDuration - action.delay - action.duration;
                   }
                  
                  
Returns the combined duration and delay for the item(s) with the longest combined delay and duration.
returns: int The longest time of any child action.

  
                  private function getLongestItemsTotalDuration():int {
                          var longestTime:int = 0;
                          var currentTime:int = 0;
                          if (childActions.length > 0) {
                                  for each (var action:IAction in childActions) {
                                          // get combined delay and duration.
                                          currentTime = action.delay + action.duration;
                                          // if it's the longest, save the value. 
                                          longestTime = currentTime > longestTime ? currentTime : longestTime;
                                  }        
                          }
                          return longestTime;
                  }
                  
          }
  }


(C) Æliens 19/08/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.