Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.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为什么这个线程在睡觉前执行两次?_Java - Fatal编程技术网

java为什么这个线程在睡觉前执行两次?

java为什么这个线程在睡觉前执行两次?,java,Java,我正在编写一个2d游戏来学习java,我使用一个线程作为计数器来设置玩家的动画(它增加一个整数,告诉paintComponent方法要绘制哪幅图片)。但是由于某些原因,线程在休眠之前执行了两次。相关线程是shipanimation线程 public class Frame extends JFrame implements KeyListener{ public static Frame frame; private JPanel contentPane; RenderPanel pan

我正在编写一个2d游戏来学习java,我使用一个线程作为计数器来设置玩家的动画(它增加一个整数,告诉paintComponent方法要绘制哪幅图片)。但是由于某些原因,线程在休眠之前执行了两次。相关线程是shipanimation线程

public class Frame extends JFrame implements KeyListener{
    public static Frame frame;
private JPanel contentPane;
RenderPanel panel;
public Ship ship = new Ship(36, 72);
int y = 0;
int time;
int animation = 0;
/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                frame = new Frame();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Frame() {
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel = new RenderPanel();
    setBounds(100, 100, 256*3, 276*3);
    ship.setPos((this.getWidth()/2), (this.getHeight()/4)*3);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(0, 0, 0, 0));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);
    Thread backgr = new Thread("Hintergrund"){
        public void run(){
            try {
            while(true){

                if(frame.y < 0){
                    frame.y = 300;
                }
                frame.y -= 1;
                Thread.sleep(50);
                panel.repaint();
                }
            }
                catch (InterruptedException e) {

                    e.printStackTrace();
            }
        }

    };

    Thread anim = new Thread("shipanimation"){
         public void run(){
             try {
                 while(true){
                 if(Frame.frame.animation > 7){
                     Frame.frame.animation = 0;
                 }else{
                Frame.frame.animation++;
                 }
            System.out.println(Frame.frame.animation);
                panel.repaint();
                Thread.sleep(500);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
         }
    };
    backgr.start();
    anim.start();
    contentPane.add(panel);
    panel.setLayout(null);

}
公共类框架扩展JFrame实现KeyListener{
公共静态框架;
私有JPanel内容窗格;
渲染面板;
公共船舶=新船舶(36,72);
int y=0;
整数时间;
int动画=0;
/**
*启动应用程序。
*/
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
试一试{
帧=新帧();
frame.setVisible(true);
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
/**
*创建框架。
*/
公共框架(){
可设置大小(假);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
面板=新的渲染面板();
立根(100100256*3276*3);
ship.setPos((this.getWidth()/2),(this.getHeight()/4)*3);
contentPane=newjpanel();
setboorder(新的EmptyBorder(0,0,0,0));
setLayout(新的BorderLayout(0,0));
setContentPane(contentPane);
线程backgr=新线程(“Hintergrund”){
公开募捐{
试一试{
while(true){
if(帧y<0){
帧y=300;
}
帧y-=1;
睡眠(50);
panel.repaint();
}
}
捕捉(中断异常e){
e、 printStackTrace();
}
}
};
线程动画=新线程(“shipanimation”){
公开募捐{
试一试{
while(true){
如果(Frame.Frame.animation>7){
Frame.Frame.animation=0;
}否则{
Frame.Frame.animation++;
}
System.out.println(Frame.Frame.animation);
panel.repaint();
睡眠(500);
}
}捕获(例外e){
e、 printStackTrace();
}
}
};
backgr.start();
anim.start();
contentPane.add(面板);
panel.setLayout(空);
}
有人能告诉我为什么会发生这种情况吗?这个程序似乎将数字增加了两次,也打印了两次,然后休眠500毫秒,然后再次执行同样的操作

编辑:谢谢你的提示,因此我将代码更改为:

public Frame() {
    aTimer = new Timer(400, this);
    aTimer.start();
    backTimer = new Timer(25, this);
    backTimer.start();
            setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel = new RenderPanel();
    setBounds(100, 100, 256*3, 276*3);
    ship.setPos((this.getWidth()/2), (this.getHeight()/4)*3);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(0, 0, 0, 0));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);
    contentPane.add(panel);
    panel.setLayout(null);

} 
@Override
public void actionPerformed(ActionEvent e) {

    if(e.getSource() == aTimer){    
    if(Frame.frame.animation > 7){
         Frame.frame.animation = 0;
     }else{
    Frame.frame.animation++;
     }
    System.out.println(Frame.frame.animation);
    panel.repaint();
    }
    if(e.getSource() == backTimer){
        if(frame.y < 0){
            frame.y = 300;
        }
        frame.y -= 1;
        panel.repaint();
    }

}
公共帧(){
aTimer=新计时器(400,此);
aTimer.start();
backTimer=新计时器(25,此);
backTimer.start();
可设置大小(假);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
面板=新的渲染面板();
立根(100100256*3276*3);
ship.setPos((this.getWidth()/2),(this.getHeight()/4)*3);
contentPane=newjpanel();
setboorder(新的EmptyBorder(0,0,0,0));
setLayout(新的BorderLayout(0,0));
setContentPane(contentPane);
contentPane.add(面板);
panel.setLayout(空);
} 
@凌驾
已执行的公共无效操作(操作事件e){
如果(e.getSource()==aTimer){
如果(Frame.Frame.animation>7){
Frame.Frame.animation=0;
}否则{
Frame.Frame.animation++;
}
System.out.println(Frame.Frame.animation);
panel.repaint();
}
如果(例如getSource()==倒计时){
if(帧y<0){
帧y=300;
}
帧y-=1;
panel.repaint();
}
}

但它仍然是一样的,计时器执行每件事情两次,然后等待时间。

你不应该使用线程和睡眠,而应该使用
javax.swing.timer
@realponsignist是正确的。你目前的认识非常奇怪。另外:你从来没有杀死你正在启动的线程,所以可能会有半死不活的线程做同样的事情。动画线程需要一段时间(Thread.currentThread没有中断)不是一个无限循环我认为这里缺少了一些东西。你能使框架不是静态的吗?我不认为我能Eclipse说:如果我这样做,就不能对非静态字段框架进行静态引用。