前言
在信息科技时代,开发一款用于休闲的五子棋游戏,既可以提升自己的编程能力,又可以作为开发项目的实战练习。
也许人们会说,现在市面上已经有很多相关的应用了,我们设计这个游戏还有什么用吗?但是仔细想想,面对这些市场上的五子棋游戏,我们似乎只能是体验者。但是它底层运作的逻辑我们一无所知,它到底是怎么运行这个步骤操作的?又是怎么实现想要的功能呢?
接下来我将用IntelliJ IDEA 2020.1编程JAVA语言教大家写一个用于休闲时间玩的五子棋游戏。
学 号 231
姓 名 福福
指导教师:赵
2021 年 12 月 26 日
1.1 设计要求
1.1.1 设计任务
使用JAVA面向对象程序设计语言,编写应用程序,能提供友好的的交互界面,完成管理、棋类、游戏类等应用功能设计。
1.1.2 性能指标要求
按照题目要求完成程序源码编写、调试及关键代码注释。
(4)具有悔棋、提示、时间设置、棋局保存等功能。
(5)具有落子音效、背景音乐、人机大战等功能。
1.2 设计思路及设计框图
1.2.1设计思路
(1)设计一个15X15围棋棋盘,由两玩家交替进行对战,并可以实现以下功能:
1.黑子先下
2.开始
3.悔棋
4.认输
(2)在游戏界面,有开始,悔棋,认输,以及棋盘名称和游戏信息;
(3)棋子分为黑白两色,棋盘为15X15,棋子放置于棋盘线交叉点上。两人对局,各执一色,轮流下一子,先将横、竖或斜线的5个同色棋子连成不间断的一排者为胜。
1.2.2总体设计框图
(1)实现开始按钮
//判断是否点击开始按钮
if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by && e.getY() < by + bh) {
//判断游戏是否开始
if (canplay == false) {
//如果游戏结束,则开始游戏
canplay = true;
JOptionPane.showMessageDialog(this, "游戏开始");
//初始化游戏
Initialize();
this.repaint();//重新执行一次paint方法
} else {
//如果游戏进行中,则重新开始
JOptionPane.showMessageDialog(this, "重新开始");
//初始化游戏
Initialize();
this.repaint();//重新执行一次paint方法
}
}
(2)实现悔棋按钮
//判断是否点击悔棋按钮
if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 60 && e.getY() < by + 60 + bh) {
//判断游戏是否开始
if (canplay == true) {
//遍历棋盘上是否有棋子
int z = 0;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
if (SaveGame[i][j] != 0) {
z++;
}
}
}
//判断是否有棋子
if (z != 0) {
JOptionPane.showMessageDialog(this, "愿赌服输!");
} else {
JOptionPane.showMessageDialog(this, "棋盘上已无棋子");
}
} else {
JOptionPane.showMessageDialog(this, "请先开始游戏");
}
}
(3)实现认输按钮
//判断是否点击认输按钮
if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 120 && e.getY() < by + 120 + bh) {
//判断游戏是否开始
if (canplay == true) {
//判断是谁认输
if (qc == 1) {
JOptionPane.showMessageDialog(this, "黑方认输,白方获胜");
canplay = false;
} else if (qc == 2) {
JOptionPane.showMessageDialog(this, "白方认输,黑方获胜");
canplay = false;
}
} else {
JOptionPane.showMessageDialog(this, "请先开始游戏");
}
}
}
(4)鼠标模块
@Override//鼠标抬起
public void mouseReleased(MouseEvent e) {
}
@Override//鼠标进入
public void mouseEntered(MouseEvent e) {
}
@Override//鼠标离开
public void mouseExited(MouseEvent e) {
}
(5)判断输赢
private boolean WinLose() {
boolean flag = false;//输赢
int count = 1;//相连数
int color = SaveGame[x][y];//记录棋子颜色
//判断横向棋子是否相连
int i = 1;//迭代数
while (color == SaveGame[x + i][y]) {
count++;
i++;
}
i = 1;//迭代数
while (color == SaveGame[x - i][y]) {
count++;
i++;
}
if (count >= 5) {
flag = true;
}
(6)弹出胜利对话框
boolean wl = this.WinLose();
if (wl) {
JOptionPane.showMessageDialog(this, "游戏结束," + (SaveGame[x][y] == 1 ? "黑方赢了" : "白方赢了"));//弹出提示对话框
canplay = false;
}
首先利用JAVA组件实现游戏主界面的设置和菜单的添加,先搞游戏的界面,再弄菜单栏,在面板中绘图。学会利用JAVA的输入输出类库和文件操作来完成文件的读写来完成保存进度和读取进度的功能。用JAVA的事件处理来完成鼠标,菜单的事件处理。用JAVA的类来生成棋子,再利用JAVA的动态数组ArrayList来存储棋子的坐标等等信息,然后建立一个15*15的矩阵来存储棋盘上黑白棋子的信息,初始值全为0,当白子或黑子有五个同时连在一起的时候则判黑子或白子一方的胜利。
4.1 测试仪器与设备
IntelliJ IDEA 2021.3软件
电脑 1台
4.2 性能指标测试
该款五子棋游戏功能简约单一,经过测试满足了开始、悔棋、认输等功能。
4.3 误差分析(某些题目需要)
经过这一次的java实训,我对本学期所学的java知识有了更深刻的了解,基础知识得到了巩固和应用,在设计五子棋的过程中我遇到了很到问题,在不断的查询资料和询问同学下还是很好的完成了。本次实训还让我懂得了写程序不能闭门造车,要努力拓宽知识面,要学会在网上查阅资料,看看别人做的优秀作品,增长自己的经验。由于自己的程序分析设计经验不足,五子棋运行的过程中,还有许多没有完善的地方,比如用户界面设计不够美观,悔棋步骤方式不太完美,游戏模式和内容比较单一,这些仍需自己努力学习和改进。
[1]张思民·java语言程序设计(第三版).清华大学出版社
[2]柳西玲.许斌编著. Java语言应用开发基础.清华大学出版社
[3]丁振凡Java语言实用教程.北京邮电大学出版社
附录
附录1:仿真波形图(部分模块)
(1)游戏界面
(2)游戏结果
链接:https://pan.baidu.com/s/1vN7T-XDcOKiOrj4MyvtBCA
提取码:1314
package aimn;
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;
import javax.sound.midi.*;
public class fufu extends JFrame implements MouseListener {
int qx = 20, qy = 40, qw = 490, qh = 490;//棋盘位置、宽高
int bw = 150, bh = 50, bx = 570, by = 150;//按钮宽高、位置
int x = 0, y = 0;//保存棋子坐标
int[][] SaveGame = new int[15][15];//保存每个棋子
int qc = 1;//记录白棋=2,黑棋=1
int qn = 0;//判断棋子是否重复
boolean canplay = true;//判断游戏是否开始和结束
String go = "黑子先行";//游戏信息
//---------------------------------------------------------------------------------------------------------------------
//窗体
public void fufu() {
this.setTitle("fufu五子棋"); //标题
this.setSize(800, 550); //窗口大小
this.setResizable(false); //窗口是否可以改变大小=否
this.setDefaultCloseOperation(fufu.EXIT_ON_CLOSE);//窗口关闭方式为关闭窗口同时结束程序
int width = Toolkit.getDefaultToolkit().getScreenSize().width;//获取屏幕宽度
int height = Toolkit.getDefaultToolkit().getScreenSize().height;//获取屏幕高度
// System.out.println("宽度:"+width);//测试
// System.out.println("高度:"+height);//测试
this.setLocation((width - 800) / 2, (height - 600) / 2); //设置窗口默认位置以屏幕居中
this.addMouseListener(this);
this.setVisible(true); //窗口是否显示=是
}
//---------------------------------------------------------------------------------------------------------------------
//覆写paint方法,绘制界面
public void paint(Graphics g) {
//双缓冲技术防止屏幕闪烁
BufferedImage bi = new BufferedImage(800, 550, BufferedImage.TYPE_INT_ARGB);
Graphics g2 = bi.createGraphics();
//获取图片路径
BufferedImage image = null;
try {
image = ImageIO.read(new File("D:/学习/java实训/xue/zhao1.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
g2.drawImage(image, 10, 10, this);//显示图片
g2.setColor(Color.red);//设置画笔颜色
g2.setFont(new Font("黑体", 10, 50));//设置字体
g2.drawString("福福五子棋", 525, 100);//绘制字符
//棋盘
g2.setColor(Color.getHSBColor(10, (float) 0.20, (float) 0.90));//设置画笔颜色
g2.fillRect(qx, qy, qw, qh);//绘制棋盘背景矩形
//开始按钮
g2.setColor(Color.WHITE);//设置画笔颜色
g2.fillRect(bx, by, bw, bh);//绘制开始按钮
g2.setFont(new Font("黑体", 10, 30));//设置字体
g2.setColor(Color.black);//设置画笔颜色
g2.drawString("开始", 615, 185);//绘制字符
//悔棋按钮
g2.setColor(Color.WHITE);//设置画笔颜色
g2.fillRect(bx, by + 60, bw, bh);//绘制悔棋按钮
g2.setFont(new Font("黑体", 10, 30));//设置字体
g2.setColor(Color.black);//设置画笔颜色
g2.drawString("悔棋", 615, 245);//绘制字符
//认输按钮
g2.setColor(Color.WHITE);//设置画笔颜色
g2.fillRect(bx, by + 120, bw, bh);//绘制认输按钮
g2.setFont(new Font("黑体", 10, 30));//设置字体
g2.setColor(Color.black);//设置画笔颜色
g2.drawString("认输", 615, 305);//绘制字符
//游戏信息栏
g2.setColor(Color.getHSBColor(30, (float) 0.10, (float) 0.90));//设置画笔颜色
g2.fillRect(550, 350, 200, 150);//绘制游戏状态区域
g2.setColor(Color.black);//设置画笔颜色
g2.setFont(new Font("宋体", 10, 20));//设置字体
g2.drawString("游戏信息", 610, 380);//绘制字符
g2.drawString(go, 610, 410);//绘制字符
g2.drawString("作者:福福", 610, 440);//绘制字符
g2.drawString("联系方式:182", 550, 465);//绘制字符
g2.setColor(Color.BLACK);//设置画笔颜色
//绘制棋盘格线
for (int x = 0; x <= qw; x += 35) {
g2.drawLine(qx, x + qy, qw + qx, x + qy);//绘制一条横线
g2.drawLine(x + qx, qy, x + qx, qh + qy);//绘制一条竖线
}
//绘制标注点
for (int i = 3; i <= 11; i += 4) {
for (int y = 3; y <= 11; y += 4) {
g2.fillOval(35 * i + qx - 3, 35 * y + qy - 3, 6, 6);//绘制实心圆
}
}
//绘制棋子
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
if (SaveGame[i][j] == 1)//黑子
{
int sx = i * 35 + qx;
int sy = j * 35 + qy;
g2.setColor(Color.BLACK);
g2.fillOval(sx - 13, sy - 13, 26, 26);//绘制实心圆
}
if (SaveGame[i][j] == 2)//白子
{
int sx = i * 35 + qx;
int sy = j * 35 + qy;
g2.setColor(Color.WHITE);
g2.fillOval(sx - 13, sy - 13, 26, 26);//绘制实心圆
g2.setColor(Color.BLACK);
g2.drawOval(sx - 13, sy - 13, 26, 26);//绘制空心圆
}
}
}
g.drawImage(bi, 0, 0, this);
// g.drawRect(20, 20, 20, 20);//绘制空心矩形
}
//---------------------------------------------------------------------------------------------------------------------
//判断输赢
private boolean WinLose() {
boolean flag = false;//输赢
int count = 1;//相连数
int color = SaveGame[x][y];//记录棋子颜色
//判断横向棋子是否相连
int i = 1;//迭代数
while (color == SaveGame[x + i][y]) {
count++;
i++;
}
i = 1;//迭代数
while (color == SaveGame[x - i][y]) {
count++;
i++;
}
if (count >= 5) {
flag = true;
}
//判断纵向棋子是否相连
count = 1;
i = 1;//迭代数
while (color == SaveGame[x][y + i]) {
count++;
i++;
}
i = 1;//迭代数
while (color == SaveGame[x][y - i]) {
count++;
i++;
}
if (count >= 5) {
flag = true;
}
//判断斜向棋子是否相连(左上右下)
count = 1;
i = 1;//迭代数
while (color == SaveGame[x - i][y - i]) {
count++;
i++;
}
i = 1;//迭代数
while (color == SaveGame[x + i][y + i]) {
count++;
i++;
}
if (count >= 5) {
flag = true;
}
//判断斜向棋子是否相连(左下右上)
count = 1;
i = 1;//迭代数
while (color == SaveGame[x + i][y - i]) {
count++;
i++;
}
i = 1;//迭代数
while (color == SaveGame[x - i][y + i]) {
count++;
i++;
}
if (count >= 5) {
flag = true;
}
return flag;
}
//---------------------------------------------------------------------------------------------------------------------
//初始化游戏
public void Initialize() {
//遍历并初始化数组
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
SaveGame[i][j] = 0;
}
}
//黑子先行
qc = 1;
go = "轮到黑子";
}
//---------------------------------------------------------------------------------------------------------------------
@Override//鼠标点击
public void mouseClicked(MouseEvent e) {
}
@Override//鼠标按下
public void mousePressed(MouseEvent e) {
//获取鼠标点击位置
x = e.getX();
y = e.getY();
//判断是否已开始游戏
if (canplay == true) {
//判断点击是否为棋盘内
if (x > qx && x < qx + qw && y > qy && y < qy + qh) {
//计算点击位置最近的点
if ((x - qx) % 35 > 17) {
x = (x - qx) / 35 + 1;
} else {
x = (x - qx) / 35;
}
if ((y - qy) % 35 > 17) {
y = (y - qy) / 35 + 1;
} else {
y = (y - qy) / 35;
}
//判断当前位置有没有棋子
if (SaveGame[x][y] == 0) {
SaveGame[x][y] = qc;
qn = 0;
} else {
qn = 1;
}
//切换棋子
if (qn == 0) {
if (qc == 1) {
qc = 2;
go = "轮到白子";
} else {
qc = 1;
go = "轮到黑子";
}
}
this.repaint();//重新执行一次paint方法
//弹出胜利对话框
boolean wl = this.WinLose();
if (wl) {
JOptionPane.showMessageDialog(this, "游戏结束," + (SaveGame[x][y] == 1 ? "黑方赢了" : "白方赢了"));//弹出提示对话框
canplay = false;
}
// System.out.println(1);//测试
} else {
// System.out.println(0);//测试
}
}
//实现开始按钮
//判断是否点击开始按钮
if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by && e.getY() < by + bh) {
//判断游戏是否开始
if (canplay == false) {
//如果游戏结束,则开始游戏
canplay = true;
JOptionPane.showMessageDialog(this, "游戏开始");
//初始化游戏
Initialize();
this.repaint();//重新执行一次paint方法
} else {
//如果游戏进行中,则重新开始
JOptionPane.showMessageDialog(this, "重新开始");
//初始化游戏
Initialize();
this.repaint();//重新执行一次paint方法
}
}
//实现悔棋按钮
//判断是否点击悔棋按钮
if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 60 && e.getY() < by + 60 + bh) {
//判断游戏是否开始
if (canplay == true) {
//遍历棋盘上是否有棋子
int z = 0;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
if (SaveGame[i][j] != 0) {
z++;
}
}
}
//判断是否有棋子
if (z != 0) {
JOptionPane.showMessageDialog(this, "愿赌服输!");
} else {
JOptionPane.showMessageDialog(this, "棋盘上已无棋子");
}
} else {
JOptionPane.showMessageDialog(this, "请先开始游戏");
}
}
//实现认输按钮
//判断是否点击认输按钮
if (e.getX() > bx && e.getX() < bx + bw && e.getY() > by + 120 && e.getY() < by + 120 + bh) {
//判断游戏是否开始
if (canplay == true) {
//判断是谁认输
if (qc == 1) {
JOptionPane.showMessageDialog(this, "黑方认输,白方获胜");
canplay = false;
} else if (qc == 2) {
JOptionPane.showMessageDialog(this, "白方认输,黑方获胜");
canplay = false;
}
} else {
JOptionPane.showMessageDialog(this, "请先开始游戏");
}
}
}
@Override//鼠标抬起
public void mouseReleased(MouseEvent e) {
}
@Override//鼠标进入
public void mouseEntered(MouseEvent e) {
}
@Override//鼠标离开
public void mouseExited(MouseEvent e) {
}
}