2012-03-12 90 views
1

我正在製作一個遊戲,其中爲了這個問題的目的,我有一個擴展JFrame的類,它增加了一個擴展JPanel(GamePanel)的類。在GamePanel中,我有一個運行方法,它有兩個函數update();和repaint();然後是Thread.sleep(20)。更新功能需要約1-2ms。我把所有繪圖的東西放在paintComponent(Graphics g)中,當我使用repaint()時,它似乎正確地被調用,因爲東西出現在屏幕上。在低計算java paintcomponent的低fps

我的問題是,它是難以置信的laggy。當我沒有Thread.sleep(20)時,它像2fps一樣無法播放。我讀到這是因爲repaint()沒有足夠的時間來完成或什麼,所以我在下一個循環前添加了延遲。高於或低於20ms的任何東西似乎都會使其更加遲滯。

我試過使用圖形配置的東西,雙緩衝和更多,但它保持laggy。在我的家用電腦,這是一個英特爾i5,四核,3.2GHz我只能達到100fps,並在學校的計算機上,我得到了15fps左右(好的電腦,就像amd雙核心,我相信)。 paintComponent循環是超輕量級的!只需根據玩家位置使用偏移繪製地圖,然後在屏幕中間繪製玩家!我使用的地圖是2000x2000,0.8mb。嘗試切換到1000x1000 0.4mb並沒有差異。

下面是代碼:

@Override 
public void paintComponent(Graphics g) { 
    //Rendering settings and stuff 
    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 

    //Draw map  gameMap.gameMap is a bufferedImage 
    g2d.drawImage(gameMap.gameMap, gameMap.x, gameMap.y, null); 
    //Draw health bar 
    g2d.setColor(healthBarColor); 
    g2d.setComposite(alphaHealthBarBackground); 
    g2d.fillRect(100, 19, 200, 23); 
    g2d.setFont(font); 
    g2d.setComposite(alphaNormal); 
    g2d.setColor(healthBarColor); 
    g2d.drawString("HP: ", 20, 40); 
    g2d.fillRect(100, 19, player.health * 2, 23); 

    //Draw player  player.playerImage is a BufferedImage 
    rotatePlayer.setToRotation(rotation, rotationAnchor.x, rotationAnchor.y); 
    rotatePlayer.translate(xResolution/2, yResolution/2); 
    g2d.drawImage(player.playerImage, rotatePlayer, this); 
    g2d.setColor(Color.white); 
} 

這導致100FPS相對真棒計算機及15fps血統計算機上!

+0

究竟有多大'這'被繪? *「下降計算機上15fps!」*如果它正在下降到哈迪斯,這將是可以理解的,因爲'它會去地獄'。 ;) – 2012-03-12 18:16:32

+0

那麼,如果我理解你的權利,那麼「這」被繪與屏幕尺寸一樣大。該應用程序是全屏。我使用工具包來獲得屏幕尺寸,所以在家裏它是1920x1080,在學校屏幕是1280x1024我相信... 哈哈,體面;)有趣的笑話...:P – Opfff 2012-03-12 18:47:31

+0

注意:1)最好做FPS測試固定的渲染大小。 2)您可以編輯問題以更改拼寫。我可以,但我會謹慎行事。 :) – 2012-03-12 19:22:01

回答

0

那麼,對於遊戲開發,我不認爲在Swing中繪製一個巨大的圖像paintComponent將永遠贏得任何速度記錄。 100 FPS仍然令人驚歎(比大多數液晶顯示器的刷新率高大約40 FPS)。

對於更多的速度,重要的是你正在使用的繪製原語是加速的。在你的學校電腦上,他們可能只是缺乏一個能提供2D加速所需的體面顯卡(這些電腦在瀏覽器和繪圖程序中如何進行正常的2D操作?)

您可能想要查看一個使用相反,像OpenGL一樣JOGL。另一種選擇是嘗試JavaFX 2 - 它可能有更好的渲染管道。

+0

有趣。我相信我的學校電腦有好的顯卡。我們不時在其上玩CS1.6,沒有任何延遲。您可以在其上播放高清視頻並播放Flash遊戲和內容。我在考慮多線程的問題。我的遊戲使用線程進行音樂,碰撞檢測,移動,正在發射的鏡頭,發送多人遊戲的UDP信息等。關於加速度。 Graphics2D默認硬件加速了嗎?我會檢查出喬吉爾和javafx2 ... – Opfff 2012-03-12 19:20:04

4

不故作最終的解決辦法,只是一些提示:

  1. 確保您的緩衝圖像是具有相同的顏色模型爲GraphicsDevice默認情況下,他們繪製。方法GraphicsConfiguration.createCompatibleImage可以創建這樣的圖像。

  2. 如果可能的話,嘗試將整個巨大的地圖拆分爲瓦片並跳過離屏(遊戲外視圖)部分的渲染。

  3. 看來你使用被動渲染,正如你所說的調用repaint()。事件調度線程用於Swing和AWT中的很多事情,並且它不能保證主動渲染的遊戲可接受的時間。也許值得重新設計遊戲的渲染部分以使用主動渲染。教程和例子可以在here找到。

+0

感謝您的答案! 1.我實際上已將所有BufferedImage更改爲Image。給了+10 fps。不太明白你的意思,在圖像中閱讀的代碼是:gameMap = ImageIO.read(new File(GM)); // GM = String GraphicsConfiguration.createCompatibleImage如何適合那裏? 2.讓它變得很有趣。沒有fps增益 3.一個痛苦的XD,但它給了我g2d.setClip(0,0,screenx,screeny)的想法。給+ 50fps。高達160fps! :) 4.要現在嘗試:D 謝謝! – Opfff 2012-03-12 19:14:48

+0

我的意思是ImageIO讀取的圖像在繪製目標表面時可能需要進行一些轉換。例如,我記得,在Windows平臺上,使用['BufferedImage.TYPE_INT_ARGB']中定義的圖像獲得最佳性能(http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage的.html#TYPE_INT_ARGB)。您可以通過'ImageIO.read'加載圖像,通過GraphicsConfiguration創建相同大小的圖像,然後在「兼容」圖像上渲染每個源圖像。並在遊戲渲染中使用結果。 – Mersenne 2012-03-12 19:27:22

+0

是的,我錯誤地指出錯誤的塗料超載。其實,我的意思是[this](http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#drawImage%28java.awt.Image,%20int,%20int,%20int ,%20int,%20int,%20int,%20int,%20int,%20java.awt.image.ImageObserver%29)版本,用於繪製圖像的一部分。 – Mersenne 2012-03-12 19:50:14

0

我也在開發一個Java遊戲,並且做了很多與您相同的事情(擴展JPanel並調用repaint())。一個區別是我使用javax.swing.Timer來調用ActionPerformed(ActionEvent e)方法來每5ms更新我的遊戲。在該方法的最後,它調用repaint()來進行渲染。

此外,如果您使用Graphics2D來進行渲染,則可以使用RenderingHints指導計算機如何渲染遊戲(例如速度或質量等)。

我沒有測量的準確FPS,但我得到我的Ubuntu 12.10系統上沒有延遲和Windows 8

慢只是有點我道歉,如果我的回答是不正是你想要的東西,但是這是到目前爲止,我的工作沒有任何問題。