for ループを使用せずに何かを何度も実行するのに問題があります。これを見てください:
package {
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite {
public function Main() {
addEventListener("done", caller);
caller();
}
public function caller(e:Event = null):void {
trace("hello!");
dispatchEvent(new Event("done"));
}
}
}
これを歌うと、「エラー #2094: イベント ディスパッチの再帰オーバーフロー」が発生します。本当に速い。イベント ディスパッチャと caller() が内部で呼び出され、エラーが発生するまでネストされていることがわかります。
私がやりたいことはこれです:「caller()が完了したら、もう一度呼び出します」ではなく、「終了する前にcaller()を呼び出します」
ここで、タイマーを使用して所要時間を推測したり、ENTER_FRAME を使用したりすることを人々が提案し始める前に、この caller() にはグラフィック データがなく、スプライトに接続されず、完了するまでにかかる時間は、コールトゥコール。完全に終了してから実行する方法を本当に探しています。
ご協力いただきありがとうございます。
ご回答ありがとうございます。タイマーを使用しましたが、呼び出しが多すぎてタイマー間隔が短すぎてオーバーフローする可能性がありました。だから私は単純化して、イベントベースのforループクラスを作成しようとしました(forループのように動作するクラスですが、すべてのリソースを飲み込むのを避けるためのイベントがあります)解決策は、関数を呼び出し、完了時にタイマーを呼び出すことでした。タイマーの完了時に関数を再度呼び出し、それらを互いに跳ね返します。基本的:
call function
wait
call function
wait etc.
タイマーが 0 に設定されていて、すべての関数が呼び出されるまで swf がフリーズしたとしても、関数は再び実行される前に完了します。
やってみて:
package {
import flash.display.Sprite;
public class Efl extends Sprite { // the main class
public function Efl() {
// make four functions...
function init (o:Object):void { // akin to the first part of the for loop
o.value = 0;
}
function condition(o:Object):Boolean { // like the condition portion of the for loop
if (o.value <= 100) {
return (true);
} else {
return (false);
}
}
function next(o:Object):void { // the increment part of a for loop
o.value++;
}
function statements(o:Object):void { // the body of the for loop
trace(o.value);
}
// put the four functions in one new EventForLoop
var test1:EventForLoop = new EventForLoop(init, condition, next, statements, 1); // delay is 1 ms
test1.start(); // set it into motion
// do it again all in one line - not pretty but it works
var test2:EventForLoop = new EventForLoop(
function (o:Object):void { o.value = 0; },
function (o:Object):Boolean { if (o.value <= 50) return (true); else return (false); },
function (o:Object):void { o.value++ },
function (o:Object):void { trace("> " + o.value) },
20); // delay in 100ms
test2.start(); // start it up
// if you try this out, the two will run intertwined since the delays are different.
}
}
}
ループを実行するクラスは次のとおりです。
package {
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class EventForLoop extends EventDispatcher {
// functions to call when simulating the for loop
private var initializer:Function; // is run once at the start of the loop
private var condition:Function; // returns boolean to tell the loop to continue or not
private var step:Function; // the function that runs after the loop is complete
private var statements:Function; // the actual body of the loop
private var timeout:Timer; // the timer to avaoid overflows
private var operator:Object = new Object(); // this is an object to hold and pass values across all the sub loop functions. it is the parameter passed to all four functions
// some event constants
static const NEXT:String = new String("EFLNext");
static const DONE:String = new String("EFLDone");
// constructor just loads vars and sets up timer
public function EventForLoop (init:Function, cond:Function, stepper:Function, stat:Function, delay:Number = 0) {
initializer = init;
condition = cond;
step = stepper;
statements = stat;
timeout = new Timer(delay, 1);
}
// the mail loop function...
private function next(e:Event = null):void {
// Try this and the lone afte the loop:
// trace ("start statements");
if (condition.call(null, operator)) { // if the condition is still true...
statements.call(null, operator); // do the body statements of the loop
step.call(null, operator); // increment
dispatchEvent(new Event(EventForLoop.NEXT)); // dispatch the event so that thw wait can start
} else { // condition returns false??
dispatchEvent(new Event(EventForLoop.DONE)); // tell the event dispatcher the loop is done
removeEventListener(EventForLoop.NEXT, wait); // stop event listeners
timeout.removeEventListener(TimerEvent.TIMER_COMPLETE, next);
}
// trace ("finish statements\n");
// this line and the one before the if() will show that the functcion ends before starting again, even if the Timer wait 0ms
}
// very simple function that waits and ten triggers the loop again
private function wait(e:Event):void {
timeout.reset();
timeout.start();
}
// metod used to set the loop running
public function start():void {
initializer.call(null, operator); // use the initioalizer to set the operator Object
addEventListener(EventForLoop.NEXT, wait); // when the loops done, wait
timeout.addEventListener(TimerEvent.TIMER_COMPLETE, next); // when done waiting, loop again
next(); //do the first loop
}
}
}