java版五子棋

 

思路:

  游戏主界面:
1.一个15*15的五子棋界面;
2.能够在界面上下黑白棋子;
3.需要把棋子下在交叉点上;
4.实现棋子重绘;——作用:当界面大小被改变时能够保持棋盘和棋盘上面的棋子不会消失;
5.相同位置不能下多个棋子;
6.只有当“开始新游戏”的按钮被点击时,才能开始下棋;
1.一个15*15的五子棋界面;

需要重写GoBangframe的重绘方法,使其在界面刚生成时就产生一个15*15的棋盘。(重绘方法会在每次页面大小被改变时执行,因此当你改变大小时,棋盘不会消失)。这里我们可以通过两个for循环画出15条行线和15条列线。

2.能够在界面上下黑白棋子;

实现这个功能需要定义一个变量turn表名当前轮到哪方下棋。如果turn=1表明轮到黑方,turn=2表明轮到白方。每次黑方下完棋之后turn+1,白方下完棋之后turn-1。

3.需要把棋子下在交叉点上;

如果鼠标点击在交叉点处的某个范围内,我们都把棋子下在这个交叉点上。在这个由于格子大小是40,我们定义的范围时以交叉点为中心的上下20的正方形。这样我们就能确保每一次点击都会落到某一个交叉点处,不会覆盖也不会出现没有落子的情况。

4.实现棋子重绘;——作用:当界面大小被改变时能够保持棋盘上面的棋子不消失;

前面的棋盘重绘,虽然15*15的棋盘不会消失,但是棋子会消失。因此我们在重绘出棋盘以后还要把棋子也重新画上去。这里用了一个二维数组isAvail[15][15]来保存棋子信息,如果isArray[i][j]=0,表明这个位置没有棋子,等于1表明是一个黑棋子,等于2表明是一个白棋子。我们根据这些信息,遍历isArray数组,把棋子重新绘制上去。

5.相同位置不能下多个棋子;

判断isArray[i][j]是不是等于0,如果是0就可以下,如果不是则提示玩家下在其它地方。

6.只有当“开始新游戏”的按钮被点击时,才能开始下棋;

下棋是通过监听棋盘界面来实现的,因此我们只需要监听“开始新游戏”这个按钮,如果这个按钮被点击了,我们在给棋盘界面添加监听方法,否则不添加。

实现五子棋界面需要的API类:
JFrame  顶级容器类
BorderLayout  框架布局类——把容器分为上北下南左西右东中间五个部分,每个部分只能添加一个组件。
需要把整个界面分为左右两部分。选择在框架布局的中间和右边两个部分。

这里我们还需要另一个容器类——JPanel  面板容器类。主要用来实现右边的部分,因为原本框架布局的右边部分只能添加
一个组件,但是我们需要添加的组件不只一个,因此就先这个部分加上一个JPanel,然后再在JPanel上加我们需要的组件,
包括按钮等等。

JFrame和JPanel的区别:JFrame是最底层的容器,JPanel放在它上面,同一个界面只有一个JFrame,但是一个JFrame
上面可以有多个JPanel。相当于JFrame是一个大餐桌,JPanel是盘子,如果我们要对餐桌JFrame上的东西进行管理分类等,
我们就需要使用这些JPanel盘子。

FlowLayout   流式布局类。因为我们右边的JPanel部分需要将按钮等组件由上到下进行排列。

JButton  按钮组件类

JComboBox   下拉列表框类——实现那个人人对战和人机对战的选择

Dimension  封装组件宽度和高度的类——组件类不能直接用setSize方法来设置

事件监听机制的类:

ActionListener  状态监听处理类

ActionEvent   状态监听事件,监听某个组件的状态是否有改变

MouseListener  鼠标监听处理类

MouseEvent  鼠标监听事件,里面包含鼠标被点击等事件的处理方法。当界面被点击时就放下一个棋子。

绘画所需要的类:

Graphics|Graphics2D   画笔类

Color  颜色类,需要设置画笔的颜色,实现黑白棋子

1.判断输赢——出现了五颗连在一起的同颜色的棋子

