How can I make a function to make a child of an object in the library based on the variables supplied? - actionscript-3

I'm trying to do a little project for my class and though I know how to do it the long way I'd prefer to do it in a more intuitive way so that I can avoid having to copy and paste a load of essentially the same code. The idea is to have a function which will create an instance of a class object with it's own unique name, set it's position/size/etc, and then add that child to the stage. Looking at this (what I have now) might help out a little bit.
//Set up variables for all deco pieces
var decoGreen:GreenBall;
var decoRed:RedBall;
var decoStar:Star;
var decoFlower:Flower1;
var decoYellow:YellowBall;
var decoBlue:BlueBall;
//Functions to allow easier object placement
function makeDeco(posX:Number, posY:Number, decoName:String, rootClass:Object):void
{
decoName = new (rootClass)();
decoName.x = posX;
decoName.y = posY;
addChild((decoName));
}
makeDeco(90,320,"greenBall",GreenBall)
Now obviously this code doesn't work and it's pretty rough right now but I think it's sufficient to understand what I'm trying to accomplish here. Thanks for any and all who attempt to decipher my mess! :D

You are pretty close from what I can tell and if I understand your question, it would simply be using the getDefinitionByName class
function makeDeco(posX:Number, posY:Number, decoName:String):void
{
var DecoClass:Class = getDefinitionByName(decoName) as Class;
var deco:DisplayObject = new DecoClass();
deco.x = posX;
deco.y = posY;
addChild((deco));
}
makeDeco(90,320,"greenBall")
You don't need to define the variables initially like you did, granted they've all set to "Export as actionscript" in the library. For example calling a string of "greenBall" would mean you have a movie clip in the library with a class name of greenBall

Related

Find what _local_x or _arg_x means?

