当前位置: 首页 > 面试题库 >

摇摆计时器-时间波动

万俟皓
2023-03-14
问题内容

我在游戏中使用了摇摆计时器,但是当游戏运行时,它似乎有平稳运行的时刻和减速的时刻。

为什么时间在波动?

我该如何解决?

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main extends JFrame {

public Main() {
    super("JFrame");

    // you can set the content pane of the frame
    // to your custom class.

    setContentPane(new ImagePanel());

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    setSize(800, 400);
    setResizable(false);
    setVisible(true);

}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    new Main();

}

class ImagePanel extends JPanel {

    Timer movementtimer;

    int x, y;

    public ImagePanel() {

        x = 0;
        y = 0;

        movementtimer = new Timer(12, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                long timstarted = System.currentTimeMillis();
                moveImage();
                repaint();
                long timefinished = System.currentTimeMillis() - timstarted;
                System.out.println(timefinished + " to run");
            };

        });

        movementtimer.start();

    }

    public void moveImage() {

        x++;
        y++;

        if (x > 800) {
            x = 0;
        }
        if (y > 400) {
            y = 0;
        }

    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        g.setColor(Color.RED);
        g.fillRect(0, 0, 800, 400);
        g.setColor(Color.BLUE);
        g.fillRect(x, y, 50, 50);

    }

}

}

这是我的代码示例。在我的实际程序中,我正在绘制图像,而不仅仅是矩形。还有很多碰撞检测和其他小的计算正在发生。

另外,这是游戏的Jar文件的链接,因此您可以运行它,(满是)明白我的意思。http://dl.dropbox.com/u/8724803/Get%20To%20The%20Chopper%201.3.jar

谢谢


问题答案:

因为渲染是微不足道的,所以我发现您的示例的这种变化非常平滑。渲染时间远低于半毫秒,所以12毫秒期间(〜83赫兹)是 足够
的时间来完成一帧,典型地以小于10%的一种核心的。随着渲染时间的增加,计时器线程变得饱和,并且事件合并。由于渲染与垃圾收集和外部处理需求竞争,因此在单个内核上放大了效果。Java不是实时系统,并且并非所有调度程序都是相同的。

您一定会按照此处的建议分析实际的代码,以查看与性能波动之间的任何关联。一种替代方法是延长周期(降低频率)以满足您的渲染截止日期,并使用更大的增量moveImage()来获得相同的速度。

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main extends JFrame {

    private static final int W = 800;
    private static final int H = 400;

    public Main() {
        super("JFrame");
        this.add(new ImagePanel());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        setSize(W, H);
        this.setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Main();
            }
        });
    }

    class ImagePanel extends JPanel {

        Timer movementTimer;
        int x, y;

        public ImagePanel() {
            x = 0;
            y = 0;
            movementTimer = new Timer(12, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    moveImage();
                    repaint();
                }
            });
            movementTimer.start();
        }

        public void moveImage() {
            x++;
            y++;
            if (x > W) {
                x = 0;
            }
            if (y > H) {
                y = 0;
            }
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            long start = System.nanoTime();
            g.setColor(Color.RED);
            g.fillRect(0, 0, W, H);
            g.setColor(Color.BLUE);
            g.fillRect(x, y, 50, 50);
            double delta = (System.nanoTime() - start) / 1000000d;
            g.drawString(String.format("%1$5.3f", delta), 5, 15);
        }
    }
}


 类似资料:
  • 问题内容: 嗨,我正在研究一个项目(Java内存游戏),首先我想了解摆动计时器的工作原理。首先,我主班级实现了和。而且我使用计时器,如果有两张卡用户选择了不同的图片,那么我会给他几秒钟的时间来查看图片,然后它们将再次关闭。但是如果用户选择了两张不同的图片,他们会突然关闭,所以我看不到第二张图片。我阅读了一些有关swing timer的教程,但我想我对SSCCE的创建方式理解不对。如果您能帮助我,我

  • 我觉得摇摆计时器有问题。我写了一些运行良好的代码,然后将其全部移动到我的新计算机上,但它很快就无法工作。我用这个方法编写了一个GUI类(基于JFrame): 该方法是从另一个类调用的。真是太夸张了。splash guy是一个只运行splash动画的JPanel类。它通过摆动计时器来实现。在splash类中,侦听器通过以下代码调整我的帧的内容: 现在,如果第一个块中的print语句被注释掉,我的程序

  • 例: “foo”和“bar”可以是任何字符串键,但它们在键集中应该是唯一的。 我知道,使用Swagger,我可以定义一个对象数组,但这给出了一个不同的API,因为那时我们将拥有如下内容: 我已经阅读了“开放API规范”-“添加地图数据类型支持#38”页面。据我了解,它推荐使用additionalProperties,但似乎并没有回答我的需求(或者说与我使用的Swagger UI 2.1.4不兼容)

  • 为了使准确,我喜欢@Tony Docherty On CR建议的逻辑和示例。这是链接。 为了一次又一次地突出显示给定的单词,总是会有几微秒的延迟。如果我有要突出显示的单词,比如说:“你好,你好”,每个单词的值分别是(延迟):200300400毫秒,那么计时器实际花费的时间总是更多。比如说,如果我有很多单词的话,需要216毫秒,而不是200毫秒。。最后,额外的延迟是显而易见的。 我必须突出显示每个字

  • 我正在用摇摆计时器打卡NetBeans: 我只是用System.out.print来测试程序,它不是真正程序的一部分。我调用停止()方法,但计时器继续计数。此外,我通过但它的计数速度是原来的两倍。有人能帮忙吗? 编辑: 这是我的计时器(有点像SSCCE): 它不能正常工作,因为秒没有出现,但它确实显示了20次,这就是我想要的。这只是在它自己的应用程序中,在我的实际程序中更容易看到问题。 我注意到游

  • 我首先想到的是:我认为有点非常准确,给出了一个值,其中as请求一个参数;上面写着什么?不要认为<代码>摆动定时器<代码>是准确的吗? 2) 假设用计时一个单词需要x毫秒;如果我们在重复一项任务(突出显示一个单词,如卡拉OK应用程序),我会包含以下代码: 安静地工作很好,但我肯定我不能依靠这一点,因为时间,长度可能会改变!如何克服这个问题?因为几毫秒内的变化可能会给我带来灾难性的后果。 3) 同时,