我正在学习Java2d,并且我试图使用Timer在x坐标中为我的图像设置动画,但是不起作用,这个想法是在时间帧之间,图像x值增加一个值使其移动,有人可以找出什么是我的代码中的问题?
以下是代码:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Screen extends JPanel {
int posX;
Timer timer;
private BufferedImage image;
public Screen() {
setDoubleBuffered(true);
posX = 1;
timer = new Timer();
timer.scheduleAtFixedRate(new Anima(), 100, 10);
//Smile Icon
try{
image = ImageIO.read(getClass().getResource("/smily.png"));
}catch(IOException e){
e.printStackTrace();
}
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(image,this.posX,100,null);
}
class Anima extends TimerTask{
public void run() {
posX += 20;
repaint();
}
}
public void incMove() {
posX += 20;
}
}
答案 0 :(得分:1)
两件主要的事情:
这意味着对象可以快速移出可见边界的一侧,通常更快,然后屏幕就可以在屏幕上实现。
你可以玩时间,但是,动画是随着时间的推移变化的幻觉,你可能会发现减少变化的大小而不是延迟(尽管100fps可能会要求更多;))
也没有边界检查,因此对象可以自由地移出可视区域,这可能是可取的,但可能至少暗示了你遇到的问题。
由于Swing不是线程安全的(您不应该从EDT的上下文之外更新UI),因此您也存在确定线程争用情况的风险。在这个例子中,它可能很难做到,但是你如何改变状态的概念是危险的。
因为Swing使用被动渲染引擎,所以在没有您的交互或知识的情况下,可能会随时发生绘制周期,因此您应该小心更新绘制方法在EDT上下文之外呈现状态所需的变量。 / p>
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Screen extends JPanel {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Screen());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
private int posX;
private int delta = 2;
public Screen() {
setDoubleBuffered(true);
posX = 1;
Timer timer = new Timer(10, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
incMove();
repaint();
}
});
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
Graphics2D g2d = (Graphics2D) g;
g2d.drawRect(this.posX, 100, 10, 10);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public void incMove() {
posX += delta;
if (posX + 10 > getWidth()) {
posX = getWidth() - 10;
delta *= -1;
} else if (posX < 0) {
posX = 0;
delta *= -1;
}
}
}
这个简单的示例使用Swing Timer
作为主要引擎,它减少了更改量(到2
)以及添加边界检查
答案 1 :(得分:0)
您的代码正常运行,但您的更新速度过快。
尝试
timer.scheduleAtFixedRate(new Anima(), 100, 1000);
检查动画。