views:

1370

answers:

2

Hi,

I want to embed some images at compilation time so I end up with just a single swf. They need to be inside of an array as I need to modify them programatically and they can be 100s of images. Cant use flex as I want to keep the whole function in actionscript (aka make files smaller)

I found how to do it in flex:

...
<mx:Array id="test">
   <mx:Image id="image0" source="@Embed(source='../../../lib/Images033,jpg')" />
   <mx:Image id="image1" source="@Embed(source='../../../lib/Images034,jpg')" /> 
   <mx:Image id="image2" source="@Embed(source='../../../lib/Images035,jpg')" />
   <mx:Image id="image3" source="@Embed(source='../../../lib/Images036,jpg')" />
</mx:Array>
...
addChild(test[1] as something);
...

So does anyone know how to do the above but just in Actionscript?

Many thanks.

+3  A: 

Hi. I think some clarification is necessary to answer your question.

First, the code you have posted is MXML (not Flex). MXML is just a way of writing ActionScript without having to know ActionScript. It also removes a lot of the work you have to do if you write your code in ActionScript. When Flex creates the SWF, it looks at the MXML and creates ActionScript from it, behind the scenes.

Second, there are two parts to what most of us refer to as 'Flex'. There is FlexBuilder, which is the application you write your Flex applications in, and there is Flex. Flex is mostly just an additional set of ActionScript libraries which provide us with a lot of additional functionality, compared to the base ActionScript language.

I think you're calling MXML 'Flex'. For what it's worth, as far as I know, file size is not increased by using MXML, as the MXML is converted to ActionScript before the SWF is created.

So, the best answer to your question may be to just go ahead and use MXML.

In case it isn't, though:

You embed images and other assets in ActionScript by using the Embed metadata tag in combination with the Class object.

You can see a good example of how to do this at this section of Adobe's 'Advanced Flex Programming' documentation.

http://livedocs.adobe.com/flex/3/html/help.html?content=embed_4.html

However, it would be really tedious to do that for hundreds of images. Even more so than doing it in MXML. I would strongly suggest loading them programmatically at runtime. It would be a lot less code, and a much smaller download time for the user, etc.

Hope that's helpful.

Ross Henderson
back2dos
@back2dos: Thanks for that comment. I probably should have said that even though MXML doesn't necessarily result in larger file sizes, using MXML can certainly have that effect, since you have much less control of the end-result ActionScript. Ben Throop gave a nice explanation on this at http://stackoverflow.com/questions/264043/what-overhead-is-there-of-using-an-mxml-file-in-flex-vs-a-plain-actionscript-cla
Ross Henderson
you can save like 100k if you remove all mxml code.As far as writting lots of code, I dont mind, as I can write an script to do so. The reason for embeding all the images is that I want to just have a single SWF file so i can email it around. (Plus it also helps hidding my beloved images from other peoples hands hahaha).Anyway, many thanks for your answer.
StfnoPad
+2  A: 

Well, one way or another, you're going to need an Embed statement for every thing you want to embed, so you won't really be able to get around that. But if you'd prefer to handle everything in script, you could do something like this (it's an AIR application, but everything between the WindowedApplication tags should work within a plain ol' Flex app):

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" initialize="onInitialize()">

    <mx:Script>
     <![CDATA[

      import mx.controls.Image;

      private var images:Array;
      private const IMAGE_COUNT:uint = 5;

      [Embed(source='Image0.png')]
      private var Image0:Class;

      [Embed(source='Image1.png')]
      private var Image1:Class;

      [Embed(source='Image2.png')]
      private var Image2:Class;

      [Embed(source='Image3.png')]
      private var Image3:Class;

      [Embed(source='Image4.png')]
      private var Image4:Class;

      private function onInitialize():void
      {
       images = new Array(IMAGE_COUNT);

       // Populate your array with Class references to embedded imagery
       for (var i:int = 0; i < IMAGE_COUNT; i++)
       {
        images[i] = this["Image" + i];
       }
      }

      override protected function createChildren():void
      {
       super.createChildren();

       // Add your children to the display list
       for (var i:int = 0; i < IMAGE_COUNT; i++)
       {
        var img:Image = new Image();
        img.source = images[i];

        addChild(img);
       }
      }

     ]]>
    </mx:Script>

</mx:WindowedApplication>

So essentially what you're doing, after making sure your images are all embedded at compile time and named according to some numeric scheme (in this case, just appended with an index), is filling your array with Class references, then instantiating and adding them to the display list during the createChildren() phase of the component lifecycle.

There's some esoteric stuff going on here, so if you don't quite understand everything, feel free to comment back, and I'll keep an eye on things. But this is tested code and should work pretty well for ya, given how you've explained your requirements so far.

Christian Nunciato
You should be able to put the embedded image classes directly into an Array like this:private var images:Array == [Image0, Image1, Image2, Image3, Image4];You can to make Image0 through ImageN static, if that doesn't work.
joshtynjala
Actually, they might need to be const instead of var too.
joshtynjala
That's right, if you didn't like the for loop in onInitialize, you could use bracket notation instead, sure. Six of one, as they say. ;)
Christian Nunciato
Thanks Everyone.
StfnoPad