Search code examples
javaswinganimationspriteanimated-gif

Sprite animation timing java swing


I tried making a sprite animation in JAVA using Swing. The code below is an array of ImageIcon which I'm going to iterate through in order to show the several different images (only 2 for testing purposes). But I don't know how to properly time each iteration. I mean, when I compile the code the label I'm working on, only displays the last image of the array (obviously), but I want it to display the first one for some ms and the other one after. I made some research and saw some suggestions regarding Time class, but I don't really know how to implement it in these circunstances. I also tried to use sleep, which works fine in C++, but only came up with thread.sleep which doesn't work in this case.

The animation is supposed to simulate a playing card being turned around (for the Monopoly game).

Can anyone give me some input on the matter?

import javax.swing.ImageIcon;
import javax.swing.JLabel;

public class Sprite2 {

    private ImageIcon[] sprites;

    private ImageIcon a = new ImageIcon("C:/Users/Guilherme/Desktop/G/FEUP/2º Ano/2nd semester/Eclipse repos/Sprite/src/images/ball.jpg");
    private ImageIcon b = new ImageIcon("C:/Users/Guilherme/Desktop/G/FEUP/2º Ano/2nd semester/Eclipse repos/Sprite/src/images/transferir.jpg");

    public Sprite2() {

        sprites = new ImageIcon[] {a, b};
    }

    public void render(JLabel lbl) {

        for (int i = 0; i < sprites.length; i++) {
                 lbl.setIcon(sprites[i]);
                 //sleep(1000); - Looking for a similar Java function which is able to delay each iteration and make it look like a gif 
    }
}

Solution

  • I figured it out using timer.

    For some reason, the first frame wouldn't show up in the first animation, hence sprites[0] and [1] are the same image.

    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    
    public class Sprite extends JPanel implements ActionListener{
    
        private ImageIcon[] sprites = new ImageIcon[4]; 
        private Timer time;
        private int delay = 500, currentFrame = 0; 
    
    
        private ImageIcon a0 = new ImageIcon("C:/Users/Guilherme/Desktop/G/FEUP/2º Ano/2nd semester/Eclipse repos/Sprite/src/images/ball.jpg");
        private ImageIcon a1 = new ImageIcon("C:/Users/Guilherme/Desktop/G/FEUP/2º Ano/2nd semester/Eclipse repos/Sprite/src/images/transferir.jpg");
        private ImageIcon a2 = new ImageIcon("C:/Users/Guilherme/Desktop/G/FEUP/2º Ano/2nd semester/Eclipse repos/Sprite/src/images/smurf_sprite.png");
    
    
        public Sprite() {
    
            sprites[0] = a0;
            sprites[1] = a0;
            sprites[2] = a1;
            sprites[3] = a2;
    
            time = new Timer(delay, this);
            time.start();
        }
    
        public void paintComponent(Graphics g) {
    
            super.paintComponent(g);
            sprites[currentFrame].paintIcon(this, g, 0, 0);
    
            if (currentFrame == sprites.length-1) {
                time.stop();
            }
            else currentFrame++;
        }
    
        public void actionPerformed(ActionEvent e) {
    
            repaint();
        }
    
        public static void main(String[] arg) {
            JFrame f = new JFrame();
            Sprite s = new Sprite();
            f.add(s);
            f.setVisible(true);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(500,400);
        }
    }