Java Swing五子棋

项目地址:https://github.com/ListeningRift/gobang

之前用python的pygame这样一个专门用于游戏制作的游戏框架写了一个扫雷,这回事用Java Swing库这个用于创建GUI的库实现了一个五子棋,我持有的观点不变,在初学时写个益智类小游戏,对算法接触基本语法等各方面都有好处。

还是一样的没有把太多精力放在界面美化上,界面的美化我个人认为大体归功于GUI框架的熟练程度,大部分时间花在API的熟悉上,所以并没有花太多精力。而且相对于一款完整的游戏,差的也比较远,我只做了主要游戏界面,开始界面,胜利界面都省略了。

贴个代码记录一哈:

首先是Game.java文件,主要做了一个JFrame窗体创建的工作,其次就是点击事件监听。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class Game extends JFrame implements MouseListener {
    private static Insets insets;
    private static GamePanel panel;
    public static final int operationWidth = 80;

    public static void main(String[] args) {
        Game game = new Game();
        game.start();
    }

    public Game() {
        addMouseListener(this);
        setSize(GamePanel.WIDTH + 14 + operationWidth, GamePanel.HEIGHT + 37);
        setTitle("五子棋");
        setBackground(new Color(209,190,130));
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        insets = getInsets();
        addButton();
    }

    public void start() {
        panel = new GamePanel();
        add(panel);
        Thread th = new Thread((Runnable) panel);
        th.start();
    }

    public void mouseClicked(MouseEvent e) {
        int[] XY = getXY(e);
        // TODO limit the range
        if (XY[0] < 0 || XY[0] > 19 ||
            XY[1] < 0 || XY[1] > 19) {
            System.out.println("over");
            return;
        }
        Piece newPiece = new Piece(getPlayer(), XY[0], XY[1]);
        GamePanel.pieces.add(newPiece);
        panel.repaint();
        newPiece.judge();
    }

    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}

    public int[] getXY(MouseEvent e) {
        int mouseX = e.getX();
        int mouseY = e.getY() - insets.top;
        int X = (int) Math.floor(mouseX / GamePanel.gridWidth);
        int Y = (int) Math.floor(mouseY / GamePanel.gridHeight);
        int restWidth = mouseX - X * GamePanel.gridWidth;
        int restHeight = mouseY - Y * GamePanel.gridHeight;
        if (restWidth < GamePanel.gridWidth / 2) {
            X = X - 1;
        }
        if (restHeight < GamePanel.gridHeight / 2) {
            Y = Y - 1;
        }
        return new int[]{X, Y};
    }

    public String getPlayer() {
        return GamePanel.pieces.size() % 2 != 0 ? "white" : "black";
    }

    public void addButton() {
        JButton back = new JButton("悔棋");
        back.setBounds(GamePanel.WIDTH + 7, GamePanel.gridHeight + 30, 60, 30);
        back.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                GamePanel.pieces.remove(GamePanel.pieces.size() - 1);
                panel.repaint();
            }
        });
        JButton giveUp = new JButton("认输");
        giveUp.setBounds(GamePanel.WIDTH + 7, GamePanel.gridHeight + 90, 60, 30);
        giveUp.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                GamePanel.win(getPlayer());
            }
        });

        add(back);
        add(giveUp);
    }
}

第二部分就是游戏JPanel部分,主要负责游戏主界面绘制,以及游戏输赢动作(这个动作没有认真去写,只是在控制台输出一下胜方而已)。

import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.BasicStroke;
import java.util.ArrayList;

public class GamePanel extends JPanel {
    public static final int WIDTH = 672;
    public static final int HEIGHT = 672;
    public static int gridWidth;
    public static int gridHeight;
    public static ArrayList<Piece> pieces = new ArrayList<Piece>();

    public GamePanel() {
        setBackground(new Color(209,190,130));
        setSize(WIDTH, HEIGHT);
        gridWidth = getWidth() / 21;
        gridHeight = getHeight() / 21;
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setStroke(new BasicStroke(2));

        for (int i = 1; i < 21; i++) {
            g.drawLine(i * gridWidth, gridHeight, i * gridWidth, gridHeight * 20);
            g.drawLine(gridWidth, i * gridHeight, gridWidth * 20, i * gridHeight);
        }

        for (Piece piece: pieces) {
            piece.paint(g2d);
        }
    }

