admin 管理员组

文章数量: 1087817

五子棋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,130for(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++) {//画实心黑子,直径16if(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);}//画实心白子,直径16if(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 stubif(!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 stubif(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();
}@Overridepublic void mouseClicked(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseReleased(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseEntered(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic 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();}}}
}

本文标签: 五子棋20(Java)