Alternative array navigation hack in AS3 not running as defined :( - actionscript-3

for some reasons, this code does not want to work; its supposed to be a convenient alternative to using "arrays" for navigation buttons whereby the clicking of one button removes the click state from the rest -
nav_mc.buttonMode=true;
nav_mc.addEventListener(MouseEvent.MOUSE_OVER, navOver);
nav_mc.addEventListener(MouseEvent.MOUSE_OUT, navOut);
nav_mc.addEventListener(MouseEvent.CLICK, navClick);
nav_mc.nav1_mc.mouseChildren=false;
nav_mc.nav2_mc.mouseChildren=false;
nav_mc.nav3_mc.mouseChildren=false;
nav_mc.nav4_mc.mouseChildren=false;
var currentNav:MovieClip;
function navOver(e:MouseEvent):void {
var navItem:MovieClip=e.target as MovieClip;
trace(navItem.name);
if (navItem!=currentNav) {
navItem.gotoAndStop(2);
}
}
function navOut(e:MouseEvent):void {
var navItem:MovieClip=e.target as MovieClip;
if (navItem!=currentNav) {
navItem.gotoAndStop(1);
}
}
function navClick(e:MouseEvent):void {
var navItem:MovieClip=e.target as MovieClip;
if (currentNav!=null) {
navItem.gotoAndStop(1);
}
currentNav=navItem;
navItem.gotoAndStop(3);
}
please, been on this for hours now, what am I missing out?

My guess is: you should change the navItem variable to the currentNav, inside of the if block here:
if (currentNav!=null) {
navItem.gotoAndStop(1);
}
It looks like you want to make some changes to the current active item (currentNav).
UPD.: My advice is: try to change the code above to the next code
if (currentNav!=null) {
currentNav.gotoAndStop(1);
}
UPD 18-11-2015, Toggle buttons:
It's hard to say if my code works or not (I don't have the whole project to test it), but it looks like it should.
function navClick(e:MouseEvent):void
{
var navItem:MovieClip=e.target as MovieClip;
if (currentNav != null)
{
currentNav.gotoAndStop(1);
}
if(currentNav == navItem)
{
currentNav = null;
}else
{
currentNav = navItem;
navItem.gotoAndStop(3);
}
}

Related

Animate CC HTML5 canvas: how do I create a private/local variable in Actionscript?

I'm using a variable to create a toggle-effect on a function. The only problem is that this code changes the variable globally, and not locally for each object using the function. I know what I have to do, just not how :)
Function:
var count;
function animateTarget($target, $rwFrame) {
this.count = false;
if(!count == true)
{
$target.gotoAndPlay(2);
count=true;
}
else
{
$target.gotoAndPlay($rwFrame); //playback from a different frame
count=false;
}
}
Call:
this.Foo_Btn.addEventListener("click", animateTarget.bind(this, this.Foo_target, 34));
Actually, I got the answer from a friend (here with some updated variable names). Since it's JS, it reads the "clicked" as false, even though this is not stated. And by binding it to the object targetit will check for each separate object that uses this function.
var clicked;
function animateTarget(target, rwFrame) {
if(!target.clicked)
{
target.gotoAndPlay(2);
target.clicked = true;
}
else
{
target.gotoAndPlay(rwFrame);
}
}

how to remove a gallery call when i click in any other button in AS3.0?

