Edit movie clip definition as3 - actionscript-3

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);

Related

Replace movieclip palced manualy in timeline with movieclip from library

I have a problem that after a lot of searches I didn't manage to solve it.
I created 2 movie clips in the library (let say mc1 and mc2). Then I manually create another movie clip in timeline (using IDE), let say foo.
As background inside foo I use mc1 with instance name bg. In ActionScript I'm trying to replace the foo.bg with mc2.
Please note that I already exported mc1 and mc2 to first frame with classes mc1() and mc2().
I tried (without any luck) :
var mc1:movieClip = new mc1()
var mc2:movieClip = new mc2()
if (....)
{
foo.bg=mc2;
}
Thanks
Mistake №1: managing objects in display list is not the same thing as assigning variables.
Mistake №2: variable names and class name MUST be different. On a case-level, at least.
So, you need to do something like that:
var mc1:MovieClip = new MC1;
var mc2:MovieClip = new MC2;
// ...
// Delete existing background.
foo.removeChild(foo.bg);
// Set the new background.
foo.addChild(mc2);
foo.bg = mc2;

How to make an instance move

I got the following code and the flash events are all loaded properly. ball is a movie clip and is assigned a class.
var speedx: Number=5;
var speedy: Number=3;
var myball = new ball();
addChild(myball);
addEventListener(Event:ENTER_FRAME,ballmove);
function ballmove(e:Event):void{
myball.x+=speedx;
myball.y+=speedy;
}
But now the instance myball won't move, it is just stuck at position 0,0. Kindly help me and advice how to get this myball to move along a staright line..
If I had dragged and dropped the instance from the library, then
myball.x+=speedx;
myball.y+=speedy;
worked perfectly, but doesn't work after addChild is given.
In your code you incorrectly used Event:ENTER_FRAME when it should be : Event.ENTER_FRAME. I wonder if there is a "silent" error? When testing movies, use Ctrl+Shift+Enter to run the debugger (gives better feedback on issues/errors).
var myball = new ball(); does not mean anything. You declare instance by using this logic : var Name : Type of Data = Value, In your code here you've said only that var Name = Value. Surprisingly it works but I wonder if getting comfortable with that could lead to issues on bigger future projects?
Instance name only affects objects already on Stage. If you're adding by code (from Library) make sure you create a new instance of object by using its Linkage name.
Solution :
In the library, right-click the "ball" object and choose "properties", in there make sure "name" is ball and tick "Export for ActionScript" (you should see "Class" becomeClass: ball). OK that.
Now in your code, you can create new instance by : var myball: ball = new ball();...
Your code should look like
var speedx: Number=5;
var speedy: Number=3;
var myball: ball = new ball();
addChild(myball);
addEventListener(Event.ENTER_FRAME, ballmove);
function ballmove(e:Event):void
{
myball.x += speedx;
myball.y += speedy;
}

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.

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

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

AS3 BitmapData Collision Detection

So I'm working on a flash game where I'm using bitmapdata to determine collision detection with terrain. The idea was to have two sets of terrain tiles, one with the actual terrain on top and a simpler one with only a few basic colors to determine collision. That way if the hero comes into contact with a certain color on the "heightmap" his movement can be halted, slowed, he can receive damage or be scaled up and down to show variance in height. In order ot do this I need to add a whole bunch of heightmap tiles by means of an array, same way as I add the tiles themselves.
Doing this through bitmapdata is proving to be a lot more difficult than I expected and I keep running into errors when using the following code.
This is the Error that I get: TypeError: Error #1010: A term is undefined and has no properties.
As far as I can tell it's coming from the following bit of the code:
var bitmapData:BitmapData = new BitmapData(heightContainer.heightMapClip.width, heightContainer.heightMapClip.height);
But I have no idea what I'm doing wrong.
Here's the code in its entirety, though I haven't gotten around to the array part yet, just need to get this to work first and I really want to try and figure out the rest for myself:
var heightMapClip = new heightMap();
heightContainer.addChild(heightMapClip);
var heightData:String;
var hContainer:Sprite = new Sprite();
heightMapClip.x=-200;
heightMapClip.y=-200;
var bitmapData:BitmapData = new BitmapData(heightContainer.heightMapClip.width, heightContainer.heightMapClip.height);
bitmapData.draw(heightContainer.heightMapClip);
var myHeightMap:Bitmap = new Bitmap(bitmapData);
heightContainer.addChildAt(hContainer,0);
heightContainer.hContainer.addChild(myHeightMap);
heightContainer.hContainer.addEventListener(Event.ENTER_FRAME, onClick);
function onClick(e:Event):void
{
var obj:Sprite = e.currentTarget as Sprite;
var myHeightMap:Bitmap = Bitmap(obj.getChildAt(0));
var pixelValue:uint = heightContainer.myHeightMap.bitmapData.getPixel(mouseX,mouseY);
heightData=pixelValue.toString(16);
if(heightData=="99ff00"){
trace("Collision Detected");
}
}
Any help on this would be greatly appreciated.
heightContainer.addChild(heightMapClip);
by doing this you don't add property heightMapClip to the heightContainer
heightContainer.heightMapClip.width this will generate error
but this won't (as long as it exists and has width property:))
heightMapClip.width
best regards
p.s. "solved it by accident" doesn't specify solution. Write what you have done to answer to your question so others can see and learn from it.