2012-03-07 18 views
1

私はJavaでゲームをしていて、レンダリング時に問題が発生しています。私は背景とすべてのスプライトをイメージに描画するスクリーンクラスを持っています。次に、フレームはdoubleBufferを使用してイメージを表示します。いくつかの奇妙な理由から、画像はフレームの端からレンダリングされています。下のリンクでは、画像が左に3ピクセル、上に28ピクセル上にレンダリングされていることがわかります。誰かがこれを引き起こしている可能性のある考えを持っていますか? ![ここに画像の説明を入力] [1]フレームの外側に画像がレンダリングされていますか?

http://imageshack.us/photo/my-images/41/weirdg.png/

public class Game extends JFrame implements Runnable{ 
private static final long serialVersionUID = 1L; 

//graphics 
public BufferStrategy buffy; 
BufferedImage image; 
Screen screen; 

public Boolean running = false; 
public Boolean playerTurn = false; 

public InputManager input; 
public Level level; 
//JButton b; 

public static final int HEIGHT = 452; 
public static final int WIDTH = 768; 

public Game() { 
    super("GridWars"); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 

    JPanel drawPanel = new JPanel(); 
    drawPanel.setPreferredSize(new Dimension(WIDTH, HEIGHT)); 
    drawPanel.setLayout(null); 
    drawPanel.setOpaque(false); 
    //drawPanel.setLocation(50,50); 

    setContentPane(drawPanel); 
    setResizable(false); 
    pack(); 
    setLocationRelativeTo(null); 
    setVisible(true); 
    requestFocus(); 
    createBufferStrategy(2); 

    //b = new JButton("this sucks"); 

    //getContentPane().add(b); 
    //b.setBounds(300, 300, 100, 50); 


    buffy = getBufferStrategy(); 
    image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 
    screen = new Screen(WIDTH, HEIGHT); 
    input = new InputManager(this); 
    level = new Level(WIDTH, HEIGHT, input, this); 
} 

public void start() { 
    running = true; 
    new Thread(this).start(); 
} 
public void setup(){ 

} 
public void run() { 
    final double TICKS = 30.0; 
    final double UPDATE_INTERVAL_NS = 1000000000/TICKS; 
    double pastUpdateNS = System.nanoTime(); 

    int updateCount = 0; 
    int frameCount = 0; 

    final double FRAPS = 60.0; 
    final double RENDER_INTERVAL_NS = 1000000000/FRAPS; 
    double pastRenderNS = System.nanoTime(); 

    int pastSecondNS = (int) (pastUpdateNS/1000000000); 

    while(running) { 
     double nowNS = System.nanoTime(); 

     if(nowNS - pastUpdateNS >= UPDATE_INTERVAL_NS) { 
      update(); 
      pastUpdateNS += UPDATE_INTERVAL_NS; 
      updateCount++; 
     } 

     float interp = Math.min(1.0f, (float) ((nowNS - pastUpdateNS)/UPDATE_INTERVAL_NS)); 
     render(interp); 
     pastRenderNS += RENDER_INTERVAL_NS; 
     frameCount++; 

     int thisSecondNS = (int) (pastUpdateNS/1000000000); 
     if (thisSecondNS > pastSecondNS) { 
      //System.out.println("TICKS: "+updateCount+" | FRAPS: "+frameCount); 
      updateCount = 0; 
      frameCount = 0; 
      pastSecondNS = thisSecondNS; 
     } 

     while(nowNS - pastRenderNS < RENDER_INTERVAL_NS && nowNS - pastUpdateNS < UPDATE_INTERVAL_NS) { 
      try { Thread.sleep(1); } catch(Exception e) {}; 
      nowNS = System.nanoTime(); 
     } 
    } 
} 

public void update() { 
    input.update(); 
    level.update(); 
} 

public void render(float interp) { 
    level.render(screen, interp); 

    image = screen.getImage(); 
    Graphics g = buffy.getDrawGraphics(); 
    g.drawImage(image, 0, 0, null, null); 
    //b.repaint(); 
    g.dispose(); 
    buffy.show(); 
} 

public static void main(String[] args) { 
    Game game = new Game(); 
    game.start(); 
} 
} 
+0

このprint文はどこにありますか? (私がそれを逃してしまった場合は申し訳ありません) –

答えて

2

0,0あなたはbuffy.getDrawGraphics();から入手Graphicsオブジェクトの座標を正確にJFrameの左上隅にあり、それは、フレームの装飾を無視しています。

  1. UPD私は1つの明白なオプションを忘れてしまいました。 JFrame.getInsets()は装飾に関する情報を提供します。単にレンダリングをシフトすることができます。

  2. フレームデコレーション(setUndecorated(true))を作成し、ウィンドウコントロールをレンダリング/管理します。

  3. または、それは簡単な方法だと思いますが、JFrameに直接レンダリングすることを忘れて、代わりにCanvasと置き換えてください。 CanvasにもcreateBufferStrategyメソッドが含まれているため、簡単な変更はほとんど必要ありません。

    JPanel drawPanel = new JPanel(); 
    drawPanel.setLayout(new BorderLayout()); 
    Canvas canvas = new Canvas(); 
    canvas.setPreferredSize(new Dimension(WIDTH, HEIGHT)); 
    drawPanel.add(canvas, BorderLayout.CENTER); 
    
    // some code skipped 
    
    canvas.setIgnoreRepaint(true); //important 
    canvas.createBufferStrategy(2); 
    
    buffy = canvas.getBufferStrategy(); 
    

私は類似して簡単なdemoを作成した別の答えのために数日前にレンダリングします。たぶん役立つでしょう。

+0

迅速な対応をありがとうございます。以前はキャンバスを使用していましたが、キャンバスを使用している間はJButtonを使用できませんでした。その問題に関する情報をフォーラムで確認したところ、私はこれに切り替えたので、うまくいかないと言われました。ボタンの問題は修正されましたが、現在の問題が発生し始めました。 Imは、setUndecoratedを使用しているときに問題が発生しました。「フレームは表示可能です。 –

+0

'setUndecorated'は' setVisible(true) 'の前に呼び出さなければなりません。 (JButtonsのような)軽量コンポーネントをヘビーな 'Canvas'と混合すると、多くの問題があります。常にボタンをレンダリングします。代わりに 'java.awt.Button'を使う価値があります。また、簡単なレンダリングボタンを実装することもできます。標準コンポーネントを使用するには、EDTからのパッシブレンダリングを意図していて、 'setIgnoreRepaint(true) 'で再描画イベントを無効にしたので、追加の作業が必要です。 – Mersenne

+0

hmmm ...私は本当に何をすべきか分からない。私のゲームは、フレーム内でクリックされたポイント上でアクションを行うマウスを使用します。したがって、インセットを使用してレンダーをシフトすると、入力がオフになります。 –

関連する問題