Movieclip dinamic fields working on flash but not on windows

I have a movieclip that acts like a button. I need to setup a custom field or variable for that button so I can check it on the mouse listeners to know which movieclip is pressed. I’m creating several diferent movieclips at runtime so I need to know which one I’m pressing.

This works on flash target but on windows it says:

openfl.display.MovieClip has no field levelNumber

This is the code example. Not exactly my project code:

    for(i in 0...100)
    {
    var btActive:MovieClip = cast(levelButton.getChildByName("btCarreras"), MovieClip);
    btActive.levelNumber = i;
    btActive.addEventListener(MouseEvent.MOUSE_UP, releaseLevelButton);
    }
    
function releaseLevelButton(e:MouseEvent):Void
    {
    	gotoLevel(e.target.levelNumber);
    }

Gotcha, why don’t you try using the “name” variable? It accepts a String, so you should be able to put in whatever meaning you need to, like “Background” or “Enemy12”

This can work, but I have to make changes to the files. I’m loading the movieclips from a .fla and I have several different buttons on the same screen composition. I’m using the names from the .fla to identify them and It is not allowing to change it latter by code.

Luckily I don’t need the windows build soon so I can wait to change this. ¿Is this going to be fixed or making dynamic fields is something to avoid?

(Thanks for your awesome work in general)

Dynamic access is very slow on C++, this could by adding “implements Dynamic” to the openfl.display.MovieClip class, but I don’t even know what this would do for performance, so I’m trying to think if there is another way. Basically, you can add fields if you create a custom class, for example, if you use the new “generate” option on the SWF library, you can export your AS class types as Haxe classes, so you can do “MyCoolClass extends MySWFSymbolClass” and add fields that way.

Another (possible?) way of going about this, if you cannot change the name, is to use a map, like this:

public var levelNumbers = new Map<String, Int> ();

Then you can store the number:

levelNumbers.set (btActive.name, i);

and look it up later:

gotoLevel(levelNumbers.get(e.target.name));

You could also use the MovieClip itself as the key (so MovieClip instead of String) but you would have to be careful, because that could prevent the object from being garbage collected. That maybe is a better path, but you would need to remove it from the Map when you are ready to remove the object, if you do, but basically it would look like this:

levelNumbers.set (btActive, i);

(and later)

gotoLevel(levelNumbers.get(e.target));

Thanks a lot!

I really like the second solution. I was already using an array to remove the listeners from the buttons so to change it to a map was easy. Also, I learned about maps!

I’m using this to remove them. I hope is enough. It seems to be working fine.

The map is: var activeButtons:Map<MovieClip, Int>;
for (key in activeButtons.keys())
{
key.removeEventListener(MouseEvent.MOUSE_DOWN, clickedButton);
key.removeEventListener(MouseEvent.MOUSE_OVER, clickedButton);
key.removeEventListener(MouseEvent.MOUSE_OUT, outButton);
key.removeEventListener(MouseEvent.MOUSE_UP, releaseLevelButton);
activeButtons.remove(key);
}

Looks good to me! :slight_smile: