mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Animate newly earned badges into position
This commit is contained in:
@@ -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,19 +67,39 @@ 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)) {
|
||||||
@@ -88,10 +112,14 @@ public class ConquestMultiverseScreen extends FScreen {
|
|||||||
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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user