在JavaSwing中实现sprite的波动效果

在JavaSwing中实现sprite的波动效果,java,swing,Java,Swing,在JavaSwing中有没有一种方法可以让精灵看起来像是活的?像是围绕中心随机移动,产生波动效应 我尝试了以下方法,但结果很糟糕: 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 j

在JavaSwing中有没有一种方法可以让精灵看起来像是活的?像是围绕中心随机移动,产生波动效应

我尝试了以下方法,但结果很糟糕:

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

        }
    }
}

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

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

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

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

动画 动画只是随着时间变化的幻觉。从表面上看,这似乎很容易实现,但实际上,它变得非常简单

在Swing中,最简单的解决方案是使用,它生成定期更新,在事件调度线程的上下文中触发,从而使从Swing更新UI变得安全,就像大多数UI框架一样,它不是线程安全的

因为它的工作方式,它不是很精确,这意味着你可能会以一个可变的帧速率结束。您可以通过使用一种方法来克服这一问题,其中移动基于持续时间,而不是计时器触发的次数

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

转型 变换图形移动/旋转最终将归结为变换的内容

Graphics2D API具有旋转图像、、、的功能

它还可以旋转图形上下文本身,这可能会很混乱,也可以旋转形状,这通常更易于管理

你应该大体上看一看

您还可以在点之间移动对象并更改其方向,如所示和/或您可以使用的,以便对象遵循预定义的移动路径或更复杂的路径,如基于时间线的动画


因此,长答案是,这取决于

短答案是肯定的,但你需要做一些工作。Graphics2D API有许多类和功能,可以很容易地帮助您实现这一点,但简短的回答太短了…:你能提供一些例子吗?或者我可以从一些互联网资源开始?请让我知道。是的,有成千上万的例子,不,我不需要为你寻找它们;这只是一个提示,如果你在寻找真实的运动,比如家蝇的运动是如何以流动的方式波动的,你可能想研究而不是使用原始RNG