How to add all symbols in library folder to stage at runtime - actionscript-3

I just submitted this question but i can't see if it posted anywhere, so I apologize if this is a duplicate.
For a Flash CS4 project, I am constantly importing new images, converting them to movieclips and storing them in the library under an "Ornaments" folder. All of these ornaments need to be on the stage in a certain place when the program is initialized. Instead of having to drag the new symbols onto the stage every time I add a new, is it possible to add all of the symbols in the "Ornament" library folder to the stage at runtime?
Thanks

You can do it in code if you wish, but you'd have to still add the names of the symbols to the code. That is, the folder is merely a convenience for organizing within the CS4 library and it does not translate to code (AFAIK).
To instantiate the item in AS3, simply right click the symbol in the library and check the box labelled "Export for ActionScript". If you can't see it, click the Advanced button. It will default the Class to the name of the symbol. That will be the class you can instantiate in ActionScript to put an instance on stage.
You could keep an array of the ornament names and loop through them adding them to the stage:
var ornaments:Array = [OrnamentGold, OrnamentSilver, OrnamentBronze];
for each(var ornament:Class in ornaments)
{
var ornamentClip:MovieClip = new ornament();
addChild(ornamentClip);
}
If you name all of your instances the same with only a trailing digit incremented, you can save yourself some time and just increment a single number:
const NUM_ORNAMENTS:int = 5;
for(var i:int = 0; i < NUM_ORNAMENTS; i++)
{
// ornaments are names Ornament0, Ornament1, Ornament2, etc. in the library
var ornamentClass:Class = new getDefinitionByName("Ornament" + i) as Class;
var ornamentClip:MovieClip = new ornamentClass();
addChild(ornamentClip);
}

Related

How can i change a couple of MovieClip instance properties in mainTimeline by ActionScript 3

I'm a beginner at ActionScript 3. I want to change a MovieClip property. Also I want to give different names for every instance. So basically I want to reach all instances by one name.
A possible solution is writing code inside the MovieClip timeline with --this--.
But I want to do that in root area.
This a picture of my scene:
https://drive.google.com/file/d/0BzXd1GMzUo9HUWozdkJjYkxXSEk/view?usp=sharing
trace(ins1.alpha); // reaching with instance name without problem
trace(ins2.alpha); // reaching with other instance name without problem
/*
trace(MovieClip("mnsmb").alpha); // trying to reach with linkage name is not working
trace(MovieClip(mnsmb).alpha); // trying to reach with linkage name is not working
trace(MovieClip("menusembolu").alpha); // trying to reach with library symbol name is not working
trace(MovieClip(menusembolu).alpha); // trying to reach with library symbol name is not working
trace(mnsmb.alpha); // trying to reach with linkage name is not working
trace(menusembolu.alpha); // trying to reach with library symbol name is not working
*/
If you need to modify the alpha property of one instance (named inst1 in the Properties panel):
ins1.alpha = 0.1;
If you want modify the alpha of all the instances of your class, you can use the is operator (mnsmb is your AS Linkage):
var inst:DisplayObject;
for(var i:int = 0; i < numChildren; i++)
{
inst = this.getChildAt(i) as DisplayObject;
if (inst is mnsmb) inst.alpha = 0.1;
}
Note : In ActionScript 3.0 the instanceof operator should not be used to test for data type membership. See Adobe help about the is operator.

AS3 - How to create a new MovieClip from externally loaded SWF

I am exporting my animated characters from Flash Professional as a SWF to externally load them into AS3. I do not want to export them as SWC's because I have hundreds of these characters and only a small portion of them will be used at a given time.
It seems impossible to create multiple of these character MovieClips from the same loaded SWF since they are not SWC's I have no ActionScript linkage to be able to say
var myClip:MovieClip = new MyMovieClip();
I need to be able to make separate MovieClips from this same loaded character SWF. I essentially want to be able to say
var newMovieClip:MovieClip = otherMovieClip.clone();
Can this be done?
Would you be able to try this:
var newMovieClip:MovieClip = new (otherMovieClip as Object).constructor()
or
var className:String = getQualifiedClassName(otherMovieClip);
if(className)
{
var _class:Class = getDefinitionByName(className);
if(_class)
{
newMovieClip = new _class;
}
}

Using a Numeric Stepper from one Flash file to affect gamespeed in an external Flash file? Actionscript 3.0

