只是希望人们可以帮助我正确理解 RepaintManager 在尝试创建动画时是如何工作的。基本上我正在创建一个将生物/图像绘制和更新到 JFrame 的程序。每个生物对象都包含用于绘制它的所有信息,例如 x,y 坐标和 BufferedImage。目前,每次生物对象移动时,它都会调用 repaint(),正如您将在下面的我的paint/paintComponent(不确定哪个是最好的)方法中看到的那样,它将在所有现有生物中运行一个循环并更新它们在屏幕上的位置和图形.
所以我的查询,这是最好的方法,因为我担心 RepaintManager 正在重绘屏幕上的所有内容,这不是很有效。我阅读了一些关于剪辑或覆盖更新方法的帖子/文章,但我无法完全理解它们 - 所以每次调用 repaint 时它是否可能只更新已更改的对象/生物?
我正在谈论的一些代码:
public void paintComponent (Graphics g) {
super.paintComponent(g);
//setDoubleBuffered(true); //Probably not needed?
Graphics2D g2d = (Graphics2D) g;
//Draws the land area for penguins.
g2d.setColor(new Color(121,133,60));
g2d.fill3DRect(land.x, land.y, land.width, land.height, true);
//OR g2d.fill(land);
g2d.setColor(Color.BLUE);
g2d.fill(sea);
drawCreatures(g2d);
}
绘制方法中的所有图形都不会改变,也不需要重新绘制,但是下面的方法将......
private void drawCreatures(Graphics2D g2d) {
try {
for (Creature c : crlist) {
g2d.drawImage(c.createImage(txs,tys), c.getPos(1).width, c.getPos(1).height, this);
//g2d.drawImage(cImg,c.getPos(1).width,c.getPos(1).height,this);
if (c instanceof Fish && c.getMating().equals(Mating.WBABY)) {
int xos=0;
for (Creature fb : c.getChildren()) {
if (fb.getMating().equals(Mating.BABY)) g2d.drawImage(fb.createImage(txs,tys),c.getPos(1).width+xos,c.getPos(1).height+50,txs/2,tys/2,this);
xos+=25;
}
}
if (c.getInfo()==true) displayInfo(g2d,c); //This changes when a creature is clicked on.
else if (c.getState()!=State.NORMAL || c.getMating().equals(Mating.LOVE)) drawState(g2d,c); //updated through a creature's move/search methods.
}
}
catch(ConcurrentModificationException cme) { System.out.println("CME ERROR!"); }
}
重要的部分是增强 for 循环的第一行,因为它将图像绘制到 JFrame 窗口。createImage 方法只是获取生物图像并转换/修改,例如当它们在绘制使用它之前向左移动时翻转它。
动画目前由每个运行线程的生物处理,但是我也想知道 Swing Timer 是否会更好,因为当一个生物尝试将新生物添加到 crlist 时,我目前正在收到 ConcurrentModificationException。
private class Creature implements Behaviours<Creature>, Runnable {
//...variables
//...constructor
//...methods for updating the creature/object
@Override
public void run() {
while (getState()!=State.DEAD) {
move(); //where the coordinates of a creature is updated.
repaint();
try { Thread.sleep(1000); }
catch(InterruptedException e) {}
}
}
因此,每个生物移动和重绘每 1 秒就会被调用一次,但我想要一种方法,要么不必循环遍历绘制中的每个生物,要么确保在调用重绘时它只更新调用它的生物。
任何建议或只是将我指向另一个帖子将不胜感激。谢谢。