diff --git a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java index 5ff4d7e307b..b06537785cd 100644 --- a/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java +++ b/forge-gui-mobile/src/forge/screens/planarconquest/ConquestMultiverseScreen.java @@ -3,6 +3,7 @@ package forge.screens.planarconquest; import java.util.List; import com.badlogic.gdx.graphics.Color; +import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import forge.Forge; @@ -23,8 +24,11 @@ import forge.planarconquest.ConquestPlane; import forge.planarconquest.ConquestPlane.Region; import forge.planarconquest.ConquestPlaneData; import forge.screens.FScreen; +import forge.toolbox.FDisplayObject; +import forge.toolbox.FOptionPane; import forge.toolbox.FScrollPane; import forge.util.Callback; +import forge.util.Utils; import forge.util.collect.FCollectionView; public class ConquestMultiverseScreen extends FScreen { @@ -63,35 +67,59 @@ public class ConquestMultiverseScreen extends FScreen { @Override public void run(ConquestEvent event) { if (event.wasConquered()) { - //spin Chaos Wheel if event was conquered - ConquestChaosWheel.spin(); + ConquestLocation loc = event.getLocation(); + ConquestEventRecord record = model.getCurrentPlaneData().getEventRecord(loc); + if (record.getWins(event.getTier()) == 1 && record.getHighestConqueredTier() == event.getTier()) { + //if first time conquering event at the selected tier, show animation of new badge being positioned on location + planeGrid.animateBadgeIntoPosition(loc); + } + else { + //just spin Chaos Wheel immediately if event tier was previously conquered + spinChaosWheel(); + } } } })); } + private void spinChaosWheel() { + ConquestChaosWheel.spin(); + } + private class PlaneGrid extends FScrollPane { private MoveAnimation activeMoveAnimation; + private BadgeAnimation activeBadgeAnimation; + + @Override + public void buildTouchListeners(float screenX, float screenY, List listeners) { + //prevent user touch actions while an animation is in progress + if (activeMoveAnimation == null && activeBadgeAnimation == null) { + super.buildTouchListeners(screenX, screenY, listeners); + } + } @Override public boolean tap(float x, float y, int count) { - if (activeMoveAnimation == null) { - //start move animation if a path can be found to tapped location - ConquestLocation loc = getLocation(x, y); - if (model.getCurrentLocation().equals(loc)) { - launchEvent(); - } - else { - List path = model.getPath(loc); - if (path != null) { - activeMoveAnimation = new MoveAnimation(path); - activeMoveAnimation.start(); - } + //start move animation if a path can be found to tapped location + ConquestLocation loc = getLocation(x, y); + if (model.getCurrentLocation().equals(loc)) { + launchEvent(); + } + else { + List path = model.getPath(loc); + if (path != null) { + activeMoveAnimation = new MoveAnimation(path); + activeMoveAnimation.start(); } } return true; } + private void animateBadgeIntoPosition(ConquestLocation loc) { + activeBadgeAnimation = new BadgeAnimation(loc); + activeBadgeAnimation.start(); + } + @Override public void draw(Graphics g) { float w = getWidth(); @@ -174,7 +202,15 @@ public class ConquestMultiverseScreen extends FScreen { break; } //shift slightly right to account for transparent edge of icon - g.drawImage(badge, Math.round(x0 + colWidth - eventIconOffset - eventIconSize * 0.9f), Math.round(y0 + eventIconOffset), eventIconSize, eventIconSize); + x0 = Math.round(x0 + colWidth - eventIconOffset - eventIconSize * 0.9f); + y0 = Math.round(y0 + eventIconOffset); + if (activeBadgeAnimation != null && activeBadgeAnimation.location.isAt(i, r, c)) { + //draw animated badge instead if animation is active + activeBadgeAnimation.drawBadge(g, badge, x0, y0, eventIconSize, eventIconSize); + } + else { + g.drawImage(badge, x0, y0, eventIconSize, eventIconSize); + } } else { //draw fog of war by default if area hasn't been conquered @@ -311,5 +347,39 @@ public class ConquestMultiverseScreen extends FScreen { launchEvent(); } } + + private class BadgeAnimation extends ForgeAnimation { + private static final float DURATION = 1.5f; + + private final ConquestLocation location; + private float progress; + + private BadgeAnimation(ConquestLocation location0) { + location = location0; + } + + private void drawBadge(Graphics g, FSkinImage badge, float x, float y, float w, float h) { + float gridWidth = PlaneGrid.this.getWidth(); + float startWidth = gridWidth * 0.75f; + float startHeight = startWidth * h / w; + Rectangle start = new Rectangle((gridWidth - startWidth) / 2, (PlaneGrid.this.getHeight() - startHeight) / 2, startWidth, startHeight); + Rectangle end = new Rectangle(x, y, w, h); + Rectangle pos = Utils.getTransitionPosition(start, end, progress / DURATION); + + g.drawImage(badge, pos.x, pos.y, pos.width, pos.height); + } + + @Override + protected boolean advance(float dt) { + progress += dt; + return progress < DURATION; + } + + @Override + protected void onEnd(boolean endingAll) { + activeBadgeAnimation = null; + spinChaosWheel(); //spin Chaos Wheel after badge positioned + } + } } } diff --git a/forge-gui-mobile/src/forge/util/Utils.java b/forge-gui-mobile/src/forge/util/Utils.java index 66dd9f9a951..29f332f311a 100644 --- a/forge-gui-mobile/src/forge/util/Utils.java +++ b/forge-gui-mobile/src/forge/util/Utils.java @@ -88,6 +88,19 @@ public class Utils { return result; } + public static Vector2 getArbitaryPoint(float x1, float y1, float x2, float y2, float percentage) { + Vector2 result = new Vector2(); + result.x = x1 * (1 - percentage) + x2 * percentage; + result.y = y1 * (1 - percentage) + y2 * percentage; + return result; + } + + public static Rectangle getTransitionPosition(Rectangle start, Rectangle end, float percentage) { + Vector2 topLeft = getArbitaryPoint(start.x, start.y, end.x, end.y, percentage); + Vector2 bottomRight = getArbitaryPoint(start.x + start.width, start.y + start.height, end.x + end.width, end.y + end.height, percentage); + return new Rectangle(topLeft.x, topLeft.y, bottomRight.x - topLeft.x, bottomRight.y - topLeft.y); + } + //get rectangle defining the interestion between two other rectangles public static Rectangle getIntersection(Rectangle r1, Rectangle r2) { float left = Math.max(r1.x, r2.x); diff --git a/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java b/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java index f297254c5c5..088441754e2 100644 --- a/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java +++ b/forge-gui/src/main/java/forge/planarconquest/ConquestLocation.java @@ -63,6 +63,10 @@ public class ConquestLocation implements IXmlWritable { return col; } + public boolean isAt(int regionIndex0, int row0, int col0) { + return regionIndex == regionIndex0 && row == row0 && col == col0; + } + public List getNeighbors() { if (neighbors == null) { //cache neighbors for performance neighbors = getNeighbors(plane, regionIndex, row, col);