简体   繁体   中英

How would I make checker pieces for a checkerboard in java?

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);
     }       
}

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");

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM