当前位置: 首页 > news >正文

开发五子棋小游戏2.0

目录

效果展示

1、游戏界面

2、弹窗功能展示

功能改进

关键知识点

1】final关键字

2】将鼠标获取的坐标转化为行列值

3】保存已落的棋子实现不重复落子

代码展示

Data接口

MyFrame类继承JFrame类

Chess类

GoBangListener类实现MouseListener监听器

GoBangUI类

缺陷与不足


效果展示

1、游戏界面

2、弹窗功能展示

在正确区域落子

避免重复落子

功能改进

1、添加图片作为背景

2、创建接口定义行为规范,并使用final关键字修饰变量

3、结合变量思想优化设计棋盘的代码

4、解决无法固定在交叉点落子的问题

5、解决在区域外落子的问题

6、解决重复落子的问题

关键知识点

1】final关键字

final是最终的意思,可以修饰类、方法、变量

1)修饰类:该类被称为最终类,特点是不能被继承了

2)修饰方法:该类被称为最终方法,特点是不能再重写了

3)修饰变量:该变量只能赋值一次

2】将鼠标获取的坐标转化为行列值

先统一已知条件:

  • 棋盘起点像素:(X,Y)
  • 相邻交叉点像素间距:SIZE
  • c:列号;r:行号
  • 鼠标像素 (x,y)
  • (px,py):交叉点像素坐标

若只需让整数向下取整c = (x-X)/SIZE

推导:

第 r 行、第 c 列交叉点像素坐标公式(正向映射,绘图用):