A.判断的时间:刚落完棋子的时候

B.判断的范围:

一开始我想要遍历整个棋盘,但仔细想想这个想法是不切实际的。整个棋盘太大了,而且相连的棋子情况不好细分。
于是我就换了一种思路:既然我们是在落子的时候开始判断,那么显然我们是要围绕我们刚落的这个棋子来进行判断。

每一个点一共有四个方向可能出现五个相连的棋子。与这个棋子是否能决定输赢相关联的棋子每一个方向上有八个,
往前四个往后四个。也就是每一个方向我们都要遍历九个棋子的颜色,判断是否有五个相同颜色的棋子,
有就说明输赢已经出现。假设我们落下的棋子对应的数组位置为isAvail[i][j]。

同一行上:遍历isAvail[i-4][j]...isAvail[i+4][j];

同一列上:遍历isAvail[i][j-4]...isAvail[i][j+4];

同一斜线上(左上到右下):遍历isAvail[i-4][j-4]...isAvail[i+4][j+4]

同一斜线上(左下到右上):令sum=i+j;遍历isAvail[i-4][sum-(i-4)]...isAvail[i+4][sum-(i+4)];

C.注意事项:

要注意防止数组越界,iaAvail[i][j]中的i,j均不能小于0,大于14;

要注意五个棋子必须是相连的,在我们一次遍历的时候一旦出现了没有棋子或者是其他棋子,必须把前面的计数值清空,重新开始计数;

2.实现悔棋操作

设置一个ChessPosition对象,该对象包含listi,listj两个数据,分别表示我们与棋子对应的数组位置中的i和j。
定义一个动态的ChessPosition对象数组ChessPositonList,每当我们落下一颗棋子时,
就把这个棋子的数组位置信息添加到对象数组中。每当我们点击悔棋时,我们就把turn相应的数值转换到另一方,
并且用remove方法,取出对象数组中最后一步所对应的棋子信息,并且删除这个信息。
然后根据这个信息把isAvail数组中对应的位置重新置为0,并且调用GoBangframe对象的重绘方法。

3.实现认输操作

一旦“认输”按钮被点击,先通过turn的数值判断当前是轮到哪一方。如果是白方,就输出“黑方赢”的信息;如果是黑方,就输出“白方赢”的信息。

具体代码:

public class Main {
    public static void main(String[] args) {
        new Welcome();
    }
}

//设置按钮监听方法ButttonLitener类
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

import java.awt.*;

import static com.sun.deploy.uitoolkit.ToolkitStore.dispose;
import static java.lang.System.*;

//实现对JPanel的监听接口处理
public class ButtonListener extends JFrame implements ActionListener{
    public WuZiQi wu;
    Date date=new Date();
    public ButtonListener(WuZiQi wu) {
        this.wu=wu;//获取左半部分的画板
    }

    //当界面发生操作时进行处理
    public void actionPerformed(ActionEvent e) {
        //获取当前被点击按钮的内容,判断是不是"开始新游戏"这个按钮
        if(e.getActionCommand().equals("开始")) {
            //如果是开始新游戏的按钮,再为左半部分设置监听方法
            MouserListe fl=new MouserListe();
            fl.setGraphics(wu);//获取画笔对象
            wu.addMouseListener(fl);//监听
        }//判断当前点击的按钮是不是悔棋
        else if(e.getActionCommand().equals("悔棋")) {
            if(wu.ChessPositonList.size()>1) {
                //把棋子数组相应的位置置为0;
                ChessPosition l=new ChessPosition();
                ChessPosition l1=new ChessPosition();
                //获取最后一个棋子的对象信息(移除)
                l=wu.ChessPositonList.remove(wu.ChessPositonList.size()-1);
                l1=wu.ChessPositonList.remove(wu.ChessPositonList.size()-1);
                //把相应的数组位置置为0
                wu.isAvail[l.Listi][l.Listj]=0;
                wu.isAvail[l1.Listi][l1.Listj]=0;
                //把玩家还原为上一步的玩家
                /*
                悔棋应该是己方落子且敌方也落子之后己方悔棋,需要撤销敌方和己方的两手棋子,悔棋后 依旧是己方落子
                 */
                if(wu.turn==1)
                {
                    wu.turn--;
                }
                else {
                    wu.turn++;
                }

                //直接调用wu的重绘方法,重绘方法的画笔应该是在棋盘页面还没生成的时候就要获取
                //调用repaint会自动调用paint方法,而且不用给参数
                wu.repaint();
            }
            else {
                System.out.println("不能悔棋!");
            }


        }else if(e.getActionCommand().equals("认输")) {
            if(wu.turn==2){
                JOptionPane.showMessageDialog(null, "白方赢");
                this.dispose();
                new WuZiQi().initUI();
            }else  if(wu.turn==1) {
                JOptionPane.showMessageDialog(null, "黑方赢");
                this.dispose();
                new WuZiQi().initUI();
                /*
                for(int ii=0;ii<date.row;ii++) {

                    for(int jj=0;jj<date.column;jj++) {
                        wu.isAvail[ii][jj]=0;
                    }
                }
                wu.repaint();*/
            }
        }else if(e.getActionCommand().equals("退出")){
            JOptionPane.showMessageDialog(null, "谢谢使用,再见!");
            System.exit(0);
        }
        }



}

