现在开始正式写代码,上一篇讲到客户端与服务器交互的五种类型,这边再提一下,因为我们游戏中的所有交互行为都是属于其中之一的。有了这个做指导,代码写起来就轻松多了,只要先思考属于哪一种类型,也就不会容易写错。
1.服务器主动发消息给所有客户端 (例如同步时间,游戏大厅中发送玩家列表给客户端)
2.客户端发送消息给服务器,服务器发送消息给除该客户端之外的所有客户端 (例如许多实时RPG游戏中的移动,虽然也可以等服务器回应后再移动人物,但对于一直要进行操作的实时RPG来说,这种延时不太会影响游戏公平性.却会大大影响操作流畅度和美感。不过对于有些竞技游戏,比如LOL,是采用服务器回应客户端的移动请求后,再进行移动的,因为这种游戏中,这点点延迟就会影响游戏公平。)
3.客户端发送消息给服务器,服务器单独回应该客户端(例如玩家需要查看别人的信息,一般来说,这种都是即时请求的,但也有部分游戏可能将一些信息在游戏初始化时存到本地)
4.客户端发送消息给服务器,服务器发送消息给另一指定客户端(例如游戏中发送好友申请)
5.客户端提交数据给服务器,不返回(例如玩家升了一级,则同步信息到服务器端的数据库中,或玩家进入了一个房间,更新服务器的房间玩家列表,等待下一次返回给所有客户端)
既然是要进行信息交互,就要有一种信息格式,使双方都能够处理,我们这边采用的是这样一种格式
|信息头(6位数字)|信息1长度|信息2长度|......|信息1|信息2|.......|终止符号|
举个例子,例如
Socket.send(Client.Login_Key + Account.length + Password.length + Account + Password+"\n");
这是客户端发送给服务器的登录请求
以上变量的意义分别是
|登录信息头|账号长度|密码长度|账号|密码|终止符号|
例子2.
Socket.send(Client.CheckOthers_Key + account.length + account + "\n");
以上变量的意义分别是
|查看他人信息信息头|他人账号长度|他人账号|终止符号|
有了信息格式当然服务器也不能直接使用,需要对该消息进行拆解才能使用
服务器和客户端有一个相同的拆解方法,这里只贴出服务器的,客户端的只是语法不一样而已public static String[] decodeString(int a, String b) {
//等待返回的字符串数组
String[] returnString=new String[a];
int[] allArgs=new int[a];
for(int i=6;i<6+a;i++)
{
allArgs[i-6]=Integer.parseInt(b.substring(i,i+1));
}
for(int i=0;i<returnString.length;i++)
{
returnString[i]=b.substring(6+a+All(allArgs,i),6+a+All(allArgs,i)+allArgs[i]);
}
return returnString;
}
public static int All(int[] allArgs, int i) {
int a=0;
for(int b=0;b<i;b++)
a+=allArgs[b];
}
return a;
}
该方法就可以将所有的信息存到一个数组中
具体使用方法举例 比如上面的登录请求字符串
Client.CheckOthers_Key + account.length + account + "\n"
服务器进行拆解
String[] lines=Main.decodeString(2,line);
这样就把收到的信息line拆解为lines的数组,数组第一第二个位置分别放着提交的账号和密码,之后服务器就可以把这个参数传给数据库进行查询了
当然,这是一种不严谨的做法,例如该方法就没办法同时拆解包含着N条内容的Y条信息,只能一次拆解一条包含着N条内容的信息,或者包含着1条内容的N条信息,所以遇到拆解不了的少数情况,还要再做特殊处理,这个之后再说
接下来介绍一下服务器和客户端各自在本游戏中要编写的类,以及他们的作用
服务器端
1.ClientThread类 该类绑定一个对应的客户端,侦听来自该客户端的消息,拆解后进行处理
2.DBEngine类 该类处理要与数据库交互的客户端信息,例如注册,登录,更新人物数据等等
3.GUI类 该类是服务器的GUI,也可以没有,全凭个人喜好
4.Main类 程序的入口,该类也保存了所有的信息头,以及前面两个拆解字符串的方法
5.ScanningThread类 该类是服务器端的定时扫描客户端线程,用于执行之前说过的第五类交互
6.ServerSocketThread类 该类负责侦听客户端的Socket连接操作,并做一些初始化的工作
客户端(有些东西和通信无关,就一笔带过)
1.Client类 该类是客户端与服务器通信的类,也是客户端最重要的类
2.PlayerData类 该类保存了玩家数据,比如账号,金钱之类,当然如果要进行更改,还是要通过服务器,例如购买道具,肯定要以数据库中保存的人物金币为准,否则本地用修改器改一下金币数,就可以直接作弊了。所以这边的数据,只是为了客户端的显示作用。
3.DialogBox类 客户端GUI之一
4.PlayerInfoBox类 客户端GUI之一
5.Bullet类 子弹类
6.Map类 地图类
7.OtherPlayer类 该类是其他玩家在当前客户端的"化身" 也就是说,该类只有收到其他客户端的信息,才能够做出反应。与之相对,当前客户端对这些"化身"做操作,也会经由服务器传给其他客户端
8.PersonBase类 该类是人物类的基类
9.Player类 玩家所操控的英雄类
在制作游戏过程中,一般都将各个模块分离出来进行开发,做完一个再做下一个。下一期这我们先来完成注册功能。