Bitmapdata.draw(MovieClip) Gives Blank BitmapData - actionscript-3

I'm predrawing all vector element in my game to bitmaps to improve performance - the vector elements are exported as swf files from Illustrator (I suspect that is part of the problem).
When embedding the swf file in as3 like so:
[Embed(source = 'file.swf')] private static const image:Class;
And then adding it to the stage, like so
stage.addChild(new image);
Everything is fine, but if instead I draw it to a bitmap data like so...
genericBitmapData.draw(new image);
It's a blank bitmapdata. I've tried using gotoAndStop on frames 0 and 1 before drawing with no avail. Does anyone have experience with the swf files that Illustrator exports and any insight as to how I can get these drawing as expected?
Here is a link to a really simple .swf that produces the same results

Here's my revised solution:
//create movieclip
var mc:MovieClip = new image();
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
//this gets called on next frame
function enterFrameHandler(event:Event):void
{
removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
genericBitmapData.draw(mc);
}

So it turns out that the object needs to be instantiated before I can use it to draw, and the easiest way to detect when that is is to listen for the ENTER_FRAME event:
(new image).addEventListener(Event.ENTER_FRAME, functionToDrawImage);
And when that function is called, it will be ready to draw to a bitmapdata, and then all is right with the world.

Related

Starling - load SWF image(vector) into a Image

I'm trying to convert an old project of mine to use Starling for some extra performance.
I've come to a problem when I'm loading my SWFs and trying to display them.
Here is the code I used before: (no Starling)
private function swfLoaded(e:LoaderEvent):void {
var spr:Sprite = new Sprite();
spr = e.currentTarget.content;
bitmapData.draw(spr ...);
}
The problem when I'm using Starling is that the currentTarget.content is a flash.display.displayObject.
cannot convert com.greensock.loading.display::ContentDisplay#90ffec1 to starling.display.Sprite
I want to find a way to "convert" the flash.display.displayObject into a starling Sprite.
I also want to be able to store the loaded swfs content into a array as a sprite.
Thanks in advance,
Tompa
You're overwriting spr with a different value immediately after you create it, for one thing.
After you do the bitmapData.draw() call:
var tex:Texture = Texture.fromBitmapData(bitmapData, false, false);
The new texture can then be used to create a Starling Image sprite.

Cannot mask Stage3D SWF in Loader

Working in FlashBuilder, I build a mobile AS3 application that uses a Loader to display a local SWF file. It masks the loader so it only shows a 640x480 window. This worked fine using an old SWF file (a Flixel game, non-Stage3D).
I then tried it with a Stage3D-enabled SWF file. This failed to run, because the application was not set to run in the 'direct' renderMode (it had been in auto up until this point). This allowed the application to run, but the SWF file now ignores the Loader's mask and displays across the entire stage.
Is it not possible to mask Stage3D SWFs when loaded in this way? The loading looks like so:
public function FlixelTest()
{
super();
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
myLoader.x = (stage.fullScreenWidth-640)/2;
myLoader.y = (stage.fullScreenHeight-480)/2;
var url:URLRequest = new URLRequest("stage3dswf.swf"); // in this case both SWFs are in the same folder
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
myLoader.load(url); // load the SWF file
addChild(myLoader);
}
private function loadProdComplete(e:Event):void{
var gameMask : Shape = new Shape;
gameMask.graphics.beginFill(0xffcc00);
gameMask.graphics.drawRect(myLoader.x,myLoader.y,640,480);
gameMask.graphics.endFill();
myLoader.content.mask = gameMask;
}
As you can read in Adobe's documentation on Stage3D, the special Stage3D layers are located "behind" the regular stage used for 2D content.
Since any mask applied within the 2D stage exists in a different display list, there is no way to use 2D masks on Stage3D content. If at all possible, the only way to get similar results is to use 3D layers and alpha masks within the Stage3D context.

Simulating a MovieClip in pure as3

I am looking for a way to make a Flash movie clip (animation, like the ones created with Flash Pro CS), but purely in as3 - so I can import them into Prezi.
I have done a lot of as3 programming in Flash Builder with Flex projects and I have no background in how MovieClips work.
What I have already tried is extending a MovieClip class and trying to base the animation on Timers, this failed so I tried with ENTER_FRAME event (because flash animations are based on frames - so I thought...). But all this fails, only graphics drawn in the constructor are displayed - no animation happens. (As I wrote in the first paragraph I am testing this importing the swf into Prezi, opening it in a browser works as expected)
Is there any way to do it? Like listening to specific events?
Give sprite sheet a try. It's the best solution for animation in AS3, and also pretty simple to implement. for changing drawing, there are Timer and ENTER_FRAME event to do this.
Funny thing happened. I wanted to show you a sample code I was trying out (I already tried Sprite with ENTER_FRAME), that was not working. By accident I found a solution. It looks like you need to draw something in the first frame, or else the other frames won't work (in Prezi at least).
So here is the working code:
public class PreziTest extends Sprite{
private var radius:uint = 10;
public function PreziTest(){
addEventListener(Event.ENTER_FRAME, onEnterFrame);
onEnterFrame(null); // WITHOUT THIS IT WON'T WORK - YOU NEED TO DRAW SOMTHING IN THE FIRST FRAME
}
private function onEnterFrame(event:Event):void{
radius += 10;
if(radius > 200)
radius = 10;
graphics.clear();
graphics.beginFill(0xff0000);
graphics.drawCircle(radius, radius, radius);
}
}
Thanks for all your help!

