Buttons within Movieclip AS3 not working - actionscript-3

I'm relatively new to flash and as3. Basically I'm trying to load a movieclip to the stage and then click a button within that movieclip to remove the child again from the stage. I have the following movieclip:
var myResultBox:ResultBox = new ResultBox();
addChild(myResultBox);
I have a button placed within the movieclip called closeButton1. I am trying to click the close button which in turn removes the movieclip.
the code within the MovieClip is -
//Event Listener for Close button within my results box
closeButton1.addEventListener(MouseEvent.CLICK, closeBMI);
function closeBMI(evt:MouseEvent):void
{
removeChild(myResultBox);
}
Following error
code: 1120: Access of undefined property closeButton1.
Any help would be most appreciated

Below is a simple program which i think has the functionality of what you are asking for. As far as I understand, you have button A on the stage. When you click button A, movie clip B is added to the stage. Movie clip B has button B in it. When you click button B, Movie clip B and button B are removed.
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.MouseEvent;
// This creates a movie clip that contains a button.
// This button will remove the movie clip that contains
// it when it is clicked.
var MovieClipB = new MovieClip();
MovieClipB.graphics.lineStyle(1,0);
MovieClipB.graphics.beginFill(0x0000FF,1);
MovieClipB.graphics.drawRect(0,0,50,50);
var ButtonB:MovieClip = new MovieClip();
ButtonB.buttonMode = true;
ButtonB.graphics.lineStyle(1,0);
ButtonB.graphics.beginFill(0xFFFFFF,1)
ButtonB.graphics.drawCircle(0,0,10);
ButtonB.x = ButtonB.y = 25;
MovieClipB.addChild(ButtonB);
ButtonB.addEventListener(MouseEvent.CLICK, removeButtonClickHandler, false, 0, true);
function removeButtonClickHandler(event:MouseEvent):void
{
var button = MovieClip(event.currentTarget);
var container = button.parent;
container.parent.removeChild(container);
}
// This creates a button that starts on the stage.
// When clicked, it adds the movie clip defined above to the stage
var ButtonA:MovieClip = new MovieClip();
ButtonA.buttonMode = true;
ButtonA.graphics.lineStyle(1,0);
ButtonA.graphics.beginFill(0xFF0000,1)
ButtonA.graphics.drawRect(0,0,50,50);
addChild(ButtonA);
ButtonA.x = ButtonA.y = 20;
ButtonA.addEventListener(MouseEvent.CLICK, addButtonClickHandler, false, 0, true);
function addButtonClickHandler(event:MouseEvent) : void
{
addChild(MovieClipB);
MovieClipB.x = 200;
MovieClipB.y = 20;
}

Within the button? But you can't reference button in such way. You should put your code within movieclip that holds button, where you add result addChild(myResultBox); So your event handler will be able reference myResultBox
For code within a button:
this.addEventListener(MouseEvent.CLICK, closeBMI);
function closeBMI(evt:MouseEvent):void
{
//removeChild(myResultBox);
//Sadly, you don't have reference on myResultBox within a button...
}

Related

AS3 / removeChild/addChild by clicking button

