五子棋小游戏

本文详细描述了一个五子棋项目的实现过程,涉及客户端窗口搭建、游戏规则按钮功能、信息交互与发送,以及服务器窗口的设计。通过代码片段展示了如何连接服务器、处理输入和聊天,以及判断输赢的功能。项目体现了团队协作和前后端交互的技术应用。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

简单五子棋小游戏


提示:以下是本篇文章正文内容,下面案例可供参考

一、项目简介

连接服务器与客户端,实现两端之间的交互,实现局域网下的联机五子棋小游戏。可以实现服务器与客户端的聊天功能。

二、功能构架图

构架图

三、负责模块

团队成员负责模块
禹程客户端窗口的搭建,鼠标监听器的添加,游戏按钮的添加和相应功能的实现,输入、聊天等功能的添加
梁钊实现客户端与服务器的信息交流,对接收到的信息进行不同情况处理
孙文博服务器窗口的搭建,棋盘棋子的绘制,判断输赢等游戏规则的编写

四、部分代码

1、窗口的搭建

public class ClientWindow extends JFrame{
	public static ClientChessBoard qipan;
	ClientChat talk = new ClientChat();;
	public ClientWindow(){
		qipan = new ClientChessBoard(); 
		this.setSize(1150, 550);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//EXIT_ON_CLOSE(在JFrame中定义:使用System exit方法退出应用程序,仅在应用程序中使用)
		this.setTitle("五子棋客户端");
		this.add(qipan,BorderLayout.CENTER); 
		this.add(talk,BorderLayout.WEST);
		this.setVisible(true);
		}
}

2、游戏规则按钮功能的添加

public class ClientChessBoard extends JPanel {

	public ClientChessBoard() {
		sendmessage = new Send_message(message, ClientChat.socket);// 创建一个对象,并且实例化
		this.setLayout(null);
		JButton ks = new JButton("开始/暂停");
		ks.setBounds(10, 460, 100, 25);
		ks.setBackground(Color.cyan);
		this.add(ks);
		
		JButton rs = new JButton("认输");
		rs.setBounds(115, 460, 80, 25);
		rs.setBackground(Color.cyan);
		this.add(rs);
		
		JButton ht = new JButton("后退");
		ht.setBounds(200, 460, 80, 25);
		ht.setBackground(Color.cyan);
		this.add(ht);
		
		JButton cxks = new JButton("重新开始");
		cxks.setBounds(290, 460, 100, 25);
		cxks.setBackground(Color.cyan);
		this.add(cxks);
		

		try {
			board = ImageIO.read(new File("img/board.gif"));
			black = ImageIO.read(new File("img/black.gif"));
			white = ImageIO.read(new File("img/white.gif"));
		} catch (IOException e) {
			//e.printStackTrace();
		}
		// 下棋位置
		MouseAdapter mouse = new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				if (ClientChat.connect) {
					if (isgamestart) {
						 // 将鼠标点的位置赋值给全局变量
						xiaqie = e;
						getmouse(xiaqie);
					} else {
						ClientChat.chatArea.append("\n系统消息:双方至少有一方没有开始游戏");
					}
				} else {
					JOptionPane.showMessageDialog(null, "还没连接服务器!!");
				}

			}

		};
		//开始
		MouseAdapter start = new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				if (ClientChat.connect) {
					myselfok = true; 
					message = "ANNIU" + "-" + "CLIENT" + "-" + "START";
					sendmessage.send(message, ClientChat.socket);// 发送消息给对方说自己准备好了
					if (!duifangok) {
						ClientChat.chatArea.append("\n系统消息:对方还没有准备好,请等待对方开始游戏");
					} 
					else if (duifangok) {
						isgamestart = true;
						ClientChat.chatArea.append("\n系统消息:双方准备就绪,游戏即将开始,对方先下,请等待");
					}

				} else {
					ClientChat.chatArea.append("\n系统消息:请先连接服务器!");
				}
			}
		};
		MouseAdapter renshu = new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				if (ClientChat.connect) {
					if (isgamestart) {
						myself_list.clear();
						duifang_list.clear();
						message = "ANNIU" + "-" + "CLIENT" + "-" + "TOUXIANG";
						sendmessage.send(message, ClientChat.socket);
						repaint();
					} 
					else {
						ClientChat.chatArea.append("\n系统消息:你还没开始游戏");
					}
				} 
				else {
					ClientChat.chatArea.append("\n系统消息:你还没有连接服务器");
				}
			}
		};

		this.addMouseListener(mouse);
		ks.addMouseListener(start); // 开始按钮与鼠标相连
		rs.addMouseListener(renshu);// 认输按钮与鼠标相连
		ht.addMouseListener(houtui); // 后退按钮与鼠标相连
		cxks.addMouseListener(chongxinkaishi);// 重新开始按钮与鼠标相连
	}

	//获取鼠标位置 保存鼠标位置到数集
	public void getmouse(MouseEvent e) {
		if (!ismyselfxiaqi && isduifangxiaqi) {
			int x = e.getX();
			int y = e.getY();
			getx = (x - 18) / 25;// 减去边距,除以格子的宽度,取整,得到第几格子
			gety = (y - 18) / 25;
			if ((x - 18) % 25 > 12)
				getx = getx + 1;
			if ((y - 18) % 25 > 12)
				gety = gety + 1;
			if (!myself_list.contains(getx + "," + gety)&& !duifang_list.contains(getx + "," + gety)) {
				myself_list.add(getx + "," + gety);// 把格子的x坐标和y坐标变成字符串用逗号连接,保存到list里面
				
				ismyselfxiaqi = true;// 自己下完了就不能下,要等对方下了之后才能下
				isduifangxiaqi = false; 
				message = "XIAQI" + "-" + getx + "," + gety + "-" + "CLIENT";
				sendmessage.send(message, ClientChat.socket);// 将下的棋子发送给对方
			}
			repaint();
			if (myself_list.size() > 5)
				//调用判断胜负方法
				baipanduan();
			
		}
	}

	

