AS3 MovieClip not playing consistently - actionscript-3

So at the beginning when my SWF loads up it also loads up a sequence of animated clips like so:
var loader:Loader = new Loader();
loader.load(new URLRequest("clips/clip4.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, clip4Loaded);
And my clipLoaded function is:
private function clip4Loaded(e:Event):void {
clip4 = e.target.content as MovieClip;
}
The clip4 file being loaded in has a stop() at the first frame. Later in the game (clip4 is the "outro") I use:
clip4.gotoAndPlay(0);
clip4.addFrameScript(clip4.totalFrames - 1, clip4End);
However, the clip only seems to play about 25% of the time and all the other clips which I load the exact same way play fine. The only difference is that those clips get played fairly soon after they load which leads me to believe clip4 is being autoreleased at some point but I really have no clue.

strange - i've got a timeline-animated swf with stop(); in the first frame and the following code:
package {
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
/**
*
* #author www0z0k
*/
[SWF(width='400', height='300', frameRate='30')]
public class NewClass extends Sprite {
private const URL:String = 'res/1.swf';
private var spr:MovieClip;
public function NewClass():void {
var ldr:Loader = new Loader();
ldr.contentLoaderInfo.addEventListener(Event.INIT, onloaded);
ldr.load(new URLRequest(URL));
}
private function onloaded(e:Event):void {
spr = e.target.content as MovieClip;
addChild(spr);
spr.addFrameScript(spr.totalFrames - 1, function():void { x = x == 0 ? 100 : 0; } );
spr.addEventListener(MouseEvent.CLICK, onclick);
}
private function onclick(e:MouseEvent):void {
spr.gotoAndPlay(0);
}
}
}
and it works exactly as it's written.
could you please upload your clip4.swf anywhere (or test this code with it yourself)?

Related

Problems with STAGE

I am pretty new to as3 programming. This forum helped me already a lot, but now I have a problem where I don't know how to get on. So this is my first Post on stack overflow.com.
I need StageWebView for displaying a PDF-document. After several hours, I was successful. I created the code in a new blank document and tested it step by step.
This is my code:
import flash.display.MovieClip;
import flash.media.StageWebView;
import flash.geom.Rectangle;
import flash.filesystem.File;
import flash.display.Sprite;
import flash.display.Stage;
public function StageWebViewExample(pdfdoc:String, xpos:Number, ypos:Number, breite:Number, hoehe:Number)
{
var webView:StageWebView = new StageWebView();
webView.stage = this.stage; //PROBLEM LINE
webView.viewPort = new Rectangle (xpos, ypos, breite, hoehe);
var file:String = pdfdoc;
var pdf:File = File.applicationDirectory.resolvePath(file);
webView.loadURL(pdf.nativePath);
}
StageWebViewExample("test.pdf", 200, 200, 600, 1200);
After testing, I copied the code in my existing flash-document. (The code in a several as-File and the "calling" (StageWebViewExample("....) in the existing flash-document...)
But now the code does't work anymore and there are the following Errors:
- 1119 Access of possibly undefined property stage...
- 1059 Property is read-only.
--> Both Errors referring to the same line I marked in the Code.
Has anyone an idea why it don't work?
I would really appreciate a good hint!
Answer for question is your actions ;) You moved code from the Document Class, in another one, that don't have access to the stage as instance property. I mean this.stage.
Pass Stage also to the method StageWebViewExample, function signature will look like:
public function stageWebViewExample(stage: Stage, pdfdoc:String, xpos:Number, ypos:Number, breite:Number, hoehe:Number):void {
var webView:StageWebView = new StageWebView();
webView.stage = stage;
webView.viewPort = new Rectangle (xpos, ypos, breite, hoehe);
var file:String = pdfdoc;
var pdf:File = File.applicationDirectory.resolvePath(file);
webView.loadURL(pdf.nativePath);
}
Working AIR example:
package {
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.media.StageWebView;
public class StackOverflow extends Sprite {
public function StackOverflow() {
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function onAdded(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, onAdded);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
start();
}
private function start():void {
showWebViewAt(this.stage, "http://www.iab.net/media/file/VASTv3.0.pdf", new Rectangle(0, 0, stage.stageWidth * 0.5, stage.stageHeight));
}
private function showWebViewAt(stage:Stage, path:String, frame:Rectangle):void {
var webView:StageWebView = new StageWebView();
webView.stage = stage;
webView.viewPort = frame;
webView.loadURL(path);
}
}
}

How many images I need to have more fluently animation(Actionscript);

I have an onEnterFrame event:
package {
import flash.display.MovieClip;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
import flash.display.BitmapData;
import flash.geom.Matrix;
import flash.errors.IOError;
public class Ball extends MovieClip {
private var images:Array;
private var frames:Array;
var i:int = 0;
public function Ball(images:Array) {
this.images = images
frames = new Array();
images.forEach(function(current){
trace(current);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadCompleted);
loader.load(new URLRequest(current));
});
}
private function onLoadCompleted(e:Event):void{
frames.push(e.currentTarget.content);
i++;
if(i == images.length)
{
ready();
}
}
private function ready():void{
i = 0;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void{
graphics.clear();
var bitmapData:BitmapData = frames[i].bitmapData;
graphics.beginBitmapFill(bitmapData, new Matrix(), false, true);
graphics.drawRect(0, 0, 100, 100);
graphics.endFill();
i++;
if(i == frames.length)
{
i = 0;
}
}
}
}
this class is getting an array of images and then animates it, and this is my main class:
public class Test extends MovieClip {
private var ball:Ball;
public function Test()
{
var images:Array = new Array();
for(var i:int = 1; i < 21; i++)
{
images.push('ball' + i.toString(10) + '.png');
}
ball = new Ball(images);
addChild(ball);
}
}
so as you see I am passing an array of 20 images, so the question is how many images I need to make a good animation, not roughly, but smoothly, creating every time a new image like ball1.png, ball2.png, ball3.png, ball4.png - I need to move the ball pixel by pixed to make a good animation? or is there a better way to do this?
It depends upon your perception and device and what you want to visualize from your content.
Please refer to this site:
http://www.mathworks.com/help/toolbox/mupad/plot/INTRO_FramesAndTimeRange.html
First thing I would consider is the framerate. There is no point in having more images as your framerate.
Basically for a smooth animation 30 fps should be ok. Also if you consider this for mobile devices I think you should not go higher than 30fps in order to have a good performance.
Regarding the number of images and how to animate them, I suggest you have a look into this game tutorial (Hungry Hero)
http://www.hsharma.com/tutorials/starting-with-starling-ep-3-sprite-sheets/
http://www.hsharma.com/tutorials/starting-with-starling-ep-5-parallax-background/

Dragging a movieclip as3

I have a Movieclip which is a child of another movieclip. I use startDrag() and stopDrag() with first (parent) Movieclip but the nested one doesnt move. Why?
relevant code on stage:
var main:rt = new rt(); // rt being a class in my library, which extends MovieClip object.
addChild(main);
stage.addEventListener(MouseEvent.MOUSE_DOWN, stage_mousedownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, stage_mouseupHandler);
function stage_mousedownHandler(event_object:Event) {
main.startDrag();
}
function stage_mouseupHandler(event_object:Event) {
main.stopDrag();
}
rt's constructor code:
public function rt() {
var bmp_bar:Bitmap;
var br_male:Bar_male; // Bar_male is a Bitmap in my library. (AS Linkage)
bmp_bar = new Bitmap(br_male);
this.addChild(bmp_bar);
}
Made this simple program to test and it works as expected in Flash Develop, there is a main sprite and a child bitmap when I mouse down any where on stage the main sprite is dragged and the child bitmap is moved.
So I am guessing there is something going on in your workflow in flash professional and linkage. Make sure the mouse event handlers are triggered put some breakpoints and debug.
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
public class Test extends Sprite
{
private var sp:Sprite = new Sprite();
public function Test()
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
var bmpData:BitmapData = new BitmapData(100, 100,false,0x000000);
bmpData.fillRect(new Rectangle(0, 0, 100, 100), 0xff0000);
var bmp:Bitmap = new Bitmap(bmpData);
sp.addChild(bmp);
addChild(sp);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
private function onMouseUp(e:MouseEvent):void
{
sp.stopDrag();
}
private function onMouseDown(e:MouseEvent):void
{
sp.startDrag();
}
}
}

Control loaded swish animation in AS 3.0

I'm developing an AS 3.0 wrapper to add some extra stuff that has to load some old and plain frame to frame SwishMax 3 animations and then be able to stop them, play them, and so...
Here is my code:
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.net.URLRequest;
import flash.events.*;
[SWF(backgroundColor="#ffffff", frameRate="17", width="300", height="250")]
public class SwishMaxWrapper extends Sprite {
function SwishMaxWrapper() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
addChild(loader);
var request:URLRequest = new URLRequest("swishy.swf");
loader.load(request);
}
private function completeHandler(event:Event):void {
var movie:MovieClip = event.target.content;
movie.stop();
}
}
}
The animation load works as expected but the movie.stop() doesn't. What is wrong?
I tested your code and it works on my machine. The SWF that I loaded had its animation in the main timeline. Is it possible that the swishy.swf has animation that is not on the main timeline? Perhaps the animation is in another symbol instead, and an instance of that symbol is on the stage. Anyway, when you call stop() in your code above, it's just telling the main timeline to stop, but other movie clips on the stage will keep on going.
I think that's what Simsoft was pointing out.
I tested your code using a SWF that had a symbol on the stage that had animation in it, and I got the problem that you are describing. I fixed it by modifying completeHandler() as follows:
public function completeHandler(event:Event):void {
var movie:MovieClip = event.target.content;
movie.stop(); //doesn't work - main timeline is only one frame long
for(var i:int = 0; i<movie.numChildren; i++) {
var child:MovieClip = movie.getChildAt(i) as MovieClip;
if(child) { //need this test - if the cast to MovieClip fails, child will be null
child.stop(); //works
}
}
}
Hopefully you don't have more animations nested at deeper layers. If that's the case, you'll have to modify this to keep peering into the children of each child and trying to stop their timelines as well.
Anyway, hope that helps. Good luck!
stop() isn't recurive, I think the problem is here.
function ruleThemAll(target : DisplayObjectContainer, doStop : Boolean = true) : void
{
for(var i : uint = 0; i < target.childNum; ++i)
{
var child : DisplayObject = target.getChildAt(i);
// If it's a container, go into to stop children
if(child is DisplayObjectContainer)
ruleThemAll(child as DisplayObjectContainer, doStop);
if(child is MovieClip)
{
if(doStop)
MovieClip(child).stop();
else
MovieClip(child).play();
}
}
}

Access a function inside a loaded .swf file?

Is there a way to call a function inside a loaded SWF file?
Basically, I have a .swf file (A) that loads another .swf file (B)...I would just like to treat B as if it was any other instance added to my class .swf "A"...
Have to recast "Loader" with the name of your .swf file class:
Loaded .swf class:
package src {
import flash.display.MovieClip;
public class LoadedSWF extends MovieClip {
public function LoadedSWF() {
}
public function helloWorld():void
{
trace("hello world from loaded swf!");
}
}
}
Main class:
package src {
import flash.display.Loader;
import flash.net.URLRequest;
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip {
private var loader:Loader;
public function Main() {
loadSWF("LoadedSWF.swf")
}
private function loadSWF(url:String):void {
var urlRequest:URLRequest = new URLRequest(url);
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded, false, 0, true);
loader.load(urlRequest);
addChild(loader);
}
private function onLoaded(e:Event):void {
var target:LoadedSWF = e.currentTarget.loader.content as LoadedSWF;
trace(target);
target.helloWorld();
addChild(target);
}
}
}
There are two cases i.e
Child swf(B) calls function of Parent swf(A) or
Parent swf(A) calls function of loaded swf(B)
Firstly, in both cases, You must make sure that loaded swf(B) has been loaded and added to Loader swf(A) using Event.COMPLETE. Then communication between two swf is possible. The Loaded swf is just like any other child.
Here is the sample code for case 2
var mLoader:Loader = new Loader();
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onCompleteHandler);
mLoader.load(new URLRequest("B.swf"));
public function onCompleteHandler(evt:Event)
{
var embedSWF:MovieClip = MovieClip(evt.target.content);
addChild(embedSWF);
embedSWF.function_OF_B();
}
embedSWF.function_OF_B() statement will call the function of child swf B i.e function_OF_B()
In Adobe Flex, you can use the flash.display.Loader class to load another SWF, and add an event listener to it.
This example is taken from the Adobe Documentation:
var url:String = "http://www.helpexamples.com/flash/images/image2.jpg";
var urlRequest:URLRequest = new URLRequest(url);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete);
loader.load(urlRequest);
addChild(loader);
function loader_complete(evt:Event):void {
var target_mc:Loader = evt.currentTarget.loader as Loader;
target_mc.x = (stage.stageWidth - target_mc.width) / 2;
target_mc.y = (stage.stageHeight - target_mc.height) / 2;
}
Because contentLoaderInfo is a subclass of EventDispatcher, you can also dispatch events to the loaded SWF.
This is basically like calling a function from the SWF, just a little more complicated.