gpt4 book ai didi

Java AWT/Swing 何时使用 repaint() 方法?

转载 作者:行者123 更新时间:2023-11-30 03:05:14 26 4
gpt4 key购买 nike

我编写了一个生成贪吃蛇游戏中的“蛇”的代码以供练习。(如果您不熟悉贪吃蛇游戏中的蛇,它是一条 5 格长的蛇,有一个头部(使用 JLabel 创建)和跟随头部的 body 部位(也使用 JLabels 创建)。)

import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;

public class SnakeGameFrame extends JFrame {
Thread snakeThread;
GroundPanel p;
public SnakeGameFrame() {
super("Moving Snake!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

p = new GroundPanel();
setContentPane(p);
setSize(400,400);
setVisible(true);
p.requestFocus();
snakeThread = new Thread(p);
snakeThread.start();
}

class GroundPanel extends JPanel implements Runnable{
static final int LEFT = 0;
static final int RIGHT = 1;
static final int UP = 2;
static final int DOWN = 3;
int direction;
Image img;
SnakeBody snakeBody;
final int delay = 200;
public GroundPanel() {
setLayout(null);
snakeBody = new SnakeBody();
snakeBody.addIn(this);
direction = LEFT;
this.addKeyListener(new MyKeyListener());
ImageIcon icon = new ImageIcon("twilight.jpg");
img = icon.getImage();
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0,0,getWidth(), getHeight(), null);
}
public void run() {
while(true) {
try {
Thread.sleep(delay);
snakeBody.move(direction);
}catch(InterruptedException e) {
return;
}
}
}

class MyKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
direction = LEFT;
break;
case KeyEvent.VK_RIGHT:
direction = RIGHT;
break;
case KeyEvent.VK_UP:
direction = UP;
break;
case KeyEvent.VK_DOWN:
direction = DOWN;
break;
}
}
}
}

class SnakeBody {
Vector<JLabel> v = new Vector<JLabel>();

public SnakeBody() {
ImageIcon head = new ImageIcon("head.jpg");
JLabel la = new JLabel(head);
la.setSize(head.getIconWidth(), head.getIconHeight());
la.setLocation(100, 100);
v.add(la);

ImageIcon body = new ImageIcon("body.jpg");
for(int i=1; i<10; i++) {
la = new JLabel(body);
la.setSize(body.getIconWidth(), body.getIconHeight());
la.setLocation(100+i*20, 100);
v.add(la);
}
}

public void addIn(JPanel p) {
for(int i=0; i<v.size(); i++)
p.add(v.get(i));
}

public void move(int direction) {
for(int i=v.size()-1; i>0; i--) {
JLabel b = v.get(i);
JLabel a = v.get(i-1);
b.setLocation(a.getX(), a.getY());
}
JLabel head = v.get(0);
switch(direction) {
case GroundPanel.LEFT :
head.setLocation(head.getX()-20, head.getY());
break;
case GroundPanel.RIGHT :
head.setLocation(head.getX()+20, head.getY());
break;
case GroundPanel.UP :
head.setLocation(head.getX(), head.getY()-20);
break;
case GroundPanel.DOWN :
head.setLocation(head.getX(), head.getY()+20);
break;
}
}
}

public static void main(String[] args) {
new SnakeGameFrame();
}
}

我的问题是为了继续“更新”我的蛇,我想我必须在我的蛇中使用 repaint() 方法

public void run()

方法。像这样

try { Thread.sleep(delay); snakeBody.move(direction); repaint(); }

但事实证明,没有它它也能正常工作..我读过很多关于 repaint() 的文章,但我仍然不知道何时需要使用它。有人可以用菜鸟友好的术语解释一下吗?谢谢:)

最佳答案

只要 RepaintManager 尚未代表您执行此操作(例如更新文本或颜色等绑定(bind)属性),您就必须调用 repaint()。在您的示例中,更改 JLabel 的大小和位置会自动触发重绘。

更严重的是,您的示例以两种方式错误地同步:

相反,请使用 javax.swing.Timer调整动画的节奏。您的 actionPerformed() 实现将在事件调度线程上调用。

关于Java AWT/Swing 何时使用 repaint() 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34975768/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com