以特定模式对矩形进行动画处理

问题描述

我想为特定图案中的矩形设置动画。有人告诉我使用SwingTimer来制作动画,而不是Thread

我的计划是为向前移动的矩形设置动画,直到它碰到帧的末端。然后它向下移动一个单位(矩形的高度,在我的情况下为30),然后向后移动;当它到达终点时,它再次向下移动,依此类推。

Here´s a sketch of how I want it to move

现在SwingTimer的问题在于整个操作是一个连续循环,因此矩形不会按照我想要的方式移动。为了使它起作用,我想我必须开始和停止一些复杂的方法的循环,而我不知道该如何正确地进行。

那么我该如何为矩形设置动画呢? SwingTimer确实是做这种事情的正确方法还是其他方法更好?

这是我到目前为止获得的代码。我知道这并不多,ActionPerformed做的动画完全不同。

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


    public class Test extends javax.swing.JPanel implements ActionListener{
    
        private int x = 0;
        private int y = 0;
        Timer tm = new Timer(50,this);
    
        public test() {
            initComponents();
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(new java.awt.Color(102,102,102));
            g.fillRect(x,y,30,30);
            tm.start();
        }
    
        public void moveForward() {
            x = x + 30;
            repaint();
            System.out.println("(" + x + "|" + y + ")");
        }
    
        public void moveBackwards() {
            x = x - 30;
            repaint();
            System.out.println("(" + x + "|" + y + ")");
        }
    
        public void moveDown() {
            y = y + 30;
            repaint();
            System.out.println("(" + x + "|" + y + ")");
        }
    
        public void moveUp() {
            y = y - 30;
            repaint();
            System.out.println("(" + x + "|" + y + ")");
        }
    
        public void actionPerformed(ActionEvent e) {
           moveForward();
           if (x >= 270){
               moveDown();
              }
            }
        
        public static void main(String[] args) {
            Test t = new test();
            JFrame f = new JFrame();
            f.setSize(300,300);
            f.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
            f.add(t);
            f.setVisible(true);
        }

解决方法

到目前为止,您所做的一切看起来不错。您只需要操作方法即可正常工作。为此,我将使用一个名为direction的类变量:

private boolean direction = true;

现在,在操作方法中,您可以根据方向向前或向后移动矩形。如果碰到末端,则向下移动矩形并反转方向:

public void actionPerformed(ActionEvent e) {
    
    if (direction){
        moveForward();
    }
    else {
        moveBackwards();
    }

    //Check if it is at the end
    if(((x >= 270) && (direction)) || ((x <= 30) && (!direction))) {
        moveDown();
        direction = !direction;
    }
}

if子句有点复杂,但是如果希望它更具可读性,可以将其拆分。