当前位置:首页 > 开发教程 > java教程 >

Java实现五子棋游戏(2.0)

时间:2022-04-26 09:32 来源:未知 作者:天大地 收藏

这篇文章主要为大家详细介绍了Java实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Java实现五子棋游戏的具体代码,供大家参考,具体内容如下

简介

相比之前,做出了以下修改:

1.新增菜单栏,将重新开始和退出的按钮移到了菜单栏;
2.可以实时显示时间(多线程);
3.下棋时可以显示当前是哪一方在下棋;
4.可以更改背景颜色;
5.可以更改先行方(默认黑子)。

结果

Java实现五子棋游戏(2.0)

Java实现五子棋游戏(2.0)

Java实现五子棋游戏(2.0)

完整代码

1.Frame.java(主界面)

package Gobang;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;

//import java.applet.*;
//import java.net.*;
//import java.io.*;
//import javax.imageio.*;
public class Frame extends JFrame implements MouseListener,ActionListener{//JFrame的扩展类
 
 //ImageIcon image;
 //JLayeredPane layeredPane;
 //JPanel jp;
 /*本来想用于播放背景音乐,但是没有成功,,,先暂时放弃
 File f;
 URI uri;
 URL url;
 @SuppressWarnings("deprecation")
 */
 private static final long serialVersionUID = 1L;
 public JButton AdmitDefeatButton,RegretButton;//两个按钮,各有其功能。
 JLabel TimeLabel;//用来显示时间
 JLabel jl1,jl2,jl3;//游戏信息
 Graphics g;//画笔
 BufferedImage buf;
 
 int x;//鼠标的坐标
 int y;
 int[][] Chess = new int[20][20];  // 保存棋子,1表示黑子,2表示白子
 boolean IsBlack = true;  //表示当前要下的是黑子还是白子,true表示黑子,false表示白子
 boolean IsFinish = false;  //表示当前游戏是否结束
 int xRange;
 int yRange;
 int[] chessX = new int[400];//用来保存从开始到当前的所有棋子,用于悔棋;
 int[] chessY = new int[400];
 int countX = 0;
 int countY = 0;
 
 
 //菜单栏
 JMenuBar menubar;
 JMenu menu;
 JMenu setmenu;
 JMenuItem RestartItem,ExitItem,IntroItem,BackgroundItem,FirstItem;
 
 //获取屏幕的宽度和高度
 Toolkit kit = Toolkit.getDefaultToolkit();
 Dimension screenSize = kit.getScreenSize();
 int screenWidth = screenSize.width;
 int screenHeight = screenSize.height;
 
