• 締切済み

ダブルバッファによるチラつきの軽減具合

こんばんわ。 私は今、課題研究としてJava appletでゲームを作っています。 キー入力でキャラクターを動かすという所を作っているんですが キーを押すたびに背景であるマップのチラつきがあります。 一応ネットに上がっていつダブルバッファの処理は書きました。 (プログラム) //宣言     Image ura_cimg;     Graphics buff_c; //ダブルバッファ     ura_cimg = this.createImage(32,32);     buff_c = ura_cimg.getGraphics(); でもまだ完全に無くなった訳ではありません。 ダブルバッファの処理をしたら、チラつきは完全に無くせますか? 無くせない場合は、どこまで減るかアバウトでいいので教えてください。 回答お願いします。

みんなの回答

  • Yanch
  • ベストアンサー率50% (114/225)
回答No.1

ポイント 1)ダブルバッファリングするとなぜチラツキがなくなるか理解していますか? 分かっているところまで、説明してみてください。 2)フラッシュの処理のタイミングとかどのように記述しているでしょうか? フラッシュ処理を適切に記述できないと、ダブルバッファリングによるチラツ キ防止は失敗します。

rui12
質問者

お礼

回答ありがとうございます。 どうやら画像のサイズを無理やり変更していたのが問題だったようです。 無事チラつきはなくなりました。 この先、詰まったときはまたよろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ダブルバッファリング

    ダブルバッファリングを使ったつもりですが、キー操作するたびに画面がチカチカします。 特に <applet code="test.class" width="1600" height="600"> とした場合、repaint()メソッドを何回も呼んだ時に激しいです。 以下、ソースですが間違っているでしょうか? // ダブルバッファリング private Image imgOff; // オフイメージ private Graphics graOff; // オフグラフィックス public void paint(Graphics g){ if (imgOff == null) { Dimension dim = getSize(); imgOff = createImage( dim.width, dim.height ); graOff = imgOff.getGraphics(); } // ここに何か書く 例) graOff.setColor( new Color(255,255,255) ); graOff.fillRect(0, 0, 1600, 600); // 画面に反映 g.drawImage(imgOff,0,0,this); }

    • ベストアンサー
    • Java
  • java ダブルバッファリングするがちらつく

    javaでゲームをつくろうかと考えています。 そこで、ダブルバッファリングを実装したのですが、ちらついてしまいます。 いろいろ検索をかけて調べたのですが、これ以上改善が見込めないので 質問します。 以下がソースコードです。 画面がちらつくので、画面のリフレッシュレートが関係しているのかわからず、 しかし、ふつうにjava applet でゲームがあるので、多分どこかが間違っていると思います。 ご指摘をお願いします。 import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.net.URL; /*<applet code="applet01" width="320" height="480"></applet>*/ public class applet01 extends Applet implements KeyListener, Runnable { String text = ""; Image image; int x = 100, y = 100; KeyInput key; Image image弾; Bullet bullet; int flag_x = 1; Image backbuffer; Graphics ct; Dimension dim; // 初期化 public void init() { // image = getImage( getDocumentBase(), "test.jpg" ); image = getImage( getCodeBase(), "test.jpg" ); image弾 = getImage( getCodeBase(), "弾.jpg" ); bullet = new Bullet(); key = new KeyInput(); dim = getSize(); backbuffer = createImage( dim.width, dim.height ); ct = backbuffer.getGraphics(); Thread th = new Thread( this ); th.start(); addKeyListener( this ); requestFocus(); } // public void run() { try { while(true) { repaint(); Thread.sleep(1000/60); if( x>640 ) flag_x = 1; if( x<0 ) flag_x = 0; if( 1 == flag_x ) x--; if( 0 == flag_x ) x++; } } catch( Exception err ) { } } // 描画 public void paint( Graphics g ) { ct.setColor( Color.white ); ct.fillRect( 0, 0, dim.width, dim.height ); ct.setColor( Color.red ); ct.fillRect( (dim.width/2)-50 , (dim.height/2)-50, x, y ); // 裏画面に描画 ct.drawString( "画面をクリックしてキーボードで操作できます。", 0, 20 ); ct.drawString( "Hello from Java!", 60, 100 ); ct.drawImage( image, x, y, this ); bullet.Draw( ct, this, image弾 ); // 裏画面を表に反映 g.drawImage( backbuffer, 0, 0, this ); } // キーの入力があったとき public void keyTyped( KeyEvent e ) { repaint(); } // キーが押されたとき public void keyPressed( KeyEvent e ) { key.keyPressed( e ); if( key.isPressing( KeyEvent.VK_UP ) ) y = y - 5; if( key.isPressing( KeyEvent.VK_DOWN ) ) y = y + 5; if( key.isPressing( KeyEvent.VK_LEFT ) ) x = x - 5; if( key.isPressing( KeyEvent.VK_RIGHT ) ) x = x + 5; if( KeyEvent.VK_UP == e.getKeyCode() ) y = y - 5; if( KeyEvent.VK_Z == e.getKeyCode() ) { bullet.x = x; bullet.y = y; } repaint(); } // キーが放されたとき public void keyReleased( KeyEvent e ) { key.keyReleased( e ); } }

    • ベストアンサー
    • Java
  • ダブルバッファリングについて

    Javaで時計を作成していますが、 裏画面への作画がうまくいきません。 コンパイルはできますが、実行すると以下のエラーがでます。  Exception in thread "main" java.lang.NullPointerException   at AnalogClock.<init>(AnalogClock.java:22)   at AnalogClock.main(AnalogClock.java:54) オブジェクトが必要なときに、アプリケーションがnullを返すと、この例外がでることはわかりましたが、どうしてアプリケーションがnullを返すのかがわからず困っています。 プログラムは、表画面に直接表示するとちゃんとでます。 どなたか教えて頂けるとうれしいです。よろしくお願いします。 7)public class AnalogClock extends Frame implements Runnable { 8) 9) Calendar cal; 10) Image backimg; 11) Graphics bg; 中略 19) AnalogClock() { 20)//ダブルバッファリング用裏画面 21) backimg = createImage(width,height); 22) bg = backimg.getGraphics(); 23) setBackground(Color.black); 24) } 25) 26) public void paint(Graphics g) { 27)//カレンダーの取得(時・分・秒) 28) cal = Calendar.getInstance(); 29) hour = cal.get(cal.HOUR); 30) min = cal.get(cal.MINUTE); 31) sec = cal.get(cal.SECOND); 32)//時計の文字盤を作画 33) //文字盤の作画開始座標 34) x = 50; 35) y = 50; 36) //文字盤の直径 37) across = 200; 38) bg.setColor(Color.yellow); 39) bg.fillOval(x,y,across,across); 40)//裏画面のイメージを面画面に作画 41) g.drawImage(backimg,0,0,null); 42) } 中略 53) public static void main(String[] args) { 54) final AnalogClock ac = new AnalogClock(); 55) Thread th = new Thread(ac); 56) th.start(); 57) ac.setSize(300,300); 58) ac.setVisible(true); 以下略 (左の数字は行数です)

  • Graphicsについて

    Graphicsで描かれた線や図形は、ダブルバッファリングを使用しないと、ウィンドウのサイズを変更したり、別のウィンドウで覆ったりすると、描かれたものは消えてしまいます。 そこで今回JPanelを用いて、消えてしまわないようにしたいですが、 JPanel p = new JPanel(); Graphics g = p.getGraphics(); g.drawLine( x, x, y, y); のようにして、を実行すると上記の行為をすると消えてしまいます。JPanelはデフォルトでダブルバッファリングを備えているはずですよね。なぜなのでしょうか? どなたかご教授願います。宜しくお願いします。

    • ベストアンサー
    • Java
  • .Net Compact でのダブルバッファリング

    .Net Comapct Frameworkを利用してのC#プログラミングで、 ダブルバッファリングを利用して画面を描画しようとしていますが、 ちらつきが解消されません。 どこがおかしいかご指摘いただけると幸いです。 【環境】 Visual Studio 2005 C# .Net Compact Framework 2.0 【コード(抜粋)】 public partial class Form1 : Form { private Bitmap m_offScr; // オフスクリーンイメージ private Graphics m_offG; // オフスクリーングラフィックス private System.Windows.Forms.Timer timer1; public Form1() { this.timer1.Enabled = true; this.timer1.Interval = 1000; this.timer1.Tick += new System.EventHandler(this.timer1_Tick); ~略~ this.m_offScr = new Bitmap(400, 200); this.m_offG = Graphics.FromImage(this.m_offScr); } private void Form1_Paint(object sender, PaintEventArgs e) { m_offG.FillRectangle(new SolidBrush(Color.Red), 10, 10, 100, 100); e.Graphics.DrawImage(this.m_offScr, 0, 0); } // イベントハンドラ private void timer1_Tick(object sender, EventArgs e) { // 秒の更新 this.Refresh(); } } よろしくお願いいたします。

  • ダブルバッファについて

    スタート画面にBitmapを用いたアニメーションを用いて、次の場面に移動したいのですが 実行すると画面がちかちかしてしまいます。どう直せばよいか教えてもらえると助かります プログラムはVisualStudio2008のMFCでやっています #include "stdafx.h" #include "graph.h" #include "graphDoc.h" #include "graphView.h" #ifdef _DEBUG #define new DEBUG_NEW #endif //全域変数 CDC bkDC; CBitmap bkBMP; #define ID_REDRAW 30 #define TIMER_MS_FPS 1000/30 #define ID_BITMAP 60 #define TIMER_MS_BITMAP 300 #include <math.h> int draw_state = 0; float mouse_x = -1.0, mouse_y = -1.0; // CgraphView IMPLEMENT_DYNCREATE(CgraphView, CView) BEGIN_MESSAGE_MAP(CgraphView, CView) // 標準印刷コマンド ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint) ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview) ON_COMMAND(ID_BK_WHITE, &CgraphView::OnBkWhite) ON_COMMAND(ID_BK_BLUE, &CgraphView::OnBkBlue) ON_COMMAND(ID_BK_PINK, &CgraphView::OnBkPink) ON_WM_TIMER() ON_WM_DESTROY() ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() // CgraphView コンストラクション/デストラクション CgraphView::CgraphView() : background_color(0) , draw_state(0) , Bmp_ID(0) { // TODO: 構築コードをここに追加します。 background_color = 0; int draw_state = 0; } CgraphView::~CgraphView() { } BOOL CgraphView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: この位置で CREATESTRUCT cs を修正して Window クラスまたはスタイルを // 修正してください。 return CView::PreCreateWindow(cs); } // CgraphView 描画 void CgraphView::OnDraw(CDC* pDC) { CgraphDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: この場所にネイティブ データ用の描画コードを追加します。 //ダブルバッファに関するコード CRect rc; GetClientRect(&rc); bkDC.CreateCompatibleDC(pDC); bkBMP.CreateCompatibleBitmap(pDC, rc.right, rc.bottom); bkDC.SelectObject(&bkBMP); //描画は、裏画面bkDCにおいて行う bkDC.FillSolidRect(rc, RGB(153, 204, 255)); int x, y, sx, sy; if(draw_state == 0) { bkDC.SetTextColor(RGB(255, 255, 255)); bkDC.TextOut(480, 580, _T("Start")); sx = 128; sy = 128; y = 340; x = 200; draw_school(x, y, sx, sy);//定義は省略 x = 400; draw_health(x, y, sx, sy);//定義は省略 x = 600; draw_environment(x, y, sx, sy);//定義は省略 } else if(draw_state == 1) { CRect myRect; GetClientRect(myRect); pDC->FillSolidRect(myRect, RGB(0, 0, 0)); } //裏画面を表画面に送る //pDC->BitBlt(0, 0, rc.right, rc.bottom, &bkDC, 0, 0, SRCCOPY); //裏画面を消去 bkBMP.DeleteObject(); bkDC.DeleteDC(); //実行画面のプログラムを省略    void CgraphView::OnInitialUpdate() { CView::OnInitialUpdate(); // TODO: ここに特定なコードを追加するか、もしくは基本クラスを呼び出してください。 bitmap[0].LoadBitmap(IDB_BITMAP1); bitmap[1].LoadBitmap(IDB_BITMAP2); bitmap[2].LoadBitmap(IDB_BITMAP3); bitmap[3].LoadBitmap(IDB_BITMAP4); bitmap[4].LoadBitmap(IDB_BITMAP5); bitmap[5].LoadBitmap(IDB_BITMAP6); //タイマーをスタート SetTimer(ID_BITMAP, TIMER_MS_BITMAP, NULL); //画面再描画のタイマーをスタートする SetTimer(ID_REDRAW, TIMER_MS_FPS, NULL); Bmp_ID = 0; } void CgraphView::OnTimer(UINT_PTR nIDEvent) { // TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。 if(nIDEvent == ID_BITMAP) Bmp_ID = (Bmp_ID+1) % 2; if(nIDEvent == ID_REDRAW) InvalidateRect(NULL, FALSE); CView::OnTimer(nIDEvent); } void CgraphView::OnDestroy() { CView::OnDestroy(); // TODO: ここにメッセージ ハンドラ コードを追加します。 KillTimer(ID_BITMAP); KillTimer(ID_REDRAW); } void CgraphView::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: ここにメッセージ ハンドラ コードを追加するか、既定の処理を呼び出します。 mouse_x = point.x; mouse_y - point.y; if(draw_state == 0) { if(mouse_x > 420 && mouse_y > 500) { draw_state = 1; } } CView::OnLButtonDown(nFlags, point); } //以下は関数の定義なので省略

  • MAPコンテナの宣言部分の表記に関して質問です

    C++でSTLのMAPを勉強しだしたのですが、 よく分からない部分を見つけました。 以下のようにmapを使う際に、 mapコンテナの宣言をするのは理解できたのですが、 map<string, int> mmbr ; // (string型,int型)の対データを管理 map<int, int> ikk ; //(int型,int型)の対データを管理 他人が作成したサンプルを見ていたら、 以下のようにmapのコンテナ宣言がされていました。 ********************************************************* typedef KEY key_type; typedef typename std::map<key_type, value_type> container_type; ********************************************************* 1行目でtypedefしているだけなので理解できるのですが、 2行目で行っているmapコンテナの宣言の意味が どうも意味が分からないでいます。 mapコンテナの宣言で、 <string, int>や<int, int>のようにせず、 <key_type, value_type>としているのは、 どういう意味なのでしょうか? どうぞ宜しくお願い致します。

  • Start : アプレットは初期化されていません。

    閲覧ありがとうございます。 Fedora15でjavaの勉強をしてる者なのですが、端末では実行するとちゃんと表示されるのですが HTMLファイルをダブルクリックで実行するとタイトルのエラーが出て困っています。 内容としては、スレッドの勉強でスタートボタンを押すとリンゴが2個落ちるプログラムです。 もしよろしければ、アドバイスを頂けると嬉しいです。 下記ソースコード。 import javax.swing.*; import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.lang.*; public class Apple extends Applet implements Runnable,ActionListener { Image bu; //バッファ宣言 Graphics off_g; //グラフィック宣言 JButton b, bb; //スタートボタン Image img1 ; //ringo.gifを格納 int s=0, w = 450, h = 300; int a1 = 0, b1 = 1, a2 = 0, b2 = 1; Thread th ; //スレッドのインスタンス生成 boolean threadFlg = false; public void init(){ a1 = 0; b1 = 1; a2 = 0; b2 = 1; setBackground(Color.white); b = new JButton("スタート"); b.addActionListener(this); add(b); b.setBounds(300,30,100,30); bb = new JButton("ストップ"); bb.addActionListener(this); add(bb); bb.setBounds(370,30,100,30); threadFlg = true; th = new Thread(this); th.start(); img1 = getImage(getClass().getClassLoader().getResource("ringo.gif")); } public void actionPerformed(ActionEvent e){ if(e.getSource() == b){ s = 1; } if(e.getSource() == bb){ stop(); } } public void run(){ while(threadFlg){ if( s == 1){ a1 = a1 + b1; System.out.println(a1); a2 = a2 + b2; System.out.println(a2); if(a1 >= 300 && a2 >= 300 ){ break; } repaint(); } try{ th.sleep(30); }catch(InterruptedException e){} } } public void update(Graphics g){ paint(g); } public void paint(Graphics g){ super.paint(g); if(s == 1){ off_g.drawImage(img1,30,a1,this); off_g.drawImage(img1,250,a2,this); g.drawImage(bu,20,30,this); } } public void start(){ bu=createImage(w,h); off_g=bu.getGraphics(); //グラフィックコンテキストを得る? } public void stop(){ threadFlg = false; th = null; } } <html> <title>Apple</title> <body> <applet code="Apple.class" width="450" height="300"> </applet> </body> </html>

  • AWTの質問

    以下のようなコードを書きました。円の中をクリックすると赤色に塗りつぶしたいようにしたいのですが、現状だとどこをクリックしても赤色に塗りつぶされます。(クリックした座標が円の範囲にあれば。。)というような処理を付け加えたいのですが手順がわかりません。コードで示してもらえると助かります。 import java.applet.*; import java.awt.Color; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class En extends Applet implements MouseListener{ public void init() { this.addMouseListener(this); } public void paint(Graphics g) { g.fillOval(20, 25, 500, 400); } public void mouseClicked(MouseEvent e) { Graphics g = getGraphics(); g.setColor(Color.red); //ここに何か書くべきと思われる g.fillOval(20, 25, 500, 400); } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } }

    • ベストアンサー
    • Java
  • 画面の大きさに合わせてボールを動かせたい

    今日は。 javaの初心者です、宜しくお願いします。 下のようなボールが動くアプレットを組んでみましたが、画面の大きさを変えても ボールの動く範囲はかわりません。 画面の大きさに合わせて、動く範囲を自動的に変えてやるには、このプログラムの 何処をどのように書き換えてやるといいのでしょうか。  宜しくお願いします。 ========================================================================== import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Image; public class BallMove_1p extends Applet implements Runnable { private int width , height ; private Thread thread ; private boolean LoopEnd = false ; private int x1 = 30 , y1 = 100 ; private Image offScreen ; private Graphics screen ; private int vx = 2 , vy = 2 ; // アプレット初期化処理 public void init() { // アプレット画面サイズ取得 width = getSize().width ; height = getSize().height ; // スレッド起動 thread = new Thread( this); thread.start(); // オフスクリーンの初期化 offScreen = createImage( width, height); // オフスクリーンを作成 screen = offScreen.getGraphics(); // オブジェクトを取得 } // スレッドループ処理 public void run() { while(LoopEnd == false) { move() ; repaint() ; try { Thread.sleep( 10 ) ; } catch ( InterruptedException e ) {} } } // ボール移動 private void move() { if( x1 >= width - 50 ) { vx =- vx ; } if( y1 >= height - 50 ) { vy =-vy ; } if( x1 < 0 ) { vx =- vx ; } if( y1 < 0 ) { vy =-vy ; } x1 += vx; y1 += vy; } // 再描画時処理 public void update( Graphics g) { paint(g) ; } // 描画処理 public void paint( Graphics g) { screen.clearRect( 0 , 0 , width , height ) ; // 画面消去 screen.setColor( Color.blue ) ; screen.fillOval( x1 , y1 , 50 , 50 ) ; g.drawImage( offScreen , 0 , 0 , this ) ; // イメージを描画 } // アプレット終了時処理 public void destroy() { LoopEnd = true ; } }

    • ベストアンサー
    • Java