首先感谢08年MLDN出的这个培训视频,我把代码和文档整理了一下,发布出来给需要学习Swing的朋友。

源码地址:

https://gitee.com/indexman/gobang

一、知识点准备:

JFrame:窗体

JOptionPane:对话框

MouseListener:鼠标事件

Graphics:绘制二维图像

Thread:线程类

二、五子棋游戏的功能:

  1. 在点击鼠标时,可以在相应的位置显示棋子。
  2. 可以自动判断游戏是否结束,是否黑方或白方已经胜利
  3. 对游戏时间进行设置,判断是否超出规定时间

三、游戏开发步骤

1.开发游戏界面

计算棋盘中每一条线的间距:这里用的是19X19的围棋棋盘,

总宽度为360px, 分成18份,每份是20px

2.在棋盘上的鼠标点击位置,显示一个棋子

黑子:一个实心的黑圆表示

白子:一个空心的黑圆+一个实心的白圆表示

repaint() 方法表示重新执行一次paint()方法。

3.保存之前下过的棋子

通过一个二维数组来保存之前下过的所有棋子。

4.判断游戏胜负

依据 五子棋 的基本游戏规则,判断是否有同一颜色的棋子连城5个。

完成五子棋游戏的核心算法

这里可以把核心算法总结成一个灵活的方法。

提示信息的保存

5.处理屏幕闪烁问题

使用双缓冲技术

6.实现各个按钮的功能

开始游戏:重新开始游戏

游戏设置: 设置倒计时时间

游戏说明:用来说明游戏规则和操作

认输:某一方放弃游戏,投子认负

关于:显示游戏制作者

退出:退出程序

-----------------------------------------------------分割线------------------------------------------------------

四、代码部分

1.启动类

package com.laoxu.game;import com.laoxu.game.view.GobangFrame;
import com.laoxu.game.view.MyFrame;/*** Hello world!**/
public class App
{public static void main( String[] args ){GobangFrame frame = new GobangFrame();//MyFrame myFrame = new MyFrame();//JOptionPane/*JOptionPane.showMessageDialog(myFrame,"我的信息");int result = JOptionPane.showConfirmDialog(myFrame,"确定要开始游戏吗?","",0);if(result==0){JOptionPane.showMessageDialog(myFrame,"游戏开始");}if(result==1){JOptionPane.showMessageDialog(myFrame,"游戏结束");}if(result==2){JOptionPane.showMessageDialog(myFrame,"重新选择");}String username = JOptionPane.showInputDialog("请输入你的姓名:");System.out.println(username);JOptionPane.showMessageDialog(myFrame,"输入的姓名为:"+username);*///System.out.println(System.getProperty("user.dir")+"/src/image/background.jpg");}
}

2.五子棋类

package com.laoxu.game.view;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;/*** @description: 五子棋主界面* @author: luohanye* @create: 2019-03-21**/
public class GobangFrame extends JFrame implements MouseListener,Runnable {//获取当前平面分辨率,例如:1920x1080int swidth = Toolkit.getDefaultToolkit().getScreenSize().width;int sheight = Toolkit.getDefaultToolkit().getScreenSize().height;BufferedImage image = null;//保存坐标值int x = 0;int y = 0;//保存下过的棋子 0-没有棋子 1-黑子 2-白子int[][] allChess = new int[19][19];// 标识当前应该是黑子还是白子boolean isBlack = true;// 控制游戏是否可以玩boolean canPlay = true;// 保存游戏信息String message = "黑方先行";// 保存最多拥有多少时间(秒)int maxTime = 0;// 做倒计时的线程类Thread t = new Thread(this);// 保存黑方与白方的剩余时间int blackTime = 0;int whiteTime = 0;// 保存双方剩余时间的显示信息String blackMessage = "无限制";String whiteMessage = "无限制";public GobangFrame() {//设置标题this.setTitle("五子棋");int width = 500, height = 500;this.setSize(width, height);//设置窗体出现的位置this.setLocation((swidth - width) / 2, (sheight - height) / 2);//窗口大小不可变this.setResizable(false);//定义关闭动作this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//添加监听器this.addMouseListener(this);//窗体可见this.setVisible(true);//加载背景图片try {image = ImageIO.read(new File(System.getProperty("user.dir")+"/src/image/background.jpg"));} catch (IOException e) {e.printStackTrace();}// 启动线程t.start();t.suspend();// 刷新屏幕,防止开始游戏时出现无法显示的情况.this.repaint();}public void paint(Graphics g) {//双缓冲技术防止屏幕闪烁BufferedImage bi = new BufferedImage(500,500,BufferedImage.TYPE_INT_RGB);Graphics g2 = bi.createGraphics();g2.setColor(Color.BLACK);//绘制背景g2.drawImage(image, 0, 20, this);g2.setFont(new Font("黑体", Font.BOLD, 20));g2.drawString("游戏信息:"+message, 130, 60);//输出时间信息g2.setFont(new Font("宋体", 0, 14));g2.drawString("黑方时间:" + blackMessage, 30, 470);g2.drawString("白方时间:" + whiteMessage, 260, 470);//绘制棋盘/***          X=10 Y=70*         X=370 Y=430*         X=370 Y=70*         X=10 Y=430*/for (int i = 0; i < 19; i++) {g2.drawLine(10, 70 + 20 * i, 370, 70 + 20 * i);g2.drawLine(10 + 20 * i, 70, 10 + 20 * i, 430);}//标注点位g2.fillOval(68, 128, 4, 4);g2.fillOval(308, 128, 4, 4);g2.fillOval(308, 368, 4, 4);g2.fillOval(68, 368, 4, 4);g2.fillOval(68, 248, 4, 4);g2.fillOval(308, 248, 4, 4);g2.fillOval(188, 128, 4, 4);g2.fillOval(188, 368, 4, 4);g2.fillOval(188, 248, 4, 4);//绘制棋子for (int i = 0; i < 19; i++) {for (int j = 0; j < 19; j++) {//黑子if (allChess[i][j] == 1) {int tempX = i * 20 + 10;int tempY = j * 20 + 70;g2.fillOval(tempX - 7, tempY - 7, 14, 14);}//白子if (allChess[i][j] == 2) {int tempX = i * 20 + 10;int tempY = j * 20 + 70;g2.setColor(Color.WHITE);g2.fillOval(tempX - 7, tempY - 7, 14, 14);g2.setColor(Color.BLACK);g2.drawOval(tempX - 7, tempY - 7, 14, 14);}}}g.drawImage(bi,0,0,this);}//鼠标按键在组件上按下时调用。@Overridepublic void mousePressed(MouseEvent e) {System.out.println("X=" + e.getX() + " Y=" + e.getY());if (canPlay) {x = e.getX();y = e.getY();//判断点击是否在棋盘内if (x >= 10 && x <= 370 && y >= 70 && y <= 430) {x = (x - 10) / 20;y = (y - 70) / 20;if (allChess[x][y] == 0) {if (isBlack) {allChess[x][y] = 1;isBlack = false;message="轮到白方";} else {allChess[x][y] = 2;isBlack = true;message="轮到黑方";}//判断游戏是否结束boolean isWin = this.checkWin();if (isWin) {JOptionPane.showMessageDialog(this, "游戏结束,"+ (allChess[x][y] == 1 ? "黑方" : "白方") + "获胜!");canPlay = false;}}this.repaint();}}// 点击 【开始游戏】 按钮if(e.getX() >=400 && e.getX()<=470 && e.getY()>=70 && e.getY()<=100){int result = JOptionPane.showConfirmDialog(this,"是否重新开始游戏?","",0);if(result==0){//1.清空棋盘allChess = new int[19][19];//另一种方式:/*for (int i = 0; i < 19; i++) {for (int j = 0; j < 19; j++) {allChess[i][j] = 0;}}*///2.重置游戏信息message = "黑方先行";//3.将下一步下棋的人改为黑方isBlack = true;//4.可以游戏标志改为truecanPlay = true;//5.重置黑白双方时间限制blackTime = maxTime;whiteTime = maxTime;if (maxTime > 0) {blackMessage = maxTime / 3600 + ":"+ (maxTime / 60 - maxTime / 3600 * 60) + ":"+ (maxTime - maxTime / 60 * 60);whiteMessage = maxTime / 3600 + ":"+ (maxTime / 60 - maxTime / 3600 * 60) + ":"+ (maxTime - maxTime / 60 * 60);t.resume();} else {blackMessage = "无限制";whiteMessage = "无限制";}//6.重新绘制窗体this.repaint();}}//点击 【游戏设置】 按钮if (e.getX() >= 400 && e.getX() <= 470 && e.getY() >= 120&& e.getY() <= 150) {String input = JOptionPane.showInputDialog("请输入游戏的最大时间(单位:分钟),如果输入0,表示没有时间限制:");try {maxTime = Integer.parseInt(input) * 60;if (maxTime < 0) {JOptionPane.showMessageDialog(this, "请输入正确信息,不允许输入负数!");}if (maxTime == 0) {int result = JOptionPane.showConfirmDialog(this,"设置完成,是否重新开始游戏?");if (result == 0) {for (int i = 0; i < 19; i++) {for (int j = 0; j < 19; j++) {allChess[i][j] = 0;}}// 另一种方式 allChess = new int[19][19];message = "黑方先行";isBlack = true;blackTime = maxTime;whiteTime = maxTime;blackMessage = "无限制";whiteMessage = "无限制";this.canPlay = true;this.repaint();}}if (maxTime > 0) {int result = JOptionPane.showConfirmDialog(this,"设置完成,是否重新开始游戏?");if (result == 0) {for (int i = 0; i < 19; i++) {for (int j = 0; j < 19; j++) {allChess[i][j] = 0;}}// 另一种方式 allChess = new int[19][19];message = "黑方先行";isBlack = true;blackTime = maxTime;whiteTime = maxTime;blackMessage = maxTime / 3600 + ":"+ (maxTime / 60 - maxTime / 3600 * 60) + ":"+ (maxTime - maxTime / 60 * 60);whiteMessage = maxTime / 3600 + ":"+ (maxTime / 60 - maxTime / 3600 * 60) + ":"+ (maxTime - maxTime / 60 * 60);t.resume();this.canPlay = true;this.repaint();}}} catch (NumberFormatException e1) {JOptionPane.showMessageDialog(this, "请正确输入信息!");}}//点击 【游戏说明】 按钮if(e.getX() >=400 && e.getX()<=470 && e.getY()>=170 && e.getY()<=200){JOptionPane.showMessageDialog(this,"这是一个五子棋游戏程序,黑白双方轮流下棋,当某一方连到五子时游戏结束。");}//点击 【认输】 按钮if(e.getX() >=400 && e.getX()<=470 && e.getY()>=270 && e.getY()<=300){int result = JOptionPane.showConfirmDialog(this,"是否确认认输?","",0);if(result==0){if(isBlack){JOptionPane.showMessageDialog(this,"黑方已经认输,游戏结束!");}else{JOptionPane.showMessageDialog(this,"白方已经认输,游戏结束!");}//停止游戏canPlay = false;}}//点击 【关于】 按钮if(e.getX() >=400 && e.getX()<=470 && e.getY()>=320 && e.getY()<=350){JOptionPane.showMessageDialog(this,"本游戏由老徐制作,有问题请联系老徐。");}//点击 【退出】 按钮if(e.getX() >=400 && e.getX()<=470 && e.getY()>=370 && e.getY()<=400){JOptionPane.showMessageDialog(this,"游戏结束!");System.exit(0);}}private boolean checkWin() {boolean flag = false;//统计相连棋子数//横向int count = 1;int color = allChess[x][y];/*int i = 1;while (color == allChess[x + i][y]) {count++;i++;}i = 1;while (color == allChess[x - i][y]) {count++;i++;}if (count >= 5) {flag = true;}//竖向int count2 = 1;int i2 = 1;while (color == allChess[x][y+i2]) {count2++;i2++;}i2 = 1;while (color == allChess[x][y-i2]) {count2++;i2++;}if (count2 >= 5) {flag = true;}// 右上+左下int count3 = 1;int i3 = 1;while (color == allChess[x+i3][y-i3]) {count3++;i3++;}i3 = 1;while (color == allChess[x-i3][y+i3]) {count3++;i3++;}if (count3 >= 5) {flag = true;}// 左上+右下int count4 = 1;int i4 = 1;while (color == allChess[x-i4][y-i4]) {count4++;i4++;}i4 = 1;while (color == allChess[x+i4][y+i4]) {count4++;i4++;}if (count4 >= 5) {flag = true;}
*/      //判断横向count = this.checkCount(1,0,color);if(count>=5){flag = true;}else {//判断纵向count = this.checkCount(0,1,color);if(count>=5){flag = true;}else {//判断右上、左下count = this.checkCount(1, -1, color);if (count >= 5) {flag = true;} else {//判断右下、左上count = this.checkCount(1, 1, color);if (count >= 5) {flag = true;}}}}return flag;}private int checkCount(int xChange, int yChange, int color){int count = 1;int tempX = xChange;int tempY = yChange;while ((x+xChange>=0 && x+xChange <= 18 && y+yChange>=0 && y+yChange <= 18 )&&color == allChess[x+xChange][y+yChange]){count++;if(xChange != 0){xChange++;}if(yChange!=0){if(yChange>0){yChange++;}else {yChange--;}}}xChange = tempX;yChange = tempY;while ((x-xChange>=0 && x-xChange <= 18 && y-yChange>=0 && y-yChange <= 18 )&&color == allChess[x-xChange][y-yChange]){count++;if(xChange != 0){xChange++;}if(yChange!=0){if(yChange>0){yChange++;}else {yChange--;}}}return count;}@Overridepublic void run() {// 判断是否有时间限制if (maxTime > 0) {while (true) {if (isBlack) {blackTime--;if (blackTime == 0) {JOptionPane.showMessageDialog(this, "黑方超时,游戏结束!");}} else {whiteTime--;if (whiteTime == 0) {JOptionPane.showMessageDialog(this, "白方超时,游戏结束!");}}blackMessage = blackTime / 3600 + ":"+ (blackTime / 60 - blackTime / 3600 * 60) + ":"+ (blackTime - blackTime / 60 * 60);whiteMessage = whiteTime / 3600 + ":"+ (whiteTime / 60 - whiteTime / 3600 * 60) + ":"+ (whiteTime - whiteTime / 60 * 60);this.repaint();try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(blackTime + " -- " + whiteTime);}}}// 鼠标单击事件@Overridepublic void mouseClicked(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}
}

Java Swing实现五子棋程序相关推荐