 public Frame() {
  /*插入背景图片
  //layeredPane=new JLayeredPane();
  //image=new ImageIcon("F:\\JAVA\\eclipse-workspace\\Gobang\\src\\1.jpg");//随便找一张图就可以看到效果。
  //jp=new JPanel();
  //jp.setBounds(0,0,600,600);
  //jl=new JLabel(image);
  //jl.setBounds(0,0,image.getIconWidth(),image.getIconHeight());
  //jp.add(jl);
  //layeredPane.add(jp,JLayeredPane.DEFAULT_LAYER);
  //this.setLayeredPane(layeredPane);
  */
  
  /*音频播放部分
  try {
   f = new File("");
   uri = f.toURI();
   url = uri.toURL();
   AudioClip aau;
   aau = Applet.newAudioClip(url);
   aau.loop(); //循环播放
  } catch (Exception e)
  {
   e.printStackTrace();
  }
  */
  
  //设置标题、大小、排列方式等
  this.setTitle("五子棋");
  this.setSize(600,600);
  this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  this.setVisible(true);
  this.setLayout(null);
  int height = this.getHeight();
  int width = this.getWidth();
  this.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
  
  //实时显示时间,用到多线程来实时显示。
  jl1 = new JLabel("北京时间");
  jl1.setLocation(430, 120);
  jl1.setSize(80,20);
  this.add(jl1);
  TimeLabel = new JLabel();
  new Thread(new Time(TimeLabel)).start();//新建一个线程
  TimeLabel.setLocation(510, 120);
  TimeLabel.setSize(80,20);
  this.add(TimeLabel);
  
  //显示游戏信息,当前是谁执子;
  jl2 = new JLabel("游戏信息");
  jl2.setLocation(430, 150);
  jl2.setSize(80,20);
  jl3 = new JLabel("黑方先行");
  jl3.setLocation(510, 150);
  jl3.setSize(80,20);
  this.add(jl2);
  this.add(jl3);
  
  //设置背景颜色
  this.getContentPane().setBackground(new Color(255, 239 ,213));
  this.getContentPane().setVisible(true);
  
  //设置菜单栏
  menubar = new JMenuBar();//菜单栏
  menu = new JMenu("游戏操作");
  RestartItem = new JMenuItem("重新开始");
  ExitItem = new JMenuItem("退出");
  menu.add(RestartItem);
  menu.add(ExitItem);
  menubar.add(menu);
  setmenu = new JMenu("设置");
  IntroItem = new JMenuItem("游戏说明");
  BackgroundItem = new JMenuItem("背景颜色");
  FirstItem = new JMenuItem("先行方");
  setmenu.add(IntroItem);
  setmenu.add(BackgroundItem);
  setmenu.add(FirstItem);
  menubar.add(setmenu);
  menubar.setBackground(new Color(249,205,173));
  menubar.setVisible(true);
  this.setJMenuBar(menubar);
  
  //两个按钮,认输和悔棋;
  AdmitDefeatButton = new JButton("认输");
  AdmitDefeatButton.setSize(80,40);
  AdmitDefeatButton.setLocation(120, 480);
  RegretButton = new JButton("悔棋" );
  RegretButton.setSize(80,40);
  RegretButton.setLocation(240, 480);
  this.add(AdmitDefeatButton);
  this.add(RegretButton);
  
  
  /*
  五个按钮添加到中间容器;
  panel1 = new JPanel();
  panel1.setBorder(BorderFactory.createLoweredBevelBorder()); //设置边框
  panel1.setLayout(new GridLayout(1,5));
  panel1.add(RestartButton);
  panel1.add(SetButton);
  panel1.add(AdmitDefeatButton);
  panel1.add(RegretButton);
  panel1.add(ExitButton);
  this.add(panel1);
  panel1.setSize(460,30);
  panel1.setLocation(0, 460);
  */
  
  this.repaint();//表示重新绘制画布,可以自动调用paint函数;
  //本类作为监听类,包括鼠标监听和按钮动作监听;
  this.addMouseListener(this);
  IntroItem.addActionListener(this);
  BackgroundItem.addActionListener(this);
  FirstItem.addActionListener(this);
  RestartItem.addActionListener(this);
  AdmitDefeatButton.addActionListener(this);
  RegretButton.addActionListener(this);
  ExitItem.addActionListener(this);
 }
 //画布绘制
 public void paint(Graphics g)
 {
  if(g == null)//如果第一次绘制,新建一个图片,并且创建画布。
  {
   buf = new BufferedImage(450, 450, BufferedImage.TYPE_INT_RGB);
   g = buf.createGraphics();
  }
  if(g != null)//
  {
   super.paint(g);//表示在原来图像的基础上,再画图
   g.setColor(new Color(249,205,173));//画笔颜色调成褐色;
   g.fill3DRect(20, 130, 400, 400,true);//用画笔画一个边长为400的正方形;边距为20,130
   for(int i = 0; i <= 20; i++)//用画笔横竖各画19条线
   {
    g.setColor(Color.BLACK);//画笔颜色调为黑色;
    g.drawLine(20,130+i*20,420,130+i*20);
    g.drawLine(20+i*20,130,20+i*20,530);
   }
  }
   for(int i=0; i<20; i++){
    for (int j = 0; j < 20; j++) {
     //画实心黑子,直径16
     if(Chess[i][j] == 1){  
      int tempX = i*20+12;
      int tempY = j*20+122;
      g.setColor(Color.BLACK);
      g.fillOval(tempX, tempY, 16, 16);
      g.setColor(Color.BLACK);
      g.drawOval(tempX, tempY, 16, 16);
     }
     
     //画实心白子,直径16
     if(Chess[i][j] == 2){
      int tempX = i*20+12;
      int tempY = j*20+122;
      g.setColor(Color.WHITE);
      g.fillOval(tempX, tempY, 16, 16);
      g.setColor(Color.WHITE);
      g.drawOval(tempX, tempY, 16, 16);
     }
    }
   }
  g.drawImage(buf, 0, 0,this);
  
 }  

