我正在使用j2me編寫手機遊戲。在這個遊戲中,我使用了多個Canvas對象。 例如,遊戲菜單是一個Canvas對象,實際的遊戲也是一個Canvas對象。 我注意到,在某些設備上,當我從一個Canvas切換到另一個Canvas時,例如從主菜單切換到遊戲時,屏幕瞬間「閃爍」。我正在使用自己的雙緩衝Canvas。j2me畫面在畫布之間切換時閃爍
有沒有辦法避免這種情況?
我正在使用j2me編寫手機遊戲。在這個遊戲中,我使用了多個Canvas對象。 例如,遊戲菜單是一個Canvas對象,實際的遊戲也是一個Canvas對象。 我注意到,在某些設備上,當我從一個Canvas切換到另一個Canvas時,例如從主菜單切換到遊戲時,屏幕瞬間「閃爍」。我正在使用自己的雙緩衝Canvas。j2me畫面在畫布之間切換時閃爍
有沒有辦法避免這種情況?
你使用雙緩衝嗎?如果設備本身不支持雙緩衝,您應該定義一個屏幕外緩衝區(圖像)並首先對其進行繪製,然後將最終結果繪製到實際屏幕上。爲你的每個畫布做這個。下面是一個示例:
public class MyScreen extends Canvas {
private Image osb;
private Graphics osg;
//...
public MyScreen()
{
// if device is not double buffered
// use image as a offscreen buffer
if (!isDoubleBuffered())
{
osb = Image.createImage(screenWidth, screenHeight);
osg = osb.getGraphics();
osg.setFont(defaultFont);
}
}
protected void paint(Graphics graphics)
{
if (!isDoubleBuffered())
{
// do your painting on off screen buffer first
renderWorld(osg);
// once done paint it at image on the real screen
graphics.drawImage(osb, 0, 0, Tools.GRAPHICS_TOP_LEFT);
}
else
{
osg = graphics;
renderWorld(graphics);
}
}
}
可能的解決方法是使用Display.callSerially()同步開關。閃爍可能是由於應用程序試圖在畫布切換仍在進行時畫到屏幕上而引起的。在嘗試再次調用run()之前,callSerially()應該等待重新繪製完成。
但是,這一切都完全依賴於手機,因爲許多設備沒有實現callSerially(),沒關係按照官方文檔中列出的實現。我已經知道與callSerially()正確工作的唯一設備是西門子手機。
另一種可能的嘗試是將Thread.sleep()的值設置爲1000毫秒,確保事先調用了setCurrent()方法。這樣,設備可能會設法在可顯示的繪圖嘗試之前進行更改。
最可能的問題是,它是一個設備問題,並保證閃爍的修復很簡單 - 使用一個畫布。可能不是你想聽到的。 :)
我遵循你的建議,並在代碼中放置了一個很長的Thread.sleep()。我發現閃爍實際上發生在Canvas'run()方法中的第一個repaint()之後。有什麼想法嗎? – Dimitris 2008-09-16 12:33:24
我會說,使用多個畫布通常是不好的設計。在某些手機上它甚至會崩潰。最好的方法是使用一個畫布來跟蹤應用程序的狀態。然後在paint方法你會
protected void paint(final Graphics g) {
if(menu) {
paintMenu(g);
} else if (game) {
paintGame(g);
}
}
有更好的方法來處理與畫面對象應用程序的狀態,這將使得設計更清潔,但我覺得你有這個想法:)
/JaanusSiim
假設在你的應用中使用1個帶有狀態機器代碼的畫布是個好主意。然而,我唯一需要測試應用程序的設備(MOTO v3)在資源加載時崩潰,僅僅因爲代碼過多/要在GameCanvas中加載(沒有使用Canvas進行嘗試)。這是痛苦的,因爲它是真實的,我沒有找到解決問題的方法。 如果你很幸運有很多設備可以測試,那麼實施這兩種方法是值得的,並且爲每款設備製作遊戲的版本非常有用。
我用類似於你的方法定義一個屏幕外緩衝區來使用雙緩衝。當新Canvas的主線程開始運行時,總會發生閃爍。 – Dimitris 2008-09-15 21:14:59