3.输入、聊天等功能的添加

public class ClientChat extends JPanel {
	ClientChessBoard qipan;
	public static boolean connect = false;                                                                              
	static TextArea chatArea; // 所有消息内容区域
	public static Socket socket; // 连接服务器
	private String message = ""; // 要发送给服务器的内容
	Send_message sendmessage; // 发送的方法
	private String who = "客户端说:";
	private JTextField txt_message; // 将要发送给服务器的内容
	private JTextField serverip; // 服务器的IP地址
	public ClientChat() {
		socket =new Socket();
		sendmessage = new Send_message(message, socket);
		chatArea = new TextArea("聊天窗口\n", 20, 40);//聊天窗口
		txt_message = new JTextField("请输入要发送的信息");
		serverip = new JTextField("10.186.190.14");
		JButton jb_connectserver = new JButton("连接服务器");
		JButton jb_send = new JButton("发送");
		MouseAdapter connect = new MouseAdapter() {
		public void mouseClicked(MouseEvent e) {
				if (connectserver()) {
					JOptionPane.showMessageDialog(null, "成功连接服务器");
					// 客户端连接服务器后才打开线程
					Recive_thred rth = new Recive_thred(socket, chatArea,ClientWindow.qipan);
					rth.start();
					sendmessage.send(message, socket);
				}
			}

		};
		// 给服务器发送消息按钮
		MouseAdapter send = new MouseAdapter() {
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				chatArea.append("\n客户端说:" + txt_message.getText());
				message = "CHANT" + "-" + who + txt_message.getText() + "\n";
				sendmessage.send(message, socket);
			}
		};
		this.add(serverip);
		this.add(jb_connectserver);
		jb_connectserver.addMouseListener(connect);	
		this.add(chatArea);
		this.add(txt_message);
		this.add(jb_send);
		jb_send.addMouseListener(send);

	}
	//连接服务器
	public boolean connectserver() {
		try {
			// 获取输入的IP地址,并且进行连接
			socket = new Socket(serverip.getText(), 7778);
			chatArea.append("\n连接服务器成功!");
			connect = true;
			return true;
		} catch (UnknownHostException e) {
			//e.printStackTrace();
		} catch (IOException e) {
			//e.printStackTrace();
			chatArea.append("\n连接失败");
		}
		return false;
	}

}

