Swingを使って2Dスクロールゲームを作るときに、ダブルバッファリングを実装したのですが、バッファイメージのサイズを大きくすると動きが遅くなってしまいました。以下はその詳細です。何か分かることがございましたら、アドバイスをお願いします。
#ダブルバッファリング実装方法
※クラス[変数名]
・JFrameにおいてインスタンス生成時に、createImage(this.getWidth(), this.getHeight())でバッファイメージImage[back]
とback.getGraphics()でそのグラフィクスGraphics[buffer]
を変数として取得しておく。
・paint(Graphics g)をオーバーライドしてbufferに描画して、最後に**graphics.drawImage(back, 0, 0, this)**でバッファイメージを描画する。
・componentResizedをオーバーライドしてImage[back]
とGraphics[buffer]
を変更(更新)する。
・update(Graphics g)はオーバーライドしていない。
#問題点
・実行してみて、画面を大きくすると動きが遅くなることに気がついた。
・フレームレートを測定すると、画面の大きさに比例して時間が遅くなっていた。
・試しに、**graphics.drawImage(back, 0, 0, this)**だけをコメントアウトすると画面は変わらないが、フレームレートは速くなった。
・試しに、**paint(Graphics g)において、先頭でbuffer = g;を書くと(ダブルバッファリングしないようにすると)ちらつくが速くなった。
・試しに、インスタンス生成時にcreateImage(2000, 2000)**とするとずっと遅くなった。
#修正(該当のコード)
java
1package orgmarigo.test; 2 3import javax.swing.*; 4import java.awt.Graphics; 5import java.awt.Image; 6import java.awt.event.*; 7 8import orgmarigo.util.Vector2; 9import orgmarigo.util.TimeMeasure;//フレームレートを測定するクラス 10import orgmarigo.util.MyUtilities; 11 12public class ScreenTest extends JFrame implements ActionListener, ComponentListener{ 13 static public final Vector2 INITIAL_WINDOW_SIZE = new Vector2(630, 560); 14 static public TimeMeasure timeMeasure = new TimeMeasure(100); 15 static public final int FPS = 100; 16 17 private Timer timer; 18 private Image back; 19 private Graphics buffer; 20 private Image titleImage; 21 22 public static void main(String[] args) { 23 new ScreenTest(); 24 } 25 26 public ScreenTest(){ 27 this.setTitle("ScreenTest"); 28 this.setBounds(300, 200, (int)INITIAL_WINDOW_SIZE.getX(), (int)INITIAL_WINDOW_SIZE.getY()); 29 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 30 31 this.addComponentListener(this); 32 33 this.setVisible(true); 34 35 timer = new Timer(1000 / FPS, this); 36 back = createImage(this.getWidth(), this.getHeight());//バッファイメージ 37 buffer = back.getGraphics();//イメージのグラフィクス 38 titleImage = MyUtilities.getImage("../images/title/TitleImage.jpg"); 39 40 timer.start(); 41 } 42 43 @Override 44 public void paint(Graphics graphics){ 45 if(buffer != null){ 46 //イメージの更新、描画 47 buffer.clearRect(0, 0, this.getWidth(), this.getHeight()); 48 buffer.drawImage(titleImage, 0, 0, this.getWidth(), this.getHeight(), null); 49 } 50 51 graphics.drawImage(back, 0, 0, this); 52 } 53 54 @Override 55 public void actionPerformed(ActionEvent e){ 56 Object source = e.getSource(); 57 58 if(source == timer){ 59 timeMeasure.Update(); 60 repaint();//再描画 61 } 62 } 63 64 @Override 65 public void componentHidden(ComponentEvent e) {} 66 67 @Override 68 public void componentMoved(ComponentEvent e) {} 69 70 @Override//リサイズしたとき 71 public void componentResized(ComponentEvent e) { 72 back = createImage(this.getWidth(), this.getHeight()); 73 buffer = back.getGraphics(); 74 } 75 76 @Override 77 public void componentShown(ComponentEvent e) {} 78}
#その他
・ネットで調べて、setDoubleBuffered(boolean)を見つけたが使い方がわからなかった。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。