简体   繁体   中英

How to stop JComponent.setLocation() from causing a repaint?

I'm trying to achieve camera shake for my game by randomly setting the location of the JPanel which everything in the game is drawn on. After a bit of experimentation, I am certain that JPanel.setLocation(Point p) triggers a repaint, which I don't want to happen.

So the way I create screen shake is by specifying the intensity and the frames it should last. However, the effect always wore off far too quickly, so I did some experimentation. I found that the paintComponent(Graphics g) method of the JPanel was triggered multiple times within one frame, but only while there was screen shake (how really does not add much to the point).

This is how the effect is generated:

public void display(){
  framesAlive++; //<-- used to track when the effect has worn off
  int intensityX = (int) (Math.random() * vals[0] - vals[0] / 2);
  int intensityY = (int) (Math.random() * vals[0] - vals[0] / 2);
  pane.setLocation(new Point(intensityX, intensityY));
}

And this is the simplified version of the paintComponent method:

@Override
protected void paintComponent(Graphics g){
  super.paintComponent(g);
  for (int i = 0; i < stockEffects.size(); i++) {
    stockEffects.get(i).display(g);
  }
}

Again, my guess is that setLocation() causes a repaint, which basically results in an infinite loop in which the paintComponent() method triggers the display() function, which triggers setLocation() , which triggers a repaint that starts the whole cycle again. This results in the framesAlive variable being incremented multiple times per frame, which throws the whole timing system off. Is there an elegant way to solve this?

you can use AffineTransform. this don't have to change objects real location.

it just change how to draw. you can shake, rotate, flip, scale etc....

public static void main (String[] arg) {
    MainFrame mainFrame = new MainFrame();
    mainFrame.setVisible(true);
}

public static class MainFrame extends JFrame{
    public MainFrame() {
        this.setSize(600,600);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        MainPanel mainPanel = new MainPanel();
        this.add(mainPanel);
    }
}

public static class MainPanel extends JPanel{
    public void paint(Graphics g) {
        super.paint(g);
        // Panel Size = 400 X 400
        g.drawLine(200, 0, 200, 400); // Y Axis
        g.drawLine(0, 200, 400, 200); // X Axis

        // Create Transform
        AffineTransform at = new AffineTransform();
        at.translate(200, 200); // Move Center Form (0, 0) To JPanel Center (200, 200)

        // Change Transform 
        at.translate(-200, 0); // Move Center

        // Set Transform To Graphics2D
        Graphics2D g2d = (Graphics2D) g;
        g2d.setTransform(at);

        // Draw Rectangle By Graphics2D
        g2d.fillRect(100, 100, 100, 100);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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