首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将不同的物体动画化

将不同的物体动画化
EN

Stack Overflow用户
提问于 2014-03-18 14:22:09
回答 2查看 615关注 0票数 0

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

你们能不能建议一种方法或者给我建议,让他们彼此分开,比如独立地上下移动他们?当我只有一部电梯的时候,我就能移动它,但当我试图将它应用于多部电梯时,它却不起作用。

我之前的尝试涉及一个ActionListener (它监听按下按钮来“启动”动画),它只是改变了单个电梯的x和y坐标。那么,如何使用多台电梯(电梯的数量对用户来说是任意的),如何做到这一点。我是否必须制造出和电梯一样多的ActionListeners,这样它就可以独立地听它们了吗?

这是在只有一个电梯的情况下工作的ActionListener。它只上升到目前为止。

代码语言:javascript
复制
  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();
      }



    }
};

非常感谢!

EN

回答 2

Stack Overflow用户

发布于 2014-03-18 18:37:41

“我是否必须制作和电梯一样多的ActionListeners,这样它就可以独立地听它们的声音了吗?”

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

“你们能不能建议一种方法,或者给我一些建议,让它们彼此分开,比如把它们分别上下移动?”

您应该做的是尝试在Elevator类中的方法中实现业务逻辑,只需调用这些方法,同时遍历数组中的所有Elevators

两个使Elevators看起来独立移动,您可以有标志,例如在您的move方法中

代码语言:javascript
复制
public void move() {
    if (move) {
        // do something
    }
}

什么是你让电梯移动的原因,这将是升旗的原因。反之亦然。也许类似于if (onFloor) { elevator.move = false },可能持续20个计时器“迭代”,并在电梯类中保持一个计数,当计数达到20时,这个计数将重置为0,那么move将返回true。

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

代码语言:javascript
复制
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);
            }
        });
    }
}
票数 2
EN

Stack Overflow用户

发布于 2014-03-18 21:21:28

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

代码语言:javascript
复制
// 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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22482196

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档