繁体   English   中英

停止 JPanel 的 paintComponent 方法绘制背景

[英]Stop JPanel's paintComponent method from painting the background

我正在 Java 中制作蛇游戏。

为了提高效率,我只绘制改变了这一帧的位置(蛇的第一个和最后一个单元格)。

这是我的代码:

public class GameCanvas extends JPanel {

private final List<GameChange> changes;

public GameCanvas() {
    setBackground(Color.darkGray);

    changes = new ArrayList<>();
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D) g;

    for (GameChange change : changes) {
        Vector2 pos = change.position;
        int val = change.value;

        if (val != 0) g2d.setColor(Color.BLACK);
        else g2d.setColor(Color.WHITE); //getBackground();

        g2d.fillRect(GameWindow.pixelSize * pos.x,GameWindow.pixelSize * pos.y, GameWindow.pixelSize, GameWindow.pixelSize);
    }

    changes.clear();
}

public void applyChanges(List<GameChange> changes) {
    this.changes.addAll(changes);
    repaint();
}
}

唯一的问题是paintComponent方法正在重新绘制背景并且蛇的中间正在消失。

黑色单元格是新头,白色单元格是我要删除的那个。 中间的牢房应该是黑色的。

编辑:

每个人都告诉我画整个 map 但我真的很想提高性能。 这是我到目前为止所做的:

private void paintChanges(List<GameChange> changes) {
    Graphics2D g2d = (Graphics2D) getGraphics();

    // Here I paint only the changes
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;

    // Here I paint everything
}

当蛇移动时,我只绘制变化,但如果框架自动重新绘制,蛇不会消失。 它似乎正在工作,但我不确定使用getGraphics()方法是否安全。

这显然不是你的游戏,但它可能有助于消除你需要做一些特别的事情来提高绘画效率的观念。

  • 要创建蛇,请按住左键并拖出一条曲线。
  • 然后释放按钮并在面板中移动鼠标并观察"snake"跟随鼠标。
  • 您可以随时通过拖动鼠标添加更多点。

这可以通过简单地创建一个点列表并在它们之间画一条线来实现。 当鼠标移动时,它会删除第一个点并将当前点添加到末尾。 paint 方法只是为每次鼠标移动遍历列表并绘制所有线条,从而呈现出移动的外观。

这有一个明显的(也许还有其他不那么明显的)缺陷。 点的数量是恒定的,但蛇的大小expandscontracts ,因为随着鼠标移动得更快,点会分散开,因此点之间的线会更长。 但这与绘画无关,而是与鼠标移动的速度有关。

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SimpleSnake extends JPanel {
    JFrame frame = new JFrame("Simple Snake");
    List<Point> snake = new ArrayList<>();
    final static int WIDTH = 500;
    final static int HEIGHT = 500;
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()-> new SimpleSnake());
    }
    public SimpleSnake() {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addMouseMotionListener(new MyMouseListener());
        setBackground(Color.white);
        frame.add(this);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(WIDTH, HEIGHT);
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (snake.size() < 2) {
            return;
        }
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setColor(Color.black);
        g2d.setStroke(new BasicStroke(3)); // line thickness
        Point start = snake.get(0);
        for(int i = 1; i < snake.size(); i++) {
            Point next = snake.get(i);
            g2d.drawLine(start.x, start.y, next.x, next.y);
            start = next;
        }
        g2d.dispose();
    }
    
    public class MyMouseListener extends MouseAdapter {
        public void mouseDragged(MouseEvent me) {
            snake.add(new Point(me.getX(), me.getY()));
            repaint();
        }
        
        public void mouseMoved(MouseEvent me) {
            if(snake.isEmpty()) {
                return;
            }
            snake.remove(0);
            snake.add(new Point(me.getX(), me.getY()));
            repaint();
        }       
    }
}

暂无
暂无

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

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