让很多按钮共享一个功能的简单方法? AS3

Easy way to make a lot of buttons share a function? AS3

我正在尝试在 Flash 中制作一个简单的发光钉板。我已经完成了 1 个钉子的一般逻辑,但总共会有 2,300 个钉子,我不想为每个动画片段添加一个事件侦听器。

这是我的代码:

import flash.events.Event;
var my_color:ColorTransform = new ColorTransform();
movieClip_1.addEventListener(MouseEvent.MOUSE_UP, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{

    if (my_color.color == 0)
    {
        my_color.color = 0x0000FF;
        event.target.transform.colorTransform = my_color;
    }
    else if (my_color.color == 255)
    {
        my_color.color = 0x00FF00;
        event.target.transform.colorTransform = my_color;
    }
    else if (my_color.color == 65280)
    {
        my_color.color = 0xFF0000;
        event.target.transform.colorTransform = my_color;
    }
    else if (my_color.color == 16711680)
    {
        my_color.color = 0xFFFFFF;
        event.target.transform.colorTransform = my_color;
    }
    else if (my_color.color == 16777215)
    {
        my_color.color = 0x000000;
        event.target.transform.colorTransform = my_color;
    }
    else
    {
        trace(my_color.color);
    }   
}

[

这里有 3 种方法可以做到这一点:

  1. 将代码放在挂钩自己的时间轴上。 (或制作一个 class 文件,并将其附加到您的挂钩对象)。这将为每个挂钩实例自动 re-use 相同的代码。只需使用您拥有的相同代码,但使用 this 关键字而不是对影片剪辑的硬引用:

    var my_color:ColorTransform = new ColorTransform();
    this.addEventListener(MouseEvent.MOUSE_UP, fl_MouseClickHandler);
    function fl_MouseClickHandler(event:MouseEvent):void
    {
        //.....
    
  2. 创建一个容器 Sprite/MovieClip 并让所有钉子成为它的唯一子项。然后遍历该容器的所有子项并附加监听器:

    //loop through all children of the container and add an event listener
    var i:int = container.numChildren;
    
    while(i--){
        container.getChildAt(i).addEventListener(....);
    }
    

    这很好,因为您不必给它们实例名称,这会很乏味。

  3. 将点击侦听器附加到所有定位钉的公共父级,并使用事件的目标 属性 查看点击是否在定位钉上。 假设你有 right-clicked 你的 peg 库对象,转到属性并检查 "export for actionscript" 并给它 Class 名称 "MyPeg",你可以这样做:

    commonParent.addEventListener(MouseEvent.CLICK, parentClick);
    
    function parentClick(e:Event):void {
        if(e.target is MyPeg){
            //it's a PEG, do something
        }
    }
    

    现在,根据您的 peg 对象的结构,target 也可以引用您的 peg 的子对象(而不是 peg 本身)。为避免这种情况(如果适用),您可以在挂钩的子项上禁用鼠标输入。所以在你的 peg 对象的第一帧,你可以这样:this.mouseChildren = false;


现在,更好(不那么乏味)的是也通过代码实例化您的钉子。因此,如前所述,在其属性中导出用于 actionscript 的挂钩,并为其指定一个 class 名称(在我的示例中为“MyPeg”)。然后沿着这些方向:

var curRow:int = 0;
var curCol:int = 0;

var totalRows:int = 25;
var totalCols:int = 92;

var startingY:int = 10;
var startingX:int = 10;

var padding:int = 2; //gap between pegs

var curPeg:MyPeg;

while(true){
    //create the peg, and add it to the display.
    curPeg = new MyPeg();
    addChild(curPeg);

    //add the click listener to this peg
    curPeg.addEventListener(MouseEvent.CLICK, fl_mouseClickHandler);

    //assign the position of this peg
    curPeg.x = startingX + (curCol * (curPeg.width + padding));
    curPeg.y = startingY + (curRow * (curPeg.height + padding));

    //increment the column
    curCol++;

    //check if we've reached the last column in the row
    if(curCol >= totalCols - 1){
        //yes, so reset the column to 0 and increment the row
        curCol = 0;
        curRow++;

        //break out of the loop if the curRow exceeds or is equal to the total rows var
        if(curRow >= totalRows) break;
    }
}

这样您就可以通过修改分配给 totalColstotalRows 的数字来更改网格大小 - 无需在 FlashPro 中乏味地移动 2300 个对象。

一种方法是遍历 2300 个钉子的父项的所有子项。

for (var i:int=0; i<numChildren; i++) {
  var clip = getChildAt(i);
  if (clip.name.indexOf('movieClip_')==0) {
     clip.addEventListener((MouseEvent.MOUSE_UP, fl_MouseClickHandler);
  }
}

另一种方法是将处理程序添加到整个父剪辑,然后在处理程序中检查并查看单击的内容是否是您的一个钉子。但是您必须在子剪辑上禁用 mouseChildren 才能正常工作。

请注意,您可能希望将那个大的 if/then 语句替换为 switch/case,这在这种情况下更清晰、更紧凑。