  1. Java+Swing实现五子棋游戏

    目录 一.系统介绍 1.开发环境 2.技术选型 3.系统功能 二.系统展示 1.首页 2.黑棋走 3.白棋走 三.部分代码 AI.java Chess.java Gobang.java GobangL ...

  2. java swing开发窗体程序开发(三)事件(Mouse,Foucs,Key,Window)

    接着刚刚的事件讲 补充一点:事件的触发前提,添加了这个监听器的组件必须是处于激活状态的才可行 (一)MouseEvent事件 该事件的触发是由鼠标的动作引起的,引起的情况可以是下面5种,按下鼠标,释放 ...

  3. java swing开发窗体程序开发(四)MVC结构

    MVC是一种设计结构(非设计模式,非设计原则) M:Model 模型层:即用于存储数据的对象 V:View 视图层:即用于为模型提供数据显示的对象 C:Controller 控制器层:即处理用户的业务 ...

  4. java swing开发窗体程序开发(一)GUI编程

    Java SWing就是java提供的一个类库专门用于开发窗体程序的,相对于C#的winform,java swing的开发要比C#更加麻烦,他不像C#拥有可视化的界面编辑工具 而是需要像QT一样纯代 ...

  5. JNoteHelper 给你的java swing或桌面程序提供一双翅膀