//新建一个棋子类ChessPosition保存每一步棋子所在的位置
public class ChessPosition {
    public int Listi, Listj;
    public ChessPosition() {

    }

    public ChessPosition(int Listi, int Listj) {
        this.Listi = Listi;
        this.Listj = Listj;
    }
}

/*
    定义与棋盘数据相关的接口,保存棋盘的起点,格子大小,行数列数等信息
 */
public class Date {

    public int x=20,y=20,size=40,row=15,column=15;
    //x=20,y=20 棋盘的起点
    //size=40 格子大小
    //row,column=15 行列数皆为15
}

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

/*
    游戏使用帮助
 */
public class Help extends JFrame implements ActionListener {
    JPanel jPanel;
    JButton b1,b2;
    TextArea text;
    public Help(){
        this.setTitle("游戏帮助");
        b1=new JButton("确定");
        b2=new JButton("退出");
        this.setBounds(100,100,300,300);
        text=new TextArea("双方分别使用黑白两色的棋子,空棋盘开局。黑色棋子先下,白色棋子后下," +
                "每次只能下一子。轮流下子是双方的权利,但允许任何一方放弃下子权," +
                "先形成5子连线者获胜。",8,15);

        jPanel=new JPanel();

        jPanel.add(text);
        jPanel.add(b1);
        jPanel.add(b2);
        this.add(jPanel);
        this.setBackground(Color.blue);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b1.addActionListener(this);
        b2.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==b1){
            this.dispose();
            new Welcome();
        }else{
            JOptionPane.showMessageDialog(this,"谢谢使用,再见!");
            System.exit(0);
        }
    }
}
//import java.awt.*;
//import java.awt.event.MouseEvent;
//import java.awt.event.MouseListener;
//
///*
//
// */
//public class MouserListe implements MouseListener {
//    WuZiQi wuziqi;//定义WuZiQi对象
//    Date date;
//    int turn=1;//判断当前轮到谁了,1表示黑方,2表示白方
//
//    public void setGraphics(WuZiQi wuziqi) {
//        this.wuziqi=wuziqi;
//    }
//
//    @Override
//    public void mouseClicked(MouseEvent e) {
//        int x=e.getX();
//        int y=e.getY();//得到鼠标的(像素)位置
//
//
//        //计算棋子要落在棋盘的哪个交叉点上
//        int countx=(x/40)*40+20;
//        int county=(y/40)*40+20;
//        Graphics g=wuziqi.getGraphics();//
//
//
//
//        if(wuziqi.isAvail[(countx-20)/40][(county-20)/40]!=0) {
//            System.out.println("此处已经有棋子了,请下在其它地方");
//        }
//        else {
//            //当前位置可以落子,先计算棋盘上棋子在数组中相应的位置
//            int colu=(countx-20)/40;
//            int ro=(county-20)/40;
//
//            if(turn==1) {
//                //先设置颜色
//                g.setColor(Color.black);
//                //落子
//                g.fillOval(countx-date.size/2, county-date.size/2, date.size, date.size);
//                //设置当前位置已经有棋子了,棋子为黑子
//                wuziqi.isAvail[colu][ro]=1;
//                turn++;
//            }
//            else {
//                g.setColor(Color.white);
//                g.fillOval(countx-date.size/2, county-date.size/2, date.size, date.size);
//                //设置当前位置已经有棋子了,棋子为白子
//
//                wuziqi.isAvail[colu][ro]=2;
//                turn--;
//            }
//        }
//
//
//
//    }
//
//    @Override
//    public void mousePressed(MouseEvent e) {
//
//    }
//
//    @Override
//    public void mouseReleased(MouseEvent e) {
//
//    }
//
//    @Override
//    public void mouseEntered(MouseEvent e) {
//
//    }
//
//    @Override
//    public void mouseExited(MouseEvent e) {
//
//    }
//
//    public void setGraphics() {
//
//    }
//}
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.awt.event.ActionEvent;
import java.awt.Graphics;
import java.awt.Color;

