Как бы я сделал шашки для шахматной доски в java? - PullRequest
1 голос
/ 03 мая 2020

Я пытаюсь сделать игру в шашки. Я создал доску уже используя JButtons. Я использовал JButtons, так как думал, что это будет самый простой способ сделать это. Я не совсем уверен в том, как реализовать сами штуки. Я думал о том, чтобы сделать кусочки из JButtons и поставить один квадрат сверху, но я не уверен, сработает ли это. Я также думал об использовании JLabels, но не думал, что смогу сделать JLabels кликабельным. Мой код для того, что у меня есть до сих пор. Спасибо за помощь.

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:

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

Ответы [ 3 ]

0 голосов
/ 03 мая 2020

Просто мысль на этой ранней стадии игры, и с тех пор, как вы воспитали JLabels. Вы хотите, чтобы игровые плитки имели для них действие? Разве не должны быть кликабельными только те квадраты, которые на самом деле являются клетками, а не пустые квадраты на доске?

Как насчет, если играющие плитки являются JLabels, цвет фона установлен на соответствующий цвет. Тогда, где вы хотите иметь шашку ... есть кнопка, окрашенная в цвет, как обычно предлагают люди. Но вы не хотите, чтобы на ваших досках были кликабельные вещи. Правильно? Если вы щелкнете по нему, вы хотите, чтобы этот пункт проверки выполнял действие, а не квадрат доски.

Просто некоторые начальные данные для рассмотрения.

Отредактировано, чтобы добавить: Мне нравится то, что ты сделал здесь Я даже сделал шаг, загрузил ваш код в мой проект макетов и запустил его. Хорошая работа! А если серьезно ... подумайте о том, чтобы иметь квадрат, который является кнопкой проверки, и кнопкой ... а пустое место на доске просто JLabel. Затем вы нажимаете на квадраты (кнопки) проверки команд, чтобы вычислить активность, и пустое место на доске - это просто пустое место на доске (Метка). Рассмотрим это как еще одну стратегию дизайна.

0 голосов
/ 04 мая 2020

У вас есть набор кнопок, и вы хотите поставить Королеву на одну из них.

JButton place = buttons[0, 4];
place.setIcon(queenIcon);

Теперь у этой кнопки есть королева.

Это довольно маленькая Разница между JLabel и JButton. Вы можете сделать JLabels активным, или вы можете использовать JButton с actionEvent.

Вот пример с JLabels. (Я обнаружил, что версия 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. и сделай пустое состояние c

public void placeQueen(MouseEvent evt){
    JLabel label = (JLabel)evt.getSource();
    queen.setLocation(label);
}

Теперь королева только на одном куске.

Что касается использования доски в качестве джабеля, а затем добавления фигур в качестве кнопок. Если вы хотите забрать кусок, это будет легко. Нажмите на кусок. Когда вы хотите разместить его, что вы будете делать? Я думаю, вам по-прежнему нужно будет нажимать на пустые места.

0 голосов
/ 03 мая 2020

Вы можете использовать изображения для фигур и jbutton.setIcon(new ImageIcon("path-to-image")); для рисования своих фигур. Перемещение фигуры эквивалентно сбросу и установке значка.

РЕДАКТИРОВАТЬ: достаточно создать один значок для черных фигур и один элемент для белых фигур

Icon blackIcon = new ImageIcon("path-to-black-piece-image");
Icon whiteIcon = new ImageIcon("path-to-white-piece-image");
...