双缓冲 JFrame

发布于 2025-01-07 18:41:19 字数 2532 浏览 1 评论 0原文

当我开发 2D 游戏时,我阅读了很多有关双缓冲的内容。我遇到过许多不同的实施策略,但不确定双缓冲如何适合我创建游戏窗口的方式。例如,我遇到的一篇文章(http://content.gpwiki.org/index.php/Java:Tutorials:Double_Buffering)建议采用单独的绘图方法;但是,我怀疑如果您绘制形状而不是向窗口添加组件,这将适用。

这是我的主要 GUI 代码(省略了 keylistener 方法)

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。

问候, 杰克。

I have been reading a lot about Double Buffering as I am working on a 2D game. I have come across many different strategies for implementation, but am unsure how Double Buffering would fit into the way I have created my game window. For example, one article I came across (http://content.gpwiki.org/index.php/Java:Tutorials:Double_Buffering) suggested having a separate method for drawing; however, I suspect this would be applicable if you were drawing shapes, instead of adding components to the window.

Here is my main GUI code (keylistener methods omitted)

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;
    }
}
}

How would you recommend I approach this? Bearing in mind that the Board is a JPanel consisting of a grid of scaled images, and the sprite will be a JComponent displaying a scaled image.

Regards,
Jack.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

未蓝澄海的烟 2025-01-14 18:41:19

重写 JPanel 的 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);  
}

Override the JPanel's paintComponent() Method and paint the content into a BufferedImage image first. Once done, copy the content of the BufferedImage into the graphics context you get from 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);  
}
海风掠过北极光 2025-01-14 18:41:19

由于 Java 图形库速度不快,功能也不好,您应该了解一下“轻量级 Java 游戏库”( http:// lwjgl.org/)。它使用 OpenGL,一个强大的图形库,使用本机代码。
Lwjgl 也用于《我的世界》游戏。
此外,OpenGL适用于不同的语言,因此您可以学习多功能和高级编程。

As the Java Graphics Library is not fast, either well functional, you should inform yourself about the 'Lightweight Java Game Library' ( http://lwjgl.org/ ). It uses OpenGL, a strong Graphics Library, using native code.
Lwjgl is also used for the game Minecraft.
Also, OpenGL is used for different languages, so you could learn multi-functional and high-level programming.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文