//实现对WuZiQi界面的监听接口处理
public class MouserListe implements MouseListener {
    Date date = new Date();
    public WuZiQi gf;
    public int turn = 1;//判断当前轮到谁了,1表示黑方,2表示白方

    public void setGraphics(WuZiQi gf) {
        this.gf = gf;
    }


    public void mouseClicked(java.awt.event.MouseEvent e) {
        //获取鼠标位置(像素)
        int x = e.getX();
        int y = e.getY();
        //计算棋子要落在棋盘的哪个交叉点上
        int countx = (x / 40) * 40 + 20;
        int county = (y / 40) * 40 + 20;
        Graphics g = gf.getGraphics();//获取画笔
        //相同位置不能下多个棋子
        //判断isArray[i][j]是不是等于0,如果是0就可以下
        if (gf.isAvail[(countx - 20) / 40][(county - 20) / 40] != 0) {
            JOptionPane.showMessageDialog(null, "此处已经有棋子了,请下在其它地方");
        } else {
            //当前位置可以落子,先计算棋盘上棋子在数组中相应的位置
            int colu = (countx - 20) / 40;
            int ro = (county - 20) / 40;

            if (turn == 1) {
                //先设置颜色
                g.setColor(Color.black);
                //落子
                g.fillOval(countx - date.size / 2, county - date.size / 2, date.size, date.size);
                //设置当前位置已经有棋子了,棋子为黑子
                gf.isAvail[colu][ro] = 1;
                //把当前所下的棋子位置保存在动态数组中
                gf.ChessPositonList.add(new ChessPosition(colu, ro));
                turn++;

                //判断是否已经出现五颗棋子了
                //列判断
                //首先界定数组范围,防止越界
                int imin = colu - 4, imax = colu + 4;
                if (imin < 0) imin = 0;
                if (imax > 14) imax = 14;
                int count1 = 0;//判断相连的棋子数
                for (int i = imin; i <= imax; i++) {
                    if (gf.isAvail[i][ro] == 1) count1++;
                        //如果出现了其他棋子,或者是没有棋子时,就重新开始计数
                    else count1 = 0;
                    if (count1 == 5) {
                        JOptionPane.showMessageDialog(null, "黑方赢");
                        new WuZiQi().initUI();
                        return;
                        /*for (int ii = 0; ii < date.row; ii++) {
                            for (int jj = 0; jj < date.column; jj++) {
                                gf.isAvail[ii][jj] = 0;
                            }
                        }
                        gf.repaint();*/
                    }
                }
                //行判断
                //首先界定数组范围,防止越界
                int jmin = ro - 4, jmax = ro + 4;
                if (jmin < 0) jmin = 0;
                if (jmax > 14) jmax = 14;
                int count2 = 0;//判断相连的棋子数
                for (int j = jmin; j <= jmax; j++) {
                    if (gf.isAvail[colu][j] == 1) count2++;
                    else count2 = 0;
                    if (count2 == 5) {
                        JOptionPane.showMessageDialog(null, "黑方赢");
                        new WuZiQi().initUI();
                        return;
                        /*for (int ii = 0; ii < date.row; ii++) {
                            for (int jj = 0; jj < date.column; jj++) {
                                gf.isAvail[ii][jj] = 0;
                            }
                        }
                        gf.repaint();*/
                    }
                    //如果出现了其他棋子,或者是没有棋子时,就重新开始计数

                }
                //135度判断左下到右上
                //首先界定数组范围,防止越界
                int count3 = 0;//判断相连的棋子数
                for (int i = -4; i <= 4; i++) {
                    if ((colu + i >= 0) && (ro + i >= 0) && (colu + i <= 14) && (ro + i <= 14)) {
                        if (gf.isAvail[colu + i][ro + i] == 1) count3++;
                            //如果出现了其他棋子,或者是没有棋子时,就重新开始计数
                        else count3 = 0;
                        if (count3 == 5) {
                            JOptionPane.showMessageDialog(null, "黑方赢");
                            new WuZiQi().initUI();
                            return;
                            /*for (int ii = 0; ii < date.row; ii++) {
                                for (int jj = 0; jj < date.column; jj++) {
                                    gf.isAvail[ii][jj] = 0;
                                }
                            }
                            gf.repaint();*/
                        }
                    }
                }
                //左上到右下
                int count4 = 0;//判断相连的棋子数
                for (int i = -4; i <= 4; i++) {
                    if ((colu + i >= 0) && (ro - i >= 0) && (colu + i <= 14) && (ro - i <= 14)) {
                        //System.out.print("count4:"+count4);
                        if (gf.isAvail[colu + i][ro - i] == 1) count4++;
                            //如果出现了其他棋子,或者是没有棋子时,就重新开始计数
                        else count4 = 0;
                        if (count4 == 5) {
                            JOptionPane.showMessageDialog(null, "黑方赢");
                            new WuZiQi().initUI();
                            return;
                            /*for (int ii = 0; ii < date.row; ii++) {
                                for (int jj = 0; jj < date.column; jj++) {
                                    gf.isAvail[ii][jj] = 0;
                                }
                            }
                            gf.repaint();*/
                        }
                    }
                }

            } else {
                g.setColor(Color.white);
                g.fillOval(countx - date.size / 2, county - date.size / 2, date.size, date.size);
                //设置当前位置已经有棋子了,棋子为白子
                //把当前所下的棋子位置保存在动态数组中
                gf.ChessPositonList.add(new ChessPosition(colu, ro));
                gf.isAvail[colu][ro] = 2;
                turn--;

                //列判断
                //首先界定数组范围,防止越界
                int imin = colu - 4, imax = colu + 4;
                if (imin < 0) imin = 0;
                if (imax > 14) imax = 14;
                int count1 = 0;//判断相连的棋子数
                for (int i = imin; i <= imax; i++) {
                    if (gf.isAvail[i][ro] == 2) count1++;

                        //如果出现了其他棋子,或者是没有棋子时,就重新开始计数
                    else count1 = 0;
                    if (count1 == 5) {
                        JOptionPane.showMessageDialog(null, "白方赢");
                        new WuZiQi().initUI();
                        return;
                        /*for (int ii = 0; ii < date.row; ii++) {
                            for (int jj = 0; jj < date.column; jj++) {
                                gf.isAvail[ii][jj] = 0;
                            }
                        }
                        gf.repaint();*/
                    }
                }
                //行判断
                //首先界定数组范围,防止越界
                int jmin = ro - 4, jmax = ro + 4;
                if (jmin < 0) jmin = 0;
                if (jmax > 14) jmax = 14;
                int count2 = 0;//判断相连的棋子数
                for (int j = jmin; j <= jmax; j++) {
                    if (gf.isAvail[colu][j] == 2) count2++;
                        //如果出现了其他棋子,或者是没有棋子时,就重新开始计数
                    else count2 = 0;
                    if (count2 == 5) {
                        JOptionPane.showMessageDialog(null, "白方赢");
                        new WuZiQi().initUI();
                        return;
                        /*for (int ii = 0; ii < date.row; ii++) {
                            for (int jj = 0; jj < date.column; jj++) {
                                gf.isAvail[ii][jj] = 0;
                            }
                        }
                        gf.repaint();*/
                    }

                }
                //135度判断
                //首先界定数组范围,防止越界
                int count3 = 0;//判断相连的棋子数
                for (int i = -4; i <= 4; i++) {
                    if ((colu + i >= 0) && (ro + i >= 0) && (colu + i <= 14) && (ro + i <= 14)) {
                        if (gf.isAvail[colu + i][ro + i] == 2) count3++;
                            //如果出现了其他棋子,或者是没有棋子时,就重新开始计数
                        else count3 = 0;
                        if (count3 == 5) {
                            JOptionPane.showMessageDialog(null, "白方赢");
                            new WuZiQi().initUI();
                            return;
                            /*for (int ii = 0; ii < date.row; ii++) {
                                for (int jj = 0; jj < date.column; jj++) {
                                    gf.isAvail[ii][jj] = 0;
                                }
                            }
                            gf.repaint();*/
                        }
                    }
                }
                int count4 = 0;//判断相连的棋子数
                for (int i = -4; i <= 4; i++) {
                    if ((colu + i >= 0) && (ro - i >= 0) && (colu + i <= 14) && (ro - i <= 14)) {
                        if (gf.isAvail[colu + i][ro - i] == 2) count4++;
                            //如果出现了其他棋子,或者是没有棋子时,就重新开始计数
                        else count4 = 0;
                        if (count4 == 5) {
                            JOptionPane.showMessageDialog(null, "白方赢");
                            new WuZiQi().initUI();
                            return;
                            /*for (int ii = 0; ii < date.row; ii++) {
                                for (int jj = 0; jj < date.column; jj++) {
                                    gf.isAvail[ii][jj] = 0;
                                }
                            }
                            gf.repaint();*/
                        }
                    }
                }

            /*
            判断是否和局
             */
            int k=0;
            for (int i = 0; i < date.row; i++) {//循环所有的交叉点
                for (int j = 0; j < date.column; j++) {
                    if (gf.isAvail[i][j]!=0) {
                       k++;
                    }
                }
                if(k==30){
                    JOptionPane.showMessageDialog(null, "和局");
                    new WuZiQi().initUI();
                    return;
                }

            }
            }
        }

    }


    // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
    public void mousePressed(java.awt.event.MouseEvent e) {

    }

    // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
    public void mouseReleased(java.awt.event.MouseEvent e) {

    }

    // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
    public void mouseEntered(java.awt.event.MouseEvent e) {

    }

    // Method descriptor #8 (Ljava/awt/event/MouseEvent;)V
    public void mouseExited(java.awt.event.MouseEvent e) {

    }
}

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

/*
    游戏主界面:
 1.
 15*15格子
 2,

 */
public class Welcome  extends JFrame implements ActionListener {
    JLayeredPane layeredPane;
    JPanel jpanel;
    JLabel jlable;
    JButton b1,b2,b3;//开始游戏 帮助 结束游戏
    //创建一个容器
    Container ct;
    //创建背景面板。
    BackgroundPanel bgp;
    public Welcome (){
        this.setTitle("五子棋");
        /*this.setBounds(50,50,580,550);
        jlable=new JLabel();
        ImageIcon img=new ImageIcon("D:\\wuziqi.jpg");
        jlable=new JLabel(img);
        jpanel=new JPanel();
        b1=new JButton("开始");
        b2=new JButton("帮助");
        b3=new JButton("退出");
        jpanel.add(b1);
        jpanel.add(b2);
        jpanel.add(b3);

        jpanel.add(jlable);
        this.add(jpanel);*/

        //不采用任何布局方式。
        ct=this.getContentPane();
        this.setLayout(null);

        //在这里随便找一张400*300的照片既可以看到测试结果。
        bgp=new BackgroundPanel((new ImageIcon("D://wuziqi.jpg")).getImage());
        bgp.setBounds(0,0,600,550);
        ct.add(bgp);

        //创建按钮
        b1=new JButton("开始");
        b2=new JButton("帮助");
        b3=new JButton("退出");
        b1.setBounds(130,30,80,30);
        b2.setBounds(230,30,80,30);
        b3.setBounds(330,30,80,30);
        ct.add(b1);
        ct.add(b2);
        ct.add(b3);
        this.setSize(600,550);
        this.setLocation(200,100);






        this.setBackground(Color.blue);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==b1){
            this.dispose();
            new WuZiQi().initUI();
        }else if(e.getSource()==b2){
            this.dispose();
            new Help();
        }else{
            JOptionPane.showMessageDialog(this,"谢谢使用,再见!");
            System.exit(0);
        }
    }
}
class BackgroundPanel extends JPanel {
    Image im;