4、信息交互

public class Recive_thred extends Thread {
	private Socket socket;
	TextArea chantArea;
	String who; 
	String[] split;
	int xianxing = 1;
	JPanel jp = new JPanel();

	public Recive_thred(Socket socket, TextArea chantArea, JPanel jp) {
		this.socket = socket;
		this.chantArea = chantArea;
		this.jp = jp;
	}
	public void run() {
		super.run();
		InputStream is;
		try {
			is = socket.getInputStream();
			BufferedReader reader = new BufferedReader(
					new InputStreamReader(is));
			while (true) {
				String m = reader.readLine();
				split = m.split("-");
				// 聊天控制
				if (split[0].equals("CHANT")) {
					//System.out.println(split[1]);
					if (split[1].equals("OK")) {
						chantArea.append("\n" + split[2]);
						ServerWindow.clientconnect = true;
					} else {
						chantArea.append("\n" + split[1]);
					}

				} else if (split[0].equals("ANNIU")) {
					anniucontrol();
				}

				else if (split[0].equals("XIAQI"))//
				{
					System.out.println("到下棋来了");
					// 下棋控制
					who = split[2]; 
					xiaqicontrol();

				}
			}
		} catch (IOException e) {
			//e.printStackTrace();
		}

	}

	
	 //按钮控制
	public void anniucontrol() {

		if (split[1].equals("SERVER")) {
			// 收到是从服务器发过来启动的消息,要对客户端里面进行修改
			if (split[2].equals("START")) {
				ClientChessBoard.duifangok = true;
				if (ClientChessBoard.myselfok) {
					ClientChessBoard.isgamestart = true;
					ClientChat.chatArea.append("\n---系统消息:两方准备就绪,服务器先下---");
				}
				jp.repaint();
			}
			// 服务器投降
			if (split[2].equals("TOUXIANG")) {

				ClientChat.chatArea.append("\n---系统消息:对方已经投降,恭喜你赢了---");
				JOptionPane.showMessageDialog(null, "恭喜您,对面怂得投降了!");
				// 清除黑棋白棋
				ClientChessBoard.myself_list.clear();
				ClientChessBoard.duifang_list.clear();
				ClientChessBoard.isgamestart = false;
				jp.repaint();

			}
			// 服务器悔棋
			if (split[2].equals("HUIQI")) {
				ClientChessBoard.duifang_list.remove(ClientChessBoard.duifang_list.get(ClientChessBoard.duifang_list.size() - 1));// 后退
				ClientChat.chatArea.append("\n---系统消息:对方毁了一步棋!---");
				ClientChessBoard.isduifangxiaqi = false;
				ClientChessBoard.ismyselfxiaqi = true;
				jp.repaint();

			}
			// 服务器重新开始
			if (split[2].equals("CHONGXINLAI")) {
				ClientChat.chatArea.append("\n---系统消息:对方要求重新开始!---");
				JOptionPane.showMessageDialog(null, "对方要求开始,确认就清除所有数据,重新开始");
				ClientChessBoard.myself_list.clear();
				ClientChessBoard.duifang_list.clear();
				ClientChessBoard.isgamestart = false;
				ClientChessBoard.myselfok = true;
				ClientChessBoard.duifangok = false;
				jp.repaint();
			}

		} else if (split[1].equals("CLIENT")) {
			// 客户端开始
			if (split[2].equals("START")) {
				ServerChessBoard.isduifangxiaqi = true;
				//System.out.println("线程里面,服务器从客户端收到按下开始按钮");
				ServerChessBoard.duifangok = true;
				if (ServerChessBoard.myselfok) {
					ServerChessBoard.isgamestart = true;
					ServerChat.chantArea.append("\n---系统提示:对方准备就绪,游戏开始了,请服务器先下");
				}
				jp.repaint();
			}
			// 客户端投降
			if (split[2].equals("TOUXIANG")) {
				ServerChat.chantArea.append("\n---系统消息:对方已经投降,恭喜你赢了!");
				JOptionPane.showMessageDialog(null, "恭喜您,对面投降了!");
				// 清除黑棋白棋
				ServerChessBoard.myself_list.clear();
				ServerChessBoard.duifang_list.clear();
				ServerChessBoard.isgamestart = false;
				jp.repaint();

			}
			// 客户端悔棋
			if (split[2].equals("HUIQI")) {
				if (ServerChessBoard.duifang_list.size() > 0)
					ServerChessBoard.duifang_list.remove(ServerChessBoard.duifang_list.get(ServerChessBoard.duifang_list.size() - 1));// 后退
				ServerChat.chantArea.append("---系统消息:对方毁了一步棋!---\n");
				ServerChessBoard.isduifangxiaqi = false;
				ServerChessBoard.ismyselfxiaqi = true;
				jp.repaint();
			}
			// 客户端重新开始
			if (split[2].equals("CHONGXINLAI")) {
				ServerChat.chantArea.append("\n---系统消息:对方要求重新开始!---");
				JOptionPane.showMessageDialog(null, "对方要求开始,确认就清除所有数据,重新开始");
				ServerChessBoard.myself_list.clear();
				ServerChessBoard.duifang_list.clear();
				ServerChessBoard.isgamestart = false;
				ServerChessBoard.myselfok = false;
				ServerChessBoard.duifangok = true;
				jp.repaint();
			}
		}
	}

5、发送功能的实现

public class Send_message {
	Socket socket;
	String message;

