2012-07-14 75 views
1

我正在編寫一個帆布賽車遊戲,並計劃使用事件來確定每個遊戲對象何時被初始化並可以使用。首先,我嘗試將事件偵聽器添加到我的對象,但意識到它們只能附加到html元素。作爲解決方法,我添加了一個偵聽器到窗口對象。確定對象何時準備就緒。我應該使用事件嗎?

我會很感激我是否應該爲這個問題使用事件,以及是否有任何常見的模式/方法,我應該看看?我正在閱讀觀察者模式,這是否適合這種情況?

下面的代碼片段顯示了我目前正在做的事情。當Track對象的所有項目都被加載後,它將調度由附加到窗口對象的事件偵聽器捕獲的事件。

主營:

function game() { 
    var loadCount = 0; 
    var itemsToLoad = 10; 

    window.addEventListener("finishedLoading", itemLoaded, false);  
    function itemLoaded(event) { 
    loadCount++; 
    if(loadCount >= itemsToLoad) 
    { 
     gameStateFunction = title; 
    } 
    } 
} 

跟蹤對象:

function Track(name, bgTileSheet) { 
    this.backgroundImage = new Image(); 
    this.itemsLoaded = 0; 
    this.itemsToLoad = 3; 
    this.loadedEvent = new CustomEvent("finishedLoading", { 
    detail: { 
     objectType: "track" 
    }, 
    bubbles: true, 
    cancelable: false 
    }); 

    this.centerPath = null; 
} 

Track.prototype.updateLoadProgress = function() { 
    this.itemsLoaded++; 
    if(this.itemsLoaded >= this.itemsToLoad) 
    { 
    dispatchEvent(this.loadedEvent); 
    } 
}; 

Track.prototype.init = function() { 
    //calls loadItems() when XML data is ready 
}; 

Track.prototype.loadItems = function() { 
    this.loadBackground(); 
    this.loadMapDimensions(); 
    this.loadPaths(); 
}; 

Track.prototype.loadBackground = function() { 
    var self = this; 
    this.backgroundImage.addEventListener("load", 
    function() { 
     self.updateLoadProgress(); 
    }, 
    false);  
    this.backgroundImage.src = Track.TILESHEET_DIR + this.bgTileSheet; 
}; 

回答

0

是的,我要說的事件是去與像這樣的方式。只是你不得不放鬆你對事件的定義,使其不能僅僅附屬於HTML元素。

你最終會用到這種事情的大多數模式 - 觀察者,訂閱者,調停者,無論如何 - 都會使用某種意義上的事件形式。

你可能想要考慮的一件事是jQuery的延期對象。這些通常與AJAX相關聯,但也可以以非常有效的方式與人爲的主觀事件一起使用。

我寫了a blog post這在幾個月前就顯示了這個技術。

下面是一個簡單示例:

function SomeClass() { 
    this.ready = false; 
    this.deferred = $.Deferred(); 
} 
SomeClass.prototype.makeReady = function() { 
    this.ready = true; 
    this.deferred.resolve(); 
} 
var myInstance = new SomeClass(); 

//listen for ready 
$.when(myInstance.deferred).done(function() { alert('object is ready!'); }); 

//after a while, let's say we're ready 
setTimeout(function() { myInstance.makeReady(); }, 2000); 

這裏的超時只是你的真實環境的模擬,你將設立目標 - 做AJAX請求,其他代碼,等等。

最後,儘管您確實無法直接將事件附加到對象,但可以通過getters/setters將對象附加到對象屬性。