如何在一定时间内按顺序显示ImageIcons? Java,计时器

时间:2016-12-12 08:18:14

标签: java user-interface timer

所以,让我说我有四个ImageIcons,

private ImageIcon characterIntro;
private ImageIcon characterIdle;
private ImageIcon characterAttack;
private ImageIcon characterJump;
Timer time;

并在构造函数中使用gif初始化它们。

我知道如何使用我的paintComponent在屏幕上绘制它们,但是如何让它们在一定时间内出现呢?我想按以下顺序进行:

  • 显示characterIntro 5秒
  • 之后,显示characterIdle 3秒
  • 一旦characterIdle显示3秒钟,显示characterAttack 6秒
  • 之后,显示characterIdle 5秒
  • 之后,显示characterJump 3秒
  • 之后,显示characterIdle 3秒
  • 重复 characterIntro
  • 之外的所有内容

通常我的paintComponent看起来像这样,并且它同时显示所有这些:

public void paintComponent (Graphics page)
{
    super.paintComponent(page); 
    page.drawImage(background, 0, 0, null);

    if(stage1_completed && stage2_completed && stage3_completed && stage4_completed)
    {
        characterIntro.paintIcon   (this, page, char.x, char.y-10);
        characterIdle.paintIcon    (this, page, char.x, char.y);
        characterAttack.paintIcon   (this, page, char.x, char.y);
        characterIdle.paintIcon    (this, page, char.x, char.y);
        characterJump.paintIcon    (this, page, char.x, char.y);
        characterIdle.paintIcon    (this, page, char.x, char.y);
     }
}

我如何使用Timer来达到我想要的效果?

谢谢:)

2 个答案:

答案 0 :(得分:0)

对于使用具有不同延迟的Timer,您可以创建如下方法:

public void scheduleTask(int delay){
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            timer.cancel();
            doSomething();
        }
    } , delay, 1);
}

这将在ms中的doSomething过去后运行方法delay。在doSomething()方法中,您更改了应显示的ImageIcon,然后使用下一个scheduleTask()再次调用delay方法。

为了实现这个目的,我将介绍一个名为Animation的类,它包含一个图像以及它应该显示的持续时间。

class Animation{
    public ImageIcon Image;
    public int Duration;
    public Animation(ImageIcon Image, int Duraction){
        this.Image = Image;
        this.Duration = Duraction;
    }
}

使用此类,您可以轻松地创建一系列动画作为数组。

private Animation[] Sequence = {
    new Animation(characterIdle, 3000),
    new Animation(characterAttack, 6000),
    new Animation(characterIdle, 5000),
    new Animation(characterJump, 3000),
    new Animation(characterIdle, 3000)
};

我忘记了你的characterIntro图片。这将是初始化而不是序列的一部分。

在您的代码中使用private ImageIcon actualIcon;对象,该对象包含您要显示的实际图像,并且您在doSomething()方法中更改了一个private int actualSequenceId;值,其中包含实际的动画ID序列数组。

现在,您使用actualIcon初始化characterIntro对象,并使用scheduleTask(5000);

安排第一次图像更改

并按照以下方式实施doSomething()方法:

public void doSomething(){      
    // change the actual Image and schedule next image change
    actualImage = Sequence[actualSequenceId].Image;
    scheduleTask(Sequence[actualSequenceId].Duration);

    // increment sequence Id
    if(actualSequenceId + 1 == Sequence.length) actualSequenceId = 0;
    else actualSequenceId++;
}

答案 1 :(得分:0)

在一个表格(或列表)中收集您的图标

p.ico = new ImageIcon[]{p.characterIntro, p.characterIdle, p.characterAttack, p.characterJump};

然后用“要显示的内容”逻辑创建一个线程。 这样的事情:

        new Thread(){
            @Override
            public void run() {
                int[] idxrep = {0,1,2,1,3};
                int[] dlyrep = {5,3,6,5,3};

                int idx=0;
                while (true) {
                    lbl.setIcon(ico[idxrep[idx]]);
                    try {Thread.sleep(dlyrep[idx]*1000);}catch(Exception e){}

                    ++idx;
                    if (idx == idxrep.length) idx=1;//skip intro
                }
            }
        }.start();

lbl JLabel我放入了JPanel,但你不能以同样的方式重新绘制paintComponent()中的当前图标

编辑:

ico应在所有“字符”存在的JPanel中声明。 必须先将字符初始化。 new Thread()可以放在构造函数中,也可以放在start()

等专用方法中