Java如何设计五子棋游戏?java程序设计五子棋小游戏

Java能开发的东西还是很多的,我们生活中有很多都是利用java开发的,比如小程序,网页等,当然java也可以开发一些小型游戏,那Java如何设计五子棋游戏?下面来我们就来给大家讲解一下。

棋盘是15*15(可以自己规定)

游戏规则:

(1)对局双方各执一色棋子。

(2)空棋盘开局。

(3)黑先、白后,交替下子,每次只能下一子。

(4)棋子下在棋盘的空白点上,棋子下定后,不得向其它点移动,不得从棋盘上拿掉或拿起另落别处。

(5)黑方的第一枚棋子可下在棋盘任意交叉点上。

(6)任意一方达成五连子即可获胜

Java开发用到了Swing轻量级组件用来处理游戏界面,判断胜利的逻辑代码是核心。

1.整体的设计

public class MyJpanel extends JFrame
{
    PicJpanel pj;
    public MyJpanel()
    {
        init();
    }
    private void init()
    {
        // 逻辑代码处理部分
    }
    public static void main(String[] args)
    {
        new MyJpanel();
    }
}
class PicJpanel extends JPanel
{
    MyJpanel mj;
    public PicJpanel(MyJpanel mj)
    {
        // 设定面板在窗体中的位置以及高度和宽度
        this.setBounds(0, 0, mj.getWidth(), mj.getHeight());
        this.mj = mj;
    }
    /**
    * 画组件
    */
    @Override
    protected void paintComponent(Graphics g)
    {
        // 设置一个背景
        try
        {
            BufferedImage bi = ImageIO.read(new File("img/bj.jpg"));
            g.drawImage(bi, 0, 0, this);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    class MyMouse extends MouseAdapter
    {
        MyJpanel mj;
        public MyMouse(MyJpanel mj)
        {
            super();
            this.mj = mj;
        }
        @Override
        public void mousePressed(MouseEvent e)
        {
            //点击事件的处理
        }
    }

MyJpanel 继承Jfram作为整体的一个框架,PicJpanel继承JPanel描绘图画,两者是通过双向关联来互相取值的.MyMouse用来处理点击时间(也是双向关联Jfram)。

2.整体设计模式确定后,就是画图了

在MyJpanel的Init()方法里设置大小,布局方式等,在PicJanel里的paintComponent(Graphics g)方法里通过画图工具画出棋盘。

画图的思路是通过循环画一个15*15的格子。

init()和paintComponent(Graphics g)里的代码:

private void init()
{
    // 窗体的常用设置
    this.setSize(750, 780); // 设置窗体的大小,宽度和高度,单位是像素
    this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); // 设置窗体关闭时主线程自动关闭
    this.setLocationRelativeTo(null); // 设置窗体出现的位置在显示器正中间
    this.setResizable(false); // 设置窗体固定大小
    this.setLayout(null); // 不启用布局管理器,改为手动布局
    this.setTitle("画图");
    // 添加面板到窗体
    pj = new PicJpanel(this);
    this.add(pj);
    this.setVisible(true);
}
protected void paintComponent(Graphics g)
{
    // 设置一个背景
    try
    {
        BufferedImage bi = ImageIO.read(new File("img/bj.jpg"));
        g.drawImage(bi, 0, 0, this);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    g.setColor(Color.BLACK);
    //通过循环画格子
    for (int i = 0; i < 15; i++)
    {
        for (int j = 0; j < 15; j++)
        {
            g.drawRect(50 * i, 50 * j, 50, 50);
        }
    }
}

画好之后就是这样

Java如何设计五子棋游戏?java程序设计五子棋小游戏.jpg

3.接着添加点击事件

要求

1.精确点击

2.首先落子的是黑棋

2.每次一方下完棋子颜色改变

说一下思路,我这里是750*750的,行和列都是15,这样就很容易获取x和y的值(通过鼠标点击事件getX和getY再除以50则可得到x,y),说到x,y大家肯定想到要使用二维数组,每错,我们在前台看到的是棋盘,但是实际存储值的地方在二维数组,所以要定义一个二维数组map[15][15]。每次获取到x和y则将map[x][y]=1或2(黑子或白子),每次点击之后都要调用repaint()方法重新绘制图画。看看MyMouse里的mousePressed()方法。

在这之前先在MyJpanel里设置2个全局变量

int map[][] = new int[15][15]; // 棋盘

int flag = 2; // 1为白 2为黑 黑白交替默认为黑

由于MyMouse 关联了MyJpanel 所以可以获取到MyJpanel 的值

public void mousePressed(MouseEvent e)
{
    Point p = e.getPoint(); // 获取鼠标点下的位置的坐标
    // 点击之后map值发生改变
    int x = (int) p.getX() / (750 / 15);
    int y = (int) p.getY() / (750 / 15);
    System.out.println("x=" + p.getX() + " y=" + p.getY());
    System.out.println("x=" + x + " y=" + y);
    // 改变棋子的颜色
    if (map[y][x] == 0)
    {
        map[y][x] = mj.flag;
    }
    // 改变顺序
    if (mj.flag == 1)
    {
        mj.flag = 2;
    }
    else if (mj.flag == 2)
    {
        mj.flag = 1;
    }
    //重置绘图
    mj.pj.repaint();
}

做完点击事件处理后,要回到图像处理部分PicJpanel在循环里添加一行代码如下:

for (int i = 0; i < 15; i++)
{
    for (int j = 0; j < 15; j++)
    {
        g.drawRect(50 * i, 50 * j, 50, 50);
        // 1为白
        if (map[i][j] == 1)
        {
            g.setColor(Color.WHITE);
            g.fillOval(50 * j, 50 * i, 50, 50);
        }
        g.setColor(Color.black);
        // 2为黑
        if (map[i][j] == 2)
        {
            g.setColor(Color.black);
            g.fillOval(50 * j, 50 * i, 50, 50);
        }
    }

看看效果

1.jpg

点击第一行一列后台处理之后输出结果。嗯差不多做了一大半了。剩下来的就是核心部分了

4.胜负判断

每次调用鼠标点击时间都要判断一次输赢。

讲一下思路。要判断输赢。要判断每次落子的地方该子的四个大方向是否有五颗连续的子,4个大方向为上下,左右,左斜,右斜,想一下米子的写法就可以了。同方向上是否有五颗颜色一样的棋子,实际上就是连续问题,这里有很多处理方法。博主给出的不是最佳方案。

4步完成后稍微修改处理一下代码就可以了。

代码如下,这个小游戏主要是画图和数组两个部分的内容,基础稍好的同学可以试着自己实现一下,可以参照设计思路,细节上可以自己处理。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class MyJpanel extends JFrame
{
    PicJpanel pj;
    int map[][] = new int[16][16]; // 棋盘
    int flag = 2; // 1为白 2为黑 黑白交替默认为黑
    int winer = 0; //规定赢者
    public int[][] getMap()
    {
        return map;
    }
    public void setMap(int[][] map)
    {
        this.map = map;
    }
    public MyJpanel()
    {
        init();
    }
    private void init()
    {
        // 窗体的常用设置
        this.setSize(750, 780); // 设置窗体的大小,宽度和高度,单位是像素
        this.setDefaultCloseOperation(this.EXIT_ON_CLOSE); // 设置窗体关闭时主线程自动关闭
        this.setLocationRelativeTo(null); // 设置窗体出现的位置在显示器正中间
        this.setResizable(false); // 设置窗体固定大小
        this.setLayout(null); // 不启用布局管理器,改为手动布局
        this.setTitle("画图");
        // 添加面板到窗体
        pj = new PicJpanel(this);
        pj.addMouseListener(new MyMouse(this)); // 给面板添加一个鼠标监听事件
        this.add(pj);
        this.setVisible(true);
    }
    public static void main(String[] args)
    {
        new MyJpanel();
    }
}
class PicJpanel extends JPanel
{
    MyJpanel mj;
    public PicJpanel(MyJpanel mj)
    {
        // 设定面板在窗体中的位置以及高度和宽度
        this.setBounds(0, 0, mj.getWidth(), mj.getHeight());
        this.mj = mj;
    }
    /**
    * 画组件
    */
    @Override
    protected void paintComponent(Graphics g)
    {
        try
        {
            BufferedImage bi = ImageIO.read(new File("img/bj.jpg"));
            g.drawImage(bi, 0, 0, this);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        int map[][] = mj.map;
        g.setColor(Color.BLACK);
        for (int i = 0; i < 15; i++)
        {
            for (int j = 0; j < 15; j++)
            {
                g.drawRect(50 * i, 50 * j, 50, 50);
                // 1为白
                if (map[i][j] == 1)
                {
                    g.setColor(Color.WHITE);
                    g.fillOval(50 * j, 50 * i, 50, 50);
                }
                g.setColor(Color.black);
                // 2为黑
                if (map[i][j] == 2)
                {
                    g.setColor(Color.black);
                    g.fillOval(50 * j, 50 * i, 50, 50);
                }
            }
        }
        // g.setColor(Color.RED);//设置画笔为红色
        // g.drawRect(50, 50, 100, 100);//画一个矩形.前面两个参数决定位置,后两个参数决定大小
        // g.setColor(Color.BLUE);
        // g.fillRect(200,50, 100, 100);//画一个实心的矩形
        // g.drawOval(50, 200, 100, 100);
        // g.fillOval(200, 200, 100, 100);
    }
}
class MyMouse extends MouseAdapter
{
    MyJpanel mj;
    public MyMouse(MyJpanel mj)
    {
        super();
        this.mj = mj;
    }
    @Override
    public void mousePressed(MouseEvent e)
    {
        //重置1
        if (mj.winer != 0)
        {
            mj.setMap(new int[16][16]);
            mj.winer = 0;
            mj.pj.repaint();
            return;
        }
        int map[][] = mj.map;
        Point p = e.getPoint(); // 获取鼠标点下的位置的坐标
        // 点击之后map值发生改变
        int x = (int) p.getX() / (750 / 15);
        int y = (int) p.getY() / (750 / 15);
        System.out.println("x=" + p.getX() + " y=" + p.getY());
        System.out.println("x=" + x + " y=" + y);
        // 改变棋子的颜色
        if (map[y][x] == 0)
        {
            map[y][x] = mj.flag;
        }
        // 改变顺序
        if (mj.flag == 1)
        {
            mj.flag = 2;
        }
        else if (mj.flag == 2)
        {
            mj.flag = 1;
        }
        //判断输赢
        MyMouse mouse = new MyMouse(mj);
        if (mouse.isWin(y, x, map))
        {
            if (map[y][x] == 1)
            {
                mj.winer = 1;
                mj.pj.repaint();
                //弹出获胜信息
                JOptionPane.showMessageDialog(mj, "白子胜");
                //重置棋子颜色为黑棋
                mj.flag = 2;
            }
            if (map[y][x] == 2)
            {
                mj.winer = 2;
                mj.pj.repaint();
                JOptionPane.showMessageDialog(mj, "黑子胜");
                //重置棋子颜色为黑棋
                mj.flag = 2;
            }
        }
        //先调整数组 在绘图
        mj.setMap(map);
        mj.pj.repaint();
    }
    public boolean isWin(int x, int y, int map[][])
    {
        // 对胜负判断
        // 4个方向 左右 上下 左斜 右斜
        // 对一个棋子的一个方向的10颗棋子进行判断 是否满足5子连续
        // 左右
        int num = 1;
        for (int i = 0; i < 14; i++)
        {
            if (map[x][i] != 0)
            {
                if (map[x][i] == map[x][i + 1])
                {
                    num++;
                    if (num >= 5)
                    {
                        System.out.println("win");
                        return true;
                    }
                }
                else
                {
                    num = 1;
                }
            }
        }
        // 上下
        num = 1;
        for (int i = 0; i < 14; i++)
        {
            if (map[i][y] != 0)
            {
                if (map[i][y] == map[i + 1][y])
                {
                    num++;
                    if (num >= 5)
                    {
                        System.out.println("win");
                        return true;
                    }
                }
                else
                {
                    num = 1;
                }
            }
        }
        num = 1;
        // 右斜 x-1 j+1
        for (int i = 0; i < map.length * 2 - 1; i++)
        {
            for (int j = 1; j < map.length; j++)
            {
                if (((i - j) >= 0) && ((i - j) < map.length))
                {
                    if (map[j][i - j] != 0)
                    {
                        if (map[j][i - j] == map[j - 1][i - j + 1])
                        {
                            num++;
                            if (num >= 5)
                            {
                                System.out.println("win");
                                return true;
                            }
                        }
                        else
                        {
                            num = 1;
                        }
                    }
                }
            }
        }
        num = 1;
        //左斜 x+1 y+1
        for (int i = -map.length; i < map.length; i++)
        {
            for (int j = 1; j < map.length; j++)
            {
                if (((i + j) >= 0) && ((i + j) < map.length))
                {
                    < p = "" >
                        if (map[j][j + i] != 0)
                        {
                            if (map[j][i + j] == map[j + 1][i + j + 1])
                            {
                                num++;
                                if (num >= 5)
                                {
                                    System.out.println("win");
                                    return true;
                                }
                            }
                            else
                            {
                                num = 1;
                            }
                        }
                }
            }
        }
        return false;
    }
}

我们再使用java开发游戏的时候,一定要明确项目开发思路,这样才会开发好项目,减少出错的机会!最后大家如果想要了解更多java实战知识,敬请关注奇Q工具网。

推荐阅读:

java贪吃蛇游戏如何设计?java贪吃蛇游戏设计报告

java软件如何安装?java软件安装详细教程

java程序的并发机制是什么?Java运行机制是怎样的?