	public Send_message(String message, Socket socket) {
		this.message = message;
		this.socket = socket;
	}

	public void send(String message, Socket socket) {
		OutputStream os;
		try {
			os= socket.getOutputStream();
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));	
			bw.write(message);//输出
			bw.newLine();//另起一行
			bw.flush(); //清除缓存
		} catch (IOException e) {
			//e.printStackTrace();
		}
	}
}

6、服务器窗口的搭建

public class ServerWindow extends JFrame {
	public static boolean isstart = false;
	public static boolean clientconnect=false;
	public static Socket socket;
	ServerChessBoard qipan;
	ServerChat talk;
	public static ServerSocket server;
	public ServerWindow(){
		qipan = new ServerChessBoard();
		talk = new ServerChat();
		this.setSize(1000, 550);
		this.setTitle("五子棋服务器");
		this.add(qipan, BorderLayout.CENTER);
		this.add(talk, BorderLayout.WEST);
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		JMenu gameMenu = new JMenu("游戏"); // 创建游戏菜单
		// 创建游戏菜单项
		JMenuItem connect_ser = new JMenuItem("开启服务器");
		connect_ser.addActionListener(new AbstractAction("开启服务器") {
			public void actionPerformed(ActionEvent event) {
				boolean flag = Serverstart();
				if (flag == false) {
					JOptionPane.showMessageDialog(null, "开启失败");
					return;
				} else {
                    // 服务器开启成功后开启线程
					Recive_thred rth = new Recive_thred(socket,ServerChat.chantArea,qipan);
					rth.start();
				}

			}
		});
		menuBar.add(gameMenu);
		gameMenu.add(connect_ser);
		this.setVisible(true);
	}


五、 运行结果

客户端窗口
服务器窗口
判断输赢

总结及感想

感受:感受到了项目设计的不易,认识了自己许多学习上的不足,通过实践提高了对理论知识的理解,提高了自己的能力。感受到了合作的重要性,明白了团队力量的强大,希望以后能够学到更多东西。懂得了不要过分沉迷于书本知识,要多多实践,将书上的知识转化成自己的能力,不断提高自己,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值