Currently I have an intro screen to my flash file which has two objects.
A button which will load an external flash file using:
var myLoader:Loader = new Loader();
var url:URLRequest = new URLRequest("flashgame.swf");
The second thing is a Numeric Stepper, which will be from 1 to 10. If the user selects a number e.g. 3 then the game speed I have set in the flashgame.swf should be changed
Such as:
var gameSpeed:uint = 10 * numericStepper.value;
But I think my problem is coming into place because the stepper and gamespeed are from different files.
Anyone got any idea please?
I have also tried creating a stepper in the game file and used this code:
var gameLevel:NumericStepper = new NumericStepper();
gameLevel.maximum = 10;
gameLevel.minimum = 1;
addChild(gameLevel);
var gameSpeed:uint = 10 * gameLevel.value;
For some reason the stepper just flashes on the stage, no errors come up and the game doesn't work
When you execute you code, the stepper has no chance to wait for user input.
There is no time between theese two instructions.
addChild(gameLevel);
var gameSpeed:uint = 10 * gameLevel.value;
You should wait for user input in your NumericStepper, and then, on user event, set the game speed.
Edit: Yeah I know it's kinda sad to type out all this code (especially since some people wouldn't even be grateful enough to say thanks) but I think this question is important enough to justify the code as it may be helpful to others in future also.
Hi,
You were close. In your game file you could have put a var _setgameSpeed and then from Intro you could adjust it by flashgame._setgameSpeed = gameSpeed; It's a bit more complicated though since you also have to setup a reference to flashgame in the first place. Let me explain...
Ideally you want to put all your code in one place (an .as file would be best but...) if you would rather use timeline then you should create a new empty layer called "actions" and put all your code in the first frame of that.
Also change your button to a movieClip type and remove any code within it since everything will be controlled by the code in "actions" layer. In the example I have that movieclip on the stage with instance name of "btn_load_SWF"
Intro.swf (Parent SWF file)
var my_Game_Swf:MovieClip; //reference name when accessing "flashgame.swf"
var _SWF_is_loaded:Boolean = false; //initial value
var set_gameSpeed:int; //temp value holder for speed
var swf_loader:Loader = new Loader();
btn_load_SWF.buttonMode = true; //instance name of movieclip used as "load" button
btn_load_SWF.addEventListener(MouseEvent.CLICK, load_Game_SWF);
function load_Game_SWF (event:MouseEvent) : void
{
//set_gameSpeed = 10 * numericStepper.value;
set_gameSpeed = 100; //manual set cos I dont have the above numericStepper
if ( _SWF_is_loaded == true)
{
stage.removeChild(swf_loader);
swf_loader.load ( new URLRequest ("flashgame.swf") );
}
else
{ swf_loader.load ( new URLRequest ("flashgame.swf") ); }
swf_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, Game_SWF_ready);
}
function Game_SWF_ready (evt:Event) : void
{
swf_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, Game_SWF_ready);
//Treat the Loader contents (flashgame.swf) as a MovieClip named "my_Game_Swf"
my_Game_Swf = swf_loader.content as MovieClip;
my_Game_Swf.gameSpeed = set_gameSpeed; //update gameSpeed variable in flashgame.swf
//also adjust SWF placement (.x and .y positions etc) here if necessary
stage.addChild(my_Game_Swf);
_SWF_is_loaded = true;
}
Now in you flashgame file make sure the there's also an actions layers and put in code like this below then compile it first before debugging the Intro/Parent file. When your Intro loads the flashgame.swf it should load an swf that already has the code below compiled.
flashgame.swf
var gameSpeed:int;
gameSpeed = 0; //initial value & will be changed by parent
addEventListener(Event.ADDED_TO_STAGE, onAdded_toStage);
function onAdded_toStage (e:Event):void
{
trace("trace gameSpeed is.." + String(gameSpeed)); //confirm speed in Debugger
//*** Example usage ***
var my_shape:Shape = new Shape();
my_shape.graphics.lineStyle(5, 0xFF0000, 5);
my_shape.graphics.moveTo(10, 50);
my_shape.graphics.lineTo(gameSpeed * 10, 50); //this line length is affected by gameSpeed as set in parent SWF
addChild(my_shape);
}
The key line in intro.swf is this: my_Game_Swf.gameSpeed = set_gameSpeed; as it updates a variable in flashgame.swf (referred as my_Game_Swf) with an amount that is taken from a variable in the Parent SWF.
This is just one way you can access information between two separate SWF files. Hope it helps out.

AS3 dynamic variable creation in DC

Can variables be created dynamically without declaration when we write as Document class in AS3?
For example, from a library I'm importing sound files. Some 20 sound files.
If the code is in fla itself, we can assign in for loop like:
this["SOUND"+increasingNumber]
But in documentClass this is not working , since this refers the class here not the stage.
Any method to create variables?
When imported into your library, right click the sound file and go to its properties. Click the actionscript tab and check 'export for actionscript'. Give it a class name which you can then use in your document class to instantiate that sound.
If you named it Sound1:
var sound:Sound = new Sound1();
sound.play();
more detailed info here
[Edit to loxxy's reply] above shows how to create the variables in the document class.
To dynamically create all the sound variables, I'd recommend using an array, like so:
Suppose you named all your sounds in your library Sound1 to Sound20
import flash.utils.getDefinitionByName;
var sounds:Array = [];
var soundClass:Class;
for(var i:int = 1; i<21; i++){
soundClass = getDefinitionByName("Sound" + i) as Class;
sounds.push(new soundClass());
}
In fla when you add code, you add it into a framescript.
A framescript is a block of code repeated at a regular interval (framerate).
You can achieve that using addFrameScript like this.
However a better approach would be to not mix up framescript & the regular class methods.
You can access the 'stage' from the code but only after the added_to_stage event to be sure.
addEventListener(Event.ADDED_TO_STAGE, init);
function init(e:Event):void{
// Access 'stage' here
}

I can't seem to access automatically named objects (instance##) placed on the stage in AS3, am I missing something?

I have a movieclip in the library that is added to the stage dynamically in the document class's actionscript. This movieclip contains many many child images that were imported directly from photoshop at their original positions (which must be preserved).
I do not want to manually name every single image instance, as there are dozens upon dozens.
I have already gone through and manually converted the images to symbols, as apparently flash won't recognize the "bitmap" objects as children of a parent movieclip in AS3 (numChildren doesn't see the bitmaps, but it sees the symbols).
I have an array filled with references to the dozens of children, and I loop through it, checking if each one is under the mouse when clicked. However, somehow, it is not detecting when I click over the items unless I manually name the child symbols (I tested by manually naming a few of them -- those ones became click-sensitive.)
I have already done trace() debugging all throughout the code, verifying that my array is full of data, that the data is, in fact, the names of the instances (automatically named, IE instance45, instance46, instance47, etc.), verifying that the function is running on click, verifying that the code works properly if I manually name the symbols.
Can any one see what's going wrong, or what aspect of flash I am failing to understand?
Here is the code:
//check each animal to see if it was clicked on
private function check_animal_hits():void
{
var i:int = 0;
var animal:Object = this.animal_container;
for (i=0; i<animal.mussels.length; i++)
{
if (this.instance_under_cursor(animal.mussels[i].name))
{
var animal_data = new Object();
animal_data.animal = "mussel";
this.send_data(animal_data);
}
}
}
Here is the code for the instance_under_cursor() method:
// Used for finding out if a certain instance is underneath the cursor the instance name is a string
private function instance_under_cursor(instance_name)
{
var i:Number;
var pt:Point = new Point(mouseX,mouseY);
var objects:Array = stage.getObjectsUnderPoint(pt);
var buttons:Array = new Array ;
var o:DisplayObject;
var myMovieClip:MovieClip;
// add items under mouseclick to an array
for (i = 0; i < objects.length; i++)
{
o = objects[i];
while (! o.parent is MovieClip)
{
o = o.parent;
}
myMovieClip = o.parent as MovieClip;
buttons.push(myMovieClip.name);
}
if (buttons.indexOf(instance_name) >= 0)
{
return true;
}
return false;
}
Update:
I believe I have narrowed it down to a problem with getObjectsUnderPoint() not detecting the objects unless they are named manually.
That is the most bizarre way to find objects under mouse pointer... There is a built-in function that does exactly that. But, that aside, you shouldn't probably rely on instance names as they are irrelevant / can be changed / kept solely for historical reasons. The code that makes use of this property is a subject to refactoring.
However, what you have observed might be this: when you put images on the scene in Flash CS, Flash will try to optimize it by reducing them all to a shape with a bitmap fill. Once you convert them to symbols, it won't be able to do it (as it assumes you want to use them later), but it will create Bitmpas instead - Bitmap is not an interactive object - i.e. it doesn't register mouse events - no point in adding it into what's returned from getObjectsUnderPoint(). Obviously, what you want to do, is to make them something interactive - like Sprite for example. Thus, your testing for parent being a MovieClip misses the point - as the parent needs not be MovieClip (could be Sprite or SimpleButton or Loader).
But, if you could explain what did you need the instance_under_cursor function for, there may be a better way to do what it was meant to do.