四国军棋系统
1.无需注册登录,支付后按照提示操作即可获取该资料.
2.资料以网页介绍的为准,下载后不会有水印.资料仅供学习参考之用.
密 惠 保
目录
第一章 绪论 1
1.1 问题概述 1
1.1.1 问题的来源 1
1.1.2 目的和意义 1
1.1.3 国内外研究现状 1
1.2 问题剖析 2
1.2.1 主要问题 2
1.2.2 难点和关键 3
1.2.3 思路和方法 3
第二章 相关的知识和工具 4
2.1 解决问题的知识基础 4
2.2 开发平台 5
2.3 数据库 5
第三章 总体设计 6
3.1 总体设计的框架 6
3.2 模块功能概述 7
3.3 关键算法 8
3.4关键技术 12
第四章 详细设计 14
4.1数据库结构 14
4.2模块结构 14
4.3 重要模块详述 15
第五章 程序编码 19
5.1 数据结构 19
5.2主要界面 22
5.3 重要模块程序实现 24
第六章 问题和展望 32
6.1 特色与成功 32
6.2 问题与展望 32
参考文献 33
附录 34
游戏大厅 34
游戏类 38 think58 [来源:http://think58.com]
第三章 总体设计
3.1 总体设计的框架
军棋游戏的总体设计框架,客户端如图3-1所示。
图3-1 军棋游戏架构-客户端 [资料来源:www.THINK58.com]
军棋游戏的总体设计框架,服务器如图3-2所示。
图3-2 军棋游戏架构-服务器
3.2 模块功能概述
客户端类的划分:
游戏基本类:负责处理游戏中一些完成基本功能的类,如处理声音类、处理动画图标,图形按钮等类,基本类的特点是被其他类在特定处所调用,并不动生成对象。
游戏框架类:负责处理游戏中客户端用于显示程序界面和绘制游戏界面以及显示用户信息和广告信息等处理任务。
游戏通信类:负责处理游戏中客户服务器之间的网络传输细节,从而在编程中不用考虑网络通信细节,达到客户和服务器之间的透明的效果。
游戏应用程序类:主要负责处理应用程序中各种设置显示对话框、程序主线程处理、程序中基本的运行类框架的管理,以及游戏中图形的处理和显示等任务的处理。
游戏处理类:主要用于处理游戏简单逻辑、负责解析和处理与服务器端交互的游戏数据,以及在游戏运行中维护游戏中的各种数据,同时维护处理游戏主线程逻辑等功能。 [资料来源:http://www.THINK58.com]
服务器类的划分:
游戏通信类:负责处理游戏中客户服务器之间的网络传输细节,从而在编程中不用考虑网络通信细节,达到客户和服务器之间透明传输的效果。
游戏协议类:负责处理游戏中客户服务器之间交互所传递的数据,并且对该数据格式进行打包和解包,同时根据该包中所包含的指令串进行相应的操作。
游戏逻辑类:负责处理游戏逻辑,如军棋游戏中用于维护军棋逻辑,判断下棋,得分等处理类。
用户管理类:用于管理用户资料,在用户登录后通过数据库验证用户名和密码,通过验证后从数据库读取用户的详细资料。同时在程序中维护用户数据,在用户游戏结束和退出游戏时将用户数据保存到数据库中。
服务器框架类:用于管理游戏大厅的数据,包括一些数据的列表。
数据库类:用于网络游戏的服务器端在处理大量的客户资料时,使用数据库进行大量数据的存储和查询所调用的类方法。 think58好,好think58 [来源:http://www.think58.com]
3.3 关键算法
模块间的数据传递设计,如图3-3所示。
图3-3 模块间的数据传递设计
think58.com
这样,在CTableView和CGameDlg中通过指针,也可向服务器发送消息。而CCGameHallFrameView收到消息后,同时也控制CTableView和CGameDlg的行为。
采用内存作图的方式,消除了闪烁。首先创建一个内存dc,将绘图的工作先在内存dc中做好,再贴到实际dc上去。做法如下:
首先创建关于屏幕的内存DC,代码为MemDC.CreateCompatibleDC( pDC); 之后创建一幅关于屏幕DC的图画,部分代码如下:
CRect rect;
this->GetClientRect(rect);
CBitmap bmpFace;
bmpFace.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
注意把握rect的尺寸为客户区域大小;
之后将这幅画选入内存DC中,部分代码如下:
CBitmap* pOldBmp = NULL;
pOldBmp = MemDC.SelectObject(&bmpFace);
之后可以开始在内存DC中进行任何绘制动作;部分代码如下:
CBrush brush(RGB(255,255,255));
MemDC.FillRect(rect,&brush);
for(int i=0;i<500;i++)
{
MemDC.MoveTo(22+i,22);
MemDC.LineTo(22+i,277);
}
绘制完后将内存DC中的这幅图绘制到屏幕DC中来,部分代码如下:
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,rect.left,rect.top,SRCCOPY); think58
最后进行相关的资源回收动作,部分代码如下:
MemDC.SelectObject(pOldBmp);
bmpFace.DeleteObject();。
同时我们要把系统的ON_WM_ERASEBKGND消息函数重载为return FALSE,
否则还是会出现闪烁情况。
在对话框中用这个方法的时候,要注意将有控件的部分和需要绘图的部分分开,可采用如下方法,部分代码如下::
CRect rectClient;CRgn rgn1,rgn2;//rgn3,rgn4;
GetClientRect(rectClient);
rgn1.CreateRectRgnIndirect(rectClient);
rgn2.CreateRectRgn(730,0,962,670);
if(rgn1.CombineRgn(&rgn1,&rgn2,RGN_XOR) == ERROR)
{
return;
}
MemDC.FillRgn(&rgn1,&brush);
服务器对连接的用户数据的数据结构的设计,用下面两个结构:
typedef struct TT{
int d[4];
int ID[4];
int board[17][17];
BOOL begin[4];
};
typedef struct MM{
CString name,sex;
int score;
};
连接的socket保存在如下链表中:
typedef CList <SOCKET,SOCKET&> SOCKET_ARRAY; copyright think58 [资料来源:http://think58.com]
SOCKET_ARRAY m_connectionList;
与服务器建立连接后,相应的用户数据,保存在MM结构数组中,位置为其socket在m_connectionList中的相应位置,这样就可以通过连接的socket找到相应的信息。TT是保存大厅数据的结构,d表示四个坐位有没有人,ID表示就坐的人的socket在链表中的位置。board为棋盘数据。每个桌子有每个桌子的棋盘数据,互不干扰。随着游戏的进行而不断更新。begin表示四个玩家有没有下调度完成的指令。
应用矩阵的变换实现坐标旋转。不管你坐在哪个方位,玩游戏时,你始终是在正下方,这就需要实现虚拟坐标到目标坐标的旋转变换,如图3-4。
图3-4 坐标图
X为实际坐标,x为虚拟坐标,转换公式推导如下,见图3-5。
[来源:http://www.think58.com]
图3-5 坐标变换公式推导
think58.com [资料来源:THINK58.com]
[资料来源:www.THINK58.com]direct 为自己座位方向,
switch(direct)
case 0: (a=90o) [X,Y,1]=[-y+16,x,1] //东
case 1:(a=0o) [X,Y,1]=[x,y,1] //南
case 2:(a=-90o) [X,Y,1]=[y,-x+16,1] //西
case 3:(a=180o) [X,Y,1]=[-x+16,-y+16,1] //北
回溯法求工兵路径,军棋游戏逻辑不复杂,只有工兵能够自由飞行。在这里没有求工兵起点到目标点的最短路径,而只是用回溯法求出其中一条路径,所以在游戏中你会发现工兵有时候会绕些弯路。这和老鼠走迷宫差不多的。
工兵迷宫数组:
int RAILWAY[17][17]={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,3,1,3,1,1,0,0,0,0,0}, [来源:http://think58.com]
{0,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1,0},
{0,1,0,0,0,2,2,0,2,0,2,2,0,0,0,1,0},
{0,1,0,0,0,1,1,3,1,3,1,1,0,0,0,1,0},
{0,1,0,0,0,2,2,0,2,0,2,2,0,0,0,1,0},
{0,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1,0}, [来源:http://www.think58.com]
{0,0,0,0,0,1,1,3,1,3,1,1,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0},
{0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
}
0表示该位置不在工兵铁道上,1表示在该位置可向上下左右方向移动,2表示在
该位置只能向上下方向移动,3表示在该位置只能向左右方向移动。
3.4关键技术
网络通信,Windows Socket 编程接口:
Windows Socket (简称 WinSock)是在Win32平台上访问基层网络协议的接口。在不同的Win32平台上,Windows Socket以不同的方式存在着,作为网络编程接口而不是协议存在。
套接字(Socket)概念,套接字是从英文单词Socket翻译而来,它是网络通信的基本操作单元,是应用层到传输层的接口,可以将套接字看作不同主机间的进程进行双向通信的端点。
Windows Socket组成部分,Windwos Sockets实现一般都由两部分组成:开发组件和运行组件。开发组件是供程序员开发Windows Sockets应用程序使用的,主要是WinSock.h头文件。对于Windows Sockets应用程序的源文件来说,只要包括WinSock.h就可以了。除此之外,在使用WinSock的项目中还需要加入WinSock API引入库wsock32.lib。运行组件是Windows Sockets应用程序接口的动态连接库(DLL),文件名为WinSock.dll,应用程序在执行时通过装入它实现网络通信功能。
think58.com [来源:http://think58.com]
Windows Sockets编程的基本模式,要通过互联网进行通信,你至少需要一对套接字,其中一个运行于客户端,我们称之为ClientSocket,另一个运行于服务器端,我们称之为ServerSocket。使用Socket进行网络通信一般有两种方式:基于面向连接的流方式和基于无连接的数据报方式。面向连接的的流方式调用过程如图3-6所示。
图3-6 面向连接的流方式调用 think58 [资料来源:http://THINK58.com]
第四章 详细设计
4.1数据库结构
服务器端数据库结构如表4-1。
User
列名 数据类型 长度 允许空 描述
主键 name char 10 no 用户名
code char 10 no 密码
score int 4 yes 游戏积分
sex char 2 yes 性别
表4-1,玩家信息
用作记录玩家游戏数据。
4.2模块结构
客户端模块结构:
游戏基本类,该类包中包括CBorderButton、CClockObject、CWave类。
游戏框架类,该类包中包括CMainFrame、CCGameHallFrameView、CHtmlViewEx、CTableView类。
游戏通信类,该类包中包括CClient类。
游戏应用程序类,该类包包括CGameDlg类,其中包括对游戏处理类的调用。
游戏处理类,该类包中主要包括TakeGame类。
服务器模块结构:
游戏通信类,由CServer类实现。
游戏协议类,由CServerProtocol类实现。
游戏逻辑类,由CServerLogic类实现。
数据库类,由CServerFrameSet类实现。 本文来自think58
用户管理类,由CServerFrameView类实现。
服务器框架类,由CServerFrame类实现。
4.3 重要模块详述
客户端模块:
CBorderButton 类是带有边框的图片按钮类,CClockObject 类是时钟类,CWave是用来播放声音的类,当游戏用户下棋,吃子,起身或坐下时要播放声音,选择在程序中调用API函数PlaySound直接播放在资源中的声音文件。模块描述如图4-1。
图4-1 游戏基本类模块描述 本文来自think58
[资料来源:http://think58.com]
CMainFrame类是游戏窗口中的游戏大厅框架类,其中包括构架广告显示窗口,可玩的游戏类、工具栏、游戏桌的信息、显示信息等,CCGameHallFrameView类是用来在游戏大厅窗口左侧显示可以玩的游戏以及游戏室,采用树状结构显示。CHtmlViewEx类用于构造广告显示窗口,用于游戏框架中显示广告页。CTableView显示包含游戏桌的游戏大厅,在大厅中多人在等待开始游戏。模块描述如图4-2。
图4-2 游戏框架类模块描述 内容来自think58 [资料来源:www.THINK58.com]
游戏通信类,CClient,功能为建立和服务器的连接,能及处理通信,采用异步机制,以自定义消息事件处理通信等功能。采用自定义消息:WM_USER + 101。模块描述如图4-3。
图4-3 游戏通信类模块描述
游戏应用程序类,CGameDlg,其中包括对游戏处理类的调用。CGameDlg 主要负责处理应用程序中各种设置显示对话框、程序主线程处理、以及游戏中的图形的处理和显示等任务的处理。模块描述如图4-4。
图4-4 游戏应用程序类模块描述
copyright think58 [来源:http://think58.com]
[资料来源:www.THINK58.com] 游戏处理类,TakeGame主要用于处理游戏简单逻辑、负责解析和处理与服务器端交互的游戏数据,以及在游戏运行时维护游戏中的各种数据,同时维护处理游戏主线程逻辑等功能。模块描述如图4-5。
图4-5 游戏处理类模块描述
think58.com
[资料来源:http://THINK58.com]
[资料来源:THINK58.com]服务器模块:
游戏通信类,由CServer类实现。负责处理游戏中客户与服务器之间的网络连接细节,从而使得对于客户和服务器之间的数据传输可以忽略通信细节。模块描述如图4-6。
图4-6 游戏通信类模块描述 内容来自think58 [来源:http://think58.com]
游戏协议类,由CServerProtocol类实现。游戏协议类负责解析客户/服务器端所传输的协议,同时根据不同的协议调用不同的操作函数,并根据用户状态变化维护用户信息。模块描述如图4-7。
图4-7 游戏协议类模块描述 内容来自think58 [版权所有:http://think58.com]
游戏逻辑类负责处理游戏逻辑,在军棋游戏中包括计算得分,计算赢等。游戏逻辑类CServerLogic和游戏协议类分离的优点是可以只通过修改逻辑类来改变为不同的网络游戏,如修改为“象棋逻辑”即可以成为象棋游戏,修改为“升级逻辑”即可以成为升级游戏。
用户管理类,直接在CCServerFrameView中实现。
数据库类,采用SQL Server 2000数据库,只是用来保存玩家的资料等一些数据。采用MFC ODBC数据库编程,在程序中为CServerFrameSet类。正如MFC提供的其他类库很好地对相应的Win32 API作了封装,MFC提供的ODBC类库也相应地对ODBC API作了封装,通过提供一种高级接口而避免直接使用ODBC API所涉及的种种繁琐处理,简化了对ODBC数据库的应用程序编程。模块描述如图4-8。
图4-8 数据库类模块描述
think58好,好think58
[资料来源:http://THINK58.com]
think58.com [来源:http://think58.com]