Рендеринг изображения вне кадра? - PullRequest
1 голос
/ 08 марта 2012

Я работаю над игрой на Java и у меня возникла проблема (я считаю, это связано с областью содержимого) при рендеринге.У меня есть класс экрана, который рисует фон и все спрайты в изображение.Затем кадр отображает изображение, используя двойной буфер.По какой-то странной причине изображение рендерит с края кадра.Из приведенной ниже ссылки видно, что изображение отображается на 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();
}
}

1 Ответ

2 голосов
/ 08 марта 2012

Координата 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 с похожим рендерингом несколько дней назаддля другого ответа.Может быть, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...