2011-09-28 53 views
2

我有一個16x16的按鈕網格,並且希望爲每個按鈕添加一個事件監聽器,因此單擊它時將返回其唯一的網格位置編號(0到255之間的任何值); 我有什麼至今:動態地將參數傳遞給事件監聽器AS3

public static const GRID_SIZE:Number = 16; 
    private var i:int; 
    private var j:int; 

    // Constructor 
    public function Grid() 
    { 
     for (i = 0; i < GRID_SIZE; i++) 
     { 
      for (j = 0; j < GRID_SIZE; j++) 
      { 
       // Creates new instance of GridButton, a custom class that extends SimpleButton 
       var button:GridButton = new GridButton(); 

       // Arranges buttons into a grid 
       button.x = (i + 1) * button.width; 
       button.y = (j + 1) * button.height; 

       // Create unique value for grid position 
       var position:Number = i * GRID_SIZE + j; 

       // Add listener to button, with position as extra param 
       button.addEventListener(MouseEvent.CLICK, function(e:MouseEvent) : void { buttonClick(e, position) }); 

       // Adds button to Sprite 
       addChild(button); 
      } 
     } 
    } 
} 

不幸的是每一個聽者的功能是由每個按鈕調用的時候,它使用i和j的最後兩個值,它在每一個按鈕這種情況下返回255。

有什麼建議嗎?

+0

您也可以使用閉包。檢查我的答案以下問題:http://stackoverflow.com/questions/7396845/how-to-use-a-method-of-a-class-inside-a-callback-function-in-actionscript/7412402# 7412402 –

+0

除非您完全理解使用閉包的後果,否則不應使用它們。 –

回答

1

你可以添加一個名字到該按鈕,例如button.name = "button" + position;和事件處理函數,你可以提取目標名稱(e.target.name)位置參數:

button.name = "button" + position; 
button.addEventListener(MouseEvent.CLICK, buttonClick); 

和事件處理程序:

function buttonClick(e:MouseEvent) { 
    var position:Number = Number(e.target.name.replace("button", "")); 
    // ... do wathever you want with position parameter 
} 
0

您可以從用於將x和y值分配給按鈕的相同表達式中獲取i和j的值。例如:

button.addEventListener(MouseEvent.CLICK, clickHandler); 

function clickHandler(e:MouseEvent) { 
    var i:int = (e.target.x/e.target.width) - 1; 
    var j:int = (e.target.y/e.target.height) - 1; 

    var position:Number = i * GRID_SIZE + j; 
} 
1

還有一些其他的選擇...

使用signals而不要使用閃光燈事件監聽器,here's a post描述它,並給出更多的細節。另外一個video tutorial讓你快速入門。我提出這個建議的原因是你可以設置一個信號來傳遞一個參數,所以你不需要使用事件目標,它並不總是最好的。

使用功能工廠。

// factory: 
public function fooFactory($mc:GridButton):Function{ 
    var $f:Function = new Function($e:MouseEvent):void{ 
     trace($mc.x, $mc.y); 
    } 
    // you might want to consider adding these to a dictionary or array, so can remove the listeners to allow garbage collection 
    return $f; 
} 


// then assign the function to the button like this 
button.addEventListener(MouseEvent.CLICK, fooFactory(button)); 

這樣做基本上是你想要做什麼,但它會工作,因爲position VAR沒有改變。在你的代碼中,position每次循環執行時都會改變,然後當你啓動監聽器函數時,它會使用最後一個值position被賦值,這就是爲什麼你得到了255的全部值。讓我知道如果這是沒有意義的...

0

我試過這個,它工作得很好....即。點擊不同的文本字段追蹤不同的值。 的想法是創建一個新的參考POS:號碼,這樣即使更新POS機後,關閉仍指向舊

package 
{ 
    import flash.display.Sprite; 
    import flash.events.MouseEvent; 
    import flash.text.TextField; 
    import flash.text.TextFieldType; 

    public class AsDing extends Sprite 
    { 
     private static const GRID_SIZE:uint = 2; 
     public function AsDing() 
     { 
      for(var i:uint=0; i<GRID_SIZE; i++) 
      { 
       for(var j:uint=0; j<GRID_SIZE; j++) 
       { 
        var tf:TextField = new TextField(); 
        var pos:Number = i*GRID_SIZE + j; 
        tf.text = pos.toString(); 
        tf.type = TextFieldType.DYNAMIC; 
        tf.addEventListener(MouseEvent.MOUSE_DOWN, createMCHdlr(pos)); 
        addChild(tf); 
        tf.x = i*100; tf.y = j*100; 
       } 
      } 
     } 

     private function createMCHdlr(pos:Number):Function 
     { 
      var ret:Function = function(evt:MouseEvent):void 
      { 
       trace('pos: ' + pos); 
      }; 
      return ret; 
     } 
    } 
} 
1

通過使用匿名函數內部,從外部範圍的變量你有大麻煩已關閉和內存泄漏:position用於function(e:MouseEvent),但它創建於function Grid(),因此它會服從function Grid()的更改。你正在處理你添加的256 function(e:MouseEvent),但無法刪除,重載內存!

讓我們重拍你的代碼最簡單的工作方式:

public static const GRID_SIZE:Number = 16; 
private var i:int; 
private var j:int; 

public function Grid() { 
    var functions:Object; 

    for (i = 0; i < GRID_SIZE; i++) { 
    for (j = 0; j < GRID_SIZE; j++) { 
     var button:GridButton = new GridButton(); 
     button.x = (i + 1) * button.width; 
     button.y = (j + 1) * button.height; 
     var position:Number = i * GRID_SIZE + j; 
     functions[position] = buttonClick(position); 
     button.addEventListener(MouseEvent.CLICK, functions[position]); 
     //button.removeEventListener(MouseEvent.CLICK, functions[position]); 
     addChild(button); 
    } 
    } 

    buttonClick(position:Number):Function { 
    return function(e:MouseEvent):void { 
     // Now you can use both unique "e" and "position" here for each button 
    } 
    } 
} 

既然你加入256名的聽衆,你需要存儲每個不同的變量(屬性functions[position]的名單爲它寫了),所以你可以安全刪除每個後面以釋放內存以您添加它們的相同方式。

這是從this answer詳細闡述的。

相關問題