views:

2754

answers:

5

OK, I feel dumb asking this, but I've spent the whole afternoon trying to figure it out, without success.

In AS3, I want to add an image to the Library (let's call it image.png) and instantiate it using just code.

I succeeded in instantiating an external image this way

var pLoad:Loader = new Loader();
pLoad.load(new URLRequest("image.png"));
addChild(pLoad);

But no matter what I tried, I can't do the same loading the image from the library. How is that done?

Aside : I've seen the [embed] syntax but ideally I'd like to avoid hardcoded image names, that is, I want to choose an image, and thus generate the image name, programatically.

A: 

Looks like this works :

var pDef:Class = getDefinitionByName("image.png") as Class;
var _image:BitmapData = new pDef(10, 10);

m_pSprite = new Sprite();     
m_pSprite.graphics.beginBitmapFill(_image);
m_pSprite.graphics.drawRect(0, 0, _image.width, _image.height);
m_pSprite.graphics.endFill();
addChild(m_pSprite)

Looks ugly and unnecesarily complex, though. Any other way?

ggambett
You could also create a Bitmap object, fill it with the BitmapData and then add the Bitmap as a child of the Sprite.
Branden Hall
+1  A: 

According to what I have found, this is nowhere as easy to do in AS3 as it was in previous versions. One method that worked was to create a MovieClip to hold the image, then create an instance of that MovieClip and add it to the stage. The other method was to create a class for each image you add, then instantiate and add that class to the stage (the steps for which are located here.

There must be better ways to do this. I'll continue searching.

Michael Todd
+3  A: 

Well, first of all you need to open the properties window of the library and check the "Export to Actionscript" checkbox, after that just put a nice reference to your object in the class textfields, for this example I'll call it MyImage, ok. Now let's get the code.

var ImageClass:Class = getDefinitionByName("MyImage") as Class;
var image:Bitmap = new Bitmap(new ImageClass(575,430));
addChild(image);

That's it, works nice here.

ruyadorno
This appears to be the easiest way to do it. It's only one line more than the "old way" so I'd say that'll do.
Michael Todd
The thing is I need a Sprite or something I can apply transforms to, particularly scaling and rotation - from what I've read, Bitmaps don't do that. My own answer posted below uses the same basic idea to load the bitmap data and draw it into a Sprite, but I still hope there's a better way.
ggambett
You can always add your bitmap object to a Sprite and then perform the modifications you want.
ruyadorno
+3  A: 

The Flash library is quite a mystical beeing, but if well used, it can be quite a nice way to setup your Flash workflows... I'll try to clarify all of this:

Library symbols with the "Export for ActionScript" option are actually compiled as classes. If there is no class file with the same class name, Flash will create one on compilation with the same name you declare in the "Class" field. That means, in your case, if the name of the class is "image.png" it will actually create a "png" class in the "image" package extending BitmapData (of course, it would be wiser to give it another classname, say proyect.library.MyImage)... this means you don't need getDefinitionByName, just instantiate it as you would with any other class:

import image.png;
var bmd:BitmapData = new png(0,0); //the dimensions are irrelevant but necessary

Then you need a Bitmap instance to be able to add it to the displayList:

var bitmap:Bitmap = new Bitmap(bmd,"auto", true); //see the docs for the las two args
addChild(bitmap);
//Bitmap is a DisplayObject, so you can apply transformations to it as with any Sprite or MovieClip.

All of this applies to any Library Symbol (except Graphic)... let's say you "export for AS" a sound symbol as "project.library.MySound", then you can just do this:

import proyect.library.MySound;
var sound:Sound = new MySound();
sound.start();

If you do have a class file with the same name as your library's symbol, Flash will try to use it (if it inherits the default base class). You will notice that all of these symbols have an editable Base Class field. You can also set a custom class in there, as long as it inherts the default base class... In bitmaps it's flash.display.BitmapData, sounds are flash.media.Sound, fonts are flash.text.Font, movieclips are flash.display.MovieClip, etc... In the case of MovieClips, as long as you don't have frames, you can also subclass from Sprite.

All of this, while it may sound a bit mystical, if well applied, can result in quite a comfortable workflow for both designers and developers working with Flash. For instance, you can just setup a nice package with the whole UI definition, and make your designers use those base classes to assemble the graphics and animations.

Cay
+1  A: 

An improvement on ruyadorno's way, if you already know what the classname is, is just:

var image:Bitmap = new Bitmap(new MyImage(0, 0));
addChild(image);

Bitmaps can be put into Sprites easily enough:

var image:Bitmap = new Bitmap(new MyImage(0, 0));
var sprite:Sprite = new Sprite;
sprite.addChild(image);
addChild(sprite);

Then you can transform the sprite as normal.

n.b. The parameters to MyImage are width and height, but they are dummy for subclasses, you can pass anything.

Chris Burt-Brown
Well pointed chris, thanks!
ruyadorno