    public BackgroundPanel(Image im) {
        this.im = im;
        this.setOpaque(true);
    }

    //Draw the back ground.
    public void paintComponent(Graphics g) {
        super.paintComponents(g);
        g.drawImage(im, 0, 0, this.getWidth(), this.getHeight(), this);

    }
}

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

/*
    游戏主界面:
 1.
 15*15格子
 2,

 */
public class Welcome  extends JFrame implements ActionListener {
    JLayeredPane layeredPane;
    JPanel jpanel;
    JLabel jlable;
    JButton b1,b2,b3;//开始游戏 帮助 结束游戏
    //创建一个容器
    Container ct;
    //创建背景面板。
    BackgroundPanel bgp;
    public Welcome (){
        this.setTitle("五子棋");
        /*this.setBounds(50,50,580,550);
        jlable=new JLabel();
        ImageIcon img=new ImageIcon("D:\\wuziqi.jpg");
        jlable=new JLabel(img);
        jpanel=new JPanel();
        b1=new JButton("开始");
        b2=new JButton("帮助");
        b3=new JButton("退出");
        jpanel.add(b1);
        jpanel.add(b2);
        jpanel.add(b3);

        jpanel.add(jlable);
        this.add(jpanel);*/

        //不采用任何布局方式。
        ct=this.getContentPane();
        this.setLayout(null);

        //在这里随便找一张400*300的照片既可以看到测试结果。
        bgp=new BackgroundPanel((new ImageIcon("D://wuziqi.jpg")).getImage());
        bgp.setBounds(0,0,600,550);
        ct.add(bgp);

        //创建按钮
        b1=new JButton("开始");
        b2=new JButton("帮助");
        b3=new JButton("退出");
        b1.setBounds(130,30,80,30);
        b2.setBounds(230,30,80,30);
        b3.setBounds(330,30,80,30);
        ct.add(b1);
        ct.add(b2);
        ct.add(b3);
        this.setSize(600,550);
        this.setLocation(200,100);






        this.setBackground(Color.blue);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==b1){
            this.dispose();
            new WuZiQi().initUI();
        }else if(e.getSource()==b2){
            this.dispose();
            new Help();
        }else{
            JOptionPane.showMessageDialog(this,"谢谢使用,再见!");
            System.exit(0);
        }
    }
}
class BackgroundPanel extends JPanel {
    Image im;

