Java 停止JPanel';从绘制背景开始绘制组件方法
我正在用Java做一个蛇游戏 为了提高效率,我只画改变了这个框架的位置(蛇的第一个和最后一个单元格) 这是我的密码:Java 停止JPanel';从绘制背景开始绘制组件方法,java,swing,jframe,Java,Swing,Jframe,我正在用Java做一个蛇游戏 为了提高效率,我只画改变了这个框架的位置(蛇的第一个和最后一个单元格) 这是我的密码: public class GameCanvas extends JPanel { private final List<GameChange> changes; public GameCanvas() { setBackground(Color.darkGray); changes = new ArrayList<>(); } pu
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();
}
}
当蛇移动时,我只绘制变化,但如果框架自动重新绘制,蛇不会消失。它似乎在工作,但我不确定使用
getGraphics()
方法是否安全。这显然不是你的游戏,但它可能有助于消除你需要做一些特殊事情来提高绘画效率的想法
- 要创建蛇,请按住左键并拖出一条曲线
- 然后松开按钮,在面板中移动鼠标,观察
跟随鼠标“snake”
- 您可以随时通过拖动鼠标添加更多点
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();
}
}
}
这其中有一个明显的(也许还有另一个不那么明显的)缺陷。点的数量是恒定的,但由于点随着鼠标移动速度的加快而展开,因此点之间的线更长,因此蛇的大小会扩展和收缩。但这与绘画无关,而是与鼠标移动的速度有关
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();
}
}
}
import java.awt.BasicStroke;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类SimpleSnake扩展了JPanel{
JFrame=新JFrame(“简单蛇”);
List snake=new ArrayList();
最终静态整数宽度=500;
最终静态内部高度=500;
公共静态void main(字符串[]args){
调用器(()->new SimpleSnake());
}
公共SimpleSnake(){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addMouseMotionListener(新的MyMouseListener());
挫折地面(颜色:白色);
框架。添加(此);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
@凌驾
公共维度getPreferredSize(){
返回新尺寸(宽度、高度);
}
@凌驾
公共组件(图形g){
超级组件(g);
if(snake.size()<2){
返回;
}
Graphics2D g2d=(Graphics2D)g.create();
g2d.setColor(Color.black);
g2d.设定行程(新基本行程(3));//线厚度
点开始=snake.get(0);
对于(inti=1;i
这不是paintComponent
的工作方式,调用时,您需要更新整个组件。你“可以”做三角洲的过程,但它需要油漆旧的地区(清除有什么)和新的地区。您也可以考虑使用其中一种方法,它允许您指定要更新的区域以使其高效——不必担心效率。您可以轻松地重新绘制蛇的3个单元格,没有问题。您不需要显式删除任何内容。您只需不断地重新绘制整个背景,其中应包括新位置。但是,通过额外的逻辑,可以仅使用剪辑区域绘制已更改的区域。但是对于这么简单的东西,它是没有必要的。