タイムラインにスクリプトは書きたくないけど重いのも嫌だよ
/**
* Copyright kske ( http://wonderfl.net/user/kske )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/iIZ0
*/
package {
import flash.utils.Dictionary;
import flash.utils.getTimer;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
/**
* @author KSKe SAKAI
* タイムラインにスクリプトは書きたくないけどMCの終了を検知したい。できればstopだって書きたくない
* テスト1. ごく普通にENTER_FRAME
* テスト2. ifブロックをなくす
* テスト3. ENTER_FRAMEを一つにまとめる
* テスト4. (参考)@projectnya様からも指摘があった addFrameScriptを使う。
* 多分タイムラインに書くのと同じくらいだけど公式ドキュメントにないので実戦で使いたくない
*/
public class DispatchMovieClipEnd extends Sprite {
private var lib : Loader;
private var TestMovieClip : Class;
private var mcVector : Vector.<MovieClip> = new Vector.<MovieClip>();
private var enterFrameDict : Dictionary = new Dictionary();
private var finishedMcNum : uint = 0;
private var startTime : uint;
private var text : SimpleText;
public function DispatchMovieClipEnd() {
init();
}
private function init() : void {
lib = new Loader();
var req : URLRequest = new URLRequest("http://kske.info/swf/wonderfl/60fps10secBox.swf");
lib.load(req);
lib.contentLoaderInfo.addEventListener(Event.COMPLETE, start);
}
private function start(e : Event) : void {
var libDomain : ApplicationDomain = lib.contentLoaderInfo.applicationDomain;
TestMovieClip = libDomain.getDefinition("TestBox") as Class;
addActors();
useIfBlockEnterFrame();
}
private function addActors() : void {
var i : uint;
var j : uint;
var mc : MovieClip;
for(i = 0;i < 10;i++) {
for(j = 0;j < 10;j++) {
mc = new TestMovieClip() as MovieClip;
mc.x = i * 40;
mc.y = j * 40;
addChild(mc);
mcVector.push(mc);
}
}
text = new SimpleText();
addChild(text);
}
private function useIfBlockEnterFrame() : void {
var i : uint;
for(i = 0;i < mcVector.length;i++) {
mcVector[i].addEventListener(Event.ENTER_FRAME, ifBlockEnterFrameListener);
mcVector[i].addEventListener("MovieClipLastFrame", movieClipIfBlockTestEnd);
}
startTime = getTimer();
}
private function useBooleanEnterFrame() : void {
text.print("time: " + (getTimer() - startTime));
var i : uint;
finishedMcNum = 0;
for(i = 0;i < mcVector.length;i++) {
mcVector[i].gotoAndPlay(0);
mcVector[i].addEventListener(Event.ENTER_FRAME, booleanEnterFrameListener);
mcVector[i].addEventListener("MovieClipLastFrame", movieClipBooleanTestEnd);
}
startTime = getTimer();
}
private function useDictionaryEnterFrame() : void {
text.print("time: " + (getTimer() - startTime));
var i : uint;
var c : EventCard;
finishedMcNum = 0;
for(i = 0;i < mcVector.length;i++) {
mcVector[i].gotoAndPlay(0);
c = addDictionaryEvent(mcVector[i], dictionaryEnterFrameListener);
c.addEventListener("MovieClipLastFrame", movieClipDictionaryTestEnd);
}
addEventListener(Event.ENTER_FRAME, doDictionaryEvent);
startTime = getTimer();
}
private function addDictionaryEvent(t : MovieClip, l : Function) : EventCard {
var c : EventCard = new EventCard(t, l);
enterFrameDict[c] = c;
return c;
}
private function doDictionaryEvent(event : Event) : void {
for each( var c:EventCard in enterFrameDict) {
(c.Listener)(c);
}
}
private function useAddFrameScript() : void {
removeEventListener(Event.ENTER_FRAME, doDictionaryEvent);
text.print("time: " + (getTimer() - startTime));
var i : uint;
finishedMcNum = 0;
for(i = 0;i < mcVector.length;i++) {
mcVector[i].gotoAndPlay(0);
mcVector[i].addFrameScript(mcVector[i].totalFrames - 1, getMcLastFrameScript(mcVector[i]));
mcVector[i].addEventListener("MovieClipLastFrame", movieClipAddScriptTestEnd);
}
startTime = getTimer();
}
private function testEnd() : void {
text.print("time: " + (getTimer() - startTime));
}
private function movieClipIfBlockTestEnd(event : Event) : void {
var mc : MovieClip = event.target as MovieClip;
mc.stop();
mc.removeEventListener(Event.ENTER_FRAME, ifBlockEnterFrameListener);
mc.removeEventListener("MovieClipLastFrame", movieClipIfBlockTestEnd);
++finishedMcNum === mcVector.length && useBooleanEnterFrame();
}
private function movieClipBooleanTestEnd(event : Event) : void {
var mc : MovieClip = event.target as MovieClip;
mc.stop();
mc.removeEventListener(Event.ENTER_FRAME, booleanEnterFrameListener);
mc.removeEventListener("MovieClipLastFrame", movieClipBooleanTestEnd);
++finishedMcNum === mcVector.length && useDictionaryEnterFrame();
}
private function movieClipDictionaryTestEnd(event : Event) : void {
var c : EventCard = event.target as EventCard;
var mc : MovieClip = c.Target as MovieClip;
mc.stop();
c.removeEventListener("MovieClipLastFrame", movieClipDictionaryTestEnd);
delete enterFrameDict[c];
++finishedMcNum === mcVector.length && useAddFrameScript();
}
private function movieClipAddScriptTestEnd(event : Event) : void {
var mc : MovieClip = event.target as MovieClip;
mc.stop();
mc.removeEventListener("MovieClipLastFrame", movieClipAddScriptTestEnd);
++finishedMcNum === mcVector.length && testEnd();
}
private function ifBlockEnterFrameListener(event : Event) : void {
var mc : MovieClip = event.target as MovieClip;
if(mc.currentFrame >= mc.totalFrames - 1) {
mc.dispatchEvent(new Event("MovieClipLastFrame"));
}
}
private function booleanEnterFrameListener(event : Event) : void {
var mc : MovieClip = event.target as MovieClip;
(mc.currentFrame >= mc.totalFrames - 1) && mc.dispatchEvent(new Event("MovieClipLastFrame"));
}
private function dictionaryEnterFrameListener(c : EventCard) : void {
var target : MovieClip = c.Target as MovieClip;
(target.currentFrame >= target.totalFrames - 1) && c.dispatchEvent(new Event("MovieClipLastFrame"));
}
private function getMcLastFrameScript(mc : MovieClip) : Function {
return function():void {
(mc.currentFrame >= mc.totalFrames - 1) && mc.dispatchEvent(new Event("MovieClipLastFrame"));
};
}
}
}
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.EventDispatcher;
class EventCard extends EventDispatcher {
private var listener : Function;
private var target : EventDispatcher;
public function EventCard(t : EventDispatcher, l : Function) {
listener = l;
target = t;
}
public function dispose() : void {
listener = null;
target = null;
}
public function get Listener() : Function {
return listener;
}
public function get Target() : EventDispatcher {
return target;
}
}
class SimpleText extends Sprite {
private var text : TextField;
public function SimpleText() {
text = new TextField();
addChild(text);
}
public function print(s : String) : void {
text.appendText(s + "\n");
}
}