 public void mousePressed(MouseEvent e) {
  // TODO Auto-generated method stub
  
  if(!IsFinish) //判断棋局是否结束
  {
   x = e.getX(); //获取当前鼠标点击位置
   y = e.getY();
   if(x >= 20 && x < 420 && y >= 130 && y<= 530)//判断鼠标是否在棋局内
   {
    xRange = (x-20)%20;
    if(xRange > 10 && xRange < 20) //如果在交叉点的边长为10的范围内,就把棋子下在这;
    {
     x = (x - 20) / 20 + 1;
    }
    else
    {
     x = (x - 20) / 20;
    }
    yRange = (y-130)%20;
    if(yRange > 10 && yRange < 20)
    {
     y = (y - 130) / 20 + 1;
    }
    else
    {
     y = (y - 130) / 20;
    }
    
    if(Chess[x][y] == 0) //如果该交叉点没有被下过;
    {
     chessX[countX++] = x; //存储当前棋子的位置;
     chessY[countY++] = y;
     if(jl3.getText().equals("黑方先行"))   //如果是黑子
     {
      Chess[x][y] = 1;
      IsBlack = false;
      jl3.setText("白方先行");
     }
     else if(jl3.getText().equals("白方先行"))
     {
      Chess[x][y] = 2;
      IsBlack = true;
      jl3.setText("黑方先行");
     }
     this.repaint();//重新绘制画布
    }
    
    if(this.isWin())//如果下棋之后赢了,弹出对话框
    {
     if(Chess[x][y] == 1)
     {
      JOptionPane.showMessageDialog(this, "黑方胜利");
     }
     else
     {
      JOptionPane.showMessageDialog(this, "白方胜利");
     }
     this.IsFinish = true; //游戏结束
    }
    
   }
   

  }
 }
 