so i have this photo gallery with 2 external classes, this code is the timeline code that calls the classes in to import the gallery and make it work.
So far so good, the problem starts when i want to put this photo gallery in a media presentation or website or something with more than 1 layer, it happens that the gallery stays there after being called and increases more gallery's every time i return to that frame with the code.
So i was wondering if its possible create some simple code to add to this one thats says to remove the gallery if im not on frame number 13 or stop calling the classes if im not on that specific frame, something like that.
I tried the "removeChild", it solved half of the problem, it didnt quite removed the gallery but at least stoped the increasing effect.
All i need is a way to remove the gallery when i go to another frame/page.
Can someone help me?
import flashfold.as3.*;
var imgLoader:ImageLoader;
var thumbsToLoad:Array=[];
var menuColumnItems:int=6;
var menuTotItems:int=30;
var menuThumbs:Vector.<Bitmap>=new Vector.<Bitmap>();
var menuBigPics:Vector.<String>=new Vector.<String>();
var menu:SpinnerMenu;
btnSpin.visible=false;
errorBox.wordWrap=true;
errorBox.visible=true;
errorBox.text="Loading thumbnails...";
populatePics();
prepImgs(thumbsToLoad);
function prepImgs(a:Array):void {
imgLoader=new ImageLoader();
imgLoader.addEventListener(ImageLoader.LOAD_ERROR,errorLoading);
imgLoader.addEventListener(ImageLoader.IMGS_LOADED,allLoaded);
imgLoader.loadImgs(a);
}
function errorLoading(e:Event):void {
errorBox.visible=true;
errorBox.text="There has been an error loading images. The server may be busy.";
}
function allLoaded(e:Event):void {
errorBox.visible=false;
initApp();
}
function initApp():void {
var i:int;
for (i=0; i<menuTotItems; i++) {
menuThumbs[i]=imgLoader.bitmapsArray[i];
}
menu=new SpinnerMenu(menuThumbs,menuBigPics,menuColumnItems);
this.addChild(menu);
trace("oi");
menu.x=72;
menu.y=50;
menu.menuInfoBox.x=160;
menu.menuInfoBox.y=90;
this.transform.perspectiveProjection.fieldOfView=70;
this.transform.perspectiveProjection.projectionCenter=new
Point(menu.x+menu.menuWidth/2,menu.y+menu.menuHeight/2);
btnSpin.visible=true;
//We load the initial image.
menu.loadInitial();
}
function populatePics():void {
var i:int;
for (i=1; i<=menuTotItems; i++) {
thumbsToLoad[i-1]="small"+String(i)+".jpg";
}
for (i=1; i<=menuTotItems; i++) {
menuBigPics[i-1]="pic"+String(i)+".jpg";
trace('ok');
btnSpin.addEventListener(MouseEvent.CLICK, spinMenu);
function spinMenu(e:MouseEvent):void {
var r:Number=Math.random();
if (r<0.5) {
menu.doSpin("right");
} else {
menu.doSpin("left");
}
}
}
}
if imgLoader is the gallery that you want deleted then this should help:
if (objectParent.getChildByName("imgLoader") != null) {
trace("imgLoader exsits");
objectParent.removeChild("imgLoader");
}
Basically this is checking if imgLoader exist and if it does, it removes it.

AS3 How to wait for child component to load?

I have a movieclip, we can call it "mc". On my "mc" is a textarea component called "childta". I am creating instances of "mc" with stage.addchild. All is well and going good but when I add a line of code after that to set the text of "childta" it doesnt show up due to the code being executed prior to it being loaded.
I do know I have the code right because if i click the button to set the text of "childta" it does work. So how can I wait for mc.childta to be loaded?
var mcPM:PMBox = new PMBox();
pmwaiting = 1;
mcPM.name = sendername;
stage.addChild(mcPM);
mcPM.x = 200;
mcPM.y = 200;
mcPM.addEventListener(Event.ADDED_TO_STAGE, pmloaded);
}
while(pmwaiting == 1) {
}
MovieClip(stage.getChildByName(sendername)).pmsa.addText(dArray[3]);
mcPM.removeEventListener(Event.ADDED_TO_STAGE, pmloaded);
}
} else {
//Its chat text, add to window
sa.addText(e.data);
}
}
function pmloaded(Event):void {
pmwaiting = 0;
}
Try listening for "ADDED_TO_STAGE"
childta = new TextArea();
childta.addEventListener(Event.ADDED_TO_STAGE,childtaLoaded);
function childtaLoaded(e:Event):void {
//ready to work with
}
addChild(childta);

AS3 Passing Variable Parameters to a generic Function Menu / SubItems

I'm no code genius, but a fan of action script.
Can you help me on this:
I have a function that depending on the object selected, will call event listeners to a set of 'sub-items' that are already on stage (I want to reuse this subitems with changed parameters upon click, instead of creating several instances and several code).
So for each selected 'case' I have to pass diferent variables to those 'sub-items', like this:
function fooMenu(event:MouseEvent):void {
switch (event.currentTarget.name)
{
case "btUa1" :
trace(event.currentTarget.name);
// a bunch of code goes here
//(just cleaned to easy the view)
/*
HELP HERE <--
here is a way to pass the variables to those subitems
*/
break;
}
}
function fooSub(event:MouseEvent):void
{
trace(event.target.data);
trace(event.currentTarget.name);
// HELP PLEASE <-> How can I access the variables that I need here ?
}
btUa1.addEventListener(MouseEvent.CLICK, fooMenu);
btUa2.addEventListener(MouseEvent.CLICK, fooMenu);
btTextos.addEventListener(MouseEvent.CLICK, fooSub);
btLegislacao.addEventListener(MouseEvent.CLICK, fooSub);
Anyone to help me please?
Thank very much in advance. :)
(I'm not sure I got your question right, and I haven't developed in AS3 for a while.)
If you want to simply create function with parameters which will be called upon a click (or other event) you can simply use this:
btUa1.addEventListener(MouseEvent.CLICK, function() {
fooMenu(parameters);
});
btUa2.addEventListener(MouseEvent.CLICK, function() {
fooMenu(other_parameters)
}):
public function fooMenu(...rest):void {
for(var i:uint = 0; i < rest.length; i++)
{
// creating elements
}
}
If you want to call event listeners assigned to something else you can use DispatchEvent
btnTextos.dispatchEvent(new MouseEvent(MouseEvent.CLICK))
Remember, you can't use btTextos.addEventListener(MouseEvent.CLICK, carregaConteudo("jocasta")); because the 2nd parameter you pass while adding Eventlistener will be considered as function itself - there are two proper ways to use addEventListener:
1:
function doSomething(event:MouseEvent):void
{
// function code
}
element.addEventListener(MouseEvent.CLICK, doSomething); //notice no brackets
2:
element.addEventListener(MouseEvent.CLICK, function() { // function code });
So:
function fooSub(event:MouseEvent, bla:String):void
{
trace(event.currentTarget.name+" - "+bla);
// bla would be a clip name.
}
codebtTextos.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) { fooSub(e, "jocasta") } );
Or try something like this if you want content to be dynamically generated:
btUa1.addEventListener(MouseEvent.CLICK, function() {
createMenu(1);
});
btUa2.addEventListener(MouseEvent.CLICK, function() {
createMenu(2);
});
function createMenu(id):void
{
// Switching submenu elements
switch (id)
{
case 1:
createSubmenu([myFunc1, myFunc2, myFunc3]); // dynamically creating submenus in case you need more of them than u already have
break;
case 2:
createSubmenu([myFunc4, myFunc5, myFunc6, myFunc7]);
break;
default:
[ and so on ..]
}
}
function createSubmenu(...rest):void {
for (var i:uint = 0; i < rest.length; i++)
{
var mc:SubItem = new SubItem(); // Subitem should be an MovieClip in library exported for ActionScript
mc.addEventListener(MouseEvent.CLICK, rest[i] as function)
mc.x = i * 100;
mc.y = 0;
this.addChild(mc);
}
}
Your question is rather vague; what "variables" do you want to "pass"? And what do you mean by "passing the variable to a sub item"? Usually "passing" means invoking a function.
If you can be more specific on what exactly your trying to do that would be helpful. In the meantime, here are three things that may get at what you want:
You can get any member of any object using bracket notation.
var mc:MovieClip = someMovieClip;
var xVal:Number = mc.x; // The obvious way
xVal = mc["x"]; // This works too
var propName:String = "x";
xVal = mc[propName] ; // So does this.
You can refer to functions using variables
function echo(message:String):void {
trace(message);
}
echo("Hello"); // The normal way
var f:Function = echo;
f("Hello"); // This also works
You can call a function with all the arguments in an array using function.apply
// Extending the above example...
var fArgs:Array = ["Hello"];
f.apply(fArgs); // This does the same thing
Between these three things (and the rest parameter noted by another poster) you can write some very flexible code. Dynamic code comes at a performance cost for sure, but as long as the frequency of calls is a few hundred times per second or less you'll never notice the difference.

Actionscript 3 drop down menu link error

I'm having issues with the following menu. I've been adapting a script from kirupa into actionscript 3.
When I get to the last level of the menu it won't link properly. It always takes the last url of the bunch as the url for all links in that branch of the tree.
Can anyone help me get it to link properly? A zip with the fla and the xml can be found at the following link.
http://www.jdviz.com/projects/xmlmenu.zip
Thanks,
There's a problem with the closures at the end of the code. The current button is not identified properly.
if (node_xml.childNodes[i].nodeName != "resource") {
//cleared the code for clarity...
} else {
curr_item.arrow.visible = false;
curr_item.addEventListener(MouseEvent.MOUSE_DOWN, function(e:MouseEvent):void {
trace(curr_item.urlLink);
});
}
change the above to:
var currentButton:MenuItem_mc = new MenuItem_mc();
function mouseOverHandler(e:MouseEvent ):void
{
currentButton = e.currentTarget as MenuItem_mc;
currentButton.addEventListener( MouseEvent.CLICK , clickHandler );
}
function clickHandler(e:MouseEvent):void
{
var btn:MenuItem_mc = event.currentTarget as MenuItem_mc;
trace( btn.urlLink );
}
if (node_xml.childNodes[i].nodeName != "resource") {
//cleared the code for clarity...
} else {
curr_item.arrow.visible = false;
curr_item.addEventListener(MouseEvent.MOUSE_DOWN, mouseOverHandler );
}