Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JFrame中的精灵表动画_Java_Swing_Animation_Jframe_Paintcomponent - Fatal编程技术网

Java JFrame中的精灵表动画

Java JFrame中的精灵表动画,java,swing,animation,jframe,paintcomponent,Java,Swing,Animation,Jframe,Paintcomponent,我正在尝试使用JFrame中的精灵表获取动画。问题是一旦加载,图像就不会改变。它只显示第一个图像。 我已经搜索了很多,尝试了几乎所有的建议,但都没有成功 顺便说一下,getSprite有一个返回类型的图像。 当我在JFrame中执行所有操作时,只显示一个图像。当我在扩展JPanel的单独类中执行此操作时,我只得到一个白色窗口 更新1:感谢andrew,JFrame工作正常。也修复了我的旧部分。这是工作表 更新2: 这是我的定时器版本 class TestSpriteSheet extends J

我正在尝试使用JFrame中的精灵表获取动画。问题是一旦加载,图像就不会改变。它只显示第一个图像。 我已经搜索了很多,尝试了几乎所有的建议,但都没有成功

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

更新1:感谢andrew,JFrame工作正常。也修复了我的旧部分。这是工作表

更新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;
        }
    }
}
类TestSpriteSheet扩展JFrame{
//相同的旧变量
公共测试SpriteSheet(){
//以前这里也有同样的东西
添加(新PanelSprite(此,ss));
此.setVisible(true);
}
}
类PanelSprite扩展了JPanel{
私有长运行时间=0;
私有整数fps=3;
私有布尔停止=false;
私人SpriteSheetManager ss;
专用测试SpriteSheet temp;
公共面板Sprite(测试SpriteSheet测试,SpriteSheetManager sm){
ss=sm;
温度=试验;
设置大小(180180);
setLayout(新的BorderLayout());init();
}
公共组件(图形g){
超级组件(g);
长时间=5000;
使用_gfx(g,时间)设置_动画;
}
公共void init(){
计时器t=新计时器((int)(1000/fps),新ActionListener(){
已执行的公共无效操作(操作事件e){
如果(!停止){
重新油漆();
}否则{
((计时器)e.getSource()).stop();
}
}
});
t、 设置重复(真);
t、 设置延迟((整数)(1000/fps));
t、 start();
}
public void使用_gfx设置_动画(图形g,长时间){
if(运行时)
这部分完全错误,因为只要JRE认为视图需要重新绘制,就会调用
paintComponent()
方法。所以一定要删除
系统。退出(0);

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

它可能看起来像这样:

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.*;
导入java.awt.image.buffereImage;
导入java.awt.event.*;
导入javax.swing.*;
导入java.io.IOException;
导入java.net.URL;
导入javax.imageio.imageio;
类SpriteSheetManager{
专用缓冲图像精灵表;
int cols;
int行;
公共SpriteSheetManager(){
setpritesheet();
}
公共无效设置价格表(){
试一试{
spriteSheet=ImageIO.read(
新网址(“http://s8.postimg.org/vso6oed91/spritesheet.png"));
setColsAndRows(3,3);
}捕获(IOE异常){
e、 printStackTrace();
}
}
公共缓冲区映像getSpriteSheet(){
返回精灵表;
}
public void setColsAndRows(int cols,int rows){
this.cols=cols;
this.rows=行;
}
公共图像getSprite(整数x,整数y){
图像精灵=空;
试一试{
sprite=spriteSheet.getSubimage(
x*spriteSheet.getWidth()/cols,
y*spriteSheet.getHeight()/行,
spriteSheet.getWidth()/cols,
spriteSheet.getHeight()/行);
}捕获(例外e){
e、 printStackTrace();
}
返回精灵;
}
}
表意文字{
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新的TestSpriteSheet();
}
});
}
}
类TestSpriteSheet扩展了JFrame{
私有静态最终长serialVersionUID=1L;
私人SpriteSheetManager ss;
公共测试SpriteSheet(){
超级(“测试精灵表”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
可设置大小(假);
setLayout(新的BorderLayout());
addWindowListener(新的WindowAdapter(){
公共作废窗口关闭(WindowEvent WindowEvent){
系统出口(0);
}
});
ss=新的SpriteSheetManager();
添加(新PanelSprite(此,ss));
包装();
设置大小(200200);
此.setVisible(true);
}
}
类PanelSprite扩展了JPanel{
私有长运行时间=0;
私人整数fps=10;
私有布尔停止=false;
私人SpriteSheetManager ss;
专用测试SpriteSheet temp;
私人定时器t;
整数计数=0;
长时间=50000;
公共面板Sprite(测试SpriteSheet测试,SpriteSheetManager sm){
ss=sm;
温度=试验;
init();
}
公共组件(图形g){
超级组件(g);
使用_gfx(g)设置_动画;
}
公共void init(){
t=新计时器((int)(1000/fps),新ActionListener(){
已执行的公共无效操作(操作事件e){
如果(!停止){
重新油漆();
}否则{
((计时器)e.getSource()).stop();
}
}
});
t、 设置重复(真);
t、 设置延迟((整数)(1000/fps));
t、 start();
}
公共空间使用_gfx设置_动画(图形g){

如果(runningTime)我删除了System.exit(0),但什么也没发生。你能详细说明一下“那么计时器需要一个实例,只启动一次。这最好在构造函数或init()类型方法中完成。”?不,它仍然不会更改图像。更新了问题。
setLayout(new BorderLayout());}
应该是
setLayout(new BorderLayout());init();}
。这就是从构造函数调用
的意思!是的,但图像没有改变。1)为了更快地获得更好的帮助,发布(最小完整的可验证示例)或
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;
        }
    }
}