Java 在两个图像之间快速切换?
我想用两张快速切换的图像来制作一个对象,让它张开嘴并合上嘴。我尝试了一个for循环,但它使我的比赛落后了Java 在两个图像之间快速切换?,java,image,Java,Image,我想用两张快速切换的图像来制作一个对象,让它张开嘴并合上嘴。我尝试了一个for循环,但它使我的比赛落后了 if(direction == Constant.UP){ ImageIcon i = new ImageIcon("src\\images\\pacman up.png"); image = i.getImage(); ImageIcon i2 = new ImageIcon("src\\images\\pacman left.png"
if(direction == Constant.UP){
ImageIcon i = new ImageIcon("src\\images\\pacman up.png");
image = i.getImage();
ImageIcon i2 = new ImageIcon("src\\images\\pacman left.png");
image = i2.getImage();
}
G.drawImage(image, x, y, 20,20,null);
不要每次都创建图标。在启动时创建两个映像,然后切换回来 在运行时来回移动
if(direction == Constant.UP){
image = open;
}else {
image = closed;
}
G.drawImage(image, x, y, 20,20,null);
不要每次都创建图标。在启动时创建两个映像,然后切换回来 在运行时来回移动
if(direction == Constant.UP){
image = open;
}else {
image = closed;
}
G.drawImage(image, x, y, 20,20,null);
Swing中的任何动画都需要考虑 您不应在EDT内容内执行任何可能阻止它的操作(如循环或I/O),因为这将阻止EDT(除其他外)处理绘制请求 您应该始终使用能够支持双缓冲区的表面,例如
JPanel
,因为这将有助于消除闪烁
下面使用javax.swing.Timer
在两个图像之间切换
public class TestPacMan {
public static void main(String[] args) {
new TestPacMan();
}
public TestPacMan() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PacManPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PacManPane extends JPanel {
private BufferedImage pacOpened;
private BufferedImage pacClosed;
private BufferedImage frame;
private boolean opened = true;
public PacManPane() {
try {
pacOpened = ImageIO.read(new File("PC-Closed.png"));
pacClosed = ImageIO.read(new File("PC-Opened.png"));
frame = pacOpened;
} catch (IOException exp) {
exp.printStackTrace();
}
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
opened = !opened;
frame = opened ? pacOpened : pacClosed;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (frame != null) {
int x = (getWidth() - frame.getWidth()) / 2;
int y = (getHeight() - frame.getHeight()) / 2;
g2d.drawImage(frame, x, y, this);
}
g2d.dispose();
}
}
}
Swing中的任何动画都需要考虑 您不应在EDT内容内执行任何可能阻止它的操作(如循环或I/O),因为这将阻止EDT(除其他外)处理绘制请求 您应该始终使用能够支持双缓冲区的表面,例如
JPanel
,因为这将有助于消除闪烁
下面使用javax.swing.Timer
在两个图像之间切换
public class TestPacMan {
public static void main(String[] args) {
new TestPacMan();
}
public TestPacMan() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new PacManPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PacManPane extends JPanel {
private BufferedImage pacOpened;
private BufferedImage pacClosed;
private BufferedImage frame;
private boolean opened = true;
public PacManPane() {
try {
pacOpened = ImageIO.read(new File("PC-Closed.png"));
pacClosed = ImageIO.read(new File("PC-Opened.png"));
frame = pacOpened;
} catch (IOException exp) {
exp.printStackTrace();
}
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
opened = !opened;
frame = opened ? pacOpened : pacClosed;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (frame != null) {
int x = (getWidth() - frame.getWidth()) / 2;
int y = (getHeight() - frame.getHeight()) / 2;
g2d.drawImage(frame, x, y, this);
}
g2d.dispose();
}
}
}
这还不够。“我试过使用for循环”让我担心,因为这实际上会阻塞UI,但听起来你好像在某处使用线程……1)为了更快地获得更好的帮助,请发布一条消息。2) 但是作为一般提示,在构建组件实例时加载图像并将其存储为类级属性。3) 如果
G
是图形实例,则应将其称为G
。此外,如果它来自一个组件,它将有一个ImageObserver
-sog.drawImage(图像,x,y,20,20,这个)代码>。这还不够。“我试过使用for循环”让我担心,因为这实际上会阻塞UI,但听起来你好像在某处使用线程……1)为了更快地获得更好的帮助,请发布一条消息。2) 但是作为一般提示,在构建组件实例时加载图像并将其存储为类级属性。3) 如果G
是图形实例,则应将其称为G
。此外,如果它来自一个组件,它将有一个ImageObserver
-sog.drawImage(图像,x,y,20,20,这个)
。如果G
来自一个组件,它将有一个ImageObserver-soG.drawImage(图像,x,y,20,20,这个)
。甚至更好:g.drawImage(方向==Constant.UP?打开:关闭,x,y,20,20,null)三个字的表达让我觉得很冷。我更喜欢if-else。如果G
来自一个组件,它将有一个ImageObserver-soG.drawImage(图像,x,y,20,20,这个)
。甚至更好:g.drawImage(方向==Constant.UP?打开:关闭,x,y,20,20,null)三个字的表达让我觉得很冷。我更喜欢别的。