2014-01-15 2 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 포함). 내 문제는 내가이 변화를 만들 때, 애니메이션이 '이것'의 인스턴스를 잃어 버렸고 더 이상 그 속성을 기반으로 애니메이션을 만들 동전의 특정 인스턴스를 찾을 수 없다는 것입니다.

다른 개발자의 아이디어가 있습니까?

답변

1

슈퍼 마리오 클론을 제작한다고 가정합시다. 이 문제를 해결할 수있는 방법은 클래스를 사용하는 것입니다.이 클래스에는 MarioCoin 인스턴스가 있습니다.

Coin 클래스에 "틱"수신기가있는 대신 World 클래스에서 만듭니다. 그런 다음 대리자 유틸리티를 사용하여 틱 이벤트 처리기의 범위를 World 인스턴스로 지정합니다. 그런 다음 동전을 통해 Mario와의 충돌을 확인하고 필요할 때마다 애니메이션을 적용 할 수 있습니다. 필자가 작성한 다음 예제와 보너스 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; 
}()); 
입니다 약속 할 수