2013-08-02 24 views
0

我目前正在研究移動背景的2D射擊遊戲。背景只是一個簡單的圖像。我想實現圖像從上到下的無止境的移動。如何實現無限的圖像循環?

我想過要確定位於框架可見部分外部底部的圖像部分,並再次將其繪製在頂部。

@Override 
public void paint(Graphics go) { 
    Graphics2D g = (Graphics2D) go; 

    g.fillRect(0, 0, this.getWidth(), this.getHeight()); 
    g.drawImage(this.imgBackground, 0, this.yBackground, this); 
} 

yBackground是繪製圖像左上角的座標。它是從另一個線程改變:

while (!this.paused) { 
    try { 
     Thread.sleep(10); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 

    int y = this.display.getBackgroundY(); 

    if (y == this.display.getHeight()) { 
     y = 0; 
    } else { 
     y++; 
    } 
    this.display.setBackgroundY(y); 
} 

因此,這裏是我的問題:我怎麼能得到這個圖像的部分是幀的可見部分之外?

+0

1.請爲什麼??? 2.不要使用public void paint(Graphics go){,搜索paintComponent,3.不要使用Thread.sleep(10)阻止EDT;使用Swing Timer代替4. sleep(10);是非常快速的暫停,觸及本機操作系統的延遲,從沒有自己的RepaintManager等開始=> 33,爲了更快地發佈[SSCCE](http://sscce.org/),更好的幫助,短的,可運行的,可編譯的 – mKorbel

+0

好的我會記住這一點 – Markus

回答

1

有很多方法可以實現這一點,但基本前提是,您需要某種確定基本圖像開始的滾動偏移量。

然後,您需要填寫前後的區域(如果圖像小於可用高度),直到空間填滿。

以下示例使用javax.swing.Timer以給定量更新偏移量。然後paintComponent方法渲染它之前和之後的所有空間,包括當前的圖像位置。

enter image description here

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class ScrollingBackground { 

    public static void main(String[] args) { 
     new ScrollingBackground(); 
    } 

    public ScrollingBackground() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new BackgroundPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class BackgroundPane extends JPanel { 

     private BufferedImage bg; 
     private int yOffset = 0; 
     private int yDelta = 4; 

     public BackgroundPane() { 
      try { 
       bg = ImageIO.read(new File("Background.png")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 

      Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        yOffset += yDelta; 
        if (yOffset > getHeight()) { 
         yOffset = 0; 
        } 
        repaint();; 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (bg != null) { 
       Graphics2D g2d = (Graphics2D) g.create(); 

       int xPos = (getWidth() - bg.getWidth())/2; 
       int yPos = yOffset; 

       while (yPos > 0) { 
        yPos -= bg.getHeight(); 
        g2d.drawImage(bg, xPos, yPos, this); 
       } 

       yPos = yOffset; 
       while (yPos < getHeight()) { 
        g2d.drawImage(bg, xPos, yPos, this); 
        yPos += bg.getHeight(); 
       } 

       g2d.dispose(); 
      } 
     } 
    } 
} 

您也許能夠樂觀中使用後盾緩衝和或子圖像,但你的想法...

1

您可以再次從高度yBackground + imgBackground.getHeight()開始再次繪製圖像。視圖上方的額外擴展會被截斷,就像已經在代碼中刪除底部一樣。