Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package cad97.bejeweled.animation;
- import javax.swing.*;
- import java.awt.*;
- import java.awt.geom.Area;
- import java.util.List;
- /**
- * Animate Polygons around on a Graphics object.
- *
- * @author Christopher Durham
- * @date 11/25/2016
- */
- public final class Animator {
- public static final Animator INSTANCE = new Animator();
- private final static int ANIMATION_FRAMES = 30;
- private final static int ANIMATION_FPS = 60;
- private final static int ANIMATION_INTERVAL = 1000 / ANIMATION_FPS;
- /**
- * Convenience class bundling a {@link Color} and a {@link Polygon}
- */
- public static class ColoredPolygon {
- final Color color;
- final Polygon polygon;
- public ColoredPolygon(Color color, Polygon polygon) {
- this.color = color;
- this.polygon = polygon;
- }
- }
- /**
- * Animate the swap of two Polygons on a Graphics object.
- * <p>
- * The parameter Polygons are mutated during the execution of this method.
- * <p>
- * A redraw of the animated area in the {@code after} callback is suggested,
- * as the final frame of this animation is not guaranteed to be fully swapped.
- * (E.g. the frame before a fully swapped position.)
- *
- * @param bgColor the background Color used to erase frames
- * @param first the first ColoredPolygon being switched
- * @param second the second ColoredPolygon being switched
- * @param g the Graphics object to draw on
- * @param after callback run on UI thread after animation is finished
- */
- public void translateSwap(final Color bgColor, final ColoredPolygon first, final ColoredPolygon second,
- final Graphics g, final Runnable after) {
- new SwingWorker<Void, Void>() {
- @Override
- protected Void doInBackground() throws Exception {
- final Rectangle b1 = first.polygon.getBounds();
- final Rectangle b2 = second.polygon.getBounds();
- final int deltaX = (b1.x - b2.x) / ANIMATION_FRAMES;
- final int deltaY = (b1.y - b2.y) / ANIMATION_FRAMES;
- final Rectangle animationBounds = b1.union(b2);
- for (int i = 0; i < ANIMATION_FRAMES; i++) {
- first.polygon.translate(-deltaX, -deltaY);
- second.polygon.translate(deltaX, deltaY);
- SwingUtilities.invokeAndWait(() -> {
- g.setColor(bgColor);
- g.fillRect(animationBounds.x, animationBounds.y, animationBounds.width, animationBounds.height);
- g.setColor(first.color);
- g.fillPolygon(first.polygon);
- g.setColor(second.color);
- g.fillPolygon(second.polygon);
- });
- Thread.sleep(ANIMATION_INTERVAL);
- }
- SwingUtilities.invokeLater(after);
- return null;
- }
- }.execute();
- }
- /**
- * Translate a group of Polygons a direction on a Graphics object.
- * <p>
- * The passed Polygons are mutated during the execution of this method.
- * <p>
- * A redraw of the animated area in the {@code after} callback is suggested,
- * as the final frame of this animation is not guaranteed to be fully swapped.
- * (E.g. the frame before a fully swapped position.)
- *
- * @param bgColor the background Color used to erase frames
- * @param polygons a list of ColoredPolygons to translate
- * @param dx the delta x to translate the polygons
- * @param dy the delta y to translate the polygons
- * @param g the Graphics object to draw on
- * @param after callback run on UI thread after animation is finished
- */
- public void batchTranslate(final Color bgColor, final List<ColoredPolygon> polygons,
- final int dx, final int dy, final Graphics2D g, final Runnable after) {
- new SwingWorker<Void, Void>() {
- @Override
- protected Void doInBackground() throws Exception {
- final Area animationBounds = polygons.stream().sequential()
- .map(it -> it.polygon).map(Polygon::getBounds).peek(it -> {
- it.grow(dx / 2, dy / 2);
- it.translate(dx / 2, dy / 2);
- }).map(Area::new).reduce((lhs, rhs) -> {
- if (lhs == null) return rhs;
- rhs.add(lhs);
- return rhs;
- })
- .orElseThrow(AssertionError::new);
- final int deltaX = dx / ANIMATION_FRAMES;
- final int deltaY = dy / ANIMATION_FRAMES;
- for (int i = 0; i < ANIMATION_FRAMES; i++) {
- polygons.forEach(it -> it.polygon.translate(deltaX, deltaY));
- SwingUtilities.invokeAndWait(() -> {
- g.setColor(bgColor);
- g.fill(animationBounds);
- polygons.forEach(it -> {
- g.setColor(it.color);
- g.fill(it.polygon);
- });
- });
- Thread.sleep(ANIMATION_INTERVAL);
- }
- SwingUtilities.invokeLater(after);
- return null;
- }
- }.execute();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement