技术开发 频道

在二维动画中使用基于图像的路径

  清单 5 显示了用于移动实体的逻辑。这个过程在每个动画周期中执行一次。

  清单 5. 移动所有实体

1 /** Move the entities around the pattern */
2 public void moveEntities() {
3     // update (move) the people
4     for (Iterator iter = people.iterator(); iter.hasNext();) {
5         Object next = iter.next();
6         if (next instanceof Person) {
7             ((Person)next).updateTick();
8         }
9     }
10     // update the other entities
11     for (Iterator iter = entities.iterator(); iter.hasNext();) {
12         Object next = iter.next();
13         if (next instanceof Entity) {
14             ((Entity)next).updateTick();
15         }
16     }
17 }
18

  动画中的每个新帧(frame)都是由清单 6 所显示的过程创建的。注意实体将它们自己添加到帧中。

  清单 6. 在当前位置添加实体

1 /** Advance the animation */
2 public void prepareNextFrame(boolean update, boolean shared) {
3     setBackground(Color.black);
4     if (update) {
5         manager.moveEntities();
6     }
7     mainPanel.setBounds(getBounds());
8     mainPanel.removeAll();
9     // add the people
10     for (Iterator iter = manager.getPeople().iterator();
11          iter.hasNext();) {
12         Person person = (Person)iter.next();
13         person.addToPanel(mainPanel, shared);
14     }
15     // add the entities
16     for (Iterator iter = manager.getEntities().iterator();
17          iter.hasNext();) {
18         Entity entity = (Entity)iter.next();
19         entity.addToPanel(mainPanel, shared);
20     }
21 }
22

  我们用清单 7 中的代码实现连续的动画。 delay 值控制动画运行的快慢以及它占用 CPU 时间的多少。

  清单 7. 动画周期

1 public void runUpdates(int delay) {
2     TimerTask task = new TimerTask() {
3         public void run() {
4             SwingUtilities.invokeLater(new Runnable() {
5                     public void run() {
6                         prepareNextFrame();
7                         repaint();
8                         if (manager.getPeople().size() == 0) {
9                             cancel();
10                         }
11                     }
12             });
13         }
14     };
15     (new Timer(true)).scheduleAtFixedRate(task, 0, delay);
16 }
17

  下面是我们动画序列的几个屏幕快照。图 7 显示了在行动之前的逃生模拟(完成了全部过程的大约 10%)。

  图 7. 刚开始时的逃生序列

  图 8 显示在完成了大约 50% 时的动画序列。

  图 8. 数次更新后的逃生序列

  图 9 显示接近完成时的序列(尽管序列实际上是无限循环运行的)。

  图 9. 接近完成时的逃生序列

  在图 10 中可以看到实体是如何沿着控制路径移动的,它应当可以让您更好地理解运行是如何实现的。

  图 10. 实体沿着控制路径移动

0
相关文章