    public BackgroundPanel(Image im) {
        this.im = im;
        this.setOpaque(true);
    }

    //Draw the back ground.
    public void paintComponent(Graphics g) {
        super.paintComponents(g);
        g.drawImage(im, 0, 0, this.getWidth(), this.getHeight(), this);

    }
}

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

//游戏主界面
public class WuZiQi extends JPanel {
    public int turn=1;
    int[][] isAvail=new int [15][15];//定义一个二维数组来储存棋盘的落子情况
    public ArrayList<ChessPosition> ChessPositonList=new ArrayList<ChessPosition>();//保存每一步的落子情况

    Date date=new Date();
    JButton b1,b2,b3,b4;
    //创建一个容器
    Container ct;
    public void initUI() {
       //初始化一个界面,并设置标题大小等属性
       JFrame jf=new JFrame();
       jf.setTitle("五子棋");//界面名字
       jf.setSize(800,650);//界面大小
       jf.setLocationRelativeTo(null);//界面置于屏幕中间

       jf.setLayout(new BorderLayout());//设置顶级容器JFrame为框架布局

       Dimension dim1=new Dimension(150,0);//设置右半部分的大小
       Dimension dim3=new Dimension(550,0);//设置左半部分的大小
       Dimension dim2=new Dimension(140,40);//设置右边按钮组件的大小

       //实现左边的界面,把WuZiQi对象添加到框架布局的中间部分
       this.setPreferredSize(dim3);//设置下棋界面的大小(界面左半部分)
       this.setBackground(Color.LIGHT_GRAY);//设置下棋界面的颜色
       //这里的话直接把左边的画板添加上去,指明是在框架布局的中间版块
       jf.add(this,BorderLayout.CENTER);//添加到框架布局的中间部分

       //实现右边的JPanel容器界面
       JPanel jp=new JPanel();
       jp.setPreferredSize(dim1);//设置JPanel的大小
       jp.setBackground(Color.white);//设置右边的界面颜色为白色
       jf.add(jp,BorderLayout.EAST);//添加到框架布局的东边部分
       jp.setLayout(new FlowLayout());//设置JPanel为流式布局

       //把按钮等组件依次加到JPanel上面
       //设置按钮及大小
       b1=new JButton("开始");
       b1.setPreferredSize(dim2);
       b2=new JButton("悔棋");
       b2.setPreferredSize(dim2);
       b3=new JButton("认输");
       b3.setPreferredSize(dim2);
       b4=new JButton("退出");
       b4.setPreferredSize(dim2);
       //依次把三个按钮组件加上去
       jp.add(b1);
       jp.add(b2);
       jp.add(b3);
       jp.add(b4);

        //按键注册
        ButtonListener butListen=new ButtonListener(this);
        b1.addActionListener(butListen);//添加发生操作的监听方法
        b2.addActionListener(butListen);
        b3.addActionListener(butListen);
        b4.addActionListener(butListen);

       //设置选项按钮
       /*String[] boxname= {"人人对战","人机对战"};
       JComboBox box=new JComboBox(boxname);
       jp.add(box);
        */
       jf.setVisible(true);//界面可见
   }

