程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(3)

五子棋2.0(Java)

发布于2020-11-19 20:32     阅读(711)     评论(0)     点赞(23)     收藏(5)


简介

相比之前,做出了以下修改:
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();
			}
		}
	}
}

原文链接:https://blog.csdn.net/qq_43533435/article/details/109764861



所属网站分类: 技术文章 > 博客

作者:java之恋

链接:http://www.javaheidong.com/blog/article/845/9895b87e911777b4fb17/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)