Advertisement
Guest User

Untitled

a guest
Dec 4th, 2016
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.39 KB | None | 0 0
  1. package cad97.bejeweled.animation;
  2.  
  3. import javax.swing.*;
  4. import java.awt.*;
  5. import java.awt.geom.Area;
  6. import java.util.List;
  7.  
  8. /**
  9. * Animate Polygons around on a Graphics object.
  10. *
  11. * @author Christopher Durham
  12. * @date 11/25/2016
  13. */
  14. public final class Animator {
  15. public static final Animator INSTANCE = new Animator();
  16.  
  17. private final static int ANIMATION_FRAMES = 30;
  18. private final static int ANIMATION_FPS = 60;
  19. private final static int ANIMATION_INTERVAL = 1000 / ANIMATION_FPS;
  20.  
  21. /**
  22. * Convenience class bundling a {@link Color} and a {@link Polygon}
  23. */
  24. public static class ColoredPolygon {
  25. final Color color;
  26. final Polygon polygon;
  27.  
  28. public ColoredPolygon(Color color, Polygon polygon) {
  29. this.color = color;
  30. this.polygon = polygon;
  31. }
  32. }
  33.  
  34. /**
  35. * Animate the swap of two Polygons on a Graphics object.
  36. * <p>
  37. * The parameter Polygons are mutated during the execution of this method.
  38. * <p>
  39. * A redraw of the animated area in the {@code after} callback is suggested,
  40. * as the final frame of this animation is not guaranteed to be fully swapped.
  41. * (E.g. the frame before a fully swapped position.)
  42. *
  43. * @param bgColor the background Color used to erase frames
  44. * @param first the first ColoredPolygon being switched
  45. * @param second the second ColoredPolygon being switched
  46. * @param g the Graphics object to draw on
  47. * @param after callback run on UI thread after animation is finished
  48. */
  49. public void translateSwap(final Color bgColor, final ColoredPolygon first, final ColoredPolygon second,
  50. final Graphics g, final Runnable after) {
  51. new SwingWorker<Void, Void>() {
  52. @Override
  53. protected Void doInBackground() throws Exception {
  54. final Rectangle b1 = first.polygon.getBounds();
  55. final Rectangle b2 = second.polygon.getBounds();
  56. final int deltaX = (b1.x - b2.x) / ANIMATION_FRAMES;
  57. final int deltaY = (b1.y - b2.y) / ANIMATION_FRAMES;
  58. final Rectangle animationBounds = b1.union(b2);
  59.  
  60. for (int i = 0; i < ANIMATION_FRAMES; i++) {
  61. first.polygon.translate(-deltaX, -deltaY);
  62. second.polygon.translate(deltaX, deltaY);
  63. SwingUtilities.invokeAndWait(() -> {
  64. g.setColor(bgColor);
  65. g.fillRect(animationBounds.x, animationBounds.y, animationBounds.width, animationBounds.height);
  66. g.setColor(first.color);
  67. g.fillPolygon(first.polygon);
  68. g.setColor(second.color);
  69. g.fillPolygon(second.polygon);
  70. });
  71. Thread.sleep(ANIMATION_INTERVAL);
  72. }
  73. SwingUtilities.invokeLater(after);
  74. return null;
  75. }
  76. }.execute();
  77. }
  78.  
  79. /**
  80. * Translate a group of Polygons a direction on a Graphics object.
  81. * <p>
  82. * The passed Polygons are mutated during the execution of this method.
  83. * <p>
  84. * A redraw of the animated area in the {@code after} callback is suggested,
  85. * as the final frame of this animation is not guaranteed to be fully swapped.
  86. * (E.g. the frame before a fully swapped position.)
  87. *
  88. * @param bgColor the background Color used to erase frames
  89. * @param polygons a list of ColoredPolygons to translate
  90. * @param dx the delta x to translate the polygons
  91. * @param dy the delta y to translate the polygons
  92. * @param g the Graphics object to draw on
  93. * @param after callback run on UI thread after animation is finished
  94. */
  95. public void batchTranslate(final Color bgColor, final List<ColoredPolygon> polygons,
  96. final int dx, final int dy, final Graphics2D g, final Runnable after) {
  97. new SwingWorker<Void, Void>() {
  98. @Override
  99. protected Void doInBackground() throws Exception {
  100. final Area animationBounds = polygons.stream().sequential()
  101. .map(it -> it.polygon).map(Polygon::getBounds).peek(it -> {
  102. it.grow(dx / 2, dy / 2);
  103. it.translate(dx / 2, dy / 2);
  104. }).map(Area::new).reduce((lhs, rhs) -> {
  105. if (lhs == null) return rhs;
  106. rhs.add(lhs);
  107. return rhs;
  108. })
  109. .orElseThrow(AssertionError::new);
  110. final int deltaX = dx / ANIMATION_FRAMES;
  111. final int deltaY = dy / ANIMATION_FRAMES;
  112.  
  113. for (int i = 0; i < ANIMATION_FRAMES; i++) {
  114. polygons.forEach(it -> it.polygon.translate(deltaX, deltaY));
  115. SwingUtilities.invokeAndWait(() -> {
  116. g.setColor(bgColor);
  117. g.fill(animationBounds);
  118. polygons.forEach(it -> {
  119. g.setColor(it.color);
  120. g.fill(it.polygon);
  121. });
  122. });
  123. Thread.sleep(ANIMATION_INTERVAL);
  124. }
  125. SwingUtilities.invokeLater(after);
  126. return null;
  127. }
  128. }.execute();
  129. }
  130. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement