2014-01-15 22 views
0

我使用EaselJS創建動畫片段,並且在嘗試聲明可重用對象時遇到了繼承問題。EaselJS繼承 - 重構以允許單個動畫聲明

例如,在我的動畫片中,我想在畫布上的不同點繪製多個硬幣,然後爲所述硬幣添加動畫。

這是我的代碼看起來像此刻:

(function() { 

var Coin = function(container) { 
    this.initialize(container); 
} 

var c = Coin.prototype = new createjs.Container(); 

c.Container_initialize = c.initialize; 

c.initialize = function() { 
    this.Container_initialize(); 

    var coinInstance = this, 
    coin = new createjs.Bitmap(loader.getResult('coin')); 

    createjs.Ticker.addEventListener('tick', function() { 
     var characterBitmap = character.children[0].children[0]; 
     var coinBitmap = coinInstance.children[0], 
     collided = ndgmr.checkPixelCollision(characterBitmap, coinBitmap); 

     if(collided && coinInstance.alpha == 1) { 
      createjs.Tween.get(coinInstance).to({y: coinInstance.y-100, alpha: 0}, 300); 
     } 

    }); 

    this.addChild(coin); 
} 

window.Coin = Coin; 

}()); 

function drawCoin(container, positionX, positionY) { 
    var coin = new Coin(); 
    coin.x = positionX; 
    coin.y = positionY; 

    container.addChild(coin); 
} 

我們澄清 - 這段代碼確實工作 - 但是我覺得它可以更好地執行。理想情況下,我希望能夠聲明事件偵聽器觸發一次的函數(例如,我如何擁有c.initialize,具有c.animate)。我的問題是,當我做這個改變時,動畫失去了'this'的實例,我不能再根據它的屬性找到硬幣的具體實例來設置動畫。

任何想法的開發人員?

回答

1

我們假設你製作的是超級馬里奧克隆。我處理這個問題的方法是創建一個World類,它包含Mario和​​實例。

與其讓硬幣類中的「滴答」偵聽器在World類中創建它。然後,使用委託實用程序,將tick事件處理程序的範圍限制爲World實例。然後,您可以循環查看硬幣,檢查是否與馬里奧相撞,並根據需要爲其設置動畫。考慮下面的例子和我寫的獎金Delegate實用程序。

這裏的好處是,您不必跟蹤可能導致內存泄漏和性能問題的所有硬幣刻度線偵聽器。其次,通過委派事件監聽器,您不再需要破解查找所需的DisplayObject。即character.children[0].children[0]

聲明,我沒有執行這個代碼,所以我不能保證它沒有錯誤

World.js

(function() { 

var World = function(container) { 
    this.initialize(container); 
} 

var p = World.prototype = new createjs.Container(); 

p.Container_initialize = c.initialize; 

p.character; 
p.coins = []; 

p.initialize = function() { 
    this.Container_initialize(); 

    //Create Mario 
    this.character = new Mario(); 
    this.addChild(this.character); 

    //Create 100 coins in a horizontal row 
    var xPos = 0; 
    for(var i = 0; i < 100; i++){ 
     var coin = new Coin(); 
     coin.x = xPos; 
     this.coins.push(coin); 
     this.addChild(coin); 
     xPos += 100; 
    } 

    //Scope the tick listener to 'this', being the instance of the World class. 
    createjs.Ticker.addEventListener('tick', ns.Delegate.create(this, this.ticker_Tick)); 
} 

p.ticker_Tick = function(){ 
    //Since we have scoped this function to 'this' we can reference the World properties using 'this'; 
    for(var i = 0; i < this.coins.length; i++){ 
     var coin = this.coins[i]; 
     var collided = ndgmr.checkPixelCollision(this.character, coin); 
     if(collided){ 
      //You may want to add an on complete handler here to remove the coin once animated off 
      createjs.Tween.get(coin).to({y: coin.y-100, alpha: 0}, 300); 
     } 
    } 
}; 

window.World = World; 

}()); 

Delegate.js

this.ns = this.ns || {}; 

(function(){ 
    var Delegate = function(){ 
     throw new Error("Cannot directly instantiate Delegate. Use Delegate.create()"); 
    } 

    Delegate.create = function(contextObject, delegateMethod){ 
     return function() { 
      return delegateMethod.apply(contextObject, arguments); 
     } 
    } 

    var p = Delegate.prototype; 

    ns.Delegate = Delegate; 
}());