如何扩展 JComponent 并使用它来编写自定义游戏板?
Posted
技术标签:
【中文标题】如何扩展 JComponent 并使用它来编写自定义游戏板?【英文标题】:How to extend JComponent and use it to write a customized game board? 【发布时间】:2021-10-14 09:51:35 【问题描述】:我正在尝试自学更多有关 Java 图形的知识。为此,我正在尝试构建一个国际象棋游戏。我在制作董事会时遇到了第一个障碍。我的想法是,我将有一个名为“Square”的 JComponent 扩展,它将作为我的容器,用于存放棋盘方格的颜色和该方格上的棋子(如果有的话)。首先,我还没有尝试包含这件作品的任何表示,只是方形颜色。稍后我希望有一个抽象的“Pieces”类,它由代表所有不同类型的棋子的多个子类扩展,并根据需要将这些子类添加到每个 Square。
当我执行以下操作时,我只在左上角得到一个黑色方块。
ChessBoardTest.java
public class ChessBoardTest
public static void main(String[] args)
ChessBoard Board = new ChessBoard();
Board.Display();
ChessBoard.java
public class ChessBoard extends JFrame
public static final int FRAME_WIDTH = 500;
public static final int FRAME_HEIGHT = 500;
// Declare instance variables
private Square[][] square = new Square[rows][cols];
private final static int rows = 8;
private final static int cols = 8;
public ChessBoard()
public void Display()
JPanel Board_Layout = new JPanel();
Board_Layout.setLayout(new GridLayout(8,8));
for(int i=0;i<8;i++)
for(int j=0;j<8;j++)
if((i+j) % 2 == 0)
square[i][j] = new Square(1);
Board_Layout.add(square[i][j]);
else
square[i][j] = new Square(0);
Board_Layout.add(square[i][j]);
setTitle("Chess Mod");
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(Board_Layout);
setVisible(true);
public void messageBox(String pMessage)
JOptionPane.showMessageDialog(this, pMessage, "Message", JOptionPane.PLAIN_MESSAGE);
Square.java
public class Square extends JComponent
private int color;
public Square(int c)
this.color=c;
public void paintComponent(Graphics g)
super.paintComponent(g);
if (this.color == 1)
g.setColor(new Color(0,0,0));
else
g.setColor(new Color(255,255,255));
g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
【问题讨论】:
通常,您创建一个棋盘的逻辑模型,然后在单个绘图 JPanel 上绘制该逻辑模型。 Oracle 教程Performing Custom Painting 将向您展示如何操作。 1) “教自己更多关于 Java 图形的知识。为此,我正在尝试构建一个国际象棋游戏” 请注意,simple chessboard 可以完全使用标准组件。除非这是为了增加其他功能(例如,为棋子的移动设置动画),否则“自定义彩绘游戏”会有更好的选择。 2) 如果需要自定义绘画,通常使用JPanel
比使用JComponent
更好。 3) 这里没有很好的例子来扩展JFrame
。只需使用标准的“开箱即用”框架。 ..
.. 4) 请参阅Detection/fix for the hanging close bracket of a code block 了解我无法再费心修复的问题。请edit问题在代码末尾关闭
之前添加4个空格字符。
【参考方案1】:
我只在左上角得到一个黑色方块。
这主要是因为下面的调用:
g.fillRect(this.getX(), this.getY(), this.getWidth(), this.getHeight());
getX()
返回被调用的Component
相对于包含Component
的Container
的水平像素偏移/位置。 getY()
相应地返回被调用的Component
相对于包含Component
的Container
的垂直像素偏移/位置。
getWidth()
和 getHeight()
返回 Component
的大小。
因此想象Component
在索引为 2 的行和索引为 3 的列处,其坐标约为x == 3 * w / 8
和y == 2 * h / 8
,其中w
和h
是大小(分别为宽度和高度) 的父 Container
(即 Board_Layout
面板)。假设Board_Layout
在显示图形用户界面时的大小为 300x300... 这意味着我提到的位置处的Square
只会绘制从x == 112
和y == 75
开始并展开的区域在Board_Layout
的宽度(和高度)的八分之一处(因为网格中有 8 行和 8 列)。但是Square
本身的大小也是Board_Layout
宽度(和高度)的八分之一,即大约37x37。因此,从位置 112,75 开始并扩展的绘制区域根本不会显示(因为它完全位于 Square
的大小之外)。
只有左上角的Square
会有一些油漆,因为它在父级中的边界恰好与绘制的区域相交。
要解决这个问题,Graphics
对象的位置应该相对于每个 Square
而不是其父 Board_Layout
。例如:
g.fillRect(0, 0, getWidth(), getHeight());
【讨论】:
以上是关于如何扩展 JComponent 并使用它来编写自定义游戏板?的主要内容,如果未能解决你的问题,请参考以下文章
如何在VS代码的SonarQube扩展中自定义和关闭声纳规则
如何为 JFrame 上的 JComponent 添加滚动功能?
打字稿混淆:如何使用自定义和绝对类型库扩展 Express `Request`?