Java Upper Boundary Graphics

2019-01-29 09:46发布

问题:

Regarding this short video of basic collision detection:

https://www.youtube.com/watch?v=ptqhnmP8FY0&list=PL6E90696571998DC2

Can someone tell me why the upper boundary needs to be the size of the ball? I thought that an oval was drawn with a bounding rectangle starting from the upper left. If that is the case then it would seem that y==0 would be the upper boundary, but that is obviously not the case.

Summary question: why is the upper boundary 20 and not 0 if the bounding triangle starts in the upper left.

Here is the code:

public class JavaGame extends JFrame {

int x,y,sizeX = 350,sizeY=350;
//boolean erase = false;

private Image dbImage;
private Graphics dbg;

public class AL extends KeyAdapter{

    public void keyPressed(KeyEvent e){
        int keyCode = e.getKeyCode(); 

        if (keyCode == e.VK_LEFT){

            if(x<= 0)
                x=0;
            else
                x-=5;
        }
        if (keyCode == e.VK_RIGHT){
            if(x==sizeX-20)
                x=sizeX-20;
            else
                x+=5;
        }if (keyCode == e.VK_UP){
            if(y==20)
                y=20;
            else
            y-=5;
        }if (keyCode == e.VK_DOWN){
            if(y==sizeY-20)
                y=sizeY-20;
            else
            y+=5;
        }

        /*if (keyCode == e.VK_S){
            erase = true;
        }*/
    }
    public void keyReleased(KeyEvent e){

    }
}

public JavaGame(){
    addKeyListener(new AL());
    x=y=150;
    setTitle("Java Game");
    setBackground(Color.WHITE);
    setSize(sizeX,sizeY);
    setResizable(false);
    setVisible(true);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}


public void paint(Graphics g){

    dbImage = createImage(getWidth(), getHeight());
    dbg = dbImage.getGraphics();
    paintComponent(dbg);
    g.drawImage(dbImage, 0, 0, this);

}

public void paintComponent(Graphics g){

    g.fillOval(x, y, 20, 20);

    /*if(erase){
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, 500, 500);
        erase = false;
    }*/

    repaint();


}

public static void main(String[] args) {


    new JavaGame();

}

}

回答1:

Its the height of title bar of JFrame that's why y starts visible after 22.

Same for x that starts visible from 2 due to JFrame outer border width.

Here is the sample code along with snapshot

    g.setColor(Color.RED);
    g.drawRect(3, 22, 200, 200);

--EDIT--

I never suggest you to use it. Read below comments for it's drawbacks.



回答2:

The main problem is, overriding paint of JFrame is allowing you to paint under the frames decorations.

This is one of, the many, reasons why you should avoid overriding paint on a top level container.

As discussed:

  • How to get the EXACT middle of a screen, even when re-sized
  • Java AWT drawString() does not display on window
  • How can I set in the midst?
  • Java graphic image
  • Graphics rendering in title bar

In Swing it is generally recommended to perform custom painting within the paintComponent method of a component that extends from JComponent, like JPanel.

This not only allows you to decouple of output from a specific container (JFrame), it also ensures that when added to a top level container, it only occupies the viewable area of the window and does not render under the frames borders.

JComponent based components also benefit from been double buffered, meaning that you don't need to implement your own double buffering strategy, but it won't flicker between repaints

Also, you MUST call the super method before you perform any of your own custom painting, failing to do so can produce paint artifacts

Take a look at Painting in AWT and Swing and Performing Custom Painting for more details

Side Notes:

You should also avoid the user of KeyListener as they are notorious for having focus related issues. Instead you should make use of the Key Bindings API