I am working on a large Flash project.
I have tried "Goto Declaration" but that doesn't seem help.
Btw I am using FlashDevelop. And Yes I can perfectly compile and build TO 100% working source.
Here is a code sample. I know you can't do much with this but tell how I can work with this.
public function aim_(_arg_1:Vector3D, _arg_2:Vector3D, _arg_3:ProjectileProperties):Vector3D
{
var _local_4:Vector3D;
var _local_5:GameObject;
var _local_6:Vector3D;
var _local_7:Number;
var _local_8:Number;
var _local_9:int;
var _local_10:Boolean;
var _local_11:int;
var _local_12:Boolean;
var _local_13:* = undefined;
var _local_14:int = Parameters.data_.aimMode;
var _local_15:Number = (_arg_3.speed_ / 10000);
var _local_16:Number = ((_local_15 * _arg_3.lifetime_) + ((Parameters.data_.Addone) ? 1 : 0));
var _local_17:Number = 0;
var _local_18:Number = int.MAX_VALUE;
var _local_19:Number = int.MAX_VALUE;
aimAssistTarget = null;
for each (_local_5 in map_.goDict_)
{
if (_local_5.props_.isEnemy_)
{
_local_10 = false;
for each (_local_11 in Parameters.data_.AAException)
{
if (_local_11 == _local_5.props_.type_)
{
_local_10 = true;
break;
};
};
What you're trying to achieve is reverse engineering a decompiled code. With "_local" variables you need to investigate what values they are assigned, in what algorithms do they participate, and here you just need to read this single function in its entirety to be able to discern meaning of those local variables. But, you would also need to understand many of the named parameters to get some of those meanings. For example, _local_11 iterates through some Parameters.data_.AAException list of ints, and is compared with current outside loop iterator's props.type_, therefore "AAException" should mean "AA exemption" and _local_10 provides check result, whether current enemy is exempt from AA (whatever is that AA). And so on.
Same with _arg_X variables, you need to find out what's being passed into a function from wherever it's called, and retrieve the context of those parameters, also taking their type into consideration, like here _arg3 is of type "ProjectileProperties", meaning this function should relate to some projectile which properties affect its outcome somehow. Most likely it's taking two vectors of projectile (or source, this is outside of this code) and target (or speed, same here), and generates another vector of yet unknown purpose.
When you have investigated every function like this, you'll have quite a bunch of pieces to a single puzzle that you can combine by references, discovering all the algorithms that combine the code of whatever app you've decompiled. Then you will be able to do targeted modifications of whatever kind you wanted initially. But yes, it'll be better if you'd have access to actual sources from whoever created this the first time.
In short: Think. Think, think and think.

Edit movie clip definition as3

I'm a bit new to as3, so forgive me if these are dumb questions. Two questions...
Premise:
I'm loading a character from a swf file, and want to add avatar to it. I have him animated walking and also standing (stand_mc, walk_mc). I also have his body parts separated out, so inside each of the animations mc's is a head_mc, body_mc, etc etc.
First question, how can I access the body parts for any animation? here's my code so far:
var WalkAnim:Class = SWFLoader.getClass('walk_mc'); //Using Greensock loader; but it's the same as using appDomain.getDefinition();
var walkAnim:MovieClip = new WalkAnim();
addChild(walkAnim);
Second question, adding walkAnim just creates an instance of the mc definition. How can I edit the definition in the library to do something like..
var Hat:Class = SWFLoader.getClass('accessory_hat_mc');
var hat = new Hat();
WalkAnim:addChild(Hat)//???
So that if I have multiple instances on stage, they'll all be updated. Thanks in advance for the help!
Basically, to access child elements, you use dot syntax. That would look something like this (last line):
var WalkAnim:Class = SWFLoader.getClass('walk_mc');
var walkAnim:WalkAnim = new WalkAnim(); // I have typed your var as WalkAnim, not MovieClip.
addChild(walkAnim);
walkAnim.head_mc.rotation += 5;
To answer your second question, you wont be able to edit the definition at runtime. You can add an item to each instance though:
var Hat:Class = SWFLoader.getClass('accessory_hat_mc');
var myHat:Hat = new Hat();
walkAnim.head_mc.addChild(myHat);

Dynamic Variable Name

I need to create a variable:
var numDots0:Number=0;
But when a button is clicked the variable numDots0 becomes numDots1, then numDots2 on a second click, and so on. I then need to be able to grab that new variable name and use it in a function.
That's a really, really weird request, but anyways:
You can use the key name of an Object to store the property and then change that:
var obj:Object = { numDots0: 0 };
And then when you want to change the name:
delete obj.numDots0;
obj.numDots1 = 1;
Or to easily increment you can use this:
var i:int = 0;
function increase():void
{
delete obj["numDots" + i];
obj["numDots" + (++i)] = i;
}
To access:
trace(obj.numDotsX); // where X is the most recent variable name.
I see absolutely no benefit or need for this, so I strongly suggest taking a look at what you're trying to do and making sure it makes sense and doesn't have a different application.
I am pretty sure you are going the wrong way about the problem you are trying to solve. Dynamic variable names are not something you read in the best practices book.
Anyway to answer your question in AS2 you could use the command eval which would evaluate a string as ActionScript, so you would use something like:
function onClicked(e:MouseEvent):void
{
counter++;
eval("var numDots" + counter +"+:Number=0;");
}
In AS3 that command has been removed (because it leads to bad coding practices - like the things you are trying to do), nevertheless someone implemented an evaluator in AS3:
http://eval.hurlant.com/
With this evaluator add the library to your project and add the following to the snippet above:
function eval(expression:String):void
{
var evaluator:com.hurlant.eval.Evaluator = new com.hurlant.eval.Evaluator();
var bytes:ByteArray = evaluator.eval(expression);
bytes = ByteLoader.wrapInSWF([bytes]);
var context:LoaderContext = null
var loader:Loader = new Loader();
loader.loadBytes(bytes, context);
}
the answer is to not do what you are trying to do and use an array, hash or vector instead. give us a bit more context, or the reason you want to achieve exactly what you want to and why you might believe you'd need a dynamic variable name like that. you shouldn't be using evals or anything that changes variable name at runtime because the gods of programming will strike you down where you stand. i.e., your program is going to break, and when it does, it's going to be harder to debug for sure.
if you are sure this is what you want to do, then i'm wrong, haha. good luck!

How to duplicate loaded *.swf without setting a class name

I have read this article about abstracting assets from ActionScript:
Abstracting Assets from Actionscript in AS3.0 – Asset Libraries and DuplicateMovieClip
But it requires to set the Linkage Class name. How can I get the same result without setting the linkage class name?
What I want to do is to cache a loaded asset, and use the cached version every time I request the same URL. A solution is to clone the loaded DisplayObject, but I think it's unnecessary since I only want a new copy.
I think the way to do that is to use byte arrays
here's a quick sample
// once you load your data...
private function loaderComplete(event:Event):void
{
var loaderInfo:LoaderInfo = LoaderInfo(event.target);
var byteArray:ByteArray = loaderInfo.bytes; //<- this will create your byte array
}
you can then use byteArray.readObject(); to generate the new class;
look at senocular's post at http://www.kirupa.com/forum/showthread.php?p=1897368
where he's got a function like this:
function clone(source:Object):* {
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
//that you use with
newObjectCopy = clone(originalObject);
hope this gets you started
As of Flash 11.3, there's a function named getQualifiedDefinitionNames that tells me exactly what linkage names should I use with getDefinition, so there's no need to know the values beforehand.

Actionscript - Variable Assignment without reference?

Should be easy. I have an object. I want to modify it, but before i do I want to save a copy of it that I can go back to. I tried setting copy = original but when i modify the attributes of the original the copy also shows the changes. I am assuming this is because in actionscript any time you assign, it really just stores a reference to the original object. So whats the best way for me to store a copy of the original object for later use?
var newObj:Object = Object(ObjectUtil.copy(oldObj));
"Copies the specified Object and returns a reference to the copy. The copy is made using a native serialization technique. This means that custom serialization will be respected during the copy.
This method is designed for copying data objects, such as elements of a collection. It is not intended for copying a UIComponent object, such as a TextInput control. If you want to create copies of specific UIComponent objects, you can create a subclass of the component and implement a clone() method, or other method to perform the copy."
http://livedocs.adobe.com/flex/3/langref/mx/utils/ObjectUtil.html#copy()
What you are looking for is a deep copy of the object rather then passing by reference. I found the answer here which uses the new ByteArray class in AS3:
http://www.kirupa.com/forum/showthread.php?p=1897368
function clone(source:Object):* {
var copier:ByteArray = new ByteArray();
copier.writeObject(source);
copier.position = 0;
return(copier.readObject());
}
Which you then use like this:
newObjectCopy = clone(originalObject);
Cheers!
// duplicate any given Object (not MCs)
Object.prototype.copy = function()
{
ASSetPropFlags(Object.prototype,["copy"],1);
var _t = new this.__proto__.constructor(this) //
for(var i in this){
_t[i] = this[i].copy()
}
return _t
};
Usage
x = ["1","2","3",[4,5],[{a:1,b:2}]]
y = x.copy()
y[0] = 0
y[3][0]="d"
trace(x)
trace(y)