Java实现五子棋游戏(2.0)
本文实例为大家分享了Java实现五子棋游戏的具体代码,供大家参考,具体内容如下
简介
相比之前,做出了以下修改:
1.新增菜单栏,将重新开始和退出的按钮移到了菜单栏;
2.可以实时显示时间(多线程);
3.下棋时可以显示当前是哪一方在下棋;
4.可以更改背景颜色;
5.可以更改先行方(默认黑子)。
结果
完整代码
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(); } } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
X 关闭
X 关闭