    public static void win(String player) {
        System.out.println(player);
    }
}

第三部分写了一个棋子类,负责妻子绘制与判断连线数字判断。

import java.awt.*;

public class Piece {
    private static final int r = 14;
    public Color color;
    public int x;
    public int y;

    public Piece(String color, int x, int y) {
        if (color.equals("black")) {
            this.color = Color.BLACK;
        } else if (color.equals("white")) {
            this.color = Color.WHITE;
        }
        this.x = x;
        this.y = y;
    }

    public void paint(Graphics2D g) {
        g.setColor(color);
        g.fillArc((x + 1) * GamePanel.gridWidth - r, (y + 1) * GamePanel.gridHeight - r, 2 * r, 2 * r, 0, 360);
        g.setColor(Color.BLACK);
        g.setStroke(new BasicStroke(1));
        g.drawArc((x + 1) * GamePanel.gridWidth - r, (y + 1) * GamePanel.gridHeight - r, 2 * r, 2 * r, 0, 360);
    }

    public void judge() {
        String player = "";
        if (color == Color.BLACK) {
            player = "black";
        } else if (color == Color.WHITE) {
            player = "white";
        }
        if (judgeHorizontal() || judgeVertical() || judgeLeanToLeft() || judgeLeanToRight()) {
            GamePanel.win(player);
        }
    }

    public boolean judgeVertical() {
        int number = 1;
        for (int i = 1; i < 6; i++) {
            if (getTop(i)) {
                number++;
            } else {
                break;
            }
        }
        for (int i = 1; i < 6; i++) {
            if (getBottom(i)) {
                number++;
            } else {
                break;
            }
        }
        return number >= 5;
    }

    public boolean judgeHorizontal() {
        int number = 1;
        for (int i = 1; i < 6; i++) {
            if (getLeft(i)) {
                number++;
            } else {
                break;
            }
        }
        for (int i = 1; i < 6; i++) {
            if (getRight(i)) {
                number++;
            } else {
                break;
            }
        }
        return number >= 5;
    }

    public boolean judgeLeanToLeft() {
        int number = 1;
        for (int i = 1; i < 6; i++) {
            if (getTopLeft(i)) {
                number++;
            } else {
                break;
            }
        }
        for (int i = 1; i < 6; i++) {
            if (getBottomRight(i)) {
                number++;
            } else {
                break;
            }
        }
        return number >= 5;
    }

    public boolean judgeLeanToRight() {
        int number = 1;
        for (int i = 1; i < 6; i++) {
            if (getTopRight(i)) {
                number++;
            } else {
                break;
            }
        }
        for (int i = 1; i < 6; i++) {
            if (getBottomLeft(i)) {
                number++;
            } else {
                break;
            }
        }
        return number >= 5;
    }

    public boolean getTop(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x && y == p.y + distance) {
                return p.color == color;
            }
        }
        return false;
    }

    public boolean getBottom(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x && y == p.y - distance) {
                return p.color == color;
            }
        }
        return false;
    }

    public boolean getRight(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x - distance && y == p.y) {
                return p.color == color;
            }
        }
        return false;
    }

    public boolean getLeft(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x + distance && y == p.y) {
                return p.color == color;
            }
        }
        return false;
    }

    public boolean getTopRight(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x - distance && y == p.y + distance) {
                return p.color == color;
            }
        }
        return false;
    }

    public boolean getTopLeft(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x + distance && y == p.y + distance) {
                return p.color == color;
            }
        }
        return false;
    }

    public boolean getBottomRight(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x - distance && y == p.y - distance) {
                return p.color == color;
            }
        }
        return false;
    }

    public boolean getBottomLeft(int distance) {
        for (Piece p: GamePanel.pieces) {
            if (x == p.x + distance && y == p.y - distance) {
                return p.color == color;
            }
        }
        return false;
    }
}

实现的东西比较少,只是大概的一个骨架,贴了全部代码,记录一下在这无聊的时间里的消遣玩具。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值