2017-05-10 50 views
0

我目前正在eclipse中製作一個「英雄」動作,如果按下某個鍵,則在更改的X座標中重新繪製它。這工作,但運動是粗糙的,甚至出現遲緩。我真的很感謝任何幫助/建議,代碼看起來很長,但它確實很基礎。如何在java中使角色順利移動?

代碼級別

JFrame window = new JFrame("Level"); 
Hero hero = new Hero(0, 800); 

public Level() 
{ 
    this.setFocusable(true); 
    this.addKeyListener(this); 
    window.add(this); 
    window.setSize(1400, 980); 
    window.setLocation(40,20); 
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setVisible(true); 
} 

public void paint(Graphics g) 
{ 
    try { 
     Image i = ImageIO.read(getClass().getResource("/Sprites/Background.jpg")); 
     g.drawImage(i, 0, 0, null); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    hero.drawHero(g); 
} 

@Override 
public void keyPressed(KeyEvent kp) 
{ 
    if(kp.getKeyCode()==KeyEvent.VK_RIGHT) 
    { 
      hero.setxAxis(hero.getxAxis()+5); 
      this.repaint(); 
    } 
    if(kp.getKeyCode()==KeyEvent.VK_LEFT) 
    { 
      hero.setxAxis(hero.getxAxis()-5); 
      this.repaint(); 
    } 
} 

代碼爲英雄

public class Hero { 
int xAxis; 
int yAxis; 
Image heroImage; 
public Hero(int xAxis, int yAxis) 
{ 
    super(); 
    this.xAxis = xAxis; 
    this.yAxis = yAxis; 
    try { 
     heroImage = ImageIO.read(getClass().getResource("/Sprites/Pic1.png")); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

public int getxAxis() { 
    return xAxis; 
} 

public void setxAxis(int xAxis) { 
    this.xAxis = xAxis; 
} 

public int getyAxis() { 
    return yAxis; 
} 

public void setyAxis(int yAxis) { 
    this.yAxis = yAxis; 
} 

public void drawHero(Graphics g) { 
    g.drawImage(heroImage, xAxis, yAxis, null); 
} 

}

+0

您是否在事件調度線程(EDT)上運行GUI?如果不是,預計麻煩。 –

+0

不,我不是。你能解釋如何做到這一點? @LewBloch – cwsl26

+0

而我會在哪裏使用它? @LewBloch謝謝你的方式。 – cwsl26

回答

0

與雙或三緩衝 檢查了這一點試試! How do you double buffer in java for a game?

更多來自Wiki的信息: 在計算機圖形學中,雙緩衝是一種繪製圖形的技術,它不顯示(或更少)口吃,撕裂和其他工件。

程序很難畫出一個顯示,以便像素不會多次改變。例如,在更新文本頁面時,清除整個頁面然後繪製字母比清除舊字母和新字母中不包含的所有像素要容易得多。但是,該中間圖像被用戶看作閃爍。另外,計算機顯示器不斷重繪可見視頻頁面(大約每秒60次),所以即使是完美更新,也可以立即看到「新」圖像和未重繪的「舊」圖像之間的水平分隔符,已知作爲撕裂。

https://en.wikipedia.org/wiki/Multiple_buffering#Double_buffering_in_computer_graphics

+1

正確使用時自動擺動是默認雙重緩衝 – MadProgrammer

+0

我沒有在提供的代碼中看到BufferStrategy。鞦韆是否使用它「幕後」?我想不是。 –

+0

是的,Swing使用內部緩衝區來繪製所有子組件,自從創建後就完成了,這就是爲什麼您可以在Swing中執行動畫而不使用任何類型的雙緩衝,不像AWT – MadProgrammer

0

開始採取看看Painting in AWT and SwingPerforming Custom Painting爲更多細節如何繪畫作品,以及如何你可以用它intergarte。

Swing中的繪畫使用被動渲染算法,這意味着任何時候出於任意原因都會出現繪畫循環,許多情況下沒有您的控制權或知識。

這意味着可以在任何時候調用paint。應儘快完成繪畫,以免降低應用程序的性能。

爲此,您不應該加載資源,做出過於複雜的邏輯決策或更新繪畫方法中的狀態。

首先將圖像載入其他地方,也許以構造函數爲例。

繪畫是一個複雜的鏈式方法調用系列(「油漆鏈」),容易打破,導致各種怪異。作爲一般的建議,它建議重寫paintComponent進行自定義畫,你也應該叫super.paintComponent爲了保持原有的「漆鏈」

我也建議你使用Key Bindings API超過KeyListener,除了提供一個更靈活和可重用的解決方案,它也解決了與焦點相關的問題KeyListener