【问题标题】:EaselJS Inheritance - refactoring to allow for single animation declarationEaselJS 继承 - 重构以允许单个动画声明
【发布时间】:2014-01-15 18:25:05
【问题描述】:

我正在使用 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”的实例,并且我无法再定位硬币的特定实例以根据其属性进行动画处理。

开发者有什么想法吗?

【问题讨论】:

    标签: javascript animation easeljs createjs


    【解决方案1】:

    假设您正在制作超级马里奥克隆。我处理这个问题的方法是创建一个 World 类,其中包含 MarioCoin 实例。

    不要在 Coin 类中使用“tick”侦听器,而是在 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;
    }());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      • 2016-07-20
      • 2019-07-16
      • 2014-10-07
      • 2019-08-10
      相关资源
      最近更新 更多