AS3: Making a SimpleButton from library sprites: Possible? - actionscript-3

I'm working on a small project in AS3, and I need to make some interface buttons. I had them as separate classes at first, but then realized that it was probably overkill, and on top of that, figured out a way to simplify the event calls by making them buttons and assigning the event dispatches to their parent.
ANYWAY,
I tried remaking them using the SimpleButton class, but I can't figure out how to give the buttons any sort of design. Every tutorial on the web uses SimpleButton to make only the most bare-bones Actionscript graphics by actually drawing them with the code (why anybody would want to do that is beyond me), and my attempt at assigning a library item to the upState:
_deletebutton = new SimpleButton();
_deletebutton.upState = mc_deleteButtonUp; <--- exists in my library
doesn't do anything.
The Adobe docs say that the various states take DisplayObjects, which mean they take Sprites and MovieClips, so you should be able to do this. Does anyone know how?
THANK YOU

+1 weltraumpirat
the example in the doc generates the states by code but you can assign whatever displayObject to the different states of the button.
var btn:SimpleButton = new SimpleButton();
btn.downState = new clipFromLibDown();
btn.overState = new clipFromLibOver();
btn.upState = new clipFromLibUp();
btn.hitTestState = new clipFromLibHit();
btn.useHandCursor = true;
addChild( btn );
assuming you have 4 states called : clipFromLibDown, clipFromLibOver ... in your library, this works

You have to instantiate an item from your library in order to use it with ActionScript. To do this, click "Export for ActionScript" and assign a class or base class to mc_deleteButtonUp in the properties panel. Then use the new operator with the assigned class to instantiate it. You can start your button by using the example from Adobe's documentation, then change things to fit your own program.

You're probably not setting the hitTestState property of your SimpleButton instances. This property is a DisplayObject that defines where the user has to move the mouse to get mouse events on the SimpleButton. You will never see the DisplayObject that you set this to. I would suggest just using one of the DisplayObjects you are already using for another state.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/SimpleButton.html#hitTestState
Also you will need to use the new operator as weltraumpirat and nicoptere have already said.

Related

AddChild with GetChildByName

Complete AS3 noob here - I've tried Googling this, but I can't seem to find what I'm looking for (I stumbled across this, http://ub4.underblob.com/as3-naming-elements-dynamically/, but it doesn't weem to work for me).
I'm trying to dynamically add a Movieclip inside another Movieclip through an external AS3 class
Something like this:
var bullet:Bullet = new Bullet(x, y, "right");
var stageBackground:MovieClip = (stage.getChildByName("back") as MovieClip);
stageBackground.addChild(bullet);
However, while this compiles correctly, at run time, I get error #1009 - Cannot access a property or method of a null object reference.
The debug panel tells me the problem is with this line:
stageBackground.addChild(bullet);
But I can't seem to figure out what's wrong with it. I've tried recasting stageBackground as a Sprite, but that didn't change anything. I know the MovieClip back exists - when I reference it through near identical code in my document class, it works perfectly.
You are accessing stage here to find your container, which is very likely the problem.
You are probably thinking that the stage property refers to "the stage" in Adobe Flash authoring environment.
That's not true.
If you placed a MovieClip on "the stage" in the Flash IDE, it ends up on the main time line, this however, is not the thing the stage property is referencing. stage is the topmost DisplayObjectContainer in the display list. It only exists at runtime. It more or less represents the FlashPlayer window, the runtime environment that executes your .swf file.
In short: you are simply looking for your back MovieClip in the wrong place.
The property of a container that represents the main timeline is root.
Do not use root either.
As you can see, your code becomes dependent on the display list
structure of your application. You are already struggling to find the
container that you are looking for. If you change the structure, your code breaks. Even changing the name of the container (for example to something like "background") will wreak havoc.
Instead, use Events.
You are in another class and you want to fire a bullet.
So you create that bullet same as you do now:
var bullet:Bullet = new Bullet(x, y, "right");
Next, dispatch an Event to notify the rest of your code that a bullet was created and it should be placed in the appropriate container:
dispatchEvent(new BulletEvent(BulletEvent.CREATED, bullet));
(Create a custom event class BulletEvent that extends Event, with the apropriate setter and getter for a Bullet object)
Register a listener on the object of your class that creates the bullets, you will catch this event and place the bullet in the container:
var object:YourClass = new YourClass();
object.addEventListener(BulletEvent.CREATED, addBulletToContainer);
function addBulletToContainer(e:BulletEvent):void
{
// adding the bullet to the container
back.addChild(e.bullet);
}
This code would be placed in the parent of your back MovieClip.
The Flash IDE automatically creates variables behind the scenes that have the same names as the instance names. That's why the variable back is available here.
Using events here allows you to literally fire the bullet into your code with somebody else taking care of it, where it's easy to figure out the container it belongs into.

