用于屏幕外渲染的Java Graphics(2D)

kim*_*say 2 java graphics

我现在正在进入Java图形,我正在阅读Andrew Davison撰写的Java中的Killer游戏编程.他编写了一个简单的窗口应用程序,它使用Image类进行离屏渲染,然后将图像复制到组件.我觉得令人困惑的是,人们可以创建图像然后获取图形上下文:

dbg = dbImage.getGraphics();
Run Code Online (Sandbox Code Playgroud)

我发现它令人困惑,因为那时我们只使用dbg Graphics对象来绘制东西但后来我们在paintComponent方法中使用dbImage来显示我们绘制到dbg Object的所有东西:

g.drawImage(dbImage, 0, 0, null);
Run Code Online (Sandbox Code Playgroud)

那么dbImage如何"知道"它包含我们绘制到dbg Graphics对象上的所有图形内容?

这是整个代码:

public class GamePanel extends JPanel implements Runnable{

    private static final int PWIDTH = 500;
    private static final int PHEIGHT = 400;

    private Thread animator;

    private volatile boolean running = false;

    private volatile boolean gameOver = false;

    private Graphics dbg;
    private Image dbImage = null;

    private Counter counter;

    public GamePanel(){
        setBackground(Color.white);
        setPreferredSize(new Dimension(PWIDTH, PHEIGHT));

        // create game components eg. counter.
        counter = new Counter(10);
        counter.start();
    }

    private void stopGame(){
        running = false;
    }

    @Override public void addNotify(){
        super.addNotify();
        startGame();
    }

    public void startGame(){
        if(animator == null || !running){
            animator = new Thread(this);
            animator.start();
        }
    }

    @Override
    public void run() {
        running = true;
        while(running){
            gameUpdate();
            gameRender();
            repaint();
            try{
                Thread.sleep(20);
            }
            catch(InterruptedException ex){
                // do something with the exception...
            }
        }
    }

    private void gameUpdate(){
        if(!gameOver){
            // update game state...
             if(counter.getCounter() == 0)
                 gameOver = true;

        }
    }

    private void gameRender(){
        if(dbImage == null){
            dbImage = createImage(PWIDTH, PHEIGHT);
            if(dbImage == null){
                System.out.println("dbImage is null");
                return;
            }       
            else
                dbg = dbImage.getGraphics(); // get graphics context for drawing to off-screen images.
        }

        // clear the background
        dbg.setColor(Color.white);
        dbg.fillRect(0, 0, PWIDTH, PHEIGHT);

        // draw game elements here...
        dbg.setColor(Color.black);
        dbg.drawString(Integer.toString(counter.getCounter()), 10, 10);

        if(gameOver)
            dbg.drawString("Game over...", 10, 20);
    }

    @Override public void paintComponent(Graphics g){
        super.paintComponent(g);
        if(dbImage != null)
            g.drawImage(dbImage, 0, 0, null);
    }
}
Run Code Online (Sandbox Code Playgroud)

重要的部分只是paintComponent方法和gameRender()方法.

Rea*_*tic 5

基本上,Graphics对象是不是你画.这是你画的东西.

当你打电话时dbImage.getGraphics(),你说的是"给我一个允许我画这个图像的工具箱".对象中的所有绘制方法都在Graphics创建它的组件上绘制.它们不是绘制在Graphics对象上,而是绘制在对象上ImageComponent属于它的对象上.

Graphics对象视为调色板和画笔,并将其视为画布ImageComponent画布.

因此,当您完成对您的操作的运行时dbg,这意味着您拥有一个充满彩色像素的图像,此Graphics对象会在其上绘制.现在,您可以将此图像复制到另一个组件 - 使用该组件中的drawImage"工具" Graphics- 其"工具箱".

  • @kismay当然可以.但是特定的实现实际上取决于你拥有的组件/图像的类型,因为像素的每个这样的"光栅"可以在内存中以不同的方式组织像素.事实上,`getGraphics`为您提供了一个专门为您正在使用的图像构建的自定义对象.它恰好继承自`Graphics2D`. (2认同)