简体   繁体   English

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

[英]Java Graphics(2D) for offscreen rendering

I'm getting into Java graphics at the moment and I'm reading the book Killer game programming in Java by Andrew Davison. 目前,我正在学习Java图形,并且正在阅读Andrew Davison撰写的《用Java杀手游戏编程》一书。 He programs a simple window application that uses the Image class for off-screen rendering and then copying the image to the component. 他编写了一个简单的窗口应用程序,该应用程序使用Image类进行屏幕外渲染,然后将图像复制到组件。 What I find confusing is that one can just create the image and then get the graphics context with: 我感到困惑的是,人们只能创建图像,然后使用以下命令获取图形上下文:

dbg = dbImage.getGraphics();

I find it confusing, because then we only use the dbg Graphics object to draw stuff but later on we use the dbImage in the paintComponent method to display all the stuff we have drawn to the dbg Object: 我发现这很令人困惑,因为那时我们只使用dbg Graphics对象绘制东西,但是后来我们在paintComponent方法中使用dbImage来显示绘制到dbg对象的所有东西:

g.drawImage(dbImage, 0, 0, null);

So how does the dbImage "know", that it contains all the graphics stuff we have drawn onto the dbg Graphics object? 那么dbImage如何“知道”它包含我们已绘制到dbg Graphics对象上的所有图形内容?

Here is the whole code: 这是完整的代码:

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

the important parts are only the paintComponent method and the gameRender() method though. 重要的部分不过是paintComponent方法和gameRender()方法。

Basically, a Graphics object is not something you draw on . 基本上,一个Graphics对象是不是你借鉴 It's something you draw with . 这是您使用的东西。

When you call dbImage.getGraphics() , you are saying "Give me a toolbox that allows me to draw on this image". 当您调用dbImage.getGraphics() ,您说的是“给我一个允许我在此图像上绘画的工具箱”。 All of the draw methods in a Graphics object draw on the component for which it was created. Graphics对象中的所有draw方法都在为其创建组件的组件上绘制。 They are not drawn on the Graphics object, they are drawn on the Image or the Component that belong to it. 它们不是在Graphics对象上绘制的,而是在Image或属于它的Component上绘制的。

Think of the Graphics object as the palette and brushes, and on the Image or Component as the canvas. Graphics对象视为调色板和画笔,并将ImageComponent视为画布。

So when you are done running the operations with your dbg , it means you have an image full of colorful pixels that this Graphics object drew on it. 因此,当您完成使用dbg运行操作时,这意味着您将在此Graphics对象上绘制一个充满彩色像素的图像。 Now you can take this image and copy it to another component - by using the drawImage "tool" in that component's Graphics - its "toolbox". 现在,您可以获取此图像并将其复制到另一个组件-通过使用该组件的GraphicsdrawImage “ tool”-其“工具箱”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM