[GUI] Displaying spell target with arrow. (at the moment only first target is displayed).

This commit is contained in:
magenoxx 2010-10-22 07:10:05 +00:00
parent c82d3c6dd9
commit 2fc9fc1301
8 changed files with 337 additions and 7 deletions

View file

@ -34,6 +34,17 @@
package mage.client.cards;
import static mage.client.util.Constants.CONTENT_MAX_XOFFSET;
import static mage.client.util.Constants.FRAME_MAX_HEIGHT;
import static mage.client.util.Constants.FRAME_MAX_WIDTH;
import static mage.client.util.Constants.NAME_FONT_MAX_SIZE;
import static mage.client.util.Constants.NAME_MAX_YOFFSET;
import static mage.client.util.Constants.POWBOX_TEXT_MAX_LEFT;
import static mage.client.util.Constants.POWBOX_TEXT_MAX_TOP;
import static mage.client.util.Constants.SYMBOL_MAX_XOFFSET;
import static mage.client.util.Constants.SYMBOL_MAX_YOFFSET;
import static mage.client.util.Constants.TYPE_MAX_YOFFSET;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
@ -52,6 +63,7 @@ import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.UUID;
import javax.swing.JScrollPane;
import javax.swing.Popup;
import javax.swing.PopupFactory;
@ -60,17 +72,18 @@ import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import mage.Constants.CardType;
import mage.client.MageFrame;
import mage.client.game.PlayAreaPanel;
import mage.client.remote.Session;
import mage.client.util.ArrowBuilder;
import mage.client.util.Config;
import mage.client.util.ImageHelper;
import mage.sets.Sets;
import mage.view.AbilityView;
import mage.view.CardView;
import mage.view.StackAbilityView;
import static mage.client.util.Constants.*;
/**
*
@ -205,7 +218,7 @@ public class Card extends javax.swing.JPanel implements MouseMotionListener, Mou
for (String rule: getRules()) {
sb.append("\n").append(rule);
}
if (card.getExpansionSetCode().length() > 0) {
if (card.getExpansionSetCode() != null && card.getExpansionSetCode().length() > 0) {
sb.append("\n").append(Sets.getInstance().get(card.getExpansionSetCode()).getName()).append(" - ").append(card.getRarity().toString());
}
}
@ -350,6 +363,28 @@ public class Card extends javax.swing.JPanel implements MouseMotionListener, Mou
popup = factory.getPopup(this, popupText, (int) this.getLocationOnScreen().getX() + Config.dimensions.frameWidth, (int) this.getLocationOnScreen().getY() + 40);
popup.show();
popupShowing = true;
// Draw Arrows for targets
UUID uuid = card.getFirstTarget();
if (uuid != null) {
System.out.println("Getting play area panel for uuid: " + uuid);
PlayAreaPanel p = session.getGame().getPlayers().get(uuid);
if (p != null) {
Point target = p.getLocationOnScreen();
Point me = this.getLocationOnScreen();
ArrowBuilder.addArrow((int)me.getX() + 35, (int)me.getY(), (int)target.getX() + 40, (int)target.getY() - 40, Color.red);
} else {
for (PlayAreaPanel pa : session.getGame().getPlayers().values()) {
Permanent permanent = pa.getBattlefieldPanel().getPermanents().get(uuid);
if (permanent != null) {
Point target = permanent.getLocationOnScreen();
Point me = this.getLocationOnScreen();
ArrowBuilder.addArrow((int)me.getX() + 35, (int)me.getY(), (int)target.getX() + 40, (int)target.getY() + 10, Color.red);
}
}
}
}
}
}
@ -359,6 +394,7 @@ public class Card extends javax.swing.JPanel implements MouseMotionListener, Mou
if (popup != null) {
popup.hide();
popupShowing = false;
ArrowBuilder.removeAllArrows();
}
}

View file

@ -153,6 +153,10 @@ public class BattlefieldPanel extends javax.swing.JLayeredPane implements Compon
public boolean isOptimizedDrawingEnabled () {
return false;
}
public Map<UUID, Permanent> getPermanents() {
return permanents;
}
/** This method is called from within the constructor to
* initialize the form.

View file

@ -34,20 +34,27 @@
package mage.client.game;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import mage.client.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.logging.Logger;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import mage.client.MageFrame;
import mage.client.dialog.ExileZoneDialog;
import mage.client.dialog.PickChoiceDialog;
import mage.client.dialog.ShowCardsDialog;
import mage.client.game.FeedbackPanel.FeedbackMode;
import mage.client.remote.Session;
import mage.client.util.ArrowBuilder;
import mage.client.util.Config;
import mage.util.Logging;
import mage.view.AbilityPickerView;
@ -65,6 +72,7 @@ public class GamePanel extends javax.swing.JPanel {
private final static Logger logger = Logging.getLogger(GamePanel.class.getName());
private Map<UUID, PlayAreaPanel> players = new HashMap<UUID, PlayAreaPanel>();
//private Map<UUID, PlayAreaPanel> players = new HashMap<UUID, PlayAreaPanel>();
private Map<UUID, ExileZoneDialog> exiles = new HashMap<UUID, ExileZoneDialog>();
private UUID gameId;
private UUID playerId;
@ -73,6 +81,29 @@ public class GamePanel extends javax.swing.JPanel {
/** Creates new form GamePanel */
public GamePanel() {
initComponents();
// Override layout (I can't edit generated code)
this.setLayout(new BorderLayout());
final JLayeredPane j = new JLayeredPane();
j.add(ArrowBuilder.getArrowsPanel(), JLayeredPane.MODAL_LAYER);
j.setSize(1024,768);
//j.setBorder(BorderFactory.createLineBorder(Color.green));
j.add(jSplitPane1, JLayeredPane.DEFAULT_LAYER);
this.add(j);
// Enlarge jlayeredpane on resize
addComponentListener(new ComponentAdapter(){
@Override
public void componentResized(ComponentEvent e) {
int width = ((JComponent)e.getSource()).getWidth();
int height = ((JComponent)e.getSource()).getHeight();
j.setSize(width, height);
JPanel arrowsPanel = ArrowBuilder.getArrowsPanelRef();
if (arrowsPanel != null) arrowsPanel.setSize(width, height);
jSplitPane1.setSize(width, height);
}
});
}
public void cleanUp() {
@ -229,7 +260,9 @@ public class GamePanel extends javax.swing.JPanel {
for (PlayerView player: game.getPlayers()) {
players.get(player.getPlayerId()).update(player);
}
this.stack.loadCards(game.getStack(), bigCard, gameId);
for (ExileView exile: game.getExile()) {
if (!exiles.containsKey(exile.getId())) {
ExileZoneDialog newExile = new ExileZoneDialog();
@ -325,6 +358,14 @@ public class GamePanel extends javax.swing.JPanel {
pickChoice.showDialog(message, choices);
session.sendPlayerString(gameId, pickChoice.getChoice());
}
public Map<UUID, PlayAreaPanel> getPlayers() {
return players;
}
public javax.swing.JPanel getBattlefield() {
return pnlBattlefield;
}
/** This method is called from within the constructor to
* initialize the form.
@ -620,7 +661,7 @@ public class GamePanel extends javax.swing.JPanel {
private javax.swing.JLabel lblStep;
private javax.swing.JLabel lblTurn;
private javax.swing.JPanel pnlBattlefield;
private javax.swing.JPanel pnlGameInfo;
private javax.swing.JPanel pnlGameInfo;
private javax.swing.JPanel pnlReplay;
private mage.client.cards.Cards stack;
private javax.swing.JLabel txtActivePlayer;

View file

@ -83,6 +83,9 @@ public class PlayAreaPanel extends javax.swing.JPanel {
this.battlefieldPanel.update(player.getBattlefield());
}
public mage.client.game.BattlefieldPanel getBattlefieldPanel() {
return battlefieldPanel;
}
/** This method is called from within the constructor to
* initialize the form.
@ -160,7 +163,7 @@ public class PlayAreaPanel extends javax.swing.JPanel {
// Variables declaration - do not modify//GEN-BEGIN:variables
private mage.client.game.BattlefieldPanel battlefieldPanel;
private javax.swing.JButton btnCheat;
private javax.swing.JButton btnCheat;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private mage.client.game.ManaPool manaPool;

View file

@ -0,0 +1,141 @@
package mage.client.util;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Arrow extends JPanel {
private static final long serialVersionUID = -4631054277822828303L;
private int startX;
private int startY;
private int endX;
private int endY;
private int bodyWidth = 10;
private float headSize = 17;
private Composite composite;
private Color color = Color.red;
public Arrow () {
setOpaque(false);
setOpacity(0.6f);
}
protected void paintComponent (Graphics g) {
super.paintComponent(g);
float ex = endX - startX;
float ey = endY - startY;
if (ex == 0 && ey == 0) return;
float length = (float)Math.sqrt(ex * ex + ey * ey);
float bendPercent = (float)Math.asin(ey / length);
if (endX > startX) bendPercent = -bendPercent;
Area arrow = getArrow(length, bendPercent);
Graphics2D g2d = (Graphics2D)g;
g2d.translate(startX, startY);
g2d.rotate(Math.atan2(ey, ex));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(composite);
g2d.setColor(this.color);
g2d.fill(arrow);
g2d.setColor(Color.BLACK);
g2d.draw(arrow);
}
private Area getArrow (float length, float bendPercent) {
float p1x = 0, p1y = 0;
float p2x = length, p2y = 0;
float cx = length / 2, cy = length / 8f * bendPercent;
float adjSize, ex, ey, abs_e;
adjSize = (float)(bodyWidth / 2 / Math.sqrt(2));
ex = p2x - cx;
ey = p2y - cy;
abs_e = (float)Math.sqrt(ex * ex + ey * ey);
ex /= abs_e;
ey /= abs_e;
GeneralPath bodyPath = new GeneralPath();
bodyPath.moveTo(p2x + (ey - ex) * adjSize, p2y - (ex + ey) * adjSize);
bodyPath.quadTo(cx, cy, p1x, p1y - bodyWidth / 2);
bodyPath.lineTo(p1x, p1y + bodyWidth / 2);
bodyPath.quadTo(cx, cy, p2x - (ey + ex) * adjSize, p2y + (ex - ey) * adjSize);
bodyPath.closePath();
adjSize = (float)(headSize / Math.sqrt(2));
ex = p2x - cx;
ey = p2y - cy;
abs_e = (float)Math.sqrt(ex * ex + ey * ey);
ex /= abs_e;
ey /= abs_e;
GeneralPath headPath = new GeneralPath();
headPath.moveTo(p2x - (ey + ex) * adjSize, p2y + (ex - ey) * adjSize);
headPath.lineTo(p2x, p2y);
headPath.lineTo(p2x + (ey - ex) * adjSize, p2y - (ex + ey) * adjSize);
headPath.closePath();
Area area = new Area(headPath);
area.add(new Area(bodyPath));
return area;
}
public int getBodyWidth () {
return bodyWidth;
}
public void setBodyWidth (int bodyWidth) {
this.bodyWidth = bodyWidth;
}
public float getHeadSize () {
return headSize;
}
public void setHeadSize (float headSize) {
this.headSize = headSize;
}
public void setArrowLocation (int startX, int startY, int endX, int endY) {
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
repaint();
}
public void setOpacity (float opacity) {
composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity);
}
public void setColor(Color color) {
this.color = color;
}
public static void main (String[] args) {
final JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
final Arrow arrow = new Arrow();
frame.add(arrow, BorderLayout.CENTER);
frame.setSize(640, 480);
frame.setResizable(false);
frame.setVisible(true);
frame.getContentPane().addMouseMotionListener(new MouseMotionListener() {
public void mouseMoved (MouseEvent e) {
arrow.setArrowLocation(320, 240, e.getX(), e.getY());
}
public void mouseDragged (MouseEvent e) {
}
});
}
}

View file

@ -0,0 +1,83 @@
package mage.client.util;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BorderFactory;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
/**
* Class for dealing with arrows in the game.
*
* @author nantuko
*/
public class ArrowBuilder {
public static JPanel arrowsPanel;
/**
* Get the panel where all arrows are being drawn.
* @return
*/
public static JPanel getArrowsPanel() {
if (arrowsPanel == null) {
synchronized (ArrowBuilder.class) {
if (arrowsPanel == null) {
arrowsPanel = new JPanel();
arrowsPanel.setVisible(true);
arrowsPanel.setOpaque(false);
//arrowsPanel.setLayout(new BorderLayout());
arrowsPanel.setLayout(null);
//arrowsPanel.setBorder(BorderFactory.createLineBorder(Color.red));
}
}
}
return arrowsPanel;
}
/**
* Not synchronized method for arrows panel.
* Doesn't create JPanel in case the panel doesn't exist.
* Works faster.
*
* @return
*/
public static JPanel getArrowsPanelRef() {
return arrowsPanel;
}
/**
* Adds new arrow.
*
* @param startX
* @param startY
* @param endX
* @param endY
* @param color
*/
public static void addArrow(int startX, int startY, int endX, int endY, Color color) {
JPanel p = getArrowsPanel();
Arrow arrow = new Arrow();
arrow.setColor(color);
arrow.setArrowLocation(startX, startY, endX, endY);
arrow.setBounds(0, 0, Math.max(startX, endX) + 30, Math.max(startY, endY) + 30); // 30 is offset for arrow heads (being cut otherwise)
System.out.println(" Adding arrow (startX=" + startX + ", startY=" + startY +", endX=" + endX + ", endY=" + endY + ")");
p.add(arrow);
p.revalidate();
p.repaint();
}
/**
* Removes all arrows from the screen.
*/
public static void removeAllArrows() {
JPanel p = getArrowsPanel();
if (p.getComponentCount() > 0) {
p.removeAll();
p.revalidate();
p.repaint();
}
}
}

View file

@ -32,13 +32,17 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.ObjectColor;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
import mage.game.permanent.token.Token;
import mage.game.stack.Spell;
import mage.target.Target;
/**
*
@ -61,6 +65,8 @@ public class CardView implements Serializable {
protected Rarity rarity;
protected String expansionSetCode;
public UUID firstTarget; //TODO: there may be several targets
public CardView(Card card) {
this.id = card.getId();
this.name = card.getName();
@ -89,6 +95,17 @@ public class CardView implements Serializable {
this.rarity = card.getRarity();
this.expansionSetCode = card.getExpansionSetCode();
}
if (card instanceof Spell) {
Spell<?> spell = (Spell<?>)card;
if (spell.getSpellAbility().getTargets().size() > 0) {
Target target = spell.getSpellAbility().getTargets().get(0);
if (target.isChosen()) {
firstTarget = target.getFirstTarget();
System.out.println("First target: " + firstTarget);
}
}
}
}
protected CardView() {
@ -181,4 +198,8 @@ public class CardView implements Serializable {
public UUID getId() {
return id;
}
public UUID getFirstTarget() {
return firstTarget;
}
}

View file

@ -45,6 +45,7 @@ public abstract class BasicLand<T extends BasicLand<T>> extends CardImpl<T> {
this.supertype.add("Basic");
this.subtype.add(name);
this.addAbility(mana);
setExpansionSetCode("M11");
}
public BasicLand(BasicLand land) {