(一)设计思路:
游戏效果如下图所示:
游戏描述:
游戏框架如下:
总共有四个大的类: 服务端,客户端,用户类,以及游戏主题类 具体的类如下:
服务器端中有三个类: 分别是主题类ServerRunner,和两个类ServerThread,ServerMsgPanel;分别实现消息的发送,服务端的运行,以及服务端的多线程运行
-
2.客户端 客户端类中也有两个类: 分别是主题类ClientChess和ClientThread,分别实现客户端对于棋盘的连接和对于服务器端连接实现相互交流 -
3.玩家端 玩家中有玩家列表,玩家之间的信息交流,对玩家的消息输入,以及玩家对游戏控制 -
4.棋局端 棋局类中分别由黑棋类,白棋类,以及棋盘的主题类,和棋盘线程类;
Java中Jpanel与panel有何区别: panel是包java.awt当中的类,Jpanel是包javax.swing当中的类,属于前者的升级。二者在本质上并没有太大的区别。 相对awt图形用户界面而言,Swing图形用户界面不仅增强了功能,而且减弱了平台相关性,即Swing图形用户界面比AWT图形用户界面可以克服更多的由于操作系统不同所带来的在图形用户界面或交互方式上的差别,因此建议使用swing当中的JPanel
游戏中的难点
- 1.基于TCP/IP协议,使用socket创建客户端和服务器端
Socket clientSocket;
有关Socket编程可参考;Socket简介及客户端服务端代码实现
- 2.其中客户端和服服务器端采用Hashtable建立通信,反应速度更快,不适用HashMap是因为HashMap不能保证线程安全,但Hash大部分函数都有Synchronized关键字,可以保证线程安全,下面为服务器端所用到的Hashtable变量;
Hashtable clientDataHash = new Hashtable(50);
Hashtable clientNameHash = new Hashtable(50);
Hashtable chessPeerHash = new Hashtable(50);
关于Hashtable和HashMap的区别可参考:Hashtable和HashMap的区别
- 3.多线程并发问题:
此游戏中有客户端线程类,服务端线程类,以及棋局线程类;涉及了多线程并发问题 - 4.java.IO流输入输出问题:
主要使用了字节流inputStream,Outputstream ,
涉及到的其它知识:
JTextField() 创建一个空的文本框,初始字符串为null JTextFiled(int columns) 创建一个具有指定列数的文本框,初始字符串为null JTextField(String text) 创建一个显示指定初始字符串的文本框 JTextField(String text,int column) 创建一个具有指定列数、并显示指定初始字符串的文本框
JTextArea称为文本域,它能接收多行文本的输入,使用JTextArea构造方法创建对象时可以设定区域的行数、列数
JTextArea() 构造方法,创建一个空的文本域 JTextArea(String text) 构造方法,创建显示指定初始字符串的文本域 JTextArea(int rows,int columns) 构造方法,创建具有指定行和列的空的文本域 JTextArea(String text,int rows,int columns) 构造方法,创建显示指定初始文本并指定了行列的文本域
- WindowListener :
用于接收窗口事件的侦听器接口。旨在处理窗口事件的类要么实现此接口(及其包含的所有方法),要么扩展抽象类 WindowAdapter(仅重写所需的方法)。然后使用窗口的 addWindowListener 方法将从该类所创建的侦听器对象向该 Window 注册。当通过打开、关闭、激活或停用、图标化或取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法,并将 WindowEvent 传递给该方法。
(二)客户端和服务器端的实现:
服务器端实现:
服务器端的信息的输出:
public class ServerMsgPanel extends Panel {
public TextArea msgTextArea = new TextArea("", 30, 71, TextArea.SCROLLBARS_VERTICAL_ONLY);
public JLabel statusLabel = new JLabel(" ", Label.LEFT );
public Panel msgPanel = new Panel();
public Panel statusPanel = new Panel();
public ServerMsgPanel() {
}
}
服务器端的线程运行,处理信息
public class ServerThread extends Thread{
Socket clientSocket;
Hashtable clientDataHash;
Hashtable clientNameHash;
Hashtable chessPeerHash;
boolean isClientClosed = false;
ServerMsgPanel serverMsgPanel;
public ServerThread(Socket clientSocket, Hashtable clientDataHash, Hashtable clientNameHash,
Hashtable chessPeerHash, ServerMsgPanel server) {
this.clientSocket = clientSocket;
this.clientDataHash = clientDataHash;
this.clientNameHash = clientNameHash;
this.chessPeerHash = chessPeerHash;
this.serverMsgPanel = server;
}
public void dealWithMsg(String msgReceived) {
}
public void sendPublicMsg(String publicMsg) {
synchronized (clientDataHash) {
}
}
public boolean sendGamePeerMsg(String gamePeerTarget, String gamePeerMsg) {
}
return true;
}
public void Feedback(String feedBackMsg) {
synchronized (clientDataHash) {
DataOutputStream outputData = (DataOutputStream) clientDataHash
.get(clientSocket);
try {
outputData.writeUTF(feedBackMsg);
} catch (Exception eb) {
eb.printStackTrace();
}
}
}
public String getUserList() {
String userList = "/userlist";
for (Enumeration enu = clientNameHash.elements(); enu.hasMoreElements();) {
userList = userList + " " + enu.nextElement();
}
return userList;
}
public Object getHashKey(Hashtable targetHash, Object hashValue) {
Object hashKey;
for (Enumeration enu = targetHash.keys(); enu.hasMoreElements();) {
hashKey = (Object) enu.nextElement();
if (hashValue.equals((Object) targetHash.get(hashKey))) {
return hashKey;
}
}
return null;
}
public void sendInitMsg() {
}
public void closeClient() {
}
@Override
public void run() {
DataInputStream inputData;
synchronized (clientDataHash) {
serverMsgPanel.statusLabel.setText("当前连接数:" + clientDataHash.size());
}
}
}
服务的主体类:
public class ServerRunner extends Frame implements ActionListener {
JButton clearMsgButton = new JButton("清空");
JButton serverStatusButton = new JButton("状态");
JButton closeServerButton = new JButton("关闭");
Panel buttonPanel = new Panel();
ServerMsgPanel serverMsgPanel = new ServerMsgPanel();
ServerSocket serverSocket;
int clientAccessNumber = 1;
Hashtable clientDataHash = new Hashtable(50);
Hashtable clientNameHash = new Hashtable(50);
Hashtable chessPeerHash = new Hashtable(50);
public ServerRunner() {
}
public void createServer(int port, ServerMsgPanel serverMsgPanel) throws IOException {
}
public void actionPerformed(ActionEvent e) {
}
public static void main(String[] args) {
new ServerRunner();
}
}
通过该项目,对于Hashtable,socket编程,java.IO流以及多线程开发等有了深入认识
|