如何在java中使用计时器类

如何在java中使用计时器类,java,swing,animation,timer,Java,Swing,Animation,Timer,我正在努力弄清楚timer类是如何工作的,我可以使用它。我在网上寻找答案,虽然我找不到对我这样的初学者来说足够简单的解释。如果有人给我发了一个很棒的定时器类tut的链接,或者甚至向我解释我应该在代码中做什么,我将非常感激。谢谢 public class movement { private JComponent jt; // the JLabel (my game character) private InputMap ip; private ActionMap

我正在努力弄清楚timer类是如何工作的,我可以使用它。我在网上寻找答案,虽然我找不到对我这样的初学者来说足够简单的解释。如果有人给我发了一个很棒的定时器类tut的链接,或者甚至向我解释我应该在代码中做什么,我将非常感激。谢谢

    public class movement {
    private JComponent jt; // the JLabel (my game character)
    private InputMap ip;
    private ActionMap ap;
    private String comm; // the ActionMapKey
    private KeyStroke key;
    private int movement;
public movement(JComponent jt, InputMap ip,ActionMap ap, String comm,KeyStroke key,int movement){
    this.jt = jt;
    this.ip = ip;
    this.ap= ap;
    this.comm = comm;
    this.key = key;
    this.movement = movement;
}
public void newAction(){
    this.ip  = this.jt.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
    this.ip.put(key, comm);
    this.ap = this.jt.getActionMap();
    this.ap.put(this.comm, new AbstractAction() {


        @Override
        public void actionPerformed(ActionEvent arg0) {
            int originaly = jt.getY();
            if(key ==  KeyStroke.getKeyStroke(KeyEvent.VK_UP,0)){



                if(originaly==jt.getY()){
                    // how do i make this action animated? i want the JLabel to look like its moving up (like a jump) 
                    // after the up key is pressed 
                    // i dont really understand how to use the timer class to make it animated .. thanks!
                    jt.setBounds(jt.getX(),jt.getY()+movement , 50, 50);
                    //timer pause for 0.1 secs
                    jt.setBounds(jt.getX(),jt.getY()+movement , 50, 50);
                    //timer pause for 0.1 secs...
                    // can also be in a while loop until the y is 50 higher than original y. 
                }

            }
            else{
            jt.setBounds(jt.getX()+movement,jt.getY() , 50, 50);
            }
        }
    });

}
}

好吧,当你说“计时器暂停0.1秒”时,我想你可以用Thread.sleep(100);100->100毫秒。我看不出这里需要计时器。Thread.sleep(int)只是将代码的执行暂停一段特定的毫秒。

好的,所以问题不在于计时器,而在于理解如何实现动画

  • 动画是状态随时间的变化
  • 计时器是一个伪循环,在迭代之间有指定的延迟
好吧,这有什么帮助?好的,基本上,你需要构思一个物体从它的当前位置移动到一个新位置然后再返回的概念(上下跳跃)

这就是您的
计时器的作用。
定时器
提供一种状态和下一种状态之间的延迟,该延迟应足够长,以供用户感知

这是一个非常基本的示例,但它演示了基本原则。键绑定
操作
不负责更改位置,它负责更改状态,然后由
计时器
执行操作。为什么?假设现在有了其他键绑定(左键和右键),它们不应该更改对象的状态,因为这些更改可能会发生冲突。相反,它们设置一个状态标志,然后使用该标志确定在状态更新时应该发生什么

该对象有一个
yPos
,可以通过更改值(
yDelta
)对其进行操作,该更改值会影响实际应用于该对象的更改。当
jump
true
时,对象将移动到其最高高度,然后再次向下移动。完成此循环后,
跳跃
状态将重置,这意味着您无法继续按空格键在空中执行多次跳跃。。。因为那是不可能的;)

导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入java.io.IOException;
导入javax.swing.AbstractAction;
导入javax.swing.ActionMap;
导入javax.swing.InputMap;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.KeyStroke;
导入javax.swing.Timer;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公开课考试{
公共静态void main(字符串[]args)引发IOException{
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私人int yPos=200;
私有int yDelta=-1;
私有布尔跳跃=假;
公共测试窗格(){
InputMap im=getInputMap(在聚焦窗口中时);
ActionMap am=getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0),“SPACE”);
am.put(“space”,新抽象动作(){
@凌驾
已执行的公共无效操作(操作事件e){
跳跃=真;
}
});
计时器计时器=新计时器(5,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
如果(跳转){
如果(yPos>200){
yPos=200;
yDelta*=-1;
跳跃=假;
}否则,如果(yPos<150){
yPos=150;
yDelta*=-1;
}否则{
yPos+=yDelta;
}
重新油漆();
}
}
});
timer.start();
}
@凌驾
公共维度getPreferredSize(){
返回新维度(200200);
}
@凌驾
受保护组件(图形g){
超级组件(g);
Graphics2D g2d=(Graphics2D)g.create();
intx=(getWidth()-5)/2;
g2d.fillRect(x,yPos-10,10,10);
g2d.dispose();
}
}
}
很多无聊的理论 TL;博士

现在,这是一个过于简化的例子,它没有讨论诸如帧率、地役权或重力之类的事情。你可以看看哪个演示了可变三角洲的概念,它随着时间的推移而退化,应用了(非常基本的)重力概念

根据你想做什么,还有其他方法可以达到类似的效果,但它们围绕着相同的概念

如果你真的很勇敢的话,你可以看看哪一个讨论了缓动或变速动画的概念。您还可以看看哪一个更关注可变动画
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) throws IOException {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int yPos = 200;
        private int yDelta = -1;

        private boolean jump = false;

        public TestPane() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "space");
            am.put("space", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    jump = true;
                }
            });
            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (jump) {
                        if (yPos > 200) {
                            yPos = 200;
                            yDelta *= -1;
                            jump = false;
                        } else if (yPos < 150) {
                            yPos = 150;
                            yDelta *= -1;
                        } else {
                            yPos += yDelta;
                        }
                        repaint();
                    }
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int x = (getWidth() - 5) / 2;
            g2d.fillRect(x, yPos - 10, 10, 10);
            g2d.dispose();
        }

    }

}