2015-12-15 32 views
-1

嗨我幾乎用java完成了我的遊戲編碼,但是我遇到了一個很大的問題。 縮放 - 每個人都有一個不同大小的屏幕。如何使用java擴展整個遊戲

我的大部分遊戲都是通過鍵盤控制的,但是有一個使用按鈕的設置功能。

要修復縮放,我打算通過創建一個整數'縮放'來簡單地縮放每個JBufferedImage。

這是我的第一個遊戲,我試圖使它與封裝和正確使用可用庫都完美無瑕,並且以我自己的方式縮放一切,看起來像是一種非常即興的方法。所以我不得不問,是否有任何「官方」的方法來衡量。

+0

這將取決於你如何完成工作。例如,你可以簡單地將「AffineTransform」應用於'Graphics'上下文。更好的解決方案應該是編碼爲實際值(實際屏幕座標),而不是固定/魔術值 – MadProgrammer

+0

我添加了一個答案,但如果您提供了關於遊戲編碼方式的更多詳細信息,包括一些簡單示例代碼。 –

+2

你必須實現每一個2D遊戲假冒縮放。地獄,甚至像RPGMaker VX(或更高版本)等特定程序都會對縮放進行說明,只是將可擴展空間的邊界剪掉。我如何解決這個問題的意見?不要使用2D。期。如果你想認真對待這一點,學習3D編程,並進行2.5D遊戲。它看起來會更好,「縮放」是通過相機矩陣的縮放完成的。 – Krythic

回答

2

如果您添加了一些上下文以幫助我們瞭解您的遊戲如何工作,但這可能會有所幫助,但也許這可以幫助您走上正確的軌道。在我以前的Java遊戲中,我只需將所有內容都繪製成固定大小的BufferedImage,然後將緩衝的圖像縮放到面板大小。有更好的方法可以做到這一點,但這可能是最簡單的方法。

創建面板:

panel = new JComponent() 
{ 
    @Override 
    public void paintComponent(Graphics g) 
    { 
     Graphics2D g2 = (Graphics2D) g; 

     buffer = getCurrentBuffer(); // Get the updated game image from somewhere 

     // Figure out how to scale the image 
     int w = this.getWidth(); 
     int h = this.getHeight(); 

     int[] scale = scaleImage(buffer, w, h); 

     // Make sure scaling isn't all pixely 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     // Clear the screen 
     g2.setColor(Color.black); 
     g2.fillRect(0, 0, getWidth(), getHeight()); 

     // Paint image scaled 
     g2.drawImage(buffer, scale[2], scale[3], scale[0], scale[1], null); 
    } 
}; 

輔助功能:

/** 
* Gets image scaling keeping its aspect ratio 
* @param image Image to scale 
* @param newWidth Width goal 
* @param newHeight Height goal 
* @return new int[] {Width to make it, height to make it, x to draw at, y to draw at} 
*/ 
public static int[] scaleImage(Image image, int newWidth, int newHeight) 
{ 
    double thumbRatio = (double) newWidth/(double) newHeight; 
    int imageWidth = image.getWidth(null); 
    int imageHeight = image.getHeight(null); 
    double aspectRatio = (double) imageWidth/(double) imageHeight; 

    int x = 0; 
    int y = 0; 

    if (thumbRatio < aspectRatio) 
    { 
     y = newHeight; 
     newHeight = (int) (newWidth/aspectRatio); 
     y /= 2; 
     y -= newHeight/2; 
    } 
    else 
    { 
     x = newWidth; 
     newWidth = (int) (newHeight * aspectRatio); 
     x /= 2; 
     x -= newWidth/2; 
    } 

    return new int[] { newWidth, newHeight, x, y }; 
} 

當創建緩衝圖像的大小固定,確保只有一次創建它,因爲它是非常低效的重新創建每個遊戲循環迭代。

buffer = new BufferedImage(NOMINAL_GAME_WIDTH, NOMINAL_GAME_HEIGHT, BufferedImage.TYPE_INT_RGB); 
+0

真的,'g2.setTransform(AffineTransform.getScaledInstance(scale))'有什麼問題''。縮放並不便宜,不應該在'paintComponent'方法內完成 – MadProgrammer

+0

@MadProgrammer我不確定爲什麼這會比我在'paintComponent'裏面做的更有效率,但是如果你能解釋,那麼我肯定會對閱讀感興趣。也許你可以寫一個補充答案。 –

+0

我原本以爲你是縮放'scaleImage'中的圖像,但你只計算大小。我不確定'drawImage'是您的最佳選擇,但我傾向於專門使用'AffineTransform.getScaledInstance'。一個「更好的」選擇,可能是縮放頁面緩衝區以開始(所以它始終處於縮放的大小),並且在它的'Graphics'上下文(頁緩衝區)上使用'AffineTransform',假設它們正在使用這幅畫過程而不是'BufferedStrategy' – MadProgrammer