Flash CS5 / AS3, after preloading main class constructor can't reference movieclips

I modified an Adobe Flash CS5 sample to create a swf with a preloader.
In my FLA I've two stopped frames:
In the first frame I only put this code (and a textfield showing percentage):
stop();
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoading);
this.loaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onLoading(evt:ProgressEvent):void {
var loaded:Number = evt.bytesLoaded / evt.bytesTotal;
percent_txt.text = (loaded*100).toFixed(0) + "%";
};
function onComplete(event:Event):void {
this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, onLoading);
this.loaderInfo.removeEventListener(Event.COMPLETE, onComplete);
gotoAndStop(2);
};
In the second frame I:
exported the Main class;
I have all the needed graphics assets on stage;
When I test the Adobe sample (it has no main class on frame 2, only a large image) anything works fine, but when I compile the modified version I get strange errors.
In the Main class constructor I reference three movieclips, eg. this way: myClip.alpha=0, but it seems now Flash can't see them anymore (they are null). Why?
How can I make this preloader work?
Thanks in advance.
When you say Main class, are you referring to a class you have set as the Document Class? If I'm following you correctly, the problem is likely that the Document Class is always instantiated on the first frame, so your instances on stage wouldn't yet exist.
It's not possible to have the Document Class wait to instantiate until later frames. You'll probably have to remove your class from the Document Class assignment in order to create your instance on frame 2. At that point, you can pass a reference to your movieclips or stage through to the constructor of your class.

Transfer a BitmapData object from an AS2 swf to a parent AS3 swf via SWFBridge

I need to transfer a BitmapData object created in an AS2 swf to an AS3 swf. I'm using gskinner's SWFBridge to establish a two way communication between both flash movies.
The AS3 movie loads the AS2 swf which works completely standalone and lets the user manipulate MovieClips and finally generate an image from the composition he creates. I need the AS3 movie to receive this image (bitmapData), do some fancy image processing stuff AS2 isn't able to do and send the new image back to the AS2 movie.
So here's the code
AS2 swf:
var userCompo_mc:MovieClip = container.createEmptyMovieClip("userCompo_mc",10);
var image:BitmapData = new BitmapData(userCompo_mc._width, userCompo_mc._height);
finalCompo.attachBitmap(image); // Just to make sure the final bitmap is right
image.draw(userCompo_mc, compo.title);
//Send the image to the AS3 movie
sb1.send("imageTransfer",image);
AS3 swf:
function imageTransfer(bitmapData:BitmapData, title:String):void
{
var bmp:Bitmap = new Bitmap(bitmapData);
this.addChild(bmp);
trace(title); // --> returns the right title
trace(bitmapData); // --> returns null
}
I think using something like copyPixel32(), saving everything into an array and then passing it to AS3 would do the trick but it's really a performance hog.
Also, I'm not allowed to convert the AS2 swf into AS3 code.
Any suggestions?
Thanks you!
It seems like the as2 movie adds some decorations/movieclips to a an image.
After that you draw it and send attempt to send it to as3.
Since looping though all the pixels is slow, as you mention, I imagine it's faster to draw the as2 content from the as3 movie.
e.g.
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaded);
loader.load(new URLRequest('yourAS2Movie.swf'),new LoaderContext(true));
function loaded(event:Event):void{
var as2Clip:AVM1Movie = AVM1Movie(loader.content);
var bd:BitmapData = new BitmapData(as2Clip.width,as2Clip.height,false,0);
bd.draw(as2Clip);
addChild(new Bitmap(bd));
}
In this snippet the as2 content is drawn on load. In your case you would trigger/call a function that draws the as2 content via SWFBridge, after the as2 movie is ready/setup for what you need.
This works assuming you want to display the as2 content inside the as3 movie, which means you will load the as2 movie anyway. If not, either you load the as2 content, but don't add it to the display list, which means you'll be loading the as2 movie. Otherwise, you could try to save your final bitmap from the as2 movie using a server side language(like php for example), then trigger a function in the as3 movie, via SWFBridge, that will load the previously saved image.
HTH