{ px = X + c × SIZE
{py = Y + r × SIZE

现在需求: 已知鼠标像素 (x,y),求整数行列 c、r。

反向运算即可

而五子棋要求就近取整(即四舍五入),c = (x-X+SIZE/2)/SIZE

3】保存已落的棋子实现不重复落子

为了实现不重复落子,我们需要保存已落棋子的信息,并在每次落子前进行检查。以下是具体的实现步骤:

  1. 创建棋子类:创建一个类(如Chess),设置三个属性:行(row)、列(col)、颜色(color)。
  2. 创建存储数组:在外部创建一个数组,数组的类型就是你创建的棋子类,用于存储所有已落棋子的信息。
  3. 落子时保存数据:在落子成功时,创建一个棋子对象,将当前棋子的行、列、颜色数据保存到对象中,然后将该对象存入数组中。
  4. 落子前检查重复:在落子前,得到行列值之后,先在数组中查找一遍是否有相同行列值的对象存在:
    • 如果存在相同的行列值,说明该位置已有棋子,不能重复落子,直接return或给出提示。
    • 如果不存在,则允许落子,并执行后续的落子逻辑。

代码展示

Data接口
public interface Data { // interface 接口中的变量都是默认常量 并且可以使用接口名直接调用 // 任何一个类都可以实现多个接口 ,类实现接口之后,接口中定义的数据常量都可以直接使用 // 任何类都只能继承一个类 // final 修饰的变量必须初始化赋值 ,之后不能修改值 - 常量 final int X=50,Y=50,SIZE=40,ROW=15,COL=15; }
MyFrame类继承JFrame类
import javax.swing.*; import java.awt.*; public class MyFrame2 extends JFrame implements Data{ @Override public void paint(Graphics g) { super.paint(g); //设置背景图片 ImageIcon img = new ImageIcon("D:\\谢智宁\\其他\\编程入门\\图片素材\\3865cd33e305922fcebd3c28aa422396 (1).jpeg"); g.drawImage(img.getImage(),0,0,900,900,null); //绘制棋盘图 Color col = new Color(246, 149, 56); g.setColor(col); g.fillRect(X-SIZE/2,Y-SIZE/2,COL*SIZE,ROW*SIZE); //画线 Color col1 = new Color(0,0,0); g.setColor(col1); for(int i=0;i<COL;i++){ g.drawLine(X,Y+i*SIZE,X+(COL-1)*SIZE,Y+i*SIZE); g.drawLine(X+i*SIZE,Y,X+i*SIZE,Y+(ROW-1)*SIZE); } //画点 g.setColor(Color.black); g.fillOval(X+3*SIZE-5,Y+3*SIZE-5,10,10); g.fillOval(X+11*SIZE-5,Y+11*SIZE-5,10,10); g.fillOval(X+3*SIZE-5,Y+11*SIZE-5,10,10); g.fillOval(X+11*SIZE-5,Y+3*SIZE-5,10,10); g.fillOval(X+7*SIZE-5,Y+7*SIZE-5,10,10); } }
Chess类
import java.awt.*; public class Chess { int row; int col; Color color; }
GoBangListener类实现MouseListener监听器
import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import static xzn0723.Data.*; public class GoBangListener2 implements MouseListener { Graphics g; int chessColor = 1; int size = 0; //创建一个数组存储棋子的位置、颜色 Chess[] cs = new Chess[225]; public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e){ } public void mouseReleased(MouseEvent e){ //获取鼠标释放处的坐标值 int x = e.getX(); int y = e.getY(); //将坐标值通过算法转化为行列值 int c = (x-X+SIZE/2)/SIZE; int r = (y-Y+SIZE/2)/SIZE; //判断落子是否越界 if(x<X-SIZE/2||c>=COL||y<Y-SIZE/2||r>=ROW||c<0||r<0){ JOptionPane.showMessageDialog(null,"该区域无法落子!"); return; } //将行列值还原成坐标 int cx = c*SIZE+X; int ry = r*SIZE+Y; boolean a = false; for(int i=0;i<size;i++){ if(cs[i].col == c&&cs[i].row == r){ a = true; break; } } if(a==true){ JOptionPane.showMessageDialog(null,"无法重复落子!"); return; } //创建棋类对象,将棋子存储到数组中 Chess CS = new Chess(); CS.row = r; CS.col = c; cs[size]= CS; size++; //交替落子 if(chessColor == 1){ g.setColor(Color.black); chessColor = 2; }else if(chessColor == 2){ g.setColor(Color.white); chessColor = 1; } //绘制棋子 g.fillOval(cx-SIZE/2,ry-SIZE/2,SIZE,SIZE); } public void mouseEntered(MouseEvent e){ } public void mouseExited(MouseEvent e){ } }
GoBangUI类
import java.awt.*; public class GoBangUI2 { public void showUI(){ MyFrame2 myFrame = new MyFrame2(); myFrame.setTitle("五子棋2.0"); myFrame.setSize(850,800); myFrame.setDefaultCloseOperation(3); myFrame.setLocationRelativeTo(null); myFrame.setPreferredSize(null); myFrame.setVisible(true); //将鼠标监听器绑定在窗体上 GoBangListener2 gbl = new GoBangListener2(); myFrame.addMouseListener(gbl); gbl.g = myFrame.getGraphics();//将窗体中的画笔的地址传给监听器中成员变量g,使得该变量也可以使用画笔的方法 } static void main() { GoBangUI2 gbui = new GoBangUI2(); gbui.showUI(); } }

缺陷与不足

  • 窗口拖动、被遮挡、最小化之后,所有棋子全部消失。
  • 无法实现悔棋功能
  • 无法自动判断输赢

下篇博客,我来改进上述不足之处~

http://www.jsqmd.com/news/1272358/

相关文章:

  • 林伽一 · AI科技日报 | 6 款模型同日发布、AMD 50 亿砸向 Anthropic,开放权重运动迎来关键转折
  • 3BASiL-TM框架:大型语言模型高效压缩技术解析
  • TI TMS320C672x浮点DSP硬件设计实战:从电源时序到PCB布线的避坑指南
  • AI论文写作工具:从提纲生成到学术规范检查全解析
  • Docker 网络模式全解析:6 种驱动选型与生产环境避坑指南
  • 追觅扫地机器人:技术破局与娱乐化营销的双重突围
  • 2026亲测有效教程:档案要求TIFF格式照片怎么转 - 效率工具研究所
  • CNN-SVM混合模型在多特征分类中的应用实践
  • MySQL 存储过程详解:概念、创建与删除全教程
  • 密集型母线槽工程选型要点|导体材质、镀锡工艺如何影响长期运行稳定性
  • TMS320C645x DSP 64位定时器:模式、配置与实战指南
  • 深入解析TI C6000 DSP 64位定时器:架构、模式与实战应用
  • AI交互之AXI总线架构与DRM overlay
  • 2026 年汝州比较好的40*80镀锌偏凹槽管公司哪个好,别再乱买装修辅材,难怪你家吊顶总开裂——这玩意儿居然才是隐蔽工程的关键 - 品质体验官
  • 2026 年新发布:潜山靠谱的农田抗旱井定制厂家选型指南,干旱面前,这口井如何成为田地的“生命线”?-皖江打井钻井 - 行业推荐官【官方】
  • TMS320C6713 DSP硬件设计:从核心文档到PCB布局的实战指南
  • Unity引擎界面详解:从核心窗口到高效工作流搭建
  • C++段错误(Segmentation Fault)原理、排查与预防全指南
  • AM57xx硬件设计实战:USB、以太网、RTC与JTAG接口避坑指南
  • .NET 8构建与发布优化实践
  • 2026年最新教程:照片怎么改成JPG格式上传 亲测可用方法 - 图片处理研究员
  • 基于PyTorch与迁移学习的垃圾图像分类系统:从数据到API部署全流程实践
  • GS-Agent:构建4D物理仿真环境实现多智能体协作实践指南
  • AI编程微服务拆分的“最后一公里”难题:如何让领域专家+LLM+架构师三方对齐?3小时达成共识的协同协议
  • TI Sitara EMAC与MDIO寄存器配置实战:从原理到避坑指南
  • 固体氧化物燃料电池(SOFC)仿真建模与优化实践
  • 在 Ubuntu 上安装 Docker 并运行 DolphinScheduler
  • 2026年最新教程:报名照片必须是JPG怎么改?亲测有效的免费方法 - 效率工具研究所
  • 沈阳市防水补漏_2026严寒地区漏水维修价格与本地正规施工团队推荐 - 雨婺虹房屋维修
  • 大模型技术解析:从基础概念到Prompt工程与RAG应用