动画分离对象

时间:2014-03-18 14:22:10

标签: java swing animation timer actionlistener

我一直在研究“电梯模拟器”,我必须为“电梯”制作动画。我能够创建不同的电梯对象,我通过让每个电梯对象具有宽度,高度和坐标参数来完成。然后我将它们全部存储到一个数组中,并使用for循环使用JPanel的PaintComponent方法将它们绘制到我的框架中。

你们可以建议一种方法或者给我建议,让它们彼此分开制作动画,比如说要独立地上下移动它们吗?当我只有一部电梯时,我能够移动它,但是当我试图将它应用到多个电梯时,它没有用。

我之前的尝试涉及一个ActionListener(它按下按钮以“开始”动画),它只是改变了SINGLE电梯的x和y坐标。那么如何使用多台电梯(电梯的数量对用户来说是任意的)。我是否必须制作与电梯一样多的ActionListener,以便它可以独立收听它们?

这是只有一部电梯时工作的ActionListener。它到目前为止只会向上移动。

  private ActionListener timerActionUp = new ActionListener()
{
    private int iterator = 0;
    private int top = 0;
    public void actionPerformed(ActionEvent e)
    {
      if(top<floorQueue.length){
      if(iterator<floorQueue[top]){ //floorQueue is so that the elevator knows where to stop
        if(movefloorup<VERTICALFLOORDISTANCE*6){ //this is when the elevator reaches the "top" floor that can fit into the screen, and moves to the next column representing the floors further up
            repaint();
            movefloorup = movefloorup + VERTICALFLOORDISTANCE;
            System.out.println(movefloorup);
            iterator++;
        }
        else{
            //timer.stop();
            repaint();
            switchmarker = 1; //makes elevator moves to the next column
            movefloorup = 0;
            iterator++;

        }
      }
      else
      {
          System.out.println("Picking up passengers...");
          elevatorCapacity = elevatorCapacity + peopleQueue[floorQueue[top]];
          System.out.println("Passengers in elevator: "+elevatorCapacity);
          peopleQueue[floorQueue[top]] = 0; //Updates the number of people in the elevator
          top++;
          if(elevatorCapacity >= 5)
          {
              System.out.println("WARNING!  ELEVATOR FULL!");
              elevfull = 1;
          }
          //timer.stop();
      }

      }
      else
      {
          System.out.println("Done picking up passengers.");
          timer.stop();
      }



    }
};

非常感谢!

2 个答案:

答案 0 :(得分:2)

  

&#34;我是否必须制作与电梯一样多的ActionListener,以便它可以独立收听?&#34;

不,那需要多个计时器。尽可能避免这样做。

  

&#34;你们可以建议一种方法,或者给我建议让它们彼此分开制作,比如说要独立地上下移动它们吗?&#34;

您应该尝试在Elevator类中的方法中实现业务逻辑,并在循环遍历数组中的所有Elevators时调用这些方法。

两个让Elevators看起来独立移动,你可以有标记,比如你的move方法,比如

public void move() {
    if (move) {
        // do something
    }
}

你的理由是什么使电梯移动,这将是举起旗帜的原因。反之亦然。也许类似于if (onFloor) { elevator.move = false },可能持续20个计时器&#34;迭代&#34; ,并在电梯类中保持计数,当计数时将重置为0点击20,然后move将恢复为真。


这是一个你可以玩的例子。我正在研究它大约20分钟然后放弃了。逻辑有点偏,但它基本上指出了我提到的想法。也许你会有更好的运气。您还可以看到移动不同对象here

的良好工作示例
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ElevatorAnimate extends JPanel {

    private static final int D_W = 300;

    private static final int FLOORS = 6;
    private static final int FLOOR_HEIGHT = 100;
    private static final int BUILDING_HEIGHT = FLOORS * FLOOR_HEIGHT;
    private static final int D_H = BUILDING_HEIGHT;
    private static final int BUILDING_BASE = BUILDING_HEIGHT;
    private static final int ELEVATOR_HEIGHT = 60;
    private static final int ELEVATOR_WIDTH = 30;

    private final List<Elevator> elevators;

    public ElevatorAnimate() {
        elevators = createElevators();

        Timer timer = new Timer(50, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                for (Elevator el : elevators) {
                    el.move();
                }
                repaint();
            }
        });
        timer.start();
    }

    private List<Elevator> createElevators() {
        List<Elevator> list = new ArrayList<>();
        list.add(new Elevator(6, 30));
        list.add(new Elevator(4, 90));
        list.add(new Elevator(2, 150));
        return list;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawFloors(g);
        for (Elevator el : elevators) {
            el.drawElevator(g);
        }
    }

    private void drawFloors(Graphics g) {
        for (int i = 1; i <= FLOORS; i++) {
            g.drawLine(0, FLOOR_HEIGHT * i, D_W, FLOOR_HEIGHT * i);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(D_W, D_H);
    }

    public class Elevator {

        int floor, x, y;
        boolean move = false;
        boolean up = true;
        int stopCount = 0;

        public Elevator(int floor, int x) {
            this.floor = floor;
            y = BUILDING_HEIGHT - (floor * FLOOR_HEIGHT);
            this.x = x;
        }

        public void drawElevator(Graphics g) {
            g.fillRect(x, y, ELEVATOR_WIDTH, ELEVATOR_HEIGHT);
        }

        public void move() {
            if (y <= 0) {
                up = false;
            } else if (y >= BUILDING_BASE + ELEVATOR_HEIGHT) {
                up = true;
            }

            if (isOnFloor()) {
                move = false;
            }

            if (move) {
                if (up) {
                    y -= 2;
                } else {
                    y += 2;
                }
            } else {
                if (stopCount >= 20) {
                    move = true;
                    stopCount = 0;
                } else {
                    stopCount++;
                }
            }
        }

        private boolean isOnFloor() {
            return y / FLOOR_HEIGHT == 100;
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new ElevatorAnimate());
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

答案 1 :(得分:1)

从这个相关的Subway模拟开始,以下变体添加了两个独立的面板,每个面板都包含自己的视图和控制面板。

// Common initialization for either JApplet or JFrame
private static void initContainer(Container container) {
    container.add(createPanel(), BorderLayout.NORTH);
    container.add(createPanel(), BorderLayout.SOUTH);
}

private static JPanel createPanel() {
    JPanel panel = new JPanel(new BorderLayout());
    ButtonPanel control = new ButtonPanel();
    SubwayPanel subway = new SubwayPanel(control);
    panel.add(subway, BorderLayout.NORTH);
    panel.add(control, BorderLayout.SOUTH);
    subway.beginOperation();
    return panel;
}