 public boolean isWin(){
  boolean flag = false;
  int count = 1;
  int color = Chess[x][y]; 
  //判断横向是否有5个棋子相连
  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;
 }
  // 检查棋盘中的五子棋是否连成五子,xChange,yChange为相对于当前棋子位置的变化量
 public int checkCount(int xChange , int yChange ,int color){
  int count = 1;//统计总共有几个连着的棋子;
  int tempX = xChange;
  int tempy = yChange; 
  //判断棋子右边有没有相同颜色的棋子;
  while(x + xChange >=0 && x+xChange <20 && y+yChange >=0 &&
    y+yChange < 20 && color == Chess[x+xChange][y+yChange])
  {
   count++;      //如果有,棋子数加一
   if(xChange != 0) 
    xChange++;      //如果横向方向变化,x相对位置加一
   if(yChange != 0 )    
   {   
    if(yChange != 0)   
    {
     if(yChange > 0)   //如果纵向方向增加,y相对位置加一
     { 
      yChange++;  
     }
     else      //如果纵向方向减小,y相对位置减一
     {
      yChange--;  
     }
    }
   }
   
  }
  xChange = tempX;
  yChange = tempy; 
  //判断棋子左边有没有相同颜色的棋子;
  while(x-xChange >=0 && x-xChange <20 && y-yChange >=0 &&
    y-yChange <20 && color == Chess[x-xChange][y-yChange])
  {  
   count++;
   if(xChange != 0)
   {
    xChange++;
   }
   if(yChange != 0)
   {
    if (yChange > 0)
    {
     yChange++;   
    }
    else
    {
     yChange--;   
    }
   }
  }
  return count;
 }
 //监听动作函数
 //@SuppressWarnings("deprecation")
 public void actionPerformed(ActionEvent e) {
  // TODO Auto-generated method stub
  
  if(e.getActionCommand()=="重新开始")//如果点击的按钮是RestartButton,清空画板,还原设置
  {
   if(JOptionPane.showConfirmDialog(this, "是否重新开始游戏") == 0)
   {
    for (int i = 0; i < 20; i++)
    {
     for (int j = 0; j < 20; j++)
     {
      Chess[i][j] = 0; //清空棋盘的棋子
     }
     
    }
    
    //清空下棋棋子坐标的记录
    for (int i = 0; i < 400; i++)
    {
     chessX[i] = 0;
     chessY[i] = 0;
    }
    countX =0;
    countY =0;
    IsBlack = true;
    jl3.setText("黑方先行");
    IsFinish = false;
    this.repaint();
   }
  }
  if(e.getSource() == AdmitDefeatButton)//如果点击的按钮是AdmitDefeatButton,结束游戏,并提示
  {
   if(!IsFinish) //判断棋局是否结束
   {
    if(JOptionPane.showConfirmDialog(this, "是否确定认输") == 0)
    {
     if(IsBlack == true)
     {
      JOptionPane.showMessageDialog(this,"白方获胜");
     }
     else
     {
      JOptionPane.showMessageDialog(this,"黑方获胜");
     }
     IsFinish = true;
    }
   }
  }
  if(e.getActionCommand()=="退出")//如果点击的按钮是ExitButton,退出程序
  {
   if(JOptionPane.showConfirmDialog(this, "是否确定退出") == 0)
   {
    System.exit(0);
   }
  }
  if(e.getSource() == RegretButton)///如果点击的按钮是RegretButton,悔棋一步
  {
   if(!IsFinish) //判断棋局是否结束
   {
   if(IsBlack == true) //如果现在是黑子要下,表示悔棋的是白子
   {
    if(JOptionPane.showConfirmDialog(this, "白方想要悔棋,是否同意") == 0)
    {
     int tempX = chessX[--countX]; //获取上一步白子下的位置;
     int tempY = chessY[--countY];
     Chess[tempX][tempY] = 0; //撤回白子
     IsBlack = false; //当前要下的变为白方
     jl3.setText("白方先行");
    }
   }
   else
   {
    if(JOptionPane.showConfirmDialog(this, "黑方想要悔棋") == 0)
    {
     int tempX = chessX[--countX];
     int tempY = chessY[--countY];
     Chess[tempX][tempY] = 0;
     IsBlack = true;
     jl3.setText("黑方先行");
    }
   }
   this.repaint(); //重新绘制画布
   }
  }
  if(e.getActionCommand()=="游戏说明")
  {
   JDialog frame1 = new JDialog();//新建对话框
   frame1.setSize(200,200);
   int height = frame1.getHeight();
   int width = frame1.getWidth();
   frame1.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
    JTextArea ta = new JTextArea();//新建文本框
     ta.setText("双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连线者获胜。");
    ta.setEditable(false);
     JScrollPane jsp = new JScrollPane(ta);
    frame1.setTitle("规则");
     frame1.getContentPane().add(jsp); //添加文本框
     frame1.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);  // 设置模式类型
     frame1.setVisible(true);
  }
  if(e.getActionCommand()=="背景颜色")
  {
   JDialog frame2 = new JDialog();//新建对话框
   frame2.setSize(150,200);
   int height = frame2.getHeight();
   int width = frame2.getWidth();
   frame2.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
   frame2.setLayout(new GridLayout(3,2,10,10));
   //三个文本框;
   JLabel label1 = new JLabel("Red");
   JLabel label2 = new JLabel("Green");
   JLabel label3 = new JLabel("Blue");
   JTextField tf1 = new JTextField("255");
   //tf1.setSize(80, 20);
   JTextField tf2 = new JTextField("239");
   //tf2.setBounds(10, 40, 80, 20);
   JTextField tf3 = new JTextField("213");
   //tf3.setBounds(10, 70, 80, 20);
   frame2.setTitle("设置背景颜色");
   frame2.getContentPane().add(label1);
    frame2.getContentPane().add(tf1); //
    frame2.getContentPane().add(label2);
    frame2.getContentPane().add(tf2);
    frame2.getContentPane().add(label3);
    frame2.getContentPane().add(tf3);      
    frame2.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);  // 设置模式类型
    frame2.setVisible(true);
    
