Animate newly earned badges into position

This commit is contained in:
drdev
2016-01-10 19:18:49 +00:00
parent 11167610be
commit 5509980e36
3 changed files with 102 additions and 15 deletions

View File

@@ -3,6 +3,7 @@ package forge.screens.planarconquest;
import java.util.List; import java.util.List;
import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector2;
import forge.Forge; import forge.Forge;
@@ -23,8 +24,11 @@ import forge.planarconquest.ConquestPlane;
import forge.planarconquest.ConquestPlane.Region; import forge.planarconquest.ConquestPlane.Region;
import forge.planarconquest.ConquestPlaneData; import forge.planarconquest.ConquestPlaneData;
import forge.screens.FScreen; import forge.screens.FScreen;
import forge.toolbox.FDisplayObject;
import forge.toolbox.FOptionPane;
import forge.toolbox.FScrollPane; import forge.toolbox.FScrollPane;
import forge.util.Callback; import forge.util.Callback;
import forge.util.Utils;
import forge.util.collect.FCollectionView; import forge.util.collect.FCollectionView;
public class ConquestMultiverseScreen extends FScreen { public class ConquestMultiverseScreen extends FScreen {
@@ -63,35 +67,59 @@ public class ConquestMultiverseScreen extends FScreen {
@Override @Override
public void run(ConquestEvent event) { public void run(ConquestEvent event) {
if (event.wasConquered()) { if (event.wasConquered()) {
//spin Chaos Wheel if event was conquered ConquestLocation loc = event.getLocation();
ConquestChaosWheel.spin(); 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 class PlaneGrid extends FScrollPane {
private MoveAnimation activeMoveAnimation; private MoveAnimation activeMoveAnimation;
private BadgeAnimation activeBadgeAnimation;
@Override
public void buildTouchListeners(float screenX, float screenY, List<FDisplayObject> listeners) {
//prevent user touch actions while an animation is in progress
if (activeMoveAnimation == null && activeBadgeAnimation == null) {
super.buildTouchListeners(screenX, screenY, listeners);
}
}
@Override @Override
public boolean tap(float x, float y, int count) { public boolean tap(float x, float y, int count) {
if (activeMoveAnimation == null) { //start move animation if a path can be found to tapped location
//start move animation if a path can be found to tapped location ConquestLocation loc = getLocation(x, y);
ConquestLocation loc = getLocation(x, y); if (model.getCurrentLocation().equals(loc)) {
if (model.getCurrentLocation().equals(loc)) { launchEvent();
launchEvent(); }
} else {
else { List<ConquestLocation> path = model.getPath(loc);
List<ConquestLocation> path = model.getPath(loc); if (path != null) {
if (path != null) { activeMoveAnimation = new MoveAnimation(path);
activeMoveAnimation = new MoveAnimation(path); activeMoveAnimation.start();
activeMoveAnimation.start();
}
} }
} }
return true; return true;
} }
private void animateBadgeIntoPosition(ConquestLocation loc) {
activeBadgeAnimation = new BadgeAnimation(loc);
activeBadgeAnimation.start();
}
@Override @Override
public void draw(Graphics g) { public void draw(Graphics g) {
float w = getWidth(); float w = getWidth();
@@ -174,7 +202,15 @@ public class ConquestMultiverseScreen extends FScreen {
break; break;
} }
//shift slightly right to account for transparent edge of icon //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 { else {
//draw fog of war by default if area hasn't been conquered //draw fog of war by default if area hasn't been conquered
@@ -311,5 +347,39 @@ public class ConquestMultiverseScreen extends FScreen {
launchEvent(); 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
}
}
} }
} }

View File

@@ -88,6 +88,19 @@ public class Utils {
return result; 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 //get rectangle defining the interestion between two other rectangles
public static Rectangle getIntersection(Rectangle r1, Rectangle r2) { public static Rectangle getIntersection(Rectangle r1, Rectangle r2) {
float left = Math.max(r1.x, r2.x); float left = Math.max(r1.x, r2.x);

View File

@@ -63,6 +63,10 @@ public class ConquestLocation implements IXmlWritable {
return col; return col;
} }
public boolean isAt(int regionIndex0, int row0, int col0) {
return regionIndex == regionIndex0 && row == row0 && col == col0;
}
public List<ConquestLocation> getNeighbors() { public List<ConquestLocation> getNeighbors() {
if (neighbors == null) { //cache neighbors for performance if (neighbors == null) { //cache neighbors for performance
neighbors = getNeighbors(plane, regionIndex, row, col); neighbors = getNeighbors(plane, regionIndex, row, col);