开发五子棋小游戏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)相邻交叉点像素间距SIZEc列号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-XSIZE/2)/SIZE3】保存已落的棋子实现不重复落子为了实现不重复落子我们需要保存已落棋子的信息并在每次落子前进行检查。以下是具体的实现步骤创建棋子类创建一个类如Chess设置三个属性行row、列col、颜色color。创建存储数组在外部创建一个数组数组的类型就是你创建的棋子类用于存储所有已落棋子的信息。落子时保存数据在落子成功时创建一个棋子对象将当前棋子的行、列、颜色数据保存到对象中然后将该对象存入数组中。落子前检查重复在落子前得到行列值之后先在数组中查找一遍是否有相同行列值的对象存在如果存在相同的行列值说明该位置已有棋子不能重复落子直接return或给出提示。如果不存在则允许落子并执行后续的落子逻辑。代码展示Data接口public interface Data { // interface 接口中的变量都是默认常量 并且可以使用接口名直接调用 // 任何一个类都可以实现多个接口 类实现接口之后接口中定义的数据常量都可以直接使用 // 任何类都只能继承一个类 // final 修饰的变量必须初始化赋值 之后不能修改值 - 常量 final int X50,Y50,SIZE40,ROW15,COL15; }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 i0;iCOL;i){ g.drawLine(X,Yi*SIZE,X(COL-1)*SIZE,Yi*SIZE); g.drawLine(Xi*SIZE,Y,Xi*SIZE,Y(ROW-1)*SIZE); } //画点 g.setColor(Color.black); g.fillOval(X3*SIZE-5,Y3*SIZE-5,10,10); g.fillOval(X11*SIZE-5,Y11*SIZE-5,10,10); g.fillOval(X3*SIZE-5,Y11*SIZE-5,10,10); g.fillOval(X11*SIZE-5,Y3*SIZE-5,10,10); g.fillOval(X7*SIZE-5,Y7*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-XSIZE/2)/SIZE; int r (y-YSIZE/2)/SIZE; //判断落子是否越界 if(xX-SIZE/2||cCOL||yY-SIZE/2||rROW||c0||r0){ JOptionPane.showMessageDialog(null,该区域无法落子); return; } //将行列值还原成坐标 int cx c*SIZEX; int ry r*SIZEY; boolean a false; for(int i0;isize;i){ if(cs[i].col ccs[i].row r){ a true; break; } } if(atrue){ 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(); } }缺陷与不足窗口拖动、被遮挡、最小化之后所有棋子全部消失。无法实现悔棋功能无法自动判断输赢下篇博客我来改进上述不足之处~