Есть ли способ сгладить переход графического компонента из одной точки в другую, используя класс Timer в Java? - PullRequest
0 голосов
/ 10 ноября 2019

Я пытаюсь сделать простую анимацию плавно в Java, используя класс Timer, то есть , чтобы переместить target из его текущей позиции в самый дальний конец кадра по горизонтали .

Я использовал текущую позицию графического компонента в методе actionPerformed() класса Timer и увеличивал местоположение компонента x на определенную величину, но когда я пытаюсь запустить его, компонент мгновенно переходит наследующее местоположение и ожидает завершения таймера и перерисовки в новом месте. (Прошу прощения, если не правильно сформулировал проблему.)

Я включил код целиком, чтобы обеспечить весь контекст:

public class FireAtBill extends JPanel {
    private static final long serialVersionUID = 4682094035006759518L;

    private int hits, misses;
    private Point targetPos;
    private Timer t;
    private BufferedImage crosshair, target;


    public FireAtBill() {

        Random random = new Random();
        targetPos = new Point(random.nextInt(500),random.nextInt(500) );
        t = new Timer(500, new TimerListener());
        t.start();

        setForeground(Color.WHITE);
        setBackground(Color.BLACK);

        try {
            crosshair = ImageIO.read(new File(System.getProperty("user.dir")+ "/crosshair.jpg"));
            target = ImageIO.read(new File(System.getProperty("user.dir")+ "/target.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawString("hits: " + hits + "  misses: " + misses, 0, 10);
        g2.drawImage(crosshair, 125, 50, this);
        g2.drawImage(target, targetPos.x, targetPos.y, this);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Fire At Bill");
        frame.setSize(500,500 );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        FireAtBill fireAtBill = new FireAtBill();
        frame.getContentPane().add(fireAtBill);
        frame.setVisible(true);
    }

    private class TimerListener implements ActionListener{
        double x = targetPos.getX();
        public void actionPerformed(ActionEvent event) {
            if (x <= 500||targetPos.getX() >= 0) {
                if (x<250) {
                    targetPos.setLocation(targetPos.getX()+15, targetPos.getY());
                }
                else {
                    targetPos.setLocation(targetPos.getX()-15, targetPos.getY());
                }
            }
            repaint();
        }

    }

}

Я ожидаю, что target будет плавно перемещаться по экрану по горизонтали, но target прыгает из одного места в другое. Я попытался увеличить позицию x target, используя меньшие значения, и хотя это сглаживает движение, это происходит за счет скорости target, которую я надеюсь реализовать как переменную, которая можетбыть изменено путем изменения его стоимости. Заранее спасибо.

1 Ответ

0 голосов
/ 10 ноября 2019

Хорошо, я обнаружил, что, уменьшив значение задержки при инициализации объекта Timer, я могу ускорить процесс перерисовки здесь t = new Timer(500, new TimerListener());, изменив 500 на что-то вроде 50. Уменьшение этого значения ускорит анимацию.

И сглаживание может быть реализовано путем уменьшения значения приращения внутри метода actionPerformed() класса TimeListener здесь targetPos.setLocation(targetPos.getX()+15, targetPos.getY()); путем изменениязначение приращения 15 к чему-то вроде 3. Уменьшение этого значения поможет сгладить анимацию.

...