Ped*_*edo -1 java animation swing timer jpanel
有人可以告诉我如何减慢精灵的出现速度以创建更流畅的动画吗?当我运行代码时,它出现在 JPanel 中的最后一个(第 27 个)精灵。动画处理速度太快了!
有人告诉我有关 Swing Timer 的信息,但不幸的是我尝试了几次,但无法让代码运行良好:(
这是我到目前为止的代码:
package sprites;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Sprites extends JFrame {
public static void main(String[] args) {
JFrame frm1 = new JFrame();
frm1.setSize(400, 400);
frm1.setLocationRelativeTo(null);
frm1.setResizable(false);
frm1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Painel1 pn1 = new Painel1();
frm1.getContentPane().add(pn1);
frm1.setVisible(true);
}
}
class Painel1 extends JPanel {
BufferedImage img;
public Painel1() {
setBackground(Color.yellow);
try
{
img = ImageIO.read(new File("images/dummy.png"));
}
catch (IOException e)
{}
}
@Override
public void paintComponent(Graphics g) {
int[][] spriteSheetCoords = {{8, 10, 119, 129},
{138, 10, 118, 130},
{267, 10, 118, 132},
{402, 11, 113, 132},
{538, 12, 106, 134},
{671, 13, 103, 133},
{804, 12, 102, 132},
{23, 161, 100, 134},
{157, 162, 96, 134},
{287, 159, 95, 135},
{418, 158, 95, 133},
{545, 159, 99, 133},
{673, 159, 102, 134},
{798, 158, 108, 130},
{9, 309, 116, 126},
{137, 309, 118, 127},
{274, 310, 110, 128},
{412, 311, 102, 129},
{541, 312, 103, 130},
{671, 312, 104, 131},
{806, 312, 98, 132},
{29, 463, 94, 135},
{155, 462, 98, 135},
{279, 461, 104, 135},
{409, 461, 106, 135},
{536, 461, 109, 135},
{662, 461, 112, 133}};
Image subSprite;
for (int i = 0; i <= 26; i++) {
super.paintComponent(g);
subSprite = img.getSubimage(spriteSheetCoords[i][0], spriteSheetCoords[i][1], spriteSheetCoords[i][2], spriteSheetCoords[i][3]);
g.drawImage(subSprite, 140, 120, null);
}
}
}
Run Code Online (Sandbox Code Playgroud)
假设创建一个从第一个精灵到最后一个(第 27 个)精灵的循环。
首先,每行之间有很多空格,这使得阅读代码变得困难。
你有一个catch不安全的空块,至少这样做:
catch (IOException e){
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)您不会将程序放在事件调度线程(EDT)上来解决它,只需更改您的main方法,如下所示:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//Your constructor here
}
});
}
Run Code Online (Sandbox Code Playgroud)您正在扩展JFrame但不使用它生成的框架,同时您正在创建 a 的实例JFrame,请删除extends JFrame代码中的 。相关阅读:Java Swing 使用扩展 JFrame 与在类内部调用它
而不是调用frm1.setSize(400, 400);overridePainel1的getPreferredSize()方法来返回新Dimension的400, 400并调用frm1.pack()
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
Run Code Online (Sandbox Code Playgroud)动画处理速度太快了!
这并不是动画处理太快,而是for循环阻止了 GUI 在结束之前被绘制,这就是为什么您只能看到最后一个精灵被绘制的原因。
考虑到上述所有要点,您现在可以使用如下代码,其中包括 Swing Timer 的使用以及已包含的上述建议:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Sprites {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frm1 = new JFrame();
Painel1 pn1 = new Painel1();
frm1.getContentPane().add(pn1);
frm1.pack();
frm1.setVisible(true);
frm1.setLocationRelativeTo(null);
frm1.setResizable(false);
frm1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
}
class Painel1 extends JPanel {
int[][] spriteSheetCoords = { { 8, 10, 119, 129 }, { 138, 10, 118, 130 }, { 267, 10, 118, 132 },
{ 402, 11, 113, 132 }, { 538, 12, 106, 134 }, { 671, 13, 103, 133 }, { 804, 12, 102, 132 },
{ 23, 161, 100, 134 }, { 157, 162, 96, 134 }, { 287, 159, 95, 135 }, { 418, 158, 95, 133 },
{ 545, 159, 99, 133 }, { 673, 159, 102, 134 }, { 798, 158, 108, 130 }, { 9, 309, 116, 126 },
{ 137, 309, 118, 127 }, { 274, 310, 110, 128 }, { 412, 311, 102, 129 }, { 541, 312, 103, 130 },
{ 671, 312, 104, 131 }, { 806, 312, 98, 132 }, { 29, 463, 94, 135 }, { 155, 462, 98, 135 },
{ 279, 461, 104, 135 }, { 409, 461, 106, 135 }, { 536, 461, 109, 135 }, { 662, 461, 112, 133 } };
int i = 0;
BufferedImage img;
private ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
i++;
if (i == spriteSheetCoords.length) {
i = 0;
}
revalidate();
repaint();
}
};
public Painel1() {
Timer timer = new Timer(50, actionListener);
timer.setInitialDelay(0);
timer.start();
setBackground(Color.yellow);
try {
img = ImageIO.read(new File("/home/jesus/Pictures/tokyo.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void paintComponent(Graphics g) {
Image subSprite;
super.paintComponent(g);
subSprite = img.getSubimage(spriteSheetCoords[i][0], spriteSheetCoords[i][1], spriteSheetCoords[i][2], spriteSheetCoords[i][3]);
g.drawImage(subSprite, 140, 120, null);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,Timer有 50ms 的延迟,以使精灵的过渡更加平滑,你可以根据需要进行调整。