英文:
How would I make checker pieces for a checkerboard in java?
问题
我正在尝试制作一个跳棋游戏。我已经使用JButtons创建了棋盘。我使用JButtons,因为我认为这是最简单的方法。但我不太确定如何实现创建棋子本身。我考虑过使用JButtons制作棋子并将其放在方格上方,但我不确定是否可行。我还考虑过使用JLabels,但我认为我不能使JLabels可点击。以下是我目前的代码。感谢您的帮助。
```java
import java.awt.*;
import javax.swing.*;
public class CheckerDemo {
public static void main(String[] args) {
// 创建包含两个按钮(Play和Exit)的简单菜单
JPanel second = new JPanel();
JPanel panel = new JPanel();
JFrame frame = new JFrame();
JLabel hello = new JLabel(" 欢迎,请选择。");
JButton exit = new JButton("退出");
JButton play = new JButton("开始游戏");
panel.add(exit);
panel.add(hello);
second.add(play);
frame.setResizable(false);
frame.setTitle("主菜单");
frame.setSize(200, 250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel, BorderLayout.CENTER);
frame.add(hello, BorderLayout.NORTH);
frame.add(second, BorderLayout.WEST);
exit.addActionListener(e -> {
frame.dispose();
});
play.addActionListener(e -> {
frame.dispose();
new CheckerBoard();
});
frame.setVisible(true);
}
}
class CheckerBoard extends JFrame {
JFrame frame2 = new JFrame();
JPanel panel = new JPanel();
JButton[][] buttons = new JButton[8][8];
public CheckerBoard() {
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.setSize(750, 600);
frame2.setTitle("跳棋");
frame2.setVisible(true);
panel.setSize(500, 500);
JPanel panel = new JPanel(new GridLayout(8, 8));
for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons[i].length; j++) {
buttons[i][j] = new JButton();
if ((i + j) % 2 == 0) {
buttons[i][j].setBackground(Color.WHITE);
} else {
buttons[i][j].setBackground(Color.BLACK);
}
panel.add(buttons[i][j]);
}
}
frame2.add(panel);
panel.setVisible(true);
}
}
英文:
I am trying to make a checkers game. I created the board already using JButtons. I used JButtons since I thought that would be the easiest way to do it. I'm not entirely sure on how to implement to create the pieces itself. I thought of making the pieces of out JButtons and put one top the squares, but I'm not sure if that would work. I also thought of using JLabels, but I didn't think I could make JLabels clickable. My code for what I have so far. Thanks for the help.
import java.awt.*;
import javax.swing.*;
public class CheckerDemo {
public static void main(String[] args) {
//Creates small menu with two buttons, play and exit
JPanel second = new JPanel();
JPanel panel = new JPanel();
JFrame frame = new JFrame();
//simple message asking user to choose
JLabel hello = new JLabel(" Welcome, please choose.");
//button for exit, closes out panel
JButton exit = new JButton("Exit");
//button to play, goes to the panel with board
JButton play = new JButton("Play!");
//add label and buttons to panel
panel.add(exit);
panel.add(hello);
second.add(play);
//so frame isn't resized, stays small
frame.setResizable(false);
frame.setTitle("Main");
frame.setSize(200,250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//put buttons in certain spots
frame.add(panel, BorderLayout.CENTER);
frame.add(hello, BorderLayout.NORTH);
frame.add(second, BorderLayout.WEST);
//exits the frame on exit button click
exit.addActionListener(e -> {
frame.dispose();
});
//play button goes to the checkerboard, uses checkerboard class
play.addActionListener(e -> {
frame.dispose();
new CheckerBoard();
});
//button sizes
hello.setBounds(10, 20, 80, 50);
exit.setBounds(20,20,50,80);
//set frame to see
frame.setVisible(true);
}
}
CheckerBoard class:
import java.awt.*;
import javax.swing.*;
public class CheckerBoard extends JFrame {
//used to make the board
//creates the frame and panel for the new frame after play clicked
JFrame frame2 = new JFrame();
JPanel panel = new JPanel();
//2d array used for black and white squares
JButton[][] buttons = new JButton[8][8];
//constructor
public CheckerBoard() {
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame2.setSize(750,600);
frame2.setTitle("Checkers");
frame2.setVisible(true);
panel.setSize(500, 500);
JPanel panel = new JPanel(new GridLayout(8,8));
// add squares to the board
for (int i = 1; i < buttons.length; i++) {
for (int j = 1; j < buttons[i].length; j++) {
//creates a new JButton object every time it's looped to add to the panel
buttons[i][j] = new JButton();
//if the 2d array comes across even square( ex -> [2,2]), colors it white
if (i % 2 == j % 2) {
buttons[i][j].setBackground(Color.WHITE);
panel.add(buttons[i][j]);
}
else {
buttons[i][j].setBackground(Color.BLACK);
panel.add(buttons[i][j]);
}
}
}
frame2.add(panel);
panel.setVisible(true);
}
}
答案1
得分: 0
你可以使用图像来表示棋子,并使用 jbutton.setIcon(new ImageIcon("图像路径"));
来绘制你的棋子。移动一个棋子相当于重新设置图标。
编辑:
为黑棋创建一个图标,为白棋创建另一个图标就足够了。
Icon blackIcon = new ImageIcon("黑棋图像路径");
Icon whiteIcon = new ImageIcon("白棋图像路径");
英文:
You could use images for the pieces and jbutton.setIcon(new ImageIcon("path-to-image"));
in order to draw your pieces. Moving a piece is the equivalent to reset and set an icon.
EDIT:
Creating one icon for the black pieces and one item for the white pieces is sufficient
Icon blackIcon = new ImageIcon("path-to-black-piece-image");
Icon whiteIcon = new ImageIcon("path-to-white-piece-image");
答案2
得分: 0
刚开始阶段的一个想法,既然你提到了JLabels。你想让棋盘上的方块具有动作吗?应该只有实际上是跳棋的方块才能被点击,而不是空的方块吧?
如果玩耍的方块是JLabels,背景颜色设置为适当的颜色怎么样?然后,在你想要有跳棋的地方...放一个按钮,当然要像大家建议的那样上色。但是你不想让棋盘上的方块是可点击的东西。对吧?你想要的是如果你点击跳棋,它是你执行操作的对象,而不是棋盘方块。
这只是一些早期的建议供你考虑。
编辑后补充:我喜欢你在这里所做的。我甚至将你的代码加载到我的模型项目中并运行了起来。干得好!但是...认真考虑一下,将一个跳棋的方块设计成一个按钮...而一个空的棋盘空间只是一个JLabel。然后,你点击你团队的跳棋(按钮)方块来计算活动,而空的棋盘空间只是一个空的棋盘空间(Label)。将其视为另一种设计策略。
英文:
Just a thought at this early stage of the game, and since you brought up JLabels. Do you want the playing tiles to have an action to them? Shouldn't only squares that actually ARE checker pieces be clickable, not empty board squares?
How about if the playing tiles ARE JLabels, background color set to the appropriate color. Then, where you want to have a checker ... have a button, colored like people are suggesting, of course. But you don't want your board squares to be clickable things. Right? You want the checker to be the thing you perform an action on if you click it, not the board square.
Just some early on input to consider.
Edited to add: I like what you did here. I even went the step and loaded your code into my mockups project and ran it. Nice job! But seriously ... consider having a square that is a checker be a button ... and an empty board space just be a JLabel. Then, you click on your teams checker (button) squares to calculate activity, and an empty board space is just an empty board space (Label). Consider that as another design strategy too.
答案3
得分: 0
你有一个按钮数组,想要把皇后放在其中一个按钮上。
JButton place = buttons[0, 4];
place.setIcon(queenIcon);
现在,该按钮上有了皇后。
JLabel 和 JButton 之间的区别非常小。你可以使 JLabel 可点击,或者你可以使用带有 ActionEvent 的 JButton。
以下是使用 JLabel 的示例(我发现使用 JButton 版本会更好一些,因为它可以使图标居中显示):
public class CheckerBoard{
Icon empty;
Icon queen;
public void placeQueen(MouseEvent evt){
JLabel label = (JLabel)evt.getSource();
label.setIcon(queen);
}
private void createIcons(){
BufferedImage none = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
BufferedImage queenImg = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics g = queenImg.getGraphics();
g.setColor(Color.YELLOW);
g.fillOval(0, 0, 64, 64);
g.dispose();
empty = new ImageIcon(none);
queen = new ImageIcon(queenImg);
}
public void startGui(){
createIcons();
JFrame frame = new JFrame("board");
JPanel panel = new JPanel(new GridLayout(2, 2));
for(int i = 0; i<4; i++){
JLabel label = new JLabel();
label.setBackground( (i/2 + i)%2 == 0 ? Color.BLACK : Color.WHITE );
label.setIcon(empty);
label.setOpaque(true);
label.addMouseListener( new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent evt){
placeQueen(evt);
}
});
panel.add(label);
}
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
EventQueue.invokeLater( ()-> new CheckerBoard().startGui() );
}
}
现在,每个 JLabel 都有一个背景颜色,它是不透明的,因此它会绘制该背景颜色。然后,我将图标设置为当没有棋子时的空图标,或者当有棋子时的完整图标。
当你点击棋盘时,会添加一个皇后。不过我认为你可能会看到问题。我们可以在棋盘上添加许多皇后。为了解决这个问题,我会创建一个类来保存更多数据。
class Piece{
Icon icon;
JLabel location;
public Piece(Icon i){
icon = i;
}
public void setLocation(JLabel label){
if(location != null){
location.setIcon(CheckerBoard.empty);
}
location = label;
location.setIcon(icon);
}
}
然后我们稍微修改 placeQueen
方法。并且将 empty 变量设为静态。
public void placeQueen(MouseEvent evt){
JLabel label = (JLabel)evt.getSource();
queen.setLocation(label);
}
现在,皇后只会在一个格子上。
关于将棋盘作为 JLabel,然后将棋子作为按钮添加的想法。当你想要拿起一个棋子时,会很容易。点击棋子。但是当你想要放置它时,你会怎么做呢?我认为,你仍然需要使空白的格子可点击。
英文:
You have an array of buttons, and you want to put the Queen on one of them.
JButton place = buttons[0, 4];
place.setIcon(queenIcon);
Now that button has the queen on it.
It's a pretty small difference between JLabel and JButton. You can make JLabels clickable, or you can use a JButton with an actionEvent.
Here is an example with JLabels. ( I found a JButton version to be a bit nicer because it centers the icons. )
public class CheckerBoard{
Icon empty;
Icon queen;
public void placeQueen(MouseEvent evt){
JLabel label = (JLabel)evt.getSource();
label.setIcon(queen);
}
private void createIcons(){
BufferedImage none = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
BufferedImage queenImg = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics g = queenImg.getGraphics();
g.setColor(Color.YELLOW);
g.fillOval(0, 0, 64, 64);
g.dispose();
empty = new ImageIcon(none);
queen = new ImageIcon(queenImg);
}
public void startGui(){
createIcons();
JFrame frame = new JFrame("board");
JPanel panel = new JPanel(new GridLayout(2, 2));
for(int i = 0; i<4; i++){
JLabel label = new JLabel();
label.setBackground( (i/2 + i)%2 == 0 ? Color.BLACK : Color.WHITE );
label.setIcon(empty);
label.setOpaque(true);
label.addMouseListener( new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent evt){
placeQueen(evt);
}
});
panel.add(label);
}
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
EventQueue.invokeLater( ()-> new CheckerBoard().startGui() );
}
}
Now, each JLabel has a background color, and it is opaque so it paints that back ground color. Then, I set the icon to either an empty icon when there are no pieces or a full icon when there are pieces.
When you click on the board, a queen is added. I think you can see the issue though. We can add a bunch of queens to the board. To resolve this, I would make a class to hold more data.
class Piece{
Icon icon;
JLabel location;
public Piece(Icon i){
icon = i;
}
public void setLocation(JLabel label){
if(location != null){
location.setIcon(CheckerBoard.empty);
}
location = label;
location.setIcon(icon);
}
}
Then we change the placeQueen a small bit. and make empty static
public void placeQueen(MouseEvent evt){
JLabel label = (JLabel)evt.getSource();
queen.setLocation(label);
}
Now the queen is only on one piece.
In regards to using the board as jlabels and then adding pieces as buttons. When you want to pickup a piece, it will be easy. Click the piece. When you want to place it what will you do? I think, you'll still need to have the empty spaces clickable.
专注分享java语言的经验与见解,让所有开发者获益!
评论