    //重绘界面(重写第一个大的JPanel方法)及棋子
    /*棋盘重绘,虽然15*15的棋盘不会消失,但是棋子会消失。在重绘出棋盘后还要把棋子也重新画上去。
    用一个二维数组isAvail[15][15]来保存棋子信息,
    isArray[i][j]=0,表明这个位置没有棋子,等于1表明是一个黑棋子,等于2表明是一个白棋子。
    根据这些信息,遍历isArray数组,把棋子重新绘制上去。
     */
    public void paint(Graphics g){
        super.paint(g);//画出白框
        //重绘出棋盘
        g.setColor(Color.black);
        for(int i=0;i<date.row;i++) {//drawLine(x1,y1,x2,y2)方法是画一条线,x1,y1 是起点的坐标, x2,y2 是终点的坐标
            g.drawLine(date.x, date.y+date.size*i, date.x+date.size*(date.column-1), date.y+date.size*i);
        }
        for(int j=0;j<date.column;j++) {
            g.drawLine(date.x+date.size*j, date.y, date.x+date.size*j, date.y+date.size*(date.row-1));
        }

        //重绘出棋子
        for(int i=0;i<date.row;i++) {//循环所有的交叉点
            for(int j=0;j<date.column;j++) {
                if(isAvail[i][j]==1) {
                    int countx=date.size*i+20;
                    int county=date.size*j+20;
                    g.setColor(Color.black);
                    g.fillOval(countx-date.size/2, county-date.size/2, date.size, date.size);
                }
                else if(isAvail[i][j]==2) {
                    int countx=date.size*i+20;
                    int county=date.size*j+20;
                    g.setColor(Color.white);
                    g.fillOval(countx-date.size/2, county-date.size/2, date.size, date.size);
                }
            }
        }

}
}

 

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值