我和一个伙伴正在从头开始使用Java为我们的AP计算机科学课进行国际象棋游戏,我们需要在鼠标释放后获得最终方格的坐标。 .getX()
和.getY()
为我们提供了精确的坐标,但我们需要网格坐标。像5,4或3,2(在国际象棋中,这将是e4或c2)。定义类都运行正常,我们只需要这部分:
System.out.print(e.getX()+" "+e.getY());
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c instanceof JLabel){
Container parent = c.getParent();
parent.remove(0);
parent.add( chessPiece );
}
else {
Container parent = (Container)c;
parent.add( chessPiece );
}
chessPiece.setVisible(true);
}
完整的实施课程如下。提前谢谢!
package Boards;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ChessGame extends JFrame implements MouseListener, MouseMotionListener {
private static final long serialVersionUID = 1L;//Serial ID for unique chess games
JLayeredPane layeredPane;
JPanel chessBoard;
JLabel chessPiece;
int xAdjustment;
int yAdjustment;
public ChessGame(){
Board newGame = new Board();//Instantiate Board object w/ spots
newGame.boardSetUp();
Dimension boardSize = new Dimension(600, 600);//Instantiate Visual representation of Board.
// Use a Layered Pane for this this application
layeredPane = new JLayeredPane();
getContentPane().add(layeredPane);
layeredPane.setPreferredSize(boardSize);
layeredPane.addMouseListener(this);
layeredPane.addMouseMotionListener(this);
//Add a chess board to the Layered Pane
chessBoard = new JPanel();
layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
chessBoard.setLayout( new GridLayout(8, 8) );
chessBoard.setPreferredSize( boardSize );
chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);
JLabel Vpiece = new JLabel();
for (int i = 0; i < 64; i++) {
JPanel square = new JPanel( new BorderLayout() );
chessBoard.add( square );
int row = (i / 8);
if (row%2 == 0)
square.setBackground( i % 2 == 0 ? Color.darkGray : Color.white );//Adjusting for First square
else
square.setBackground( i % 2 == 0 ? Color.white : Color.darkGray );//Setting colored boxes for chess board
if(newGame.spotValues[row][i-(row*8)].piece!=null)
{
switch(newGame.spotValues[row][i-(row*8)].piece.name){
case "Bishop":
if(newGame.spotValues[row][i-(row*8)].piece.color.equals("White"))
Vpiece = new JLabel( new ImageIcon("resource/BishopW.png") );
else
Vpiece = new JLabel( new ImageIcon("resource/BishopB.png") );
break;
case "King":
if(newGame.spotValues[row][i-(row*8)].piece.color.equals("White"))
Vpiece = new JLabel( new ImageIcon("resource/KingW.png" ));
else
Vpiece = new JLabel( new ImageIcon("resource/KingB.png" ));
break;
case "Queen":
if(newGame.spotValues[row][i-(row*8)].piece.color.equals("White"))
Vpiece = new JLabel( new ImageIcon("resource/QueenW.png") );
else
Vpiece = new JLabel( new ImageIcon("resource/QueenB.png") );
break;
case "Pawn":
if(newGame.spotValues[row][i-(row*8)].piece.color.equals("White"))
Vpiece = new JLabel( new ImageIcon("resource/PawnW.png") );
else
Vpiece = new JLabel( new ImageIcon("resource/PawnB.png") );
break;
case "Rook":
if(newGame.spotValues[row][i-(row*8)].piece.color.equals("White"))
Vpiece = new JLabel( new ImageIcon("resource/RookW.png") );
else
Vpiece = new JLabel( new ImageIcon("resource/RookB.png") );
break;
case "Knight":
if(newGame.spotValues[row][i-(row*8)].piece.color.equals("White"))
Vpiece = new JLabel( new ImageIcon("resource/KnightW.png") );
else
Vpiece = new JLabel( new ImageIcon("resource/KnightB.png") );
break;
}
JPanel panel = (JPanel)chessBoard.getComponent(i);
panel.add(Vpiece);
}
}
}
public void mousePressed(MouseEvent e){
chessPiece = null;
Component c = chessBoard.findComponentAt(e.getX(), e.getY());
if (c instanceof JPanel)
return; //makes sure no errors are given when pressed on a blank square
Point parentLocation = c.getParent().getLocation(); //parentLocation is mouse pointer
xAdjustment = parentLocation.x - e.getX();
yAdjustment = parentLocation.y - e.getY();
chessPiece = (JLabel)c;
chessPiece.setLocation(e.getX() + xAdjustment, e.getY() + yAdjustment);
chessPiece.setSize(chessPiece.getWidth(), chessPiece.getHeight());
layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);
}
//Move the chess piece around
public void mouseDragged(MouseEvent me) {
if (chessPiece == null) { //checks if square is blank or not
return;
}
chessPiece.setLocation(me.getX() + xAdjustment, me.getY() + yAdjustment);
}
//Drop the chess piece back onto the chess board
public void mouseReleased(MouseEvent e) {
if(chessPiece == null) { //checks if square is blank or not
return;
}
chessPiece.setVisible(false);
/*
* what are we doing below??
*
*
*/
System.out.print(e.getX()+" "+e.getY());
Component c = chessBoard.findComponentAt(e.getX(), e.getY()); //checks to see if there's a new piece at the new location
if (c instanceof JLabel){
Container parent = c.getParent();
parent.remove(0);
parent.add( chessPiece );
}
else {
Container parent = (Container)c;
parent.add( chessPiece );
}
chessPiece.setVisible(true);
}
/*
*
* what are we doing above??
*
*/
public void mouseClicked(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
}
public void mouseEntered(MouseEvent e){
}
public void mouseExited(MouseEvent e) {
}
public static void main(String[] args) {
JFrame frame = new ChessGame();
frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE );
frame.pack();
frame.setResizable(true);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
答案 0 :(得分:1)
如评论中所述,我将使用JLabel网格,添加和删除图标,并为我的JLabel提供一个客户端属性值,该值对应于相应的行和列(国际象棋术语中的文件和排名)。我会给我的ChessBoard类两个String常量,以便在将客户端属性放入时以及稍后提取它们时使用:
public static final String RANK = "rank";
public static final String FILE = "file";
只需在JLabel上调用putClientProperty(...)
即可添加属性:
label.putClientProperty(RANK, rank);
label.putClientProperty(FILE, file);
其中rank和file是合适的字符串。
例如,请运行此演示程序以查看我的意思:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class SimpleChess extends JPanel {
private ChessBoard chessBoard = new ChessBoard();
private JTextField rankField = new JTextField(3);
private JTextField fileField = new JTextField(3);
public SimpleChess() {
MyMouse myMouse = new MyMouse();
chessBoard.addMouseListener(myMouse);
rankField.setHorizontalAlignment(SwingConstants.CENTER);
rankField.setFocusable(false);
fileField.setHorizontalAlignment(SwingConstants.CENTER);
fileField.setFocusable(false);
JPanel topPanel = new JPanel();
topPanel.add(new JLabel("Rank:"));
topPanel.add(rankField);
topPanel.add(Box.createHorizontalStrut(40));
topPanel.add(new JLabel("File:"));
topPanel.add(fileField);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(chessBoard, BorderLayout.CENTER);
}
class MyMouse extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
Component c = chessBoard.getComponentAt(e.getPoint());
if (!(c instanceof JLabel)) {
return;
}
JLabel cell = (JLabel) c;
String rank = (String) cell.getClientProperty(ChessBoard.RANK);
String file = (String) cell.getClientProperty(ChessBoard.FILE);
// icon = cell.getIcon();
rankField.setText(rank);
fileField.setText(file);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Chess");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SimpleChess());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
@SuppressWarnings("serial")
class ChessBoard extends JPanel {
public static final String RANK = "rank";
public static final String FILE = "file";
private static final int ROWS = 8;
private static final int COLS = 8;
private static final Color COLOR_LIGHT = new Color(240, 201, 175);
private static final Color COLOR_DARK = new Color(205, 133, 63);
private static final Dimension CELL_SIZE = new Dimension(60, 60);
private JLabel[][] chessTable = new JLabel[ROWS][COLS];
public ChessBoard() {
// create chess table
setLayout(new GridLayout(ROWS, COLS));
for (int i = 0; i < chessTable.length; i++) {
for (int j = 0; j < chessTable[i].length; j++) {
String rank = String.valueOf((char) ('8' - i));
String file = String.valueOf((char) ('a' + j));
JLabel label = new JLabel();
label.setPreferredSize(CELL_SIZE);
label.setOpaque(true);
Color c = i % 2 == j % 2 ? COLOR_LIGHT : COLOR_DARK;
label.setBackground(c);
label.putClientProperty(RANK, rank);
label.putClientProperty(FILE, file);
chessTable[i][j] = label;
add(label);
}
}
}
}
我正在开发一个更广泛的版本,一个可以移动图标的版本,但还没有完成它......
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class ChessLocation extends JPanel {
public static final String RANK = "rank";
public static final String FILE = "file";
public static final String MOUSE_PRESS = "mouse press";
public static final String PIECE_IMG_PATH = "https://upload.wikimedia.org"
+ "/wikipedia/commons/thumb/b/b2/Chess_Pieces_Sprite.svg"
+ "/320px-Chess_Pieces_Sprite.svg.png"; // for smaller pieces
// + "/640px-Chess_Pieces_Sprite.svg.png"; // for larger pieces
private static final int IMG_ROWS = 2;
private static final int IMG_COLS = 6;
private static final int ROWS = 8;
private static final int COLS = 8;
private static final Color COLOR_LIGHT = new Color(240, 201, 175);
private static final Color COLOR_DARK = new Color(205, 133, 63);
private Map<ChessPiece, Icon> pieceIconMap = new HashMap<>();
private JLabel[][] chessTable = new JLabel[ROWS][COLS];
public ChessLocation(BufferedImage img) {
// get chess images and put into pieceIconMap
int w = img.getWidth() / IMG_COLS;
int h = img.getHeight() / IMG_ROWS;
for (int row = 0; row < IMG_ROWS; row++) {
int y = (row * img.getHeight()) / IMG_ROWS;
for (int col = 0; col < IMG_COLS; col++) {
int x = (col * img.getWidth()) / IMG_COLS;
BufferedImage subImg = img.getSubimage(x, y, w, h);
Icon icon = new ImageIcon(subImg);
PieceColor color = PieceColor.values()[row];
PieceType type = PieceType.values()[col];
ChessPiece chessPiece = new ChessPiece(type, color);
pieceIconMap.put(chessPiece, icon);
}
}
// create chess table
setLayout(new GridLayout(ROWS, COLS));
Dimension pieceSize = new Dimension(w, h);
for (int i = 0; i < chessTable.length; i++) {
for (int j = 0; j < chessTable[i].length; j++) {
String rank = String.valueOf((char) ('8' - i));
String file = String.valueOf((char) ('a' + j));
JLabel label = new JLabel();
label.setPreferredSize(pieceSize);
label.setOpaque(true);
Color c = i % 2 == j % 2 ? COLOR_LIGHT : COLOR_DARK;
label.setBackground(c);
label.putClientProperty(RANK, rank);
label.putClientProperty(FILE, file);
chessTable[i][j] = label;
add(label);
}
}
resetBoard();
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
public void resetBoard() {
for (JLabel[] row : chessTable) {
for (JLabel cell : row) {
cell.setIcon(null);
}
}
chessTable[0][0].setIcon(pieceIconMap.get(new ChessPiece(PieceType.ROOK, PieceColor.BLACK)));
chessTable[0][7].setIcon(pieceIconMap.get(new ChessPiece(PieceType.ROOK, PieceColor.BLACK)));
chessTable[7][0].setIcon(pieceIconMap.get(new ChessPiece(PieceType.ROOK, PieceColor.WHITE)));
chessTable[7][7].setIcon(pieceIconMap.get(new ChessPiece(PieceType.ROOK, PieceColor.WHITE)));
chessTable[0][1].setIcon(pieceIconMap.get(new ChessPiece(PieceType.KNIGHT, PieceColor.BLACK)));
chessTable[0][6].setIcon(pieceIconMap.get(new ChessPiece(PieceType.KNIGHT, PieceColor.BLACK)));
chessTable[7][1].setIcon(pieceIconMap.get(new ChessPiece(PieceType.KNIGHT, PieceColor.WHITE)));
chessTable[7][6].setIcon(pieceIconMap.get(new ChessPiece(PieceType.KNIGHT, PieceColor.WHITE)));
chessTable[0][2].setIcon(pieceIconMap.get(new ChessPiece(PieceType.BISHOP, PieceColor.BLACK)));
chessTable[0][5].setIcon(pieceIconMap.get(new ChessPiece(PieceType.BISHOP, PieceColor.BLACK)));
chessTable[7][2].setIcon(pieceIconMap.get(new ChessPiece(PieceType.BISHOP, PieceColor.WHITE)));
chessTable[7][5].setIcon(pieceIconMap.get(new ChessPiece(PieceType.BISHOP, PieceColor.WHITE)));
chessTable[0][3].setIcon(pieceIconMap.get(new ChessPiece(PieceType.QUEEN, PieceColor.BLACK)));
chessTable[0][4].setIcon(pieceIconMap.get(new ChessPiece(PieceType.KING, PieceColor.BLACK)));
chessTable[7][3].setIcon(pieceIconMap.get(new ChessPiece(PieceType.QUEEN, PieceColor.WHITE)));
chessTable[7][4].setIcon(pieceIconMap.get(new ChessPiece(PieceType.KING, PieceColor.WHITE)));
// put in pawns
for (int i = 0; i < PieceColor.values().length; i++) {
PieceColor color = PieceColor.values()[i];
ChessPiece piece = new ChessPiece(PieceType.PAWN, color);
for (int j = 0; j < COLS; j++) {
int row = 6 - 5 * i;
chessTable[row][j].setIcon(pieceIconMap.get(piece));
}
}
}
private class MyMouse extends MouseAdapter {
String rank = "";
String file = "";
Icon icon = null;
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
rank = "";
file = "";
icon = null;
Component c = getComponentAt(e.getPoint());
if (!(c instanceof JLabel)) {
return;
}
JLabel cell = (JLabel) c;
if (cell.getIcon() == null) {
return;
}
rank = (String) cell.getClientProperty(RANK);
file = (String) cell.getClientProperty(FILE);
icon = cell.getIcon();
// cell.setIcon(null);
}
}
private static void createAndShowGui() {
BufferedImage img = null;
try {
URL imgUrl = new URL(PIECE_IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
ChessLocation chessLocation = new ChessLocation(img);
JFrame frame = new JFrame("Chess");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(chessLocation);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
enum PieceColor {
WHITE, BLACK
}
enum PieceType {
KING(100), QUEEN(9), BISHOP(3), KNIGHT(3), ROOK(5), PAWN(1);
private int value;
private PieceType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
class ChessPiece {
private PieceType type;
private PieceColor color;
public ChessPiece(PieceType type, PieceColor color) {
this.type = type;
this.color = color;
}
@Override
public String toString() {
return "ChessPiece [type=" + type + ", color=" + color + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((color == null) ? 0 : color.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ChessPiece other = (ChessPiece) obj;
if (color != other.color)
return false;
if (type != other.type)
return false;
return true;
}
}
答案 1 :(得分:0)
Java坐标系从左上角开始,坐标随着向下和向右的增加而增加。因此,对于任何width x height
棋盘,预期的行和列间隔将是这样的:
// X coordinates
A: 0.0 - (width / 8)
B: (width / 8) - (2 * width / 8)
C: (2 * width / 8) - (3 * width / 8)
...
// Y coordinates
8: 0.0 - (width / 8)
7: (width / 8) - (2 * width / 8)
6: (2 * width / 8) - (3 * width / 8)
...
我建议您使用Map
。在这里,我没有将以下代码段集成到您的代码中。然而,它基本上需要两个Double
输入和输出棋盘单元,适用于棋盘的任何给定宽度和高度:
import java.util.HashMap;
import java.util.Map;
public class chessCell {
static final int CELL_COUNT = 8;
// Dimensions
static final double HEIGHT = 600;
static final double WIDTH = 600;
static Map<String, String> columnAsLetter = new HashMap<String, String>(){{
put( "8", "a");
put( "7", "b");
put( "6", "c");
put( "5", "d");
put( "4", "e");
put( "3", "f");
put( "2", "g");
put( "1", "h");
}};
static Map<String, String> rows = new HashMap<String, String>(){{
for(int i = 0; i < CELL_COUNT; i++) {
put(Integer.toString(i + 1), (Double.toString(HEIGHT - (i + 1) * HEIGHT / 8 ) + "-" + Double.toString(HEIGHT - i * HEIGHT / 8)));
}
}};
static Map<String, String> columns = new HashMap<String, String>(){{
for(int i = 0; i < CELL_COUNT; i++) {
put(Integer.toString(i + 1), (Double.toString(WIDTH - (i + 1) * WIDTH / 8 ) + "-" + Double.toString(WIDTH - i * WIDTH / 8)));
}
}};
public static String coord2cellName(double x, double y) {
String column = "";
String row = "";
for(int i = rows.size(); i > 0; i--) {
if(x > Double.parseDouble(rows.get(Integer.toString(i)).split("-")[0]) &&
x <= Double.parseDouble(rows.get(Integer.toString(i)).split("-")[1])){
row = Integer.toString(i);
}
if(y > Double.parseDouble(columns.get(Integer.toString(i)).split("-")[0]) &&
y <= Double.parseDouble(columns.get(Integer.toString(i)).split("-")[1])){
column = columnAsLetter.get(Integer.toString(i));
}
}
System.out.println(column + row);
return column + row;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
coord2cellName(125.0, 155.0); // outputs c7
coord2cellName(24.0, 34.0); // outputs a8
coord2cellName(32.0, 88.0); // outputs b8
}
}
getX()
和getY()
应该返回Double
。所以我相信一旦你理解了上面的代码,你就可以轻松地将它集成到你的项目中。它并不完美。我没有处理掉外情况。但必不可少的部分有效。