Reputation: 338
I don't know much ActionScript. So apologies if this is really simple.
I have written an .as file as part of this I need to be able to stop the flash animation using .stop().
I have tried a few different ways to do this, some of them work - however they always through this error:
TypeError: Error #1009: Cannot access a property or method of a null object reference. at com.albionpreview::looptimer/startFrame() at test_fla::MainTimeline/frame1()
Here is everything I have tried:
this.stop();
root.stop();
MovieClip(root).stop();
MainTimeLine(parent).stop();
MovieClip(parent).stop();
parent.stop();
DisplayObject(stage).stop();
MainTimeline(parent).stop();
Main(root).stop();
Object(root).stop();
this.stage.stop();
MovieClip(this).stop();
MovieClip(this.root).stop();
(root as MovieClip).stop();
There must be something simple to try. Anyone can help?
Here is my code if it helps.
Upvotes: 0
Views: 551
Reputation: 15881
On a new layer I would make a new movieClip that is going to be a container of the frames and control that to stop via timer.
Just draw a box that has a fill colour only (no border). Same width & height as your stage, align to Top & Left (under Modify->Align with "Align to stage" ticked). It should be a perfect fit of stage area now, and then convert it to movieClip (make sure registration is set as a black dot at top/left.. not centered dot).
Call it what you want but give it the instance name of animMC (you can change this later).
Now select the entire range of your animation frames and choose "cut frames" on right-click menu. Double click the animMC movieClip to enter its timeline, delete the box shape and right-click the first frame and "paste frames".
Now in your code you can stop it like this:
package com.preview {
import flash.utils.Timer;
import flash.events.TimerEvent
import flash.utils.getTimer;
import flash.display.MovieClip;
public class looptimer extends MovieClip
{
var startTime:int = 0;
var allowedTime:int = 5000;
var loopTime:int = 0;
public function looptimer ()
{
var myTimer:Timer = new Timer(5000, 1); //count before doing function "timerListener" the 1 means do once else it will loop forever
myTimer.addEventListener(TimerEvent.TIMER, timerListener);
myTimer.start();
function timerListener (e:TimerEvent):void
{
trace("Timer countdown finished");
animMC.stop(); //anim stops
}
}
}
}
========================
Hi this code will check for an event triggered at the end of your anim. To have such event go into the MC that contains the frames and on the last frame (and on blank layer) add this actions code: (This will be the thing that
dispatchEvent(new Event("Banner_end)")); //end frame
This will be the equivalent of getting your "end Frame". In the code below the event is attached to this instruction:
animMC.addEventListener("Banner_end", check_Time);
Meaning that on reaching the end frame an event called "Banner end" is despatched from timeline, this in turn executes the check_Time function and lso another function (see code).
Now this code below will check time and also timer when the "end frame" event was dispatched and work out whether there is enough time for a second loop or more. Two things will affect how times the MC can loop. First is time limit the longer it is the more you loops you'll fit in that limit. Second is length of anim MC which if shorter means can fit more loops in the time limit. Adjust those two things. Easiest is time limit cos you just a change a number ("allowed_playing_Time") for testing but later when you have no control over the limit then you adjust banner (anim MC) frames as needed i.e by adding/dropping frames.
package com.preview
{
import flash.utils.*;
import flash.events.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.utils.getTimer;
import flash.display.MovieClip;
import flash.events.Event;
public class looptimer extends MovieClip
{
var allowed_playing_Time:int = 10; //time limit in seconds
var play_Count:int = 0; //tracking number of times played
var can_play_Amount:int = 1; //total times can be played
var _startTime:Date;//Number;
var _endTime:Date;//Number;
//for time check using actual [computer] clock = more accurate than timer
var real_Time:Date;
var anim_start_time:int;
var anim_end_time:int;
var anim_play_length:int;
public function looptimer()
{
//starting the Banner
play_Banner_anim();
}
function play_Banner_anim():void
{
animMC.stop(); //set strating banner state as paused;
_startTime = real_Time = new Date();//Real Time value initial set here
trace("current time at START is: " + _startTime.minutes + " mins past and " + _startTime.seconds + " secs");
animMC.addEventListener("Banner_end", check_Time);
animMC.addEventListener("Banner_end", calculate_Replay);
anim_start_time = getTimer();
animMC.play();
}
function check_Time(e:Event):void
{
animMC.stop(); trace( "Banner has reached last frame");
animMC.removeEventListener("Banner_end", check_Time);
play_Count = play_Count + 1;
trace("Times banner has played / looped): " + play_Count);
_endTime = real_Time = new Date();//new update of Real Time value
trace("current time at END is: " + _endTime.minutes + " mins past and " + _endTime.seconds + " secs");
anim_end_time = getTimer();
anim_end_time = Math.ceil(anim_end_time);
anim_play_length = Math.round(Math.floor(anim_end_time - anim_start_time) / 1000);
anim_play_length = anim_play_length;
trace("checking if Real Time: ");
var date1:Date = _startTime;
var date2:Date = _endTime;
var elapsed1:Number = Date.UTC(date1.minutes,date1.seconds);
var elapsed2:Number = Date.UTC(date2.minutes,date2.seconds);
var playingTime:Number = Math.round( (elapsed2/1000) - (elapsed1/1000) );
trace ("time elasped (delta) is " + playingTime );
//check seconds elapsed in banner playback (i.e total play length)
trace("Banner total playing length was " + anim_play_length + " seconds");
//so how many times can banner play within allowed time limit?
var can_fit_Num:Number = allowed_playing_Time / anim_play_length;
trace("can fit this many plays in allowed time limit: " + can_fit_Num);
can_play_Amount = can_fit_Num;
trace("can_play_Amount is : " + can_play_Amount);
if (can_play_Amount <= 0)
{
trace("Warning: Banner Anim is either longer than allowed time limit or has a play length of zero");
}
}
function calculate_Replay(e:Event):void
{
trace("Calculating replay function :::::: ");
trace("Play/looped amount is: " + play_Count);
trace("Can play amount times is : " + can_play_Amount);
if (play_Count < can_play_Amount)
{
trace("anim_play_length is:" + anim_play_length);
replay_tings();
trace("replaying anim");
}
else
{
animMC.stop();
trace("reached replaying times (" + can_play_Amount + ") available within limit (" + allowed_playing_Time + " secs)");
if (can_play_Amount <= 0)
{ trace("Warning: Banner Anim is either longer than allowed time limit or has a play length of zero"); }
//do something else. Currently just stops since no time for replay
}
}
function replay_tings():void
{
animMC.addEventListener("Banner_end", calculate_Replay);
animMC.play();
play_Count = play_Count + 1;
trace("Play Count/loops: " + play_Count);
}
}
}
Hope it helps. I've put many traces just to give you feedback. Remove any you feel is unnecessary and of course you can optimize the code if you spot something.
Upvotes: 1