[Mobile] Refactor Targeting Arrows

- Added option to use new arrow overlay
This commit is contained in:
Anthony Calosa
2021-10-07 16:22:56 +08:00
parent cb5f0f360b
commit ad939ea3bd
15 changed files with 77 additions and 29 deletions

View File

@@ -328,6 +328,51 @@ public class Graphics {
batch.begin();
}
public void drawLineArrow(float arrowThickness, FSkinColor skinColor, float x1, float y1, float x2, float y2) {
fillCircle(skinColor.getColor(), x2, y2, arrowThickness);
drawLineArrow(arrowThickness, skinColor.getColor(), x1, y1, x2, y2);
fillCircle(Color.WHITE, x2, y2, arrowThickness/2);
drawLine(arrowThickness/3, Color.WHITE, x1, y1, x2, y2);
}
public void drawLineArrow(float thickness, Color color, float x1, float y1, float x2, float y2) {
batch.end(); //must pause batch while rendering shapes
float angle = new Vector2(x1 - x2, y1 - y2).angleRad();
float arrowHeadRotation = (float)(Math.PI * 0.8f);
Vector2 arrowCorner3 = new Vector2(x2 + (thickness/3) * (float)Math.cos(angle + arrowHeadRotation), y2 + (thickness/3) * (float)Math.sin(angle + arrowHeadRotation));
Vector2 arrowCorner4 = new Vector2(x2 + (thickness/3) * (float)Math.cos(angle - arrowHeadRotation), y2 + (thickness/3) * (float)Math.sin(angle - arrowHeadRotation));
if (thickness > 1) {
Gdx.gl.glLineWidth(thickness);
}
if (alphaComposite < 1) {
color = FSkinColor.alphaColor(color, color.a * alphaComposite);
}
boolean needSmoothing = (x1 != x2 && y1 != y2);
if (color.a < 1 || needSmoothing) { //enable blending so alpha colored shapes work properly
Gdx.gl.glEnable(GL_BLEND);
}
if (needSmoothing) {
Gdx.gl.glEnable(GL_LINE_SMOOTH);
}
startShape(ShapeType.Line);
shapeRenderer.setColor(color);
shapeRenderer.line(adjustX(x1), adjustY(y1, 0), adjustX(x2), adjustY(y2, 0));
endShape();
if (needSmoothing) {
Gdx.gl.glDisable(GL_LINE_SMOOTH);
}
if (color.a < 1 || needSmoothing) {
Gdx.gl.glDisable(GL_BLEND);
}
if (thickness > 1) {
Gdx.gl.glLineWidth(1);
}
batch.begin();
}
public void drawArrow(float borderThickness, float arrowThickness, float arrowSize, FSkinColor skinColor, float x1, float y1, float x2, float y2) {
drawArrow(borderThickness, arrowThickness, arrowSize, skinColor.getColor(), x1, y1, x2, y2);
}

View File

