2014-01-15 2 views
0

Я создаю фрагмент анимации с использованием EaselJS и сталкиваюсь с проблемой наследования Inheritance при попытке объявить объекты многократного использования.EaselJS Inheritance - рефакторинг для объявления единой анимации

Например, в моей части анимации я хочу нарисовать несколько монет в разных точках на холсте, а затем оживить указанную монету.

Это как мой код выглядит на данный момент:

(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); 
} 

Теперь уточнить - этот кусок кода делает работу - однако я чувствую, что это может быть лучше выполнена. В идеале я хотел бы иметь возможность объявить функцию, которую запускает event-приемник один раз (например, как у меня c.initialize, c.animate). Моя проблема в том, когда я делаю это изменение, анимация теряет экземпляр «этого», и я больше не могу найти конкретный экземпляр монеты для анимации на основе ее свойств.

Любые идеи разработчиков-разработчиков?

ответ

1

Предположим, вы делаете клон Super Mario. То, как я бы справился с этим, было бы иметь класс World, в котором размещались Mario и Coin экземпляров.

Вместо того, чтобы прослушивать «тиканье» в классе монет, создайте его на классе World. Затем, используя утилиту делегата, разверните обработчик событий тика на экземпляр 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; 
}()); 
Смежные вопросы