2012-03-07 2 views
1

Im работает над игрой на 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

Где это заявление печати? (извините, если я пропустил это) –

ответ

2

0,0 координата Graphics объекта вы получаете от buffy.getDrawGraphics(); именно в левом верхнем углу JFrame и игнорирует украшения кадра.

  1. UPD Я забыл один очевидный вариант. 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

Большое спасибо за быстрый ответ. Я ранее использовал холст, но не смог использовать JButtons при использовании холста. Я проверил на форумах информацию об этой проблеме, и мне сказали, что она просто не работает, поэтому я переключился на это. он исправил проблему с кнопкой, но затем возникла текущая проблема. Я получаю проблему при использовании setUndecorated «Рамка может отображаться». –

+0

'setUndecorated' должен быть вызван до' setVisible (true) '. При смешивании легких компонентов (например, 'JButtons') с тяжеловесным« холстом »возникает множество проблем. Он всегда перелистывает кнопки. Возможно, стоит использовать 'java.awt.Button' вместо этого. Или даже реализовать собственные простые отображаемые кнопки. Использование стандартных компонентов требует дополнительной работы, поскольку они предназначены для пассивного рендеринга из EDT, и мы отключили события перерисовки с помощью 'setIgnoreRepaint (true)'. – Mersenne

+0

hmmm ... им действительно не уверен, что делать. В моей игре используется мышь, которая основывает действия на точках, щелкнувших внутри рамки, поэтому, если я сдвигаю рендер с помощью вставки, тогда мой вход отключен. –

Смежные вопросы