2015-06-06 44 views
3

我試圖決定在遊戲中爲物體繪製圖像的幾種方式。性能加載圖像遊戲類

我希望對象擁有自己的draw()方法,但是恐怕我可能會導致不必要的圖像副本或其他效率下降,明顯與否。

第一種方法是在關卡開始時加載BufferedImages

public class levelone{ 

    BufferedImage imageguy; 

    public void draw(Graphics2d g){ 
     g.drawImage(imageguy, null, guy.getx(), guy.gety()); 
    } 

} 

第二種方式加載在guy.class圖像,並從那裏與剛剛在levelone.class一個guy.draw(g);呼叫吸引它。

第三種方式在levelone.class中加載圖像,並在levelone.class中僅從guy.draw(imageguy, g);中從guy.class中繪製它。

請幫我理解最好的方法去請這個。如果我不清楚我在問什麼,請告訴我,我會嘗試使其更容易理解。

回答

0

這更像是一個設計問題。一開始,這個:

...效率有些下降,明顯與否。

...不是一種非常健康或富有成效的思維方式。如果它不是不明顯,這是不值得擔心的。否則,如果你想要在每個時鐘週期內着迷,你可能會用匯編代碼編寫你的遊戲。

但是這裏可能會有更廣泛的規模設計級可擴展性問題。

值得注意的是,將渲染/繪製邏輯與高級類耦合可能成爲維護負擔。這取決於您的項目範圍,但如果它是一個相當大的項目,如果將繪圖/渲染邏輯與遊戲邏輯分開,則會有更多的呼吸空間。然後,您可以全神貫注地注意到,從遊戲設計的角度來看,「怪物」或「物品」或類似的東西需要做什麼,而不用擔心它會如何繪製。繪圖在其他地方完成。

但是,如果我們假設您希望在這些對象內部具有繪圖邏輯,那麼您的問題似乎最終歸結爲您要在遊戲中存儲與圖形相關的圖形緩衝區的位置。

簡短的回答是,「這取決於」。你覺得自信有什麼假設?例如,在您貼出的代碼:

public void draw(Graphics2d g){ 
    g.drawImage(imageguy, null, guy.getx(), guy.gety()); 
} 

...這個,如果你會永遠做是塊傳送對象圖像圖形似乎有點可笑。如果你所要做的只是將物品的圖像粘貼到圖形上,那麼你可以直接消除draw方法,將公共訪問者暴露給圖像,並讓一箇中心位置負責將這些圖像傳送給正確的時間和地點。在這一點上,如果你所做的只是存儲圖像並在你的對象中公開訪問者,那麼你不妨讓外部世界關心加載/存儲這些圖像並將它們傳遞給它們,讓你的對象清潔,完全沒有繪製邏輯。這也會給你最大的靈活性來優化什麼時候以及如何繪製事物,而不會干涉所有的對象。

但是,你總是要從一個物體blit圖像嗎?會不會有遊戲中的物體可能吸引更多東西,形狀,文字等?如果是這樣,您可能需要保留draw方法。

所以對我來說最終的問題是,你真的想在你的物體內繪畫嗎?

  1. 如果沒有,那麼你將有最大的靈活性來優化你的心臟的內容,因爲你可以離開的最有效地加載和存儲和繪製圖形核心渲染引擎,而不是傳播的責任的責任覆蓋遊戲中的每個對象(如果您想要以不同的方式執行操作,可能需要更改全部)。如果你確實需要這個,那麼你可以完全地封裝一個對象在對象內部渲染的所有細節,包括保持它需要做的任何資產,這樣外部世界就不必擔心了有了它,只需調用'draw'並傳入一個繪圖目標(例如Graphics2D)即可。

所以我建議你可能沒有任何建議可能是理想的。但是如果有一個選項可能不好,我會說這是你的第三個選項。那就是:

第三種方式加載圖像中levelone.class和從 guy.class只需guy.draw(imageguy,G)繪製它;在levelone.class中。

這裏的問題是,你有兩種世界中最糟糕的。你將這個「傢伙」的繪畫細節泄漏到外部世界,但外部世界仍然需要依靠「傢伙」通過將這些繪畫細節傳回來進行繪製。如果沒有其他的東西,你想真的給這個人或外部世界的主要責任在這裏,後者更靈活,但前者更加封閉。當外部世界必須把一個人的形象傳遞給那個人來畫畫的時候,那麼你就沒有獲得這些好處。如果你真的想要一個人「自己畫畫」,那麼你通常希望能夠在沒有外部幫助的情況下做到這一點。給一個實體承擔公司責任,而不是將其分散在多個實體中。

關於相同圖像的不必要副本,無論您使用中央圖像緩存如何處理,都可以輕鬆解決。一個簡單的方法就是使用地圖。加載圖像時,在地圖上搜索路徑。如果它已經存在,則返回對已經加載的圖像的引用。否則,加載圖像並將該路徑/圖像作爲鍵/值對插入到地圖中。