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

摇摆动画优化

高朝明
2023-03-14
问题内容

我一直在使用一个简单的动画TimerJComponent。但是,当观看动画时,我会遇到难以置信的震荡。我应该采取什么步骤来优化此代码?

MyAnimationFrame

import javax.swing.*;

public class MyAnimationFrame extends JFrame {
    public MyAnimationFrame() {
        super("My animation frame!");
        setSize(300,300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(new AnimationComponent(0,0,50,50));
        setVisible(true);
    }

    public static void main(String[] args) {
        MyAnimationFrame f = new MyAnimationFrame();
    }
}

AnimationComponent

import javax.swing.*;
import java.awt.*;

public class AnimationComponent extends JComponent implements ActionListener {
    private Timer animTimer;
    private int x;
    private int y;
    private int xVel;
    private int yVel;
    private int width;
    private int height;
    private int oldX;
    private int oldY;

    public AnimationComponent(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.height = height;
        this.width = width;

        animTimer = new Timer(25, this);
        xVel = 5;
        yVel = 5;

        animTimer.start();
    }

    @Override
    public void paintComponent(Graphics g) {
        g.fillOval(x,y,width,height);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        oldX = x;
        oldY = y;

        if(x + width > getParent().getWidth() || x < 0) {
             xVel *= -1;
        }

        if(y + height > getParent().getHeight() || y < 0) {
            yVel *= -1;
        }

        x += xVel;
        y += yVel;

        repaint();
    }
}

不知道这是否重要,但是我正在使用OpenJDK 1.8.0_121版本。

任何帮助表示赞赏。


问题答案:

在与Yago进行了精彩的讨论之后,我发现问题围绕多个领域展开,很大程度上归因于Java将更新与操作系统和硬件同步的能力,有些是您可以控制的,有些是无法控制的。

受到Yago的示例以及我关于“计时框架”工作原理的“记忆”的启发,我通过提高帧速率(至5毫秒,〜=
200fps)并减小变化增量来测试代码,结果与使用“计时框架”相同,但这使您拥有了原始设计的灵活性。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Test {

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

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.add(new AnimationComponent(0, 0, 50, 50));
                frame.setSize(300, 300);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class AnimationComponent extends JComponent implements ActionListener {

        private Timer animTimer;
        private int x;
        private int y;
        private int xVel;
        private int yVel;
        private int width;
        private int height;
        private int oldX;
        private int oldY;

        public AnimationComponent(int x, int y, int width, int height) {
            this.x = x;
            this.y = y;
            this.height = height;
            this.width = width;

            animTimer = new Timer(5, this);
            xVel = 1;
            yVel = 1;

            animTimer.start();
        }

        @Override
        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            RenderingHints hints = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON
            );
            g2d.setRenderingHints(hints);
            g2d.fillOval(x, y, width, height);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            oldX = x;
            oldY = y;

            if (x + width > getParent().getWidth() || x < 0) {
                xVel *= -1;
            }

            if (y + height > getParent().getHeight() || y < 0) {
                yVel *= -1;
            }

            x += xVel;
            y += yVel;

            repaint();
        }
    }
}

如果您需要进一步降低速度,然后进一步降低变化量,则意味着您必须改用doubles,这将导致Shape的API支持双精度值

您应该使用哪个?随你(由你决定。Timing
Framework确实非常适合在一段时间内进行线性动画处理,您知道要从一种状态进入另一种状态。对于游戏之类的东西来说,状态不是很好,因为对象的状态可能会从我的周期更改为另一个周期。我敢肯定您可以做到,但是使用简单的“主循环”概念会容易得多-
IMHO



 类似资料:
  • 嗯,这是一个非常新的提示。我声明要在window builder的帮助下自己编写GUI应用程序的代码,我已经决定停止使用netbeans,因为我在这里读到一些人说这很好。你可能认为我没有调查,但相信我,我做了功课。。。 我尝试了甲骨文所说的方式: > 公共类MyClass实现ActionListener{ someComponent。addActionListener(instanceOfMyCl

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

  • 我在Swing和设置角色动画方面有一些问题,我有一个带有关键侦听器的JFrame,当用户点击时,它在这里调用我的JPanel方法 这个动画我的角色,但这么快,我们可以看到一个东西,我怎么才能看到动画?

  • 我有一段疯狂的代码。我如何用核心动画来制作动画,这样我的代码就少了很多?我已经找到了一些做“摆动”动画的代码,但那是3D的,我只想让视图左右移动,我不想让它在侧面反弹。

  • 我使用了一个教程,一切都很好,直到我开始处理swagger 2的依赖。我现在想知道是否有办法解决这个问题。 招摇配置: pom.xml: 错误: 搜索关于我试图改变版本到2.8.0,2.7.0,3.0.0...也返回错误。该应用程序是一个带有任务列表活动的apirest。

  • 问题内容: 我在游戏中使用了摇摆计时器,但是当游戏运行时,它似乎有平稳运行的时刻和减速的时刻。 为什么时间在波动? 我该如何解决? 这是我的代码示例。在我的实际程序中,我正在绘制图像,而不仅仅是矩形。还有很多碰撞检测和其他小的计算正在发生。 另外,这是游戏的Jar文件的链接,因此您可以运行它,(满是)明白我的意思。http://dl.dropbox.com/u/8724803/Get%20To%2