文章目录

  • 前言
  • 一、GUI部分
    • 1.Java.Swing 和 Java.awt
    • 2.创建基本窗体
    • 3.绘制棋盘
    • 4.绘制棋子
  • 二、监听器
    • 1.下棋
    • 2.输赢判断
    • 3.结束重绘
  • 三、面板和特效
    • 1.重开和悔棋
    • 2.特效
  • 总结

前言

学习了一些java初步知识制作了这款五子棋游戏,本篇博客用于梳理过程`


一、GUI部分

1.Java.Swing 和 Java.awt

Java.Swing 和 Java.awt是两个常用来完成图形用户界面编程的工具包。

Swing是JAVA基础类的一部分。Swing包括了图形用户界面(GUI)器件如:文本框,按钮,分隔窗格和表。 Swing提供许多比AWT更好的屏幕显示元素。它们用纯Java写成,所以同Java本身一样可以跨平台运行。

AWT全称是抽象窗口工具集,AWT是一个窗口框架,它从不同平台的窗口系统中抽取共同组件,当使用AWT编写图形界面应用时,程序仅指定了界面组件的位置和行为,并未提供真正的实现,JVM 调用操作系统本地的图形界面来创建和平台一致的对等体。

JFrame:java的GUI程序的基本思路是以JFrame为基础,它是屏幕上window的对象,能够最大化、最小化、关闭。

JPanel :JavaGUI工具包swing中的面板容器类,可以进行嵌套,功能是对窗体中具有相同逻辑功能的组件进行组合,可以加入到JFrame窗体

JButton :用于创建按钮。
此外还有JLabel,JTextField等。

2.创建基本窗体

public void showUI() {JFrame jf = new JFrame();jf.setSize(880,800);jf.setTitle("五子棋1.1");jf.setLocationRelativeTo(null);//窗口将置于屏幕的中央jf.setDefaultCloseOperation(3);//点击关闭后直接关闭应用程序jf.setVisible(true);//窗体的基本结构BorderLayout flow = new BorderLayout();jf.setLayout(flow);//流式布局JPanel ePanel = new JPanel();ePanel.setPreferredSize(new Dimension(80,0));jf.add(ePanel, BorderLayout.EAST);//加入面板,放在窗体最东的位置JButton jbu = new JButton("开始");ePanel.add(jbu);//加入按钮jf.getContentPane().setBackground(Color.lightGray);//为棋盘设置背景板颜色方便区分}

3.绘制棋盘

对于棋盘的绘制,我们知道棋盘是由若干条线段横竖交错形成的,棋子落在棋盘交界处

在这里我们单独创建一个继承JFrame的MYFrame类用来绘制棋盘,设定好初始坐标,棋盘线数,棋子大小等参数之后我们重写paint()方法,通过super.paint(g);继承父类的方法,接着绘制棋盘即可

记得将GUI类创建窗体部分的JFrame改为MYFrame

public class MYFrame extends JFrame {public int X0 = 50 ,Y0 = 70 ,LINE = 15 ,SIZE = 50 ,CHESS  = 50;//X0,Y0为棋盘最左上角坐标,LINE为棋盘线条数,SIZE为线条间距,CHESS为棋子直径public void paint(Graphics g) {super.paint(g);//super关键字用来访问父类的构造方法、普通方法和属性    //下面为重写部分用来绘制棋盘棋子   for(int i = 0;i < LINE;i++) {g.setColor(Color.black);g.drawLine(X0, Y0 + i*SIZE, (LINE-1)*SIZE + X0, Y0 + i*SIZE);g.drawLine(X0 + i*SIZE, Y0,X0 + i*SIZE , (LINE - 1)*SIZE + Y0);}//绘制棋盘}

基本效果如下所示

4.绘制棋子

对于棋子的规划我们可以想象整个棋盘的所有交点位置对应一个二维数组,对于每下入一个棋子就将数组中元素进行更改,然后根据数字不同对应不同的颜色,将下列代码加入刚才创建的MYFrame类里

public int[][] chessArr;//此数组用于存放棋子坐标
     for(int i = 0;i < LINE;i++) {for(int j = 0;j < LINE;j++) {if(chessArr[i][j] == 1) {g.setColor(Color.BLACK);g.fillOval(i*SIZE + X0 - CHESS/2, j*SIZE + Y0 - CHESS/2, CHESS, CHESS);}if(chessArr[i][j] == 2) {g.setColor(Color.WHITE);g.fillOval(i*SIZE + X0 - CHESS/2, j*SIZE + Y0 - CHESS/2, CHESS, CHESS);}}}//绘制棋子,1对应黑棋,2对应白棋

有了以上内容GUI部分的绘制就基本完成了

二、监听器

1.下棋

对于五子棋的落子,我们要知道,每个棋子对应二维数组里的一格,在这里我们详细讲一下整个棋盘的划分。
首先整个窗体我们设定的大小为880800,880我们将其分为800+80,也就是说棋盘大小为800800,控制面板大小为80800用来添加按钮
然后,我们的棋盘设定为横竖15条线,每条间距为50,因而棋盘的实际占用面积为(15
50)(1550)=750*750,同样我们棋子的大小通过 fillOval()方法绘制,长短轴皆为50的圆,但要注意的是,这个方法绘制是从左上角开始,所以当我们点击是,生成的棋子圆心实在相对点击位置偏右下的,因此我们需要校准棋子的位置,使其合理的落在横竖线交点的位置上,此外我们需要将棋子存到一个chessArr数组里,为每次重绘做准备,记录黑棋为1,白棋为2

public void mouseClicked(MouseEvent e) {//以下内容为重写的mouseClicked方法int x = e.getX();int y = e.getY();//获取当前鼠标坐标if((x - X0)%SIZE>SIZE/2) {chessX = (x - X0)/SIZE + 1;}else {chessX = (x-X0)/SIZE;}if((y-Y0)%SIZE>SIZE/2) {chessY = (y-Y0)/SIZE + 1;}else {chessY = (y-Y0)/SIZE;}
}

这里的if-else语句的实际含义为,当鼠标点击到交点上下左右25位置之内将棋子的坐标修正在交点上

修正完鼠标点击的位置后,接下来我们需要考虑的是五子棋的基本下法是黑棋白棋交错下,所以这是我们引入一个计数参量s,每下一个棋s大小加1,当s是奇数时下黑棋,偶数时下白棋,同时s的计数还能为之后的悔棋操作提供标记

public void mouseClicked(MouseEvent e) {int x = e.getX();int y = e.getY();//获取当前鼠标坐标if((x - X0)%SIZE>SIZE/2) {chessX = (x - X0)/SIZE + 1;}else {chessX = (x-X0)/SIZE;}if((y-Y0)%SIZE>SIZE/2) {chessY = (y-Y0)/SIZE + 1;}else {chessY = (y-Y0)/SIZE;}//校准棋子位置if(chessArr[chessX][chessY] == 0) {if(s%2==0) {gr.setColor(Color.BLACK);gr.fillOval(chessX*SIZE+X0-CHESS/2, chessY*SIZE+Y0-CHESS/2, CHESS,CHESS);chessArr[chessX][chessY]=1;}else {gr.setColor(Color.WHITE);gr.fillOval(chessX*SIZE+X0-CHESS/2, chessY*SIZE+Y0-CHESS/2, CHESS,CHESS);chessArr[chessX][chessY]=2;}s++;System.out.println(s);    }}

基本实现效果如下:

2.输赢判断

当我们能够顺利的下棋以后,我们开始研究一下输赢判断的方法

我们知道,五子棋顾名思义,五颗棋子率先连成线即可取得胜利,落一颗子,旁边共有八个方向四条线,我们设置四个变量用来检测四条线上的相同棋子个数,从而判断输赢int counth = 0; int counts = 0; int countl = 0; int countr = 0;

最后将输赢判断的方法加入每次下棋的步骤里,每落一颗子进行一次检测
计数判定部分如下:

//水平垂直方向的判定for(int i = x+1;i<chessArr.length;i++) {if(chessArr[x][y] == chessArr[i][y]) {counth++;}else {break;}//向右检验}for(int i = x-1;i>0;i--) {if(chessArr[x][y] ==chessArr[i][y]) {counth++;}else {break;}//向左检验}for(int i = y+1;i<chessArr[0].length;i++) {if(chessArr[x][y] == chessArr[x][i]) {counts++;}else {break;}//向下检测}for(int i = y-1;i>0;i--) {if(chessArr[x][y] == chessArr[x][i]) {counts++;}else {break;}//向上检测}//斜方向的判定for(int i = x+1,j = y+1;i<chessArr.length&&j<chessArr[0].length;i++,j++) {if(chessArr[x][y] == chessArr[i][j]) {countr++;}else {break;}//右下检测}for(int i = x-1,j = y-1;i>0&&j>0;i--,j--) {if(chessArr[x][y] == chessArr[i][j]) {countr++;}else {break;}  //左上检测}for(int i = x+1,j = y-1;i<chessArr.length&&j>0;i++,j--) {if(chessArr[x][y] == chessArr[i][j]) {countl++;}else {break;}//右下检测}for(int i = x-1,j = y+1;i>0&&j<chessArr[0].length;i--,j++) {if(chessArr[x][y] == chessArr[i][j]) {countl++;}else {break;}//左下检测}

还是在本方法中,当计数大于等于五的时候,我们需要根据当前的落子检测是白棋获胜还是黑棋获胜,根据当前数组里的数字是1还是2即可判定

if(counth>=5||counts>=5||countr>=5||countl>=5){if(chessArr[x][y] == 1){System.out.println("BLACK WIN");//控制台输出javax.swing.JOptionPane.showMessageDialog(null, "BLACK WIN");//弹出窗口显示}else if(chessArr[x][y] == 2){System.out.println("WHITE WIN");javax.swing.JOptionPane.showMessageDialog(null, "WHITE WIN");}}

3.结束重绘

输赢判定完毕后,我们要做的就是将棋盘清空,方便进行下一场对局
这里我们首先在当前类里引入MYFrame对象,然后重写构造方法传递对象,接着,在刚才的win方法最后的判断输赢部分底部加入如下:

 chessArr=new int[LINE][LINE];//创建新数组jf.chessArr=chessArr;//清空MYFrame的数组jf.paint(gr);//重绘s = 0;//计数器置零

这时我们将win方法加入每一次落子的点击中就可以判断输赢了。

三、面板和特效

1.重开和悔棋

在这里列举两个按钮效果,作为参考
首先是重开,重开的原理十分简单,有些类似结束时的清空,我们只需要让他和按钮之间联系到一起就好
在这里我们用到接口ActionListener,ActionListener只有一个方法,我们在其中进行重写,使得点击的按钮对应相应的效果即可,下图是GUI类里添加按钮的部分

在创建两个按钮的效果之前,我们需要先

String name = e.getActionCommand();//获取点击的按钮上的字符System.out.println("name = "+name);//用于测试

接着进行判定即可

if("开始".equals(name)){//刷新棋盘chessArr=new int[LINE][LINE];//创建新数组jf.chessArr=chessArr;//清空MYFrame的数组jf.paint(gr);//重绘s = 0;//计数器置零}

这里就完成了刷新棋盘的操作
接下来是悔棋,对于悔棋我们采取的方法是,新建一个chessLo类,这个是一个一维数组,每个对象用来存放每颗棋子的横纵坐标(之前下棋都是鼠标坐标修正之后得到棋子坐标,chessArr里存放的是012用来区别棋子颜色的,这点需要注意一下)

public class chessLo {private int chessX;private int chessY;public chessLo(int x ,int y) {chessX = x;chessY = y;}public int getchessX() {return chessX;}public int getchessY() {return chessY;}}

在坐标修正之后将正确坐标存入:

接着悔棋时将刚下的棋子数据清空

if("悔棋".equals(name)){if(s>0) {s--;System.out.println(s);}if(index>0) {chessLo che = Chesslo[--index];//找到刚下完的那颗棋子chessX = che.getchessX();chessY = che.getchessY();chessArr[chessX][chessY] = 0;jf.chessArr = chessArr;jf.repaint();}}

到这里整个简易的五子棋框架就基本完善了,感兴趣的朋友可以增添更多的功能来来丰富内容

2.特效

我自己是写了两种比较简陋的效果
其一是将棋子写的略微具有3D的感觉,实际上是一个渐变的效果
其二就是红框用来辅助校准棋子的位置,图片里出了一点小bug,事后会修正

示例代码放在这:

//棋子渐变for(int i=0;i<LINE;i++) {for(int j=0;j<LINE;j++) {if(chessArr[i][j]==1) {for(int t=0;t<50;t++){gr.setColor(new Color(2*t, 2*t,2*t));//下棋子gr.fillOval(i*SIZE+X0-SIZE/2+t/2, j*SIZE+Y0-SIZE/2+t/2, SIZE-t, SIZE-t);}
//                              g.setColor(Color.BLACK);
//                              g.fillOval(i*SIZE+X0-SIZE/2, j*SIZE+Y0-SIZE/2, SIZE,SIZE);}}}
//红框效果,需要接入MouseMotionListener接口public void mouseMoved(MouseEvent e) {int x=e.getX();int y=e.getY();System.out.println(x);if(x>50&&y>70&&x<800&&y<820){if(x%SIZE>SIZE/2){x=x-(x%(SIZE/2));}else{x=x-SIZE/2-(x%(SIZE/2));}if(y%SIZE>SIZE/2){y=y-(y%(SIZE/2));}else{y=y-SIZE/2-(y%(SIZE/2));}if (x != chessX || y !=chessY){gr.setColor(Color.lightGray);gr.drawLine(chessX, chessY, chessX+5, chessY);gr.drawLine(chessX, chessY, chessX, chessY+5);gr.drawLine(chessX+45, chessY, chessX+50, chessY);gr.drawLine(chessX+50, chessY, chessX+50, chessY+5);gr.drawLine(chessX, chessY+45, chessX, chessY+50);gr.drawLine(chessX, chessY+50, chessX+5, chessY+50);gr.drawLine(chessX+45, chessY+50, chessX+50, chessY+50);gr.drawLine(chessX+50, chessY+45, chessX+50, chessY+50);chessX=x;chessY=y;for(int i=0;i<LINE;i++) {gr.setColor(Color.BLACK);gr.drawLine(X0, Y0+i*SIZE, (LINE-1)*SIZE+X0, Y0+i*SIZE);gr.drawLine(X0+i*SIZE, Y0, X0+i*SIZE, (LINE-1)*SIZE+Y0);}}gr.setColor(Color.red);gr.drawLine(x,y,x+5,y);gr.drawLine(x, y, x, y+5);gr.drawLine(x+45,y,x+50,y);gr.drawLine(x+50,y,x+50,y+5);gr.drawLine(x,y+45,x,y+50);gr.drawLine(x,y+50,x+5,y+50);gr.drawLine(x+45,y+50,x+50,y+50);gr.drawLine(x+50,y+45,x+50,y+50);}}

总结

这篇博客内容算是我做的第一个比较简单的小程序,总体上的难度并不大,敲过一遍后对于一些JAVA基础知识的运用更加的熟练,同时也让我学会了沉下心来思考问题,收获颇丰。

Java -五子棋游戏相关推荐

  1. Java五子棋游戏开发博客

    一.项目简介 五子棋是大家喜闻乐见的小游戏,规则很简单,但又变化多端,具有趣味性,可玩性很强.五子棋游戏程序可以让人们方便快捷的下五子棋,让人们可以随时通过下棋提高思维能力.功能如下:在点击鼠标时,可 ...

  2. java五子棋游戏源代码_Java实现五子棋游戏的完整代码

    用Java编写简单的五子棋,供大家参考,具体内容如下 前言 这两天在空闲时间做了个五子棋项目,分享给大家看一下,界面是这样的: 界面很丑我知道,本人虽有几年PS基础,但知识浅薄,审美观不尽人意,做到如 ...

  3. java五子棋游戏设计_基于Java的五子棋游戏的设计

    摘  要 五子棋作为一个棋类竞技运动,在民间十分流行,为了熟悉五子棋规则及技巧,以及研究简单的人工智能,决定用JAVA开发五子棋游戏.主要完成了人机对战和玩家之间联网对战2个功能.网络连接部分为Soc ...

  4. java五子棋游戏人工智能_基于java的五子棋游戏(人机对战)

    [实例简介] 我毕业设计自己做的基于java的五子棋游戏软件,获得优秀论文,功能在单纯的人机对战上算比较齐全,也比较好玩!希望为毕业设计做游戏的同学提供些查考! 软件的基本功能 软件的基本功能介绍如下 ...

  5. 【Java之五子棋】——java五子棋游戏

    基本思路: 1.先有一个界面可以弹出窗口,在界面上重写paint方法,在这个方法里加入棋盘,使得棋盘可以不断重绘,不会因为刷新而消失: 2.创建鼠标监听器,为了让鼠标监听器界面可以下黑白棋子: 3.再 ...

  6. 趣味java——五子棋游戏

    1.项目结构 2.项目截图 3.主要代码展示 import javax.sound.sampled.AudioInputStream; import javax.swing.*; import jav ...

  7. java五子棋游戏代码,已获万赞

    美团一面: 收到了HR的信息,通知我去面试,说实话真的挺紧张的.自己准备了近一个月的时间,很担心面试不过,到时候又后悔不该"裸辞". 自我介绍 spring的IOC,AOP原理 s ...

  8. Java面试题库,java五子棋游戏代码

    前言 最其实不管什么时候,找工作都跑不了面试.目前很多小编都做了面试手册了,那就是别人家的孩子都有糖了,作为一个自觉的小编,必须搞. 容我先絮叨一下,制作这个面试手册差不多花了3个多星期时间,过程还是 ...

  9. 基于java五子棋游戏

    开发工具:eclipse, jdk1.8 1.无禁手: 黑白双方依次落子,任一方先在棋盘上形成连续的五个(含五个以上)棋子的一方为胜. 2.有禁手:(走禁手就输,禁手不能落子) 鉴于无禁手规则黑棋必胜 ...

最新文章

  1. 解决zabbix-agent二进制班不能连接使用docker搭建的zabbix-server
  2. 手动创建数据库实例全攻略7:UNDO
  3. CodeForces - 888G Xor-MST(贪心+字典树+最小生成树)
  4. SAP Commerce Cloud UI 的用户会话管理
  5. 重构手法——提炼函数、搬移函数、以多态取代条件表达式
  6. 整数不少于12可以表示为两个复合数字的和
  7. Hash函数加密算法(一)
  8. 一次性口令php,Multi-OTP 4.2.2 发布,PHP 一次性密码管理
  9. 云迁移实践:VMware虚拟机迁移到华为云
  10. 什么是信息安全,怎么保障信息安全?
  11. 小红书探店流程有哪些?小红书探店博主如何联系?
  12. 苹果怎么换行打字_微信悄悄上线新功能!安卓苹果都有,很多人还不知道……...
  13. 管理客户信息并非易事
  14. 在MatLab中FFT和IFFT的互相转换
  15. HTTPHTTPS账号密码获取与ettercap局域网内DNS欺骗
  16. python 实现桌面壁纸自动更换
  17. python实现蓝桥杯真题:猜美国数学家维纳的年龄
  18. 【基础】《操作系统》学习笔记(B站王道考研)(1)
  19. 给希望成为游戏美术设计师的朋友
  20. 为什么要学习单片机?如何开始上手学习单片机?

热门文章

  1. nginx -s stop 出现问题 error pid
  2. 一款简单大气的系统维护html模板
  3. JLing中文语音对话机器人 -- 1、介绍
  4. 计算机性能过剩有什么影响,电脑性能过剩?你可能对够用这个词有些误解!
  5. New 21 Game 新21点
  6. 匈奴未灭,何以家为?
  7. 笔记56--listview之selector、listview中同一时刻只有一个item能被选中
  8. 如何在计算机中输入分数,两种方法在word中轻松输入分数
  9. golang+es 爬取网易云音乐评论
  10. python编辑视频字符化_Python 视频转字符画 - 进阶