gpt4 book ai didi

java - JFrame 中的 Spritesheet 动画

转载 作者:行者123 更新时间:2023-11-30 03:37:56 25 4
gpt4 key购买 nike

我正在尝试使用 JFrame 中的 spritesheet 获取动画。问题是一旦加载,图像就不会改变。它仅显示第一张图像。我进行了很多搜索并尝试了几乎所有建议,但无法使其发挥作用。

顺便说一下,getSprite 的返回类型是 Image。当我在 JFrame 中执行所有操作时,只显示一张图像。当我在扩展 JPanel 的单独类中执行此操作时,我只得到一个白色窗口。

更新 1: 感谢 Andrew,让 JFrame 正常工作。也修复了我的旧部分。这是工作code at ideone

更新 2:这是我的带有计时器的版本。

class TestSpriteSheet extends JFrame{

//same old variables

public TestSpriteSheet(){
//same old stuff goes here before this
add(new PanelSprite(this, ss));
this.setVisible(true);
}
}

class PanelSprite extends JPanel{

private long runningTime = 0;
private int fps = 3;
private boolean stop = false;
private SpriteSheetManager ss;
private TestSpriteSheet temp;

public PanelSprite(TestSpriteSheet test, SpriteSheetManager sm){
ss = sm;
temp = test;
setSize(180,180);
setLayout(new BorderLayout()); init();
}

public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000;
animate_with_gfx(g, time);
}

public void init(){
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
}

public void animate_with_gfx(Graphics g, long time){
if(runningTime <= time){
try {
System.out.println(runningTime); //Checking if this part works
int x = 0; int y = 0;
g.drawImage(ss.getSprite(x, y), 40, 40, null);
x++; y++; runningTime+=(1000/fps);
}catch (Exception ex) {
ex.printStackTrace();
}
}
else{
stop = true;
}
}
}

最佳答案

public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000; int fps = 3;
boolean stop = false;
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
animate_with_gfx(g, time, fps, stop);
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
System.exit(0);
}

这部分是完全错误的,因为只要 JRE 认为 View 需要重新绘制,就会调用 paintComponent() 方法。所以一定要删除 System.exit(0);!

那么计时器需要一个实例,启动一次。这最好在构造函数或 init() 类型方法中完成。

它可能看起来像这样:

private int fps = 3;
private boolean stop = false;

public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000;
animate_with_gfx(g, time, fps, stop);
}

/** Called from constructor.. */
public void init(){
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
}

更新

import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.*;

import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;

class SpriteSheetManager {

private BufferedImage spriteSheet;
int cols;
int rows;

public SpriteSheetManager() {
setSpriteSheet();
}

public void setSpriteSheet() {
try {
spriteSheet = ImageIO.read(
new URL("http://s8.postimg.org/vso6oed91/spritesheet.png"));
setColsAndRows(3, 3);
} catch (IOException e) {
e.printStackTrace();
}
}

public BufferedImage getSpriteSheet() {
return spriteSheet;
}

public void setColsAndRows(int cols, int rows) {
this.cols = cols;
this.rows = rows;
}

public Image getSprite(int x, int y) {
Image sprite = null;
try {
sprite = spriteSheet.getSubimage(
x * spriteSheet.getWidth() / cols,
y * spriteSheet.getHeight() / rows,
spriteSheet.getWidth() / cols,
spriteSheet.getHeight() / rows);
} catch (Exception e) {
e.printStackTrace();
}
return sprite;
}
}

class Ideone {

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestSpriteSheet();
}
});
}

}

class TestSpriteSheet extends JFrame {

private static final long serialVersionUID = 1L;
private SpriteSheetManager ss;

public TestSpriteSheet() {
super("Testing SpriteSheets");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLayout(new BorderLayout());
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.exit(0);
}
});

ss = new SpriteSheetManager();

add(new PanelSprite(this, ss));
pack();
setSize(200, 200);
this.setVisible(true);
}
}

class PanelSprite extends JPanel {

private long runningTime = 0;
private int fps = 10;
private boolean stop = false;
private SpriteSheetManager ss;
private TestSpriteSheet temp;
private Timer t;
int count = 0;
long time = 50000;

public PanelSprite(TestSpriteSheet test, SpriteSheetManager sm) {
ss = sm;
temp = test;
init();
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
animate_with_gfx(g);
}

public void init() {
t = new Timer((int) (1000 / fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!stop) {
repaint();
} else {
((Timer) e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int) (1000 / fps));
t.start();
}

public void animate_with_gfx(Graphics g) {
if (runningTime <= time) {
Image img = ss.getSprite((count % 9) % 3, (count % 9) / 3);
g.drawImage(img, 40, 40, this);
count++;
runningTime += (1000 / fps);
} else {
stop = true;
}
}
}

关于java - JFrame 中的 Spritesheet 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27417901/

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