Assign integer values to movie clips in ActionScript 3

I am trying to make a card game in Flash using ActionScript 3. I'm not too familiar with the language(grew up with AS2) but I considered it to be more appropriate for this project.
Bad thing about this, though, is that I ran into a problem right away: I'm treating each individual card as a movieclip, but something that I really need is to assign some integer values to the card(It's not really the case, but as an example let's say that I am working on a Poker and I want all Aces to carry the value 1 because they are the best card, 2 for the kings, etc).
I tried looking for it but all I found is how to make arrays of movieclips. I know that this question shouldn't be too hard! Can somebody help me?
(As an aside note, should I really work with movie clips or would buttons be more convenient?)
Firstly, from my point of view, never use components unless you really need to since they take longer time to draw and they're not flexible. I've had so many issues with them in the past (this question I posted being one of those).
About MovieClip's… The MovieClip class is dynamic so you can assign any virtual property to it, no problem. So yourMcInstance.someVar = 3 is perfectly valid.
One of the major changes in AS3, I think, was the introduction of Sprite class, which is basically a MovieClip without a timeline. It is much lighter and unless you're manually creating frame animations it is the class to choose for any container that can handle mouse (and many other) events. However, it is not a dynamic class so yourSpriteInstance.someVar = 3 wouldn't be valid. And that's why using custom classes is encouraged. With custom classes you have the option to extend a class and create custom properties and methods.
because Movieclips are Objects, you can actually attach variables directly to them.
var card:MovieClip = new MovieClip(); //create a blank MC
addchild(card);
card.id = 5; //You can attach vars like this
To add MovieClips to an Array:
const clips:Array = [];
function addNewCardToCardsArray(array:Array, color:String, value:int):MovieClip {
const clip:MovieClip = new MovieClip();
clip.color = color;
clip.value = value;
return array[array.length] = clip;
}

When do we need to add reference to the stage from one class to another

When do we need to pass reference to the stage from one as3 class to another like in this tutorial
http://asgamer.com/2009/as3-flash-games-for-beginners-firing-weapons-with-delays
he added a ref to the stage from the bullet class to the ship class
as I understand a reference is needed when we want to use a function in a certain class from another class but why do we have to reference the stage isn't it only one stage for the whole project or each class has it's own stage ?
I am very confused
Thanks
Only objects that are connected to a stage will be shown on screen. In the tutorial he is adding the lasers onto the stage display list so that it appears on screen. Until it is added, it will not be rendered regardless of the visible property.
See this for more info about the display list.
#Geotarget is correct, but the answer is a little bit indirect.
Objects that are not on the display list do not actually have a reference to stage. So if, for example, you create a var mc:MovieClip = new MovieClip(); which is not added to the display list (as in addChild(mc)), then mc.stage will be null. (Also, checking if(mc.stage){[...]} is also a way to verify if the MovieClip is part of the display list yet.)
So you can pass a reference to the stage to non-display-list objects to allow them access to things like stageWidth.
Yes, a reference is needed when you wanna have to access a function present in that particular class ( to which reference belongs). This is one of the uses.
There is only one stage for the whole project.
In the tutorial you are following, both the classes are using the reference of a COMMON Stage, so that both of them can access the Stage.
It's like giving the address of a place to two people. So that both of them can go there. Naturally, giving addresses doesnot mean, we are building two places for each of them.
V.

Recreating stage layout in as3

I have 27 MovieClips in my Library which are all images. At the moment they are positioned on the stage as instances of their parent and then made to function in the first frame of my actions layer. I want to recreate this layout solely in code so there is nothing on the stage. How do I do this?
Thanks in advance.
Sam
Right click on a movieclip in the library, then go to Properties.
Tick "Export for ActionScript", then check the name where it says "Class". Hit OK.
Let's say this name was "Symbol1".
Then type this script:
var symbol1:MovieClip = new Symbol1();
addChild(symbol1);
var symbol1 means you created a variable, MovieClip is the type. This MovieClip variable is a "new " Symbol1 (this was the name in the library, Properties, Class.
Then add this to the stage:
addChild(symbol1)
If you want to position it on the stage, set the coordinates of the variable:
symbol1.x = 10;
symbol1.y = 10;
puts it to (10, 10).
Depending on how many objects you have you can type this code for each one of them (don't forget to Export them for actionscript in Library->Properties).
If you have tons of movieclips and you don't want to type evertyhing, but would rather write some dynamic code, give us a hint on your library structure and how you named your objects.
Hope this helps.

Is it possible to create a MovieClip using ActionScript 3 code or MXML?

I'm using the Flex 3 SDK and the free FlashDevelop IDE.
As I don't have FlexBuilder or Flash CS4 Professional I cannot make MovieClips graphically.
So instead I want to create a simple MovieClip using code or MXML. For example, lets say I want to create a MovieClip with 3 frames, and load a bitmap into each frame to create a simple animation.
Is this possible? I've had a good google around and the only examples I can find are of loading existing MovieClips and adding them to a stage.
You can create a movieclip with this simple code:
var mc:MovieClip = new MovieClip();
stage.addChild(mc);
That is of cause just and empty movieclip, you can draw on it with graphics property (see here).
As far as I know there is no way to create frame with actionscript. Though there might be some undocumented methods. There are some functions that do not appear in the documentation (like the addFrameScript method).
I would say the best way (if you absolutly can not use the Flash CS4), would be to have a series of Loader objects, and the hide and show them on every in sequence.
Just put them in an array and listen for the enterFrame event.
You can load in the bitmaps in the Loader objects.
If you use the links and checkout the examples in the documentation, I think you should be able to figure it out.
As far as I've seen, there is no easy way to create a MovieClip in Flex which behaves in a way one might see as comparable to Flash's implementation MovieClip. But I don't think you really want a MovieClip to begin with. Flex does not really play well with non-flex objects. Yes, it is possible to add something to a UIComponent, but you are much better off working withing the Flex framework than doing workarounds.
I would use the mx:Image tag to load your images. It is generally the cleanest way to load an image into Flex. It will let you embed the object into the SWF at compile time, which means that you will not have to point to an outside file. I will caution about having too many embedded graphics -- that will kill your download time and possibly your performance.
If you are only interested in having an animation move or re-size, then I would use the Move and Resize objects which are native Flex Tweens.
Your best option might be to extend the UIComponent class, add a MovieClip as a child-component, and apply the settings from MXML via proxy. e.g.,
public function set movieFrames(value:Array):void {
for each(var b:Bitmap in value) {
//add bitmap to _movieclip object.
}
}
You want a Sprite not a MovieClip. And use time instead of frames. There's a Timer class and a getTimer() function. Use them.
create a class that extends/implements Sprite.
Add a Loader class.
Google it exactly how it's done. (flashtuts.com or sth like that).