自己老早以前就想写个局域网的三国杀,以前思考过其游戏逻辑的实现,觉得有点复杂,一直也没有真正动手,上个周末,真正动手做了起来,2天里写了大约2000来行代码。算是把整个框架有了个大致的实现。下面把整个思路整理一下。
既然是轻量级的局域网版本,就没必要把服务器和客户端分开来做,就让程序自带服务端和客户端,类似于quake,一个玩家创建了房间(主机),其他玩家可以搜索到局域网内的这个房间,并连接上来,然后主机点击开始按钮,游戏开始。既然client,server模式类似于quake,那么就干脆仿quake仿到底,2000来行代码都是采用的c语言实现,没有qt,没有stl,没有mfc,程序的架构也高仿quake,这是算是向伟大的quake致敬的一种方式吧。本来图形绘制部分的代码也考虑用opengl来实现,结果被卡在绘制图片一直显示一大块白色这个问题上了,搜了半天只说可能是图片尺寸的原因,opengl要求纹理大小要是2^n+2m像素大小。手工调节了下图片尺寸也无济于事。一怒之下,图像接口全部换成了DirectDraw……
整个项目分成3个模块:2个dll模块,1个exe模块。2个dll分别是处理游戏逻辑的Game.dll和处理图像绘制的Ref.dll, exe模块里面实现client和server, client每帧调用Ref.dll来绘制整个游戏界面,server每帧调用Game.dll来处理游戏逻辑,client和server之间通过网络来通信,由于考虑到游戏要求可靠的网络传输,所以选用了tcp。而要实现客户端查找局域网类建立好的游戏主机的话,由于tcp没有广播功能,可以在server端再开个udp的socket,来响应client发的udp广播消息。
Game模块才是真正三国杀的实现,同时在内存里保存了整个战局,它负责牌堆初始化,随机抽牌,牌技能实现,技能响应,下面举个杀闪简单的例子来说明流程:玩家1对玩家2打出了一张杀(这个事件是由客户端以网络消息的形式发过来的),模块调用杀的处理函数,处理函数里向客户端发生一个请求闪的网络消息,同时把这个请求闪的事件保存起来(入栈),客户端收到消息后,知道要打出闪,如果打出来了就向服务端发生个请求响应成功的事件的网络消息,没打出来就发送响应失败的网络消息,服务端收到后,取出保存的请求闪的事件(出栈),如果是个成功的消息就结束处理,如果是失败就进入伤害计算的的事件处理。
Ref模块里面是绘制图片和ui的实现,ui包括图片按钮,窗体等的实现。exe里调用这些来绘制整个游戏。
exe是程序的主体框架,没想到有什么好说的……
最后,如果能写好,当然要开源。