动画单独的对象 [英] Animating Separate Objects

查看:75
本文介绍了动画单独的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've been working on an "elevator simulator" where I have to animate "elevators". I was able to create different elevator objects, which I did by having each Elevator Object have the parameters of width, height, and coordinates. I then stored them all into an array and used a for loop to draw them into my frame using JPanel's PaintComponent method.

你们能建议一种方法还是给我一些建议为它们分别设置动画,比如说独立地上下移动它们?当我只有一个电梯时,我就能够移动它,但是当我尝试将其应用于多部电梯时,它却无法工作。

Can you guys suggest a way or give me advice to animate them separately from each other, like say move them up and down independently? I was able to make it move when I only had ONE elevator, but when I tried to apply it to multiple elevators, it did not work.

我以前的尝试是只需更改SINGLE电梯的x和y坐标的ActionListener(侦听按钮按下即可开始动画)。因此,我该如何使用多部电梯进行操作(电梯的数量对用户是任意的)。我是否必须制作和电梯一样多的ActionListeners,以便它可以独立收听它们?

My previous attempt involved an ActionListener (that listens to a button press to "start" the animation) that simply changes the x and y coordinates of the SINGLE elevator. So How do I go and do that with several elevators (the number of elevators is arbitrary to the user). Do I have to make as many ActionListeners as there are elevators, so it can listen to them independently?

这里是只有一个电梯时才起作用的ActionListener。

Here's the ActionListener that worked when there's only ONE elevator. It only moves up so far.

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



    }
};

非常感谢!

推荐答案


我必须制作与电梯一样多的ActionListeners,以便它可以独立收听吗?

"Do I have to make as many ActionListeners as there are elevators, so it can listen to them independently?"

否,那将需要多个计时器。尽量避免这样做。

No, that would require multiple Timers. Avoid doing this whenever you can.


你们能建议一种方法还是给我一些建议,使它们彼此分开动画,比如说将它们独立地上下移动?

"Can you guys suggest a way or give me advice to animate them separately from each other, like say move them up and down independently?"

您应该做的就是尝试在<$ c $中的方法中实现业务逻辑c> Elevator 类,并在循环访问数组中的所有 Elevators 时调用这些方法。

What you should do is try and implement the business logic in methods within your Elevator class and just call the those methods while looping through all the Elevators in your array.

两个使电梯显得独立移动,可以带有标志,例如在移动中说方法,例如

Two make the Elevators to appear to move independently, you can have flags, say in your move method, like

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

您为何使电梯移动,这就是升旗的原因。反之亦然。也许像 if(onFloor){lift.move = false} 之类的,可能持续20个计时器迭代 ,并保持计数在电梯类中,当计数达到20时,它将重置为0,然后移动将恢复为真。

What ever is your reason for making the elevator move, that will be the reason the raise the flag. And vice versa. Maybe something like if (onFloor) { elevator.move = false }, maybe for a duration of 20 timer "iterations", and keep a count in the elevator class, that will reset back to 0 when the count hits 20, then move will be back at true.

这是您可以使用的示例。我在上面工作了大约20分钟,然后放弃了。逻辑有些偏离,但基本上指出了我提到的想法。也许您会有更好的运气。您还可以在此处

Here's an example you can play with. I was working on it for about 20 minutes then gave up. The logic is a bit off, but it basically points out the ideas i mentioned. Maybe you'll have better luck with it. You can also see a good working example of moving different object 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);
            }
        });
    }
}

这篇关于动画单独的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