java五子棋游戏
zzyyyxxxx 人气:0一、主要界面
1、登录界面;2、游戏选择界面;3、五子棋下棋界面
它们间的逻辑关系为先通过登录界面登录跳转到游戏选择界面,再通过游戏选择界面进入到五子棋下棋界面。
二、功能概况
1、登录界面:
a、设置一定的布局和添加一些组件;b、通过点击登录按钮判断账号和密码是否正确,正确则成功登录,反之则弹出一个提示账号或密码输入错误的窗口;c、在窗口中添加一个按钮,在点击此按钮后关闭当前窗口,并在第三次输入错误后弹出提示并关闭登录界面
2、游戏选择界面:a、添加背景图片;b、在背景面板上添加游戏选择的按钮;c、通过游戏选择按钮跳转到相应的游戏。
3、五子棋下棋界面:
(1)画出一个16*16的棋盘
(2)黑白棋实现轮流落子,落子位置在交叉点上,并且同一位置只能落一子
(3)黑白落子计数器
(4)重绘功能,在拖动改变窗体大小时保留之前的棋盘棋子及计数显示
(5)按钮:开始游戏,重新开始,悔棋,棋局回放,存档,读档,退出游戏等功能
(6)判断输赢,当且仅当五颗同色的棋子连在一起时得胜,当出现六颗及以上同色棋子相连时不算得胜
三、代码部分
1.GoBangUI类:
import javax.swing.*; //导入swing包的所有类和接口 import java.awt.*; //导入awt包的所有类和接口 //登录密码:123 账号:123 public class GoBangUI extends JFrame implements GoBangConfig { private static final Image bgimg = new ImageIcon("C:\\Users\\zyx\\Pictures\\Camera Roll\\17.jpeg").getImage(); Font f=new Font("楷体", Font.PLAIN, 30);//楷体,常规,30号字体 //主函数入口 public static void main(String[]args) { Login cx=new Login(); cx.UI(); } int[][] Array=new int[16][16];//实例化一个二维数组的对象来存储棋子信息,0表示无棋,1表示黑棋,2表示白棋;在我们未给定初值的情况下,会默认初值为0 public void initGobangUI(){ this.setTitle("五子棋"); this.setSize(1200,850);// 设置窗体的大小,单位为像素 this.setLocationRelativeTo(null);//设置窗体相对于组件的居中位置,null表示窗体相对于屏幕的中央位置 this.setDefaultCloseOperation(3); // 设置窗体的关闭操作 Dimension dm1=new Dimension(200,0);//设置JPanel的大小 Dimension dm2=new Dimension(140,50);//设置JButton的大小 Dimension dm3=new Dimension(170,110);//设置JLabel的大小 JPanel jp=new JPanel(); jp.setBackground(Color.lightGray);//设置面板JPanel的背景色 jp.setPreferredSize(dm1); this.add(jp,BorderLayout.EAST);//通过边框布局将面板添加到窗体的右边 JLabel jl=new JLabel(" "); jl.setPreferredSize(dm3); jp.add(jl); String[] name= {"开始游戏","重新开始","悔棋","棋局回放","存档","读档","退出游戏"}; JButton[] button=new JButton[7]; //依次把五个按钮组件加上去 for(int i=0;i<name.length;i++) { button[i]=new JButton(name[i]); button[i].setPreferredSize(dm2); jp.add(button[i]); } //设置窗体的背景颜色 Container con=this.getContentPane(); con.setBackground(Color.darkGray) ; this.setVisible(true); // 从当前窗体获取画笔并通过构造方法传入监听类对象中 Graphics gr=this.getGraphics(); GoBangListener goBangListener = new GoBangListener(gr); //给按钮组件添加动作监听方法 for(int i=0;i<name.length;i++) { button[i].addActionListener(goBangListener); } // 给窗体添加鼠标监听方法 this.addMouseListener(goBangListener); goBangListener.go=this; } @Override public void paint(Graphics g) { // 先调用父类绘制窗体的方法 super.paint(g); //绘制背景图片 g.drawImage(bgimg,X,Y,columns*SIZE,rows*SIZE,null); // 绘制棋盘 for (int i = 0; i <= rows; i++) { g.drawLine(X,Y+i*SIZE,X+columns*SIZE,Y+i*SIZE);//画横线 } for(int j=0;j<=columns;j++) { g.drawLine(X+j*SIZE,Y,X+j*SIZE,Y+rows*SIZE);//画竖线 } //黑白棋的落子数 g.setColor(Color.darkGray); g.fillRect( X*2+columns*SIZE, Y*11/4,SIZE*5/2, 3*SIZE); g.setColor(Color.ORANGE); g.setFont(f); g.drawString("黑棋:"+GoBangListener.m, 2*X+columns*SIZE, Y*10/3); g.drawString("白棋:"+GoBangListener.n, 2*X+columns*SIZE,Y*13/3); g.setFont(f);//设置字体 //遍历二维数组,画出已赋值的对应位置的黑白棋 for(int j=0;j<=columns;j++) { for(int i=0;i<=rows;i++) { if(Array[i][j]==1) { g.setColor(Color.BLACK); g.fillOval(j*SIZE+X-SIZE/2, i*SIZE+Y-SIZE/2, SIZE, SIZE); }else if(Array[i][j]==2){ g.setColor(Color.WHITE); g.fillOval(j*SIZE+X-SIZE/2, i*SIZE+Y-SIZE/2, SIZE, SIZE); } } } } }
2.GoBangListener类:
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.ActionListener; import javax.swing.*; public class GoBangListener implements ActionListener,MouseListener,GoBangConfig { int chessX; //列索引 int chessY; //行索引 int flag=0; //黑白棋轮流标记 int count=0; //记录落子顺序 int ct,flag1,m1,n1,q,w; //用作存档操作 GoBangUI go; String name; String name1=""; //用于开始游戏操作 JTextField jt; JPasswordField jp; JFrame jf; JFrame j = new JFrame(); JFrame j1 = new JFrame(); int i=3; //允许登录失败的次数 static int m=0,n=0; //记录黑白各自的落子数 private Graphics g; public GoBangListener() {} GoBangListener(Graphics g) { this.g=g; } GBstore[] gbs=new GBstore[16*16]; //储存棋子的落子顺序和位置信息 public void actionPerformed(ActionEvent e) { name=e.getActionCommand(); if(e.getActionCommand().equals("退出游戏")) { j.dispose(); j1.dispose(); go.dispose(); } if(e.getActionCommand().equals("开始游戏")) { name1=e.getActionCommand(); }else { if(e.getActionCommand().equals("重新开始")|e.getActionCommand().equals("再来一局")) { w=count; count=0; m=0; n=0; flag=0; for(i=0;i<w;i++) { go.Array[gbs[count+i].chessy][gbs[count+i].chessx]=0; } j.dispose(); j1.dispose(); go.repaint(); } if(e.getActionCommand().equals("悔棋")) { if(count!=0) { if(flag==0) { go.Array[gbs[count-1].chessy][gbs[count-1].chessx]=0; n--; go.repaint(); count--; flag++; }else if(flag==1) { go.Array[gbs[count-1].chessy][gbs[count-1].chessx]=0; go.repaint(); m--; count--; flag--; } }} if(e.getActionCommand().equals("棋局回放")) { if(gbs[count]!=null) { if(flag==0) { go.Array[gbs[count].chessy][gbs[count].chessx]=1; m++; go.repaint(); count++; flag++; }else if(flag==1) { go.Array[gbs[count].chessy][gbs[count].chessx]=2; go.repaint(); n++; count++; flag--; } }} if(e.getActionCommand().equals("存档")) { flag1=flag; ct=count; m1=m; n1=n; } if(e.getActionCommand().equals("读档")) { q=count-ct; count=ct; m=m1; n=n1; if(flag!=0) { flag=0; } for(int i=0;i<count;i++) { if(flag==0) { go.Array[gbs[i].chessy][gbs[i].chessx]=1; flag++; }else if(flag==1) { go.Array[gbs[i].chessy][gbs[i].chessx]=2; flag--; }} for(i=0;i<q;i++) { go.Array[gbs[count+i].chessy][gbs[count+i].chessx]=0; } flag=flag1; go.repaint(); } } if(name.equals("登录")) { if(jt.getText().equals("123")&&jp.getText().equals("123")) { GameselectUI ui=new GameselectUI(); ui.selectUI(); jf.dispose(); } else if(i>1) { JFrame lg1 = new JFrame(); lg1.setSize(400,200); lg1.setDefaultCloseOperation(3); lg1.setLocationRelativeTo(null); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); Dimension dm = new Dimension(0,50); JLabel jl = new JLabel("账号或密码输入错误,您还有"+(i-1)+"次机会"); jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体 jp2.add(jl); jp1.setPreferredSize(dm); lg1.add(jp1,BorderLayout.NORTH); lg1.add(jp2,BorderLayout.CENTER); lg1.add(jp3,BorderLayout.SOUTH); JButton jb = new JButton("确定"); jp3.add(jb); lg1.add(jp3,BorderLayout.SOUTH); jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {lg1.dispose();}}); lg1.setVisible(true); }else if(i==1) { JFrame lg1 = new JFrame(); lg1.setSize(400,200); lg1.setDefaultCloseOperation(3); lg1.setLocationRelativeTo(null); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); Dimension dm = new Dimension(0,50); JLabel jl = new JLabel("账号已锁定"); jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体 jp1.setPreferredSize(dm); jp2.add(jl); lg1.add(jp1,BorderLayout.NORTH); lg1.add(jp2,BorderLayout.CENTER); lg1.add(jp3,BorderLayout.SOUTH); JButton jb = new JButton("确定"); jp3.add(jb); lg1.add(jp3,BorderLayout.SOUTH); lg1.setVisible(true); jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {lg1.dispose();jf.dispose(); }}); jf.dispose(); } i--; }else if(name.equals("注册")) { JFrame lg1 = new JFrame(); lg1.setSize(400,200); lg1.setDefaultCloseOperation(3); lg1.setLocationRelativeTo(null); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); Dimension dm = new Dimension(0,50); JLabel jl = new JLabel("注册功能暂未开放..."); jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体 jp1.setPreferredSize(dm); jp2.add(jl); lg1.add(jp1,BorderLayout.NORTH); lg1.add(jp2,BorderLayout.CENTER); lg1.add(jp3,BorderLayout.SOUTH); JButton jb = new JButton("确定"); jp3.add(jb); lg1.add(jp3,BorderLayout.SOUTH); lg1.setVisible(true); jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {lg1.dispose(); }}); } } @Override public void mouseClicked(MouseEvent e) { if(name1.equals("开始游戏")) { int x=e.getX(); int y=e.getY(); Font f=new Font("楷体", Font.PLAIN, 30); //楷体,常规,30号 // 限制下棋的范围 if((x>=X&&x< X+columns*SIZE)&&(y>Y&&y<Y+rows*SIZE)){ // 赋值坐标 chessX = (x-X+SIZE/2)/SIZE; //列索引 chessY = (y-Y+SIZE/2)/SIZE; //行索引 if(go.Array[chessY][chessX]!=0) { //Array[][] arr=new Array[一维数组的个数(行数)][一维数组中元素的个数(列数)] System.out.println("此处已有棋子"); }else { //轮到黑方下棋 if(flag==0) { m++; g.setColor(Color.BLACK); g.fillOval(chessX*SIZE+X-SIZE/2, chessY*SIZE+Y-SIZE/2, SIZE, SIZE); flag++; //实现黑子计数 g.setColor(Color.darkGray); g.fillRect( X*2+columns*SIZE, Y*11/4, SIZE*5/2, SIZE); g.setColor(Color.ORANGE); g.setFont(f); g.drawString("黑棋:"+m, 2*X+columns*SIZE, Y*10/3); go.Array[chessY][chessX]=1; GBstore gb=new GBstore(chessX,chessY); gbs[count]=gb;//传递相应顺序对应的行列索引值 count++; //判断输赢 if(Judge.blackjudge(go.Array,chessY, chessX)){ j1.setSize(400,200); j1.setDefaultCloseOperation(3); j1.setLocationRelativeTo(null); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); Dimension dm = new Dimension(0,50); JLabel jl = new JLabel("恭喜黑棋获胜"); jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体 jp2.add(jl); jp1.setPreferredSize(dm); j1.add(jp1,BorderLayout.NORTH); j1.add(jp2,BorderLayout.CENTER); j1.add(jp3,BorderLayout.SOUTH); JButton jb = new JButton("回顾棋局"); jp3.add(jb); JButton jb1 = new JButton("再来一局"); jp3.add(jb1); j1.add(jp3,BorderLayout.SOUTH); jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {j1.dispose();}}); jb1.addActionListener(this); j1.setResizable(false); j1.setVisible(true); } }else { //轮到白方下棋 n++; g.setColor(Color.WHITE); g.fillOval(chessX*SIZE+X-SIZE/2, chessY*SIZE+Y-SIZE/2, SIZE, SIZE); flag--; g.setColor(Color.darkGray); g.fillRect( 2*X+columns*SIZE, Y*15/4, SIZE*5/2, SIZE); g.setColor(Color.ORANGE); g.setFont(f); g.drawString("白棋:"+n, 2*X+columns*SIZE,Y*13/3); go.Array[chessY][chessX]=2; GBstore gb=new GBstore(chessX,chessY); gbs[count]=gb; count++; if(Judge.whitejudge(go.Array,chessY, chessX)){ j.setSize(400,200); j.setDefaultCloseOperation(3); j.setLocationRelativeTo(null); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); Dimension dm = new Dimension(0,50); JLabel jl = new JLabel("恭喜白棋获胜"); jl.setFont(new Font("华文仿宋",Font.BOLD,18)); //华文仿宋,加粗,18号字体 jp2.add(jl); jp1.setPreferredSize(dm); j.add(jp1,BorderLayout.NORTH); j.add(jp2,BorderLayout.CENTER); j.add(jp3,BorderLayout.SOUTH); JButton jb = new JButton("回顾棋局"); jp3.add(jb); JButton jb1 = new JButton("再来一局"); jp3.add(jb1); j.add(jp3,BorderLayout.SOUTH); jb.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e) {j.dispose();}}); jb1.addActionListener(this); j.setResizable(false); j.setVisible(true); } } } } }} @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } }
3.GoBangConfig类:
public interface GoBangConfig { /** * 间距|尺寸 */ int SIZE=50; /** * 棋盘左上角 X坐 标 */ int X=40; /** * 棋盘左上角 Y 坐 标 */ int Y=65; /** * 棋盘的行列值 */ int rows=15; int columns=15; }
4.GBstore类:
/* * 储存棋子的位置信息 */ public class GBstore { int chessx,chessy; GBstore(int chessx,int chessy){ this.chessx=chessx; this.chessy=chessy; } }
5.GameselectUI类:
import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class GameselectUI extends JFrame { public void selectUI(){ JFrame j=this; //绑定当前窗体 this.setTitle("Game selection UI");//设置标题 j.setSize(370,400); ImageIcon img=new ImageIcon("C:\\Users\\zyx\\Pictures\\Camera Roll\\2.jpg"); BackgroundPanel bgp=new BackgroundPanel(img.getImage()); bgp.setSize(370,400); this.setDefaultCloseOperation(3); this.setLocationRelativeTo(null); Dimension d = new Dimension(370,190); //通过设置标签调整按钮位置,JPanel面板默认使用流式布局 Dimension dim = new Dimension(100,60);//设置按钮的大小 this.add(bgp);//给当前窗体添加背景面板 JLabel jl=new JLabel(); jl.setPreferredSize(d); bgp.add(jl); JButton gbbt1 = new JButton("五子棋"); Font f=new Font("华文仿宋",Font.BOLD,18);//字体:华文仿宋;字形:加粗;字号:18 gbbt1.setFont(f); gbbt1.setPreferredSize(dim); bgp.add(gbbt1); //添加按钮到面板上 JLabel jla=new JLabel(""); jla.setPreferredSize(new Dimension(100,60)); bgp.add(jla); JButton drbt2 = new JButton("待定"); drbt2.setFont(f); drbt2.setPreferredSize(dim); bgp.add(drbt2); //设置入口 ActionListener al=new ActionListener() {public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("五子棋")) { GoBangUI gb=new GoBangUI(); gb.initGobangUI(); j.dispose(); }else if(e.getActionCommand().equals("待定")) { } }};//添加监听方法 gbbt1.addActionListener(al); drbt2.addActionListener(al); this.setResizable(false); //设置不可调整窗体大小 GameselectUI.this.setVisible(true); //设置窗体可见 } } class BackgroundPanel extends JPanel{ Image img; BackgroundPanel(Image img){ this.img=img; } //重写paintComponent方法画出背景图 public void paintComponent(Graphics g){ super.paintComponents(g); System.out.println(); g.drawImage(img,0,0,370,400,this); } }
6.Login类:
import javax.swing.*; import java.awt.*; public class Login { public void UI() { javax.swing.JFrame jf= new javax.swing.JFrame(); jf.setSize(370, 505); jf.setDefaultCloseOperation(3); jf.setTitle("登录界面"); jf.setLocationRelativeTo(null); java.awt.FlowLayout fl= new java.awt.FlowLayout(); jf.setLayout(fl); Dimension di=new Dimension(360,360); javax.swing.ImageIcon image= new javax.swing.ImageIcon("D:\\360Downloads\\1.jpg"); javax.swing.JLabel jl=new javax.swing.JLabel(image); jl.setPreferredSize(di); jf.add(jl); javax.swing.JLabel zh=new javax.swing.JLabel("账号"); jf.add(zh); javax.swing.JTextField jtf=new javax.swing.JTextField(); Dimension dm=new Dimension(300,30); jtf.setPreferredSize(dm); jf.add(jtf); javax.swing.JLabel mm=new javax.swing.JLabel("密码"); jf.add(mm); java.awt.Dimension d=new java.awt.Dimension(300,30); JPasswordField wb=new JPasswordField(); wb.setPreferredSize(d); jf.add(wb); JButton button=new JButton("登录"); jf.add(button); javax.swing.JButton zc=new javax.swing.JButton("注册"); jf.add(zc); jf.setResizable(false); jf.setVisible(true); GoBangListener gl=new GoBangListener(); button.addActionListener(gl); zc.addActionListener(gl); gl.jt=jtf; gl.jp=wb; gl.jf=jf; } }
7.Judge类:
public class Judge { //黑棋胜负判断 public static boolean blackjudge(int[][] Array,int chessY,int chessX) { int count1=0,count2=0,count3=0,count4=0; //横向遍历 for(int i=-15;i<=15;i++) { if(chessX+i>=0&&chessX+i<=15) { //确定遍历的范围 if(count1<5) { if(Array[chessY][chessX+i]==1) { count1++; }else { count1=0; } }else if(count1==5) { if(Array[chessY][chessX+i]==1) { count1++; }}}} //纵向遍历 for(int i=-15;i<=15;i++) { if(chessY+i>=0&&chessY+i<=15) { if(count2<5) { if(Array[chessY+i][chessX]==1) { count2++; }else { count2=0; } }else if(count2==5) { if(Array[chessY+i][chessX]==1) { count2++; }}}} //斜下遍历 for(int i=-15;i<=15;i++) { if(chessY+i>=0&&chessY+i<=15&&chessX+i>=0&&chessX+i<=15) { if(count3<5) { if(Array[chessY+i][chessX+i]==1) { count3++; }else { count3=0; } }else if(count3==5) { if(Array[chessY+i][chessX+i]==1) { count3++; }}}} //斜上遍历 for(int i=-15;i<=15;i++) { if(chessY-i>=0&&chessY-i<=15&&chessX+i>=0&&chessX+i<=15) { if(count4<5) { if(Array[chessY-i][chessX+i]==1) { count4++; }else { count4=0; } }else if(count4==5) { if(Array[chessY-i][chessX+i]==1) { count4++; }}}} if(count1==5|count2==5|count3==5|count4==5) { return true; } return false; } //白棋胜负判断 public static boolean whitejudge(int[][] Array,int chessY,int chessX) { int count1=0,count2=0,count3=0,count4=0; //横向遍历 for(int i=-15;i<=15;i++) { if(chessX+i>=0&&chessX+i<=15) { if(count1<5) { if(Array[chessY][chessX+i]==2) { count1++; }else { count1=0; } }else if(count1==5) { if(Array[chessY][chessX+i]==2) { count1++; }}}} //纵向遍历 for(int i=-15;i<=15;i++) { if(chessY+i>=0&&chessY+i<=15) { if(count2<5) { if(Array[chessY+i][chessX]==2) { count2++; }else { count2=0; } }else if(count2==5) { if(Array[chessY+i][chessX]==2) { count2++; }}}} //斜下遍历 for(int i=-15;i<=15;i++) { if(chessY+i>=0&&chessY+i<=15&&chessX+i>=0&&chessX+i<=15) { if(count3<5) { if(Array[chessY+i][chessX+i]==2) { count3++; }else { count3=0; } }else if(count3==5) { if(Array[chessY+i][chessX+i]==2) { count3++; }}}} //斜上遍历 for(int i=-15;i<=15;i++) { if(chessY-i>=0&&chessY-i<=15&&chessX+i>=0&&chessX+i<=15) { if(count4<5) { if(Array[chessY-i][chessX+i]==2) { count4++; }else { count4=0; } }else if(count4==5) { if(Array[chessY-i][chessX+i]==2) { count4++; }}}} if(count1==5|count2==5|count3==5|count4==5) { return true; } return false; } }
四、部分效果展示
注意,代码中图片的路径还需自己更改设置
加载全部内容