    //改变背景颜色
    int Red =Integer.parseInt(tf1.getText());
    int Green =Integer.parseInt(tf2.getText());
    int Blue =Integer.parseInt(tf3.getText());
   this.getContentPane().setBackground(new Color(Red,Green,Blue));
   this.repaint();
  }
  if(e.getActionCommand() == "先行方") {
   new FirstDialog(IsBlack,jl3);//新建对话框,改变先行方
   
  }
 }
 public static void main(String[] args) {
  new Frame();
}
 @Override
 public void mouseClicked(MouseEvent e) {
  // TODO Auto-generated method stub
  
 }
 @Override
 public void mouseReleased(MouseEvent e) {
  // TODO Auto-generated method stub
  
 }
 @Override
 public void mouseEntered(MouseEvent e) {
  // TODO Auto-generated method stub
  
 }
 @Override
 public void mouseExited(MouseEvent e) {
  // TODO Auto-generated method stub
  
 }
}
//改变先行方
class FirstDialog extends JDialog implements ItemListener{

 /**
  *
  */
 private static final long serialVersionUID = 1L;
 Toolkit kit = Toolkit.getDefaultToolkit();
 Dimension screenSize = kit.getScreenSize();
 int screenWidth = screenSize.width;
 int screenHeight = screenSize.height;
 Boolean IsBlack;
 JLabel jl = new JLabel();
 JRadioButton rbWhite,rbBlack;

 FirstDialog(Boolean IsBlack,JLabel jl)
 {
  this.IsBlack = IsBlack;
  this.jl = jl;
  this.setSize(150,200);
  int height = this.getHeight();
  int width = this.getWidth();
  this.setLocation(screenWidth/2-width/2, screenHeight/2-height/2);
  this.setTitle("先行方");
  
  //一个单选组合;
  rbWhite = new JRadioButton("白子");
  rbBlack = new JRadioButton("黑子");
  this.setLayout(new FlowLayout());
  this.getContentPane().add(rbWhite);
  this.getContentPane().add(rbBlack); //
  ButtonGroup bgroup = new ButtonGroup();
  bgroup.add(rbWhite);
  bgroup.add(rbBlack);
  
  //本类做监听类
  rbWhite.addItemListener(this);
  rbBlack.addItemListener(this);
  this.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);  // 设置模式类型
   this.setVisible(true);
 }
 public void itemStateChanged(ItemEvent e) {
  if(rbWhite.isSelected())//选中白子时,将先行方设为白子;
  {
   IsBlack = false;
   jl.setText("白方先行");
  }
  else if(rbBlack.isSelected())
  {
   IsBlack = true;
   jl.setText("黑方先行");
  }
 }
 
}

2.Time.java(实时显示时间)

package Gobang;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.text.*;
public class Time implements Runnable{
 private JLabel lab = new JLabel();
 public Time(JLabel lab) {
  this.lab = lab;
 }
 public void run() {
  while(true) {
   SimpleDateFormat simpleFormat = new SimpleDateFormat("HH:mm:ss");
   Calendar c = Calendar.getInstance();
   lab.setText(simpleFormat.format(c.getTime()));
   lab.setForeground(Color.RED);
   try {
    Thread.sleep(1000);
   }catch(Exception e)
   {
    e.printStackTrace();
   }
  }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持源码搜藏网。


下一篇:没有了

java教程阅读排行

最新文章