簡體   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