0

I'm having real trouble trying to access the symbol dynamically, I have 9 buttons that all call this method, and they pass in their location (tl, t, tr, etc.) I've tried this method before on another program and it works without a problem, but in this program it fails.

I am attempting to access a symbol call s_tl (example location), but all I'm getting is undefined (see results).

function turn(btn : String):Function {
return function(e:MouseEvent) {
    var players_turn : int;
    var chosen : String = "s_" + btn;

    trace(this);
    trace(this[chosen]);
    trace(chosen);
    trace(this[chosen]);
    // if crosses turn 0 else 1
    if (s_c.currentFrame == 1) {
        players_turn = 0;
    } else {
        players_turn = 1;
    }       

    // check who's turn it is if it's been pressed before
    if (players_turn == 0 && this[chosen].visible == false) {
        this[chosen].gotoAndStop(1);
        this[chosen].visible = true;
    } else {
        this[chosen].gotoAndStop(2);
        this[chosen].visible = true;
    }
};
}

Results:

[object global]
undefined
s_br
undefined
TypeError: Error #1010: A term is undefined and has no properties.
    at MethodInfo-6()
Zachary
  • 65
  • 1
  • 11
  • I am tracing a new string which is '"s_" + btn' that will then give me the name of the object I am trying to access? – Zachary Feb 25 '17 at 17:46
  • On my keyframe, there are symbols with these names. s_br is a symbol and I thought you had to do this[s_br] ? – Zachary Feb 25 '17 at 18:19
  • I don't think I know what 'this' does, I though it was an object that held all of the objects in the keyframe. if not, how do I access one of said objects? – Zachary Feb 25 '17 at 18:25

1 Answers1

1

Your problem is the bad code style. You define unnamed unbind function inside function turn() and that's where the root of your problem is. Unbind function exist, as your trace shows, in global addressing context and, unlike function turn(), is not bind to any specific display object. Your buttons probably exist on the same addressing context with turn(). Argument btn is available inside unnamed function because ECMA standard instructs so (if function A creates function B then local variables, including arguments, of A are available as local variables in B), but it is a very very very bad practice that makes code messy and induce headaches.

Please explain what you tried to achieve with that code so we could untangle it and rewrite in not-so-twisted way.

Okey, I basically figured you're doing Tic Tac Toe. Now, guideline. A cell must contain 3 frames: 1st frame for the button graphics, 2nd and 3rd for X and O. Name them your way: s_1, s_2, etc.

for (var i:int = 1; i < 10; i++)
{
    var aCell:MovieClip = getChildByName("s_" + i) as MovieClip;
    aCell.addEventListener(MouseEvent.CLICK, onTic);
}

function onTic(e:MouseEvent):void
{
    var playersTurn:int = s_c.currentFrame;
    var aCell:MovieClip = e.currentTarget as MovieClip;

    trace(aCell.name);

    // Now, the magic.
    aCell.gotoAndStop(playersTurn + 1);
    aCell.removeEventListener(MouseEvent.CLICK, onTic);
}
Organis
  • 7,243
  • 2
  • 12
  • 14
  • I've coded it like that so I can avoid making 9 separate event functions, this way I use one function and pass in an "id" so to speak, then I can check which button was pressed and display the correct symbol. P.S. I've never coded anything in ActionScript before now – Zachary Feb 25 '17 at 19:02
  • Field e.currentTarget contains the origin of the event. If you subscribe one method for 9 buttons you can tell which one was pressed. – Organis Feb 25 '17 at 19:06
  • Not so long ago I did explain the same thing: http://stackoverflow.com/questions/42408816/hovering-off-dpad-sometimes-makes-character-move-infinitely-in-one-direction/42421460#42421460 – Organis Feb 25 '17 at 19:07
  • Okay this worked, however I was trying to avoid the use of a large switch at the same time, I don't seem to be able to access that name of the currentTarget to change it to "s_#" and use this[string]. it would save the 9 case long switch statement and reduce it to the assignment of a string. or should I avoid this? also, thank you, that last thing was very helpful – Zachary Feb 25 '17 at 19:35
  • @Zachary Do you need to turn it into string? Because if you want to work with the pressed object, just typecast it to a variable, for example **var aButton:MovieClip = e.currentTarget as MovieClip;** – Organis Feb 25 '17 at 21:49
  • Otherwise you can access its instance name by **(e.currentTarget as DisplayObject).name** – Organis Feb 25 '17 at 21:50
  • @Zachary I figured what you wanted to do and make edit. I think this will work for you. – Organis Feb 25 '17 at 22:16
  • Thank you for the help, that's definatly made my life easier. – Zachary Feb 26 '17 at 18:25