Двойная буферизация JFrame

Я много читал о двойной буферизации, когда работаю над 2D-игрой. Я сталкивался со многими различными стратегиями реализации, но не уверен, как двойная буферизация впишется в то, как я создал свое игровое окно. Например, в одной статье, с которой я столкнулся (http://content.gpwiki.org/index.php/Java:Tutorials:Double_Buffering), предлагалось использовать отдельный метод для рисования; однако я подозреваю, что это было бы применимо, если бы вы рисовали фигуры, а не добавляли компоненты в окно.

Вот мой основной код графического интерфейса (методы прослушивания ключей опущены)

public class MainWindow extends JFrame implements KeyListener{
private Dimension dim;
private CardLayout layout;
private JPanel panel;
private JLayeredPane gameLayers;
private Menu menu;
private MiniGame miniGame;
private Board board;
private Sprite sprite;
private Game game;
private Map map;
private GameState gs;

private Boolean[] keys;


public MainWindow(Game game, GameState gs, Map map, Sprite sprite){
    //Call superclass.
    super();

    addKeyListener(this);

    //Sore references to critical game components.
    this.game = game;//So we can call methods when an event occurs.
    this.gs = gs;
    this.map = map;//Used to construct the board.
                    //The board needs to know the layout of the map.
    this.sprite = sprite;//Used to add the sprite to one of the layers.

    //Instantiate objects.
    dim = new Dimension(800, 600);
    layout = new CardLayout();
    panel = new JPanel(layout);
    menu = new Menu();
    miniGame = new MiniGame();
    board = new Board(map);
    gameLayers = new JLayeredPane();

    //Remove decoration and place window in center of screen.
    setUndecorated(true);
    Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
    setBounds((screenDim.width /2)-(dim.width/2),
            (screenDim.height/2)-(dim.height/2),
            dim.width,
            dim.height);

    //Add the board to a layer.
    gameLayers.add(board, JLayeredPane.DEFAULT_LAYER);
    board.setBounds(0, 0, dim.width, dim.height);
    board.setBoard();

    //Add the sprite to a layer.
    gameLayers.add(sprite, JLayeredPane.PALETTE_LAYER);
    sprite.setBounds(0, 0, 50, 50);

    //Add components to window.
    panel.add(gameLayers, "gameLayers");
    panel.add(miniGame, "miniGame");
    panel.add(menu, "menu");

    //Add the "cards" to the window.
    add(panel);

    //JFrame housekeeping.
    pack();
    setSize(dim);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setResizable(false);
    setVisible(true);

    //Holds state when an event is triggered.
    //Ugly hack to circumvent delay issue.
    keys = new Boolean[4];
    for(int i=0; i<keys.length; i++){
        keys[i] = false;
    }
}
}

Как бы вы порекомендовали мне подойти к этому? Имея в виду, что Board — это JPanel, состоящий из сетки масштабированных изображений, а спрайт будет JComponent, отображающим масштабированное изображение.

С уважением, Джек.


person Jack H    schedule 20.02.2012    source источник


Ответы (2)


Переопределите метод paintComponent() JPanel и закрасьте содержимое в BufferedImage изображение сначала. После этого скопируйте содержимое BufferedImage в графический контекст, который вы получаете от paintComponent().

protected void paintComponent(Graphics g) 
{
    BufferedImage bufferedImage = new BufferedImage(500, 500, BufferedImage.TYPE_ARGB);
    Graphics2D g2d = bufferedImage.createGraphics();
    //paint using g2d ...

    Graphics2D g2dComponent = (Graphics2D) g;
    g2dComponent.drawImage(bufferedImage, null, 0, 0);  
}
person Simon    schedule 20.02.2012
comment
JPanel по умолчанию имеет двойную буферизацию. - person trashgod; 21.02.2012
comment
Да, ты прав. Только что увидел в документации. Однако должен работать как общий подход к двойной буферизации в Swing. - person Simon; 21.02.2012
comment
Да, BufferedImage хорош для создания промежуточного звена, например. наложение. - person trashgod; 21.02.2012
comment
JPanel не удваивал буфер для меня. Однако BufferedImage работал. - person Nuclear_Man_D; 19.05.2018

Поскольку графическая библиотека Java не является быстрой или хорошо функциональной, вам следует ознакомиться с «облегченной библиотекой игр Java» ( http://lwjgl.org/). Он использует OpenGL, мощную графическую библиотеку, используя собственный код. Lwjgl также используется для игры Minecraft. Кроме того, OpenGL используется для разных языков, поэтому вы можете научиться многофункциональному и высокоуровневому программированию.

person Thomas    schedule 20.02.2012