@@ -389,36 +389,33 @@ public class MatchScreen extends FScreen {
final CombatView combat = game.getCombat();
if (combat != null) {
for (final CardView attacker : combat.getAttackers()) {
final Vector2 vAttacker = CardAreaPanel.get(attacker).getTargetingArrowOrigin();
//connect each attacker with planeswalker it's attacking if applicable
final GameEntityView defender = combat.getDefender(attacker);
if (defender instanceof CardView) {
final Vector2 vDefender = new Vector2(((CardView) defender).getTargetingOriginVectorX(), ((CardView) defender).getTargetingOriginVectorY());
final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY());
final Vector2 vDefender = CardAreaPanel.get(((CardView) defender)).getTargetingArrowOrigin();
TargetingOverlay.drawArrow(g, vAttacker, vDefender, TargetingOverlay.ArcConnection.FoesAttacking);
}
final Iterable<CardView> blockers = combat.getBlockers(attacker);
if (blockers != null) {
//connect each blocker with the attacker it's blocking
for (final CardView blocker : blockers) {
final Vector2 vBlocker = new Vector2(blocker.getTargetingOriginVectorX(), blocker.getTargetingOriginVectorY());
final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY());
final Vector2 vBlocker = CardAreaPanel.get(blocker).getTargetingArrowOrigin();
TargetingOverlay.drawArrow(g, vBlocker, vAttacker, TargetingOverlay.ArcConnection.FoesBlocking);
}
}
final Iterable<CardView> plannedBlockers = combat.getPlannedBlockers(attacker);
if (plannedBlockers != null) {
//connect each planned blocker with the attacker it's blocking
for (final CardView blocker : plannedBlockers) {
final Vector2 vBlocker = new Vector2(blocker.getTargetingOriginVectorX(), blocker.getTargetingOriginVectorY());
final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY());
TargetingOverlay.drawArrow(g, vBlocker, vAttacker, TargetingOverlay.ArcConnection.FoesBlocking);
for (final CardView plannedBlocker : plannedBlockers) {
final Vector2 vPlannedBlocker = CardAreaPanel.get(plannedBlocker).getTargetingArrowOrigin();
TargetingOverlay.drawArrow(g, vPlannedBlocker, vAttacker, TargetingOverlay.ArcConnection.FoesBlocking);
}
}
//player
if (is4Player() || is3Player()) {
for (final PlayerView p : game.getPlayers()) {
if (combat.getAttackersOf(p).contains(attacker)) {
final Vector2 vAttacker = new Vector2(attacker.getTargetingOriginVectorX(), attacker.getTargetingOriginVectorY());
final Vector2 vPlayer = MatchController.getView().getPlayerPanel(p).getAvatar().getTargetingArrowOrigin();
TargetingOverlay.drawArrow(g, vAttacker, vPlayer, TargetingOverlay.ArcConnection.FoesAttacking);
}
@@ -430,9 +427,9 @@ public class MatchScreen extends FScreen {
for (VPlayerPanel playerPanel : playerPanels.values()) {
for (CardView card : playerPanel.getField().getRow1().getOrderedCards()) {
if (card != null) {
final Vector2 vCard = CardAreaPanel.get(card).getTargetingArrowOrigin();
if (card.getPairedWith() != null) {
final Vector2 vCard = new Vector2(card.getTargetingOriginVectorX(), card.getTargetingOriginVectorY());
final Vector2 vPairedWith = new Vector2(card.getPairedWith().getTargetingOriginVectorX(), card.getPairedWith().getTargetingOriginVectorY());
final Vector2 vPairedWith = CardAreaPanel.get(card.getPairedWith()).getTargetingArrowOrigin();
TargetingOverlay.drawArrow(g, vCard, vPairedWith, TargetingOverlay.ArcConnection.Friends);
}
}

View File

@@ -23,6 +23,8 @@ import com.badlogic.gdx.math.Vector2;
import forge.Graphics;
import forge.assets.FSkinColor;
import forge.assets.FSkinColor.Colors;
import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel;
import forge.util.Utils;
public class TargetingOverlay {
@@ -77,6 +79,9 @@ public class TargetingOverlay {
color = foeDefColor;
}
g.drawArrow(BORDER_THICKNESS, ARROW_THICKNESS, ARROW_SIZE, color, start.x, start.y, end.x, end.y);
if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_USE_LASER_ARROWS))
g.drawLineArrow(Utils.scale(3), color, start.x, start.y, end.x, end.y);
else
g.drawArrow(BORDER_THICKNESS, ARROW_THICKNESS, ARROW_SIZE, color, start.x, start.y, end.x, end.y);
}
}

View File

@@ -229,7 +229,7 @@ public class VStack extends FDropDown {
while (instance != null) {
for (CardView c : instance.getTargetCards()) {
TargetingOverlay.ArcConnection conn = activator.isOpponentOf(c.getController()) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting;
TargetingOverlay.drawArrow(g, arrowOrigin, new Vector2(c.getTargetingOriginVectorX(), c.getTargetingOriginVectorY()), conn);
TargetingOverlay.drawArrow(g, arrowOrigin, VCardDisplayArea.CardAreaPanel.get(c).getTargetingArrowOrigin(), conn);
}
for (PlayerView p : instance.getTargetPlayers()) {
TargetingOverlay.ArcConnection conn = activator.isOpponentOf(p) ? TargetingOverlay.ArcConnection.FoesStackTargeting : TargetingOverlay.ArcConnection.FriendsStackTargeting;

View File

@@ -598,6 +598,10 @@ public class SettingsPage extends TabPage<SettingsScreen> {
localizer.getMessage("lblShowAbilityIconsOverlays"),
localizer.getMessage("nlShowAbilityIconsOverlays")),
5);
lstSettings.addItem(new BooleanSetting(FPref.UI_USE_LASER_ARROWS,
localizer.getMessage("lblUseLaserArrows"),
localizer.getMessage("nlUseLaserArrows")),
5);
//Vibration Options
lstSettings.addItem(new BooleanSetting(FPref.UI_VIBRATE_ON_LIFE_LOSS,
localizer.getMessage("lblVibrateWhenLosingLife"),

View File

@@ -101,16 +101,12 @@ public class FCardPanel extends FDisplayObject {
float x = padding-mod/2;
float y = padding-mod/2;
float w = (getWidth() - 2 * padding)+mod;
float xoffset = w / 2f;
float h = (getHeight() - 2 * padding)+mod;
float yoffset = h / 2f;
if (w == h) { //adjust width if needed to make room for tapping
w = h / ASPECT_RATIO;
}
float edgeOffset = w / 2f;
card.setTargetingOriginVector(tapped? this.screenPos.x + yoffset : this.screenPos.x + edgeOffset, tapped ? this.screenPos.y + h - yoffset/1.5f : this.screenPos.y + h - xoffset);
if (!ZoneType.Battlefield.equals(card.getZone())) {
rotateTransform(g, x, y, w, h, edgeOffset, false);
return;