I am relatively new to ActionScript (have started with it 2 months ago), and have a little doubt of 'procedure' or 'technique' related to passing information between objects.
I have made a class that Pops-up a window that contains a panel with a textbox and two buttons, one for accepting, other for cancelling. It should work as a prompt in which you enter some text, and then if you like the changes, you accept, else, you cancel and the text you entered is discarded.
The thing I'm not sure how to handle is how to receive the text, once the user presses 'Accept', from the class I want to receive it from.
So, the approach I took is a bit cumbersome: firstly, when launching the popup, I associate with it a function (called onResult() in the code) from the 'class that launches', which will be called after the user presses the 'Accept' or 'Cancel' buttons; secondly, to get the text that the user inserted in the box, I keep a reference to it public from my class.
Please have a look at the code here:
http://pastebin.com/Kmud8rBe
I've also programmed in Android before, and the approach there would be much cleanier, just putting the text result from the popup inside a bundle inside an intent, and receiving it from the launched class. Here, I have to pass functions and such, which I don't like at all (although it works!).
So, my question is, for you ActionScript gurus out there, how would you approach this?
Thanks and regards!
pepillo
good that you created a class for your popup-functionality but why did you make all functions static? normal class with normal methods would be better ... and let the class extend from Sprite so that you can add the instance right to the stage.
package
{
import flash.display.Sprite;
public class Popup extends Sprite
{
public function Popup (label:String)
{
// add text and buttons ...
}
}
}
then you can just say:
var pop:Popup = new Popup("message");
addChild(pop);
and to get the data back after the popup is closed you would do sth like this:
private function onPressedAccept(event:MouseEvent):void
{
var text:String = _label.text;
// dispatch a custom event which saves the text as its data
dispatchEvent(new MyEvent(MyEvent.ACCEPT, text));
// close popup ...
parent.removeChild(this);
// or you would remove the popup in the ACCEPT eventlistener ...
}
listening for accept/cancel:
var pop:Popup = new Popup("message");
addChild(pop);
// add eventlistener
popup.addEventListener(MyEvent.ACCEPT, onAccept);
popup.addEventListener(MyEvent.CANCEL, onCancel);
private function onAccept(event:MyEvent):void
{
trace(event.data);
}
link about creating custom events:
http://www.8bitrocket.com/2007/7/31/Creating-Custom-Events-In-Flash-AS3-ActionScript-3/
Related
I saw plenty of questions that asked how to make a button in a movie clip that leads to a frame in the main timeline, and took a look at them. But is it different if you want to go to a random frame in a specific set of frames? I've never really used AS3 aside from simple things like stop(); or gotoAndPlay.
Here's what my main timeline looks like at the moment:
Here's the code I've got so far by using Google:
var frameB:Array=[1,28,45,56,71,91,106,126];
blue_circle1.addEventListener(MouseEvent.CLICK, choose);
function choose1(event:MouseEvent):void {
var randomFrame:Number = frameB[Math.floor(Math.random() * frameB.length)];
trace(randomFrame);
gotoAndPlay(randomFrame);
}
The code works fine when I use it on the rotation buttons in the main timeline. But it doesn't work when I put it in a button in a movie clip. I need to change it so it works. If there is a better way of doing this, I'm willing to try it.
Edit: I should clarify things more. I got rectangle on wheels that moves left to right. It does this in a movie clip. I want the button to move with it. But when I place the button into said movie clip, the code on the button stops working. I hope I didn't end up making things more confusing.
When you place the button and/or code inside the movieClip it changes the movieClip that gotoAndPlay() is referring to. You need to specify which movieClip you are calling gotoAndPlay() on. For the main timeline gotoAndPlay() works, but inside a movieClip you must use this:
parent.gotoAndPlay(randomFrame);
Or you may need to set parent's type to a MovieClip like this:
MovieClip(parent).gotoAndPlay(randomFrame);
However, it's best to use external .as files as it gives you the most control over your code.
Save the code below in a file called 'MyFlashAnimation.as'
Create a folder called 'mycodefolder' and put it in the same directory/folder as your .fla.
Use the 'MyFlashAnimation.as' as your document class. In the Flash/Animate IDE find the Properties panel, then the Publish section
In the Publish section where it says 'Class' enter: mycodefolder.MyFlashAnimation (do not add the .as)
CODE:
package mycodefolder {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class MyFlashAnimation {
private var animationClip:MovieClip;
private var blueCircle1:Button;
private var frameB:Array = [1,28,45,56,71,91,106,126];
// constructor
public function MyFlashAnimation() {
// this your main robot/car animation
// this assumes animation_clip is on the main stage
animationClip = this.animation_clip;
// this is your button. this assumes blue_circle1 is a child of
// your animation_clip. update the path if necessary.
// for example, it might be: animationClip.robot_body.blue_circle1
blueCircle1 = animationClip.blue_circle1;
// add listener
blue_circle1.addEventListener(MouseEvent.CLICK, choose);
}
function choose1(event:MouseEvent):void {
var randomFrame:Number = frameB[Math.floor(Math.random() * frameB.length)];
trace(randomFrame);
// tell animation clip to gotoAndPlay
animationClip.gotoAndPlay(randomFrame);
}
}
}
That should work. If you have all your movieClip paths correct.
"The code works fine when I use it on the rotation buttons in the main timeline. But it doesn't work when I put it in a button in a
movie clip."
What is the instance name of the MClip you paste the button into? That MC name will "add" to the final path of your button.
Examples:
(1) If your blue_circle1 on stage (you already can do this) :
blue_circle1.addEventListener(MouseEvent.CLICK, choose);
versus...
2) If your blue_circle1 is inside another MClip (with example name as: thingMC) :
thingMC.blue_circle1.addEventListener(MouseEvent.CLICK, choose);
I have a class called "airport" which extends movieclip. I have, successfully, managed to add a mouseclick-eventlistener for every object of the class that i create.
When I click on one of the objects, I am supposed to enter frame 2 on the main timeline.
I've tried to use the following code inside the class:
this.addEventListener(MouseEvent.CLICK, clickHandler);
private function clickHandler(evt:MouseEvent):void
{
MovieClip(parent).nextFrame();
}
When I click on one of the objects, I don't enter frame 2, but the whole screen goes blank. Any ideas? Thanks for advice.
PS: If you request more of my code to provide an answer, I would be happy to provide it.
Whatever 'this' is isn't a direct child of the main timeline. Try this:
private function clickHandler(evt:MouseEvent):void {
MovieClip(root).nextFrame();
}
Oh..I just found the error. In my code I used the line
this.parent.visible = false
to hide the objects when I entered next frame.
What I did not know was that this also would hide every other movieclip, which results in the screen beeing totally white.
this is actually a noobish question, but is there a possible way to save a certain state of a movieclip?, example i dynamically added a movieclip called big_mc, then inside big_mc contains three(3) smaller movie called child_mc1 and child_mc2 and a close_big to remove big_mc from the stage, when i click either of child_mc1 and child_mc2, the child_mc will disappear prior to which child_mc i clicked.
so the scenario is when I click child_mc1 which remove itself from the scene, then next I'll click the close_big movieclip to remove big_mc from the stage and will save it's own state, so then the next time i run the SWF file and dynamically add big_mc to stage, child_mc1 would be still missing and child_mc2 would still be displayed (EVEN IF I CLOSE THE SWF FILE, the state should be saved). please help..much is appreciated.
code in main time line:
var big_mc:mother_mc = new mother_mc;
add_big_btn.addEventListener(MouseEvent.CLICK, call_big);
function call_big(e:MouseEvent):void
{
addChild(big_mc);
}
the code inside big_mc:
child_mc1.addEventListener(MouseEvent.CLICK, remove_child1);
child_mc2.addEventListener(MouseEvent.CLICK, remove_child2);
close_big.addEventListener(MouseEvent.CLICK, bye);
function remove_child1(e:MouseEvent):void
{
removeChild(child_mc1);
}
function remove_child2(e:MouseEvent):void
{
removeChild(child_mc2);
}
function bye(e:MouseEvent):void
{
this.parent.removeChild(this);
}
You want to start with SharedObject, which as Adobe puts it, "is used to read and store limited amounts of data on a user's computer or on a server". To save the "state" of the MovieClip is more complicated.
What about it do you want to save? The x property? Perhaps the alpha? EVERYTHING? Each object is stored in a default state in your swf. Library items in the Flash IDE are technically miniature classes, as evidenced by the way we instantiate them. Assuming you create something called customButton, you could spawn thousands of them onscreen (or one) like this:
var foo:customButton = new customButton();
Like a hand-written class, a copy of the customButton is created with all the properties you defined on it before you compiled it. If you want to change those properties, you have to address each and every one you want different.
Looking at this broadly, let's assuming you want to save the position of your button every time you load the swf. Load with getLocal(), and save with flush().
var settings:Object = SharedObject.getLocal("foo");
function updateState(e:Event):void {
myButton.x = settings.x;
myButton.y = settings.y;
}
function saveState():void {
settings.x = myButton.x;
settings.y = myButton.y;
settings.flush();
}
It's not impossible; there's simply no push-button solution for it. If you wanted, you could write a function which iterates over all DisplayObjects, and loads/saves each relavent property from/into your SharedObject. Might be overkill, though.
I'm trying to create a disclaimer link that, when moused-over, a movie clip (disclaimer window) will show-up on the swf. How do I do this in AS3, please?
I'm new, and I've only gotten this far:
import flash.events.MouseEvent;
import flash.ui.Mouse;
addEventListener(MouseEvent.MOUSE_OVER,showOptions);
function showOptions (e: MouseEvent): void {
}
You can load your disclaimer window movieclip dynamically from your library like so:
function showOptions(e:MouseEvent):void{
var disclaimer:MovieClip = new disclaimerMC();
disclaimer.name = "disclaimer"; //give disclaimer name in case used later
disclaimer.x = 100; //set coordinates of movieclip
disclaimer.y = 100;
this.addChild(disclaimer); //add the disclaimer to the screen
}
Make sure that you go to your disclaimer movieclip in the library, right-click it, go to properties / linkage, and change the Class field. In my example, I changed the Class field to disclaimerMC.
It might also be nice to let Flash know which movieclips the EventListener should apply to. The way your code is now, mousing over anything would call showOptions. As you probably don't want that, you can say
disclaimerLink.addEventListener(MouseEvent.MOUSE_OVER,showOptions);
So then, only when you mouse over disclaimerLink will disclaimer show.
Alternatively, if the disclaimer window will always appear and disappear in the same place, it is quicker to change its transparency value. Your MOUSE_OVER and MOUSE_OUT functions can call disclaimer.alpha=100; and disclaimer.alpha=0;, respectively.
Before i start i want to let you know today is my first day with AS3.
I wanted to know how to do an onclick function in AS3.
For example i have button 1 ( as Instance name)
and when clicked i want it to hide and show another box. this is what i found online but how can i make it on click.
this.button1.alpha = 100;
Thanks so much.
You want
button1.addEventListener(EventType, callback);
You replace EventType with a mouse event (such as MouseEvent.MOUSE_DOWN) and callback is a function that you define, which is called whenever the event occurs.
See the following example, taken from this page on the FlashEnabled Blog:
// attach the event listener to this object, if you want a global event outside
// the current class attach to stage.addEventListener([event],[callback])
this.addEventListener(MouseEvent.CLICK, onMouseClickEvent);
// then make the callback
public function onMouseClickEvent(event:Event) {
trace(event);
if(event.buttonDown)
// if primary button down, left mouse button
trace(”left button was down”);
else
trace(”left button was not down”);
}
}
The above code sample attaches a click event handler to this (whatever context this code is executed in - it could be global, or inside a class). Inside your event handler, you'd want to use the Tween class (as explained on Kirupa.com) to animate the box out and the other box in.
Since you mentioned that it's your first day, note that trace() writes to the console.