2014-07-03 87 views
3

我正在爲一家公司開發遊戲。我只會開發這個遊戲2個月。我的公司要求我使我的代碼乾淨並且可擴展,以便他們可以在需要添加更多功能時僱用另一位程序員。我已閱讀Bob叔叔的Clean Code。我發現將一些概念付諸實踐真的很難。這是我的課遊戲編程中的課堂設計

public class MenuScreen extends ScreenAdapter { 

private final Game game; 

private Stage stage; 
private Actor groundActor; 
private Actor skyActor; 
private Actor titleActor; 
private Actor playbtnActor; 
private Actor optionbtnActor; 

public MenuScreen(Game _game) { 
    this.game = _game; 
} 

@Override 
public void show() { 

    this.stage = new Stage(new ScreenViewport()); 

    createGround(); 
    createSky(); 
    createTitle(); 
    createPlayButton(); 
    createOptionButton(); 
    setupStage(); 

    Gdx.input.setInputProcessor(this.stage); 

} 

public void createGround() { 
    TextureRegion groundTextureRegion = Assets.instance 
      .getTextureRegionByName("bg-ground"); 
    this.groundActor = new SRActor(groundTextureRegion); 
    this.groundActor.setPosition(0, 0); 
} 

public void createSky() { 
    TextureRegion skyTextureRegion = Assets.instance 
      .getTextureRegionByName("bg-sky"); 
    this.skyActor = new SRActor(skyTextureRegion); 
    this.skyActor.setPosition(0, 0); 
} 

public void createTitle() { 
    TextureRegion titleTextureRegion = 
      Assets.instance.getTextureRegionByName("etc-gametitlebanner"); 
    this.titleActor = new SRActor(titleTextureRegion); 

    int bottomLeftX = (int) ((Gdx.graphics.getWidth() - this.titleActor 
      .getWidth())/2); 
    int bottomLeftY = (int) Math.floor(0.6 * this.groundActor.getHeight()); 
    this.titleActor.setPosition(bottomLeftX, bottomLeftY); 
} 

public void createPlayButton() { 

    TextureRegion playbtnTextureRegion = 
      Assets.instance.getTextureRegionByName("etc-playbtn"); 
    this.playbtnActor = new SRActor(playbtnTextureRegion); 

    int bottomLeftX = (int) (0.01 * this.playbtnActor.getWidth()) 
      + (Gdx.graphics.getWidth() - (int) this.playbtnActor.getWidth()) 
      /2; 
    int bottomLeftY = (int) (this.titleActor.getY() + 0.25 * this.titleActor 
      .getHeight()); 
    this.playbtnActor.setPosition(bottomLeftX, bottomLeftY); 
} 

public void createOptionButton() { 
    TextureRegion optionbtnTextureRegion = Assets.instance 
      .getTextureRegionByName("etc-optionbtn"); 
    this.optionbtnActor = new SRActor(optionbtnTextureRegion); 

    int bottomLeftX = (int) (0.01 * this.optionbtnActor.getWidth()) 
      + (Gdx.graphics.getWidth() - (int) this.optionbtnActor 
        .getWidth())/2; 
    int bottomLeftY = (int) (this.titleActor.getY() + 0.05 * this.titleActor 
      .getHeight()); 
    this.optionbtnActor.setPosition(bottomLeftX, bottomLeftY); 

} 

public void setupStage() { 

    this.stage.addActor(this.skyActor); 
    this.stage.addActor(this.groundActor); 
    this.stage.addActor(this.titleActor); 
    this.stage.addActor(this.playbtnActor); 
    this.stage.addActor(this.optionbtnActor); 

} 

@Override 
public void render(float delta) { 
    this.stage.act(Gdx.graphics.getDeltaTime()); 
    this.stage.draw(); 
} 

@Override 
public void resize(int width, int height) { 
    this.stage.getViewport().update(width, height, true); 
} 

@Override 
public void hide() { 
    dispose(); 
} 

@Override 
public void dispose() { 
    this.stage.dispose(); 
} 

}

我的問題是這是否違反類單一職責原則之一嗎?我是否需要將每個演員分配給自己的班級?如果是這樣,我應該如何重構我的代碼?

+0

有很多存在的遊戲框架(JGame是2D遊戲不錯)。第一次試圖設計「可擴展性」是非常困難的 - 老闆們要求它,但是直到你真的需要擴展並且你知道以什麼方式,你可能犯了錯誤並且浪費了你的努力。我建議你先看看現有的框架。 – Fuhrmanator

回答

1

這對我來說似乎沒問題。如果你所有不同的演員都有相同的行爲,並且只在使用的紋理,大小,位置等方面有所不同,那麼使用具有不同屬性的單個SRActor似乎是合適的。

但是我會建議你使用靜態工廠模式,並將代移到另一個類。所以你只會舉例stage.addActor(SRActorFactory.createOptionButton())

+0

感謝您的回答。我發現你的答案真的很有幫助。如果我有另一個屏幕使用與此相同的背景會怎麼樣?我需要一個單獨的工廠還是隻需要一個工廠?例如,我有MenuObjectFactory產生上述演員,我有另一個工廠「OptionObjectFactory」產生相同的地面,天空和一些獨特的演員,如volumeSlider? – kevinyu

+1

這取決於你創建的這些演員是如何分組的。你應該擁有一個屬於一組東西的工廠,就像你主菜單中的所有按鈕一樣。但是你在這裏很自由,你也可以將所有這些靜態工廠方法放到一個工廠中,並在任何地方使用。如果你可以在很多不同的屏幕上重複使用這些工廠,甚至更好。總是儘量避免代碼重複。 – noone

1

假設菜單屏幕有天空和地面(即東西不是遊戲的一部分),那麼這麼好。看起來你有不同班級的演員,這很好。 「菜單屏幕」是一種有意義的事情,作爲單一責任。

+0

只是好奇,將createGround保持在一個單獨的地面對象不是很好嗎?標題並將相關方法放在相關類中也是如此,Afa MenuScreen關注那個類,構造方法應該在那裏構造一個屏幕並且顯示方法將顯示它? –

+0

發佈此信息以從我的經驗豐富的程序員那裏獲得更多想法。 :) :) :) –

+2

這只是一個問題的相對重要性的問題。如果他只是在菜單屏幕上繪製天空和地面,那麼這可能不足以保證不同的課程。事實上,在這種情況下,我只需抓住一張圖片並將其繪製即可。但是,如果對象具有特殊的渲染邏輯(例如,天空有動畫雲的邏輯)然後是的,你的建議將是完全合適的。 –

1

我一直在使用libgdx,並且一直在與一羣人一起製作一個非常大的遊戲。我發現特別有用的是分割渲染的組件。例如,我有一個靜態元素的單獨的UI類。然後有一個「渲染場景」類,它包含所有動態組件。

這在菜單中並不普遍。所以很難舉一個具體的例子,因爲這裏有點矯枉過正,但是當你真正開始在你的遊戲中製作核心功能時,這是一個很好的習慣。

(輸入複用器是一件好事情,看看)。

但是,現在只需在代碼中進行一些調整就是爲什麼不爲你的菜單創建一個單獨的「渲染」類?只需將它初始化爲舞臺,然後添加演員即可。這將允許你添加動畫序列,而不會讓你的課程膨脹。做到這一點,所有你需要做的是做MenuUI.render();然後它就可以工作。您的ScreenAdapter應該用於您的遊戲屏幕中的過渡,而不是硬編碼您的用戶界面。然後,如果您想更改菜單屏幕的用戶界面,只需插入新的用戶界面模塊即可。

希望這有助於:d

+0

這是如何被接受的答案? MenuUI.render()會做什麼?調用stage.render()...你需要一整套課程嗎? – noone

+0

對不起@noone。我是新的stackoverflow。我想我可以給清單多個答案。我認爲這是GameScreen的一個很好的替代方案,其中ObjectScreen的對象比MenuScreen多得多。儘管我更喜歡爲GameScreen的每個對象創建一個類 – kevinyu

+0

@progenhard感謝您的回答。你的意思是MenuUI是有階段作爲實例變量的類嗎?所有的createGround(),createSky()等應該在MenuUI初始化時調用? – kevinyu