【问题标题】:Implement fluctuating effect for sprite in Java Swing在Java Swing中实现精灵的波动效果
【发布时间】:2017-03-19 12:06:01
【问题描述】:

在 Java swing 中有没有一种方法可以让 sprite 具有真实的效果?就像它围绕中心随机移动并产生波动效果一样?

我尝试了类似以下的方法(但结果很糟糕):

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

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;
    private int last = -1;

    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 = 58;
            y = 58;
            movementTimer = new Timer(12, new ActionListener() {

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

        public void moveImage() {
            if (last < 0) {
                last = random();
                x += last;
                y += last;
            } else {
                x -= last;
                y -= last;
                last = -1;
            }
            if (x > W) {
                x = 0;
            }
            if (y > H) {
                y = 0;
            }
        }

        private int random() {

            Random r = new Random();
            int Low = 2;
            int High = 14;
            int Result = r.nextInt(High - Low) + Low;
            return Result;
        }

        @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);

        }
    }
}

结果一点都不顺利,你有什么建议吗?

【问题讨论】:

  • 简短的回答是肯定的,但是您需要做一些工作。 Graphics2D API 有许多类和功能,可以很容易地实现这一点
  • 谢谢,但简短的回答太短了... :) 是否有一些您可以提供的示例或一些互联网资源可供我开始?请告诉我。
  • 是的,有成千上万的例子,不,我不应该为你搜索它们;)
  • 只是提示,如果您正在寻找逼真的运动,例如家蝇的运动如何以流畅的方式波动,您可能需要查看 perlin noise 而不是使用原始 RNG

标签: java swing


【解决方案1】:

简短的回答是肯定的,可以做到。长答案是,您永远找不到满足您确切需求的单个示例/解决方案,您需要剖析它们并删除您需要的那些元素。这是专业开发人员的标志,相信我,我 90% 的时间都在做我以前从未做过的事情(或者不知道如何完成)。

当遇到问题/想法时,您需要退后一步,将其分解为可管理的组件

在我看来,你有两个基本要求,动画和转换。

动画

动画只是随时间变化的幻觉。表面上实现起来似乎很简单,实际上变成了very complex, very quickly

在 Swing 中,最简单的解决方案是使用Swing Timer,它会生成定期更新,在事件调度线程的上下文中触发,从而可以安全地从(Swing 与大多数 UI 框架一样,没有线程安全)。

由于这种工作方式,它不是很精确,这意味着您最终可能会获得可变帧速率。您可以通过使用time based animation 方法来克服这个问题,其中移动基于持续时间,而不是计时器触发的次数。

另一种解决方案是使用线程,计算每个更新周期所花费的时间,然后等待维持 FPS 所需的剩余时间。当您遇到线程问题(脏更新)时,这会更加复杂,并且它没有考虑在 UI 上实际渲染图形可能需要的时间(使用 Swing 的被动渲染引擎时)

转型

转换图形(移动/旋转)最终将归结为您要转换的“内容”。

Graphics2D API 具有旋转图像的能力,for exampleexampleexampleexampleexampleexample

它还可以旋转Graphics 上下文本身,这可能会很混乱,或者旋转“形状”,这通常更容易管理。

你应该看看Working with GeometryTransforming Shapes, Text and Images2D Graphics一般。

您还可以在点之间移动对象并更改其方向,如 herehere 所示,或者您可以使用 path based animation 以便对象遵循预定义的移动路径,甚至更复杂的路径,比如基于时间线的动画,for example, example, example

所以,长答案是,这取决于

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-12
    • 2011-02-14
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    相关资源
    最近更新 更多