    JNoteHelper 使用swing构建的java程序, 主要基于miglayout,swingx,flatlatf. 开发得初衷,只是打算作为个人笔记的助手, 因为基于java swing开发, ...

  6. Java swing 单机版五子棋

    一.此五子棋是基于java的swing开发,是单机版,源码见git:https://github.com/zhangliqingyun/FiveChess.git,先看效果图 二.功能介绍 1.首先建 ...

  7. Java swing写五子棋小游戏(分析)

    五子棋游戏开发 实现的功能 步骤实现代码分析 完整代码展示 实现的功能 五子棋,双方交互下,五字连珠即获胜 开始游戏,悔棋,认输,设置等选项 下方提示剩余时间,上方提示该谁下 效果图片展示如下 步骤实 ...

  8. java swing 聊天表情功能的实现(带完整代码)

    下载地址:https://gitee.com/zoyation/pic-chat 前言: 用java swing做聊天程序,可能是没事找事,也可能是大才小用,既然选择了就做吧 其中比较重要的功能可能就 ...

  9. Java Swing五子棋项目

    一.项目简介 本项目为Java Swing五子棋项目,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者. 包含:项目源码.数据库脚本等,该项目附带全部源码可作为毕设使用. 项 ...

最新文章

  1. 计算机网络·CSMA/CD协议有关计算
  2. 【BZOJ1031】[JSOI2007]字符加密Cipher 后缀数组
  3. mysql 5 可执行漏洞_漏洞预警:MySQL 0-day代码执行漏洞 可本地提权
  4. HUST 1541 Student’s question
  5. Exceptionless使用介绍
  6. vue-router 响应路由参数的变化
  7. 03-29 健壮性测试
  8. 学flash就丢人吗?
  9. idea怎么提交到dev分支_idea中新建git分支,并提交到远程github
  10. 免安装mysql配置图解_mysql免安装版配置步骤详解分享
  11. JS的IE和FF兼容性问题汇总
  12. 合并两个有序链表(Java)
  13. 妈妈帮上云之路:云上平台架构与运维实践
  14. 终止python程序的死循环_终的解释|终的意思|汉典“终”字的基本解释
  15. STP生成树/BPDU保护小实验
  16. win10+VS2012+opencv2.4.11的安装和配置
  17. SQL的LEN函数用法及实例
  18. docker容器内开启22 ssh_细述docker容器中创建SSH服务镜像
  19. API day02 IO流
  20. 安装java和scala语言开发环境

热门文章

  1. Hadoop 3的主要优缺点
  2. 【MySQL】MySQL如何合并多行数据,行转列,group_concat 多行合并
  3. ROS开发系列(7)- 在回调函数中发布topic
  4. Springboot橘子酒店管理系统eg48i计算机毕业设计-课程设计-期末作业-毕设程序代做
  5. rime切换全角标点和半角标点
  6. 互联网时代的产品战争
  7. 计算机能识别用户的物理身份,(完整版)劳顿管理信息系统习题集-第8章信息系统安全...
  8. 2023年留学基金委(CSC)青年骨干教师出国研修项目解读及建议
  9. 计算机学校大专最低录取分数线大专,2017广东大专学校分数
  10. 卓大师一键root权限图文教程(附卓大师刷机专家下载)