I have several movie clips into a frame the size of the stage and I have to switch through a button between those pages.
So if I press button, should all the other frames removeChild and the one where he is called to go addChild.
Edit: I have the actionscript placed in the timeline of the movieClip so the button is not on the stage but I put in the movie clip using action script.
So what DodgerThud showed here is not possible because the button has changed since that is in the movieClip('s).
I think I need to place the same code in every movieClip.
Put all of your MovieClips into a Vector or Array.
When you click the button, you should cycle through the Vector/Array and check if the MovieClip is currently on stage with contains(DisplayObject). If the Movieclip IS currently on the stage, remove it and add another one to the stage, for example, the next one in the Vector/Array.
var vec:Vector.<MovieClip> = new Vector.<MovieClip>
vec[0] = new MovieClip();
vec[1] = new MovieClip(); //example with MovieClips
vec[2] = new MovieClip();
addChild(vec[0]); //add one of the MovieClips to stage
button.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void
{
for(var i:int = 0; i < vec.length; i++) //go through the Vector one by one
{
if(contains(vec[i]) //if the Object at position i in the Vector is on stage
{
removeChild(vec[i]); //remove the Object
var next:int = i; //create a temporary holder
if(next == vec.length) //check if the displayed Object was the last in the list
{
next = 0; //if so, set to 0
}else{
next++; //otherwise, only add 1
}
addChild(vec[next]); //add the next Object to the stage. If the removed Object was the last in the Vector, it'll add the first Object in the Vector to the list
break; //escape the for loop, otherwise it'll always only show the last Object
}
}
}
Something like ...
function tueHandler(e:MouseEvent):void
{
while(numChildren > 0)
removeChildAt(0);
addChild(whatever);
}

Flash addChild object disappears

In the root, I have 2 buttons that when you press the first one, it goes to the first frame inside the movieclip, if I press the second button it goes to the second frame.
I have the following function in frame 2 inside a movieclip.
function loadMap(mapBoolean:Boolean):void{
if(mapBoolean == false){
var loader:Loader = new Loader();
loader.load(new URLRequest("1.png"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
function loadComplete(e:Event){
map_holder.addChild(loader);
MovieClip(root).mapLoaded = true;
}
}
}
Var declared: var mapLoaded:Boolean = false;
Button #2 function:loadMap(mapLoaded);
When I first press button #2 it goes to the second frame in the movieclip, it successfully loads the image into the holder. Then I press button #1 to return to the first frame and press button #2 to go to the second frame, and the image is gone. Why is this happening?
two options :
either you put the holder on frame 1 (and set its alpha to 0 or visible to false)
or you keep your loader in a variable, declared the same way as mapBoolean:
code frame 1
var loader:Loader;
code frame 2
if(!loader){
loader = new Loader();
loader.load(new URLRequest("1.png"));
//no need for event listening
}
map_holder.addChild(loader);

Change positions of objects on the stage by click - ActionScript 3

I have somme mc's on the stage an I want thatto change on mc with antoher by clicking on them. For example if I click on mc1 and than on mc2 than they schould change the positions.
any ideea how o do that?
thank you for your time
You need to have a click event for the movieclip, and record it on a variable which movieclip was clicked, and then when the 2nd one is clicked, you just swap their positions. I'll give you a snippet of code that should work and should be enough to teach you how it's done.
import flash.events.MouseEvent;
// Variable that will be used to store the 1st clicked MC
var lastClickedSwapMC;
//First we define the function to be called
function clickEventSwapMcs(evt : MouseEvent) {
// Verify if a mc wasn't previously clicked
if(lastClickedSwapMC == null) {
// If it wasn't, it's the 1st time, so store the MC that was clicked
lastClickedSwapMC = evt.currentTarget;
} else {
// If it was, we just need to swap the positions of the stored one with the one just clicked
var savedX : Number = evt.currentTarget.x;
var savedY : Number = evt.currentTarget.y;
evt.currentTarget.x = lastClickedSwapMC.x;
evt.currentTarget.y = lastClickedSwapMC.y;
lastClickedSwapMC.x = savedX;
lastClickedSwapMC.y = savedY;
//After swaping their position, we clear the last clicked MC
lastClickedSwapMC = null;
}
}
//Now we register the click event on them so it calls the function
mc1.addEventListener(MouseEvent.CLICK, clickEventSwapMcs);
mc2.addEventListener(MouseEvent.CLICK, clickEventSwapMcs);

Click event outside MovieClip in AS3

Is there any way to detect if the user click outside a MovieClip?
For instance, I need to detect it to close a previously opened menu (like Menu bar style: File, Edition, Tools, Help, etc).
How can I detect this kind of event? Thanks!
Add a listener to stage and check if stage is the target of the event.
Example of code here:
http://wonderfl.net/c/eFao
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
public class FlashTest extends Sprite
{
private var _menu : Sprite;
public function FlashTest()
{
_menu = new Sprite();
_menu.x = 100;
_menu.y = 100;
_menu.alpha = 0.5;
with(_menu.graphics)
{
beginFill(0xFF0000, 1);
drawRect(0, 0, 300, 300);
endFill();
}
addChild(_menu);
_menu.addEventListener(MouseEvent.CLICK, onClickHandler);
stage.addEventListener(MouseEvent.CLICK, onClickHandler);
}
private function onClickHandler(event : MouseEvent) : void
{
switch(event.target)
{
case _menu:
_menu.alpha = 0.5;
break;
case stage:
_menu.alpha = 1;
break;
}
}
}
}
You can add a listener to the click event of the root element:
MovieClip(root).addEventListener(MouseEvent.CLICK, clickObject);
then in the function clickObject, you can check to see what you are clicking.
function clickObject(e:Event):void
{
var hoverArray:Array = MovieClip(root).getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
var hoverOverObject:* = hoverArray[hoverArray.length - 1];
}
hoverOverObject references the element that you are clicking on. Often this will be the shape within the movie clip, so you'll need to look at it's parent then compare it to your movie clip. If the click wasn't on the drop down movie clip, trigger the close.
var container:MovieClip = new MovieClip();
var mc:MovieClip = new MovieClip();
with(mc.graphics){
beginFill(0xff0000,1);
drawCircle(0,0,30);
endFill();
}
mc.name = "my_mc";
container.addChild(mc);
addChild(container);
stage.addEventListener(MouseEvent.CLICK, action);
function action (e:MouseEvent):void
{
if(e.target.name != "my_mc"){
if(container.numChildren != 0)
{
container.removeChild(container.getChildByName("my_mc"));
}
}
}
Use capture phase:
button.addEventListener(MouseEvent.CLICK, button_mouseClickHandler);
button.stage.addEventListener(MouseEvent.CLICK, stage_mouseClickHandler, true);
//...
private function button_mouseClickHandler(event:MouseEvent):void
{
trace("Button CLICK");
}
private function stage_mouseClickHandler(event:MouseEvent):void
{
if (event.target == button)
return;
trace("Button CLICK_OUTSIDE");
}
Note that using stopPropagation() is good for one object, but failed for several. This approach works good for me.
Use a stage and a sprite (menu) click listener with the sprite listener executing first and apply the stopPropagation() method to the click handler of the sprite. Like this:
menu.addEventListener(MouseEvent.CLICK, handleMenuClick);
stage.addEventListener(MouseEvent.CLICK, handleStageClick);
private function handleMenuClick(e:MouseEvent):void{
// stop the event from propagating up to the stage
// so handleStageClick is never executed.
e.stopPropagation();
// note that stopPropagation() still allows the event
// to propagate to all children so if there are children
// within the menu overlay that need to respond to click
// events that still works.
}
private function handleStageClick(e:MouseEvent):void{
// put hide or destroy code here
}
The idea is that a mouse click anywhere creates a single MouseEvent.CLICK event that bubbles from the stage, down through all children to the target, then back up through the parents of the target to the stage. Here we interrupt this cycle when the target is the menu overlay by not allowing the event to propagate back up to the parent stage, ensuring that the handleStageClick() method is never invoked. The nice thing about this approach is that it is completely general. The stage can have many children underneath the overlay and the overlay can have its own children that can respond to clicks and it all works.

AS3 NumericStepper Component

I am creating an Actionscript 3 application in Flash CS4. I created a movie clip called dropDown with it exporting for Actionscript as dropDown. Inside this movie clip i dropped a numericStepper Component. I also have a basic movie clip of a box with text that says Add Dropdown exporting for Actionscript as DropDownBtn. Really basic.
the Add Dropdown button creates an instance of the movieclip via an event listener and callback function.
Once the instance is created I cant seem to access the value of the Numeric Stepper. MY code is as follows:
//create the load dropdown button
var newButton = new DropDownBtn();
//position the button
newButton.x = 20;
newButton.y = 20;
//and add it to the stage
addChild(newButton);
//add the event listener to the button
newButton.addEventListener(MouseEvent.MOUSE_DOWN, addDropdown);
function addDropdown(e:MouseEvent):void{
//create and instance of the drop down
var newDropDown = new dropDown();
//move it over beside the add dropdown button
newDropDown.x = newButton.width+40;
newDropDown.y = 20;
//add the instance of the newDropDown to the display stack
addChild(newDropDown);
//add the event listener to the dropdown
newDropDown.addEventListener(Event.CHANGE, useDropDownValue);
}
function useDropDownValue(e:Event):void{
//this is where I need to utilize the value of the Numeric Stepper
//I thought it would be accessed as follows but it doesn't seem to work
//I added a trace to make sure this function is being executed and that works
//when i comment out my attempt at using the Numeric Stepper Value
trace("useDropDownValue Function Accessed");
var dropDownValue = newDropdown.value;
}
you have
var newDropDown = new dropDown();
scoped to inside the addDropdown function
You need to move it outside that function to make it have a global scope
//create the load dropdown button
var newButton = new DropDownBtn();
//position the button
newButton.x = 20;
newButton.y = 20;
//and add it to the stage
addChild(newButton);
//add the event listener to the button
newButton.addEventListener(MouseEvent.MOUSE_DOWN, addDropdown);
// GLOBAL SCOPE HERE
//create and instance of the drop down
var newDropDown = new dropDown();
function addDropdown(e:MouseEvent):void{
//move it over beside the add dropdown button
newDropDown.x = newButton.width+40;
newDropDown.y = 20;
//add the instance of the newDropDown to the display stack
addChild(newDropDown);
//add the event listener to the dropdown
newDropDown.addEventListener(Event.CHANGE, useDropDownValue);
}
function useDropDownValue(e:Event):void{
//this is where I need to utilize the value of the Numeric Stepper
//I thought it would be accessed as follows but it doesn't seem to work
//I added a trace to make sure this function is being executed and that works
//when i comment out my attempt at using the Numeric Stepper Value
trace("useDropDownValue Function Accessed");
var dropDownValue = newDropdown.value;
}
Ok I got it.
I had to reference the instance name of the NumericStepper inside the movie clip. Like this.
var numericStepperValue = movieClip.NumericStepperInstance.value;
thanks for your help.