计算机毕业设计86vc++四国军棋系统设计与实现.doc_第1页
计算机毕业设计86vc++四国军棋系统设计与实现.doc_第2页
计算机毕业设计86vc++四国军棋系统设计与实现.doc_第3页
计算机毕业设计86vc++四国军棋系统设计与实现.doc_第4页
计算机毕业设计86vc++四国军棋系统设计与实现.doc_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

目录 第一章 绪论 . - 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 - 第五章 程序编码 . - 18 - 5.1 数据结构 . - 18 - 5.2主要界面 . - 21 - 5.3 重要模块程序实现 . - 24 - 第六章 问题和展望 . - 32 - 6.1 特色与成功 . - 32 - 6.2 问题与展望 . - 32 - 参考文献 . - 33 - 附录 . - 34 - 游戏大厅 . - 34 - 游戏类 . - 38 - 绪论 - 1 - 第一章 绪论 1.1 问题概述 1.1.1 问题的来源 随着 Internet 的普及,网络游戏已经成为大家耳濡目染的新生事物。网络游戏从出现到现在的发展的时间很短,但是其发展速度却非常之快。现在,可以说网络游戏已经成为人们休闲、娱乐的有效方式。国内比较有名气的网络游戏有联众网络游戏世界 中国游戏中心 以及这几年受玩家亲睐的传奇、魔兽世界等。 1.1.2 目的和意义 对当今网络游戏的设计、架构进行分析、探索和实践。提供友好的客户操作界面,通过客户端与服务器之间的网络传递数据,实现了多人协同游戏的目的。分析现今网络游戏体系结构及设计模式的优缺点,及对网 络游戏的发展给予分析和展望。 1.1.3 国内外研究现状 现今网络游戏的体系结构(见图 1-1) ,包括客户机程序、服务器程序、数据库服务器。 网络游戏 - 2 - 图 1-1 网络游戏体系结构 1.2 问题剖析 1.2.1 主要问题 在开发网络游戏时,首先要建立底层的网络通信类,利用网络通信类连接构建客户服务器之间的 TCP/IP连接,然后在该连接的基础上利用自设定的协议进行客户端登录、进行游戏等操作。在以上协议的基础上,根据不同的游戏编写不同的游戏逻辑处理类,在该逻辑处理类中实现了对应的游戏逻辑,如实例中的军棋,则实现相互之 间的对弈等功能。同时在服务器端还需要和数据库服务器交互,用于读取或保存客户信息(如用户积分、密码、个人资料等数据)。 绪论 - 3 - 1.2.2 难点和关键 1、有一个或多个游戏服务器启动特定游戏服务。 2、游戏者到游戏网站上下载客户端程序并且申请游戏账号 ID。然后启动客户端程序通过某种网络协议连接游戏服务器。 3、客户端程序负责处理客户端显示和操作界面,具有简单的逻辑处理功能,同时负责接收发送与服务器端交互的数据包。 4、服务器程序负责处理服务器端逻辑、游戏逻辑、客户之间的网络信息传递,以及数据库之间的数据读取保存工作。 同时服务器端还要承担客户端数据的接收、转发工作。 1.2.3 思路和方法 网络游戏通常的运行方式 (见图 1-2)。 图 1-2 网络游戏交互图 网络游戏 - 4 - 第二章 相关的知识和工具 2.1 解决问题的知识基础 网络游戏常用的网络协议有适用于 Internet 的 TCP/IP协议、适用局域网(比如星际)的 IPX协议。 (一 ) TCP/IP协议 TCP/IP协议 (Transmission Control Protocol/Internet Protocol,传输控制协议 /网际协议 )是 Internet 中计算机进行通信的标准, 其命名起源于该组协议中最重要的两个协议 TCP和 IP。任何关于 Internet协议的讨论必须由 TCP/IP开始,它也是其他所有协议的基础。 TCP/IP协议是 Internet网络的共同语言,主机之间必须利用 TCP/IP互通信息。 TCP/IP协议目前已经成为发展最成功的通信协议之一,它起源于 20 世纪 60年代末美国政府资助的一个分级交换网络研究项目,允许分布在各地的使用不同操作系统的网络进行通信。随着世界范围个人电脑的普及,日常无论收发邮件、访问网页和文件传输都已经离不开 TCP/IP协议, TCP/IP协议已经成为 Internet的基础。 (二 ) TCP/IP结构 TCP/IP实际上就是在物理网上的一组完整的协议。其核心部分是传输层协议 (TCP/UDP)、网络层 (IP)和物理接口层,这三层通常在操作系统内核中实现。 TCP/UDP 层提供了传输层服务,而 IP协议提供了网络层服务。 TCP/IP协议是一个四层协议,其结构如图 2-1 所示。 图 2-1 TCP/IP 协议体系结构图 相关的知识和工具 - 5 - 应用程序与 TCP/IP 可靠传输之间接口具有五大特性: 面向数据流 当两个用户进程传输大量数据时,我们把这些数据当做可划分为八位组( octer,字节)的比特流,在目的机器上运行的数据流投递服务软件提给接收方的八位组与信源机上发送方送出来的完全相同。 虚电路连接 数据流的传输与电话相似,使用“虚电路”这个术语来描述这种连接是因为在应用程序看来这种连接像是一条专用的硬件电路,这种可靠连接的错觉是由数据流投递服务提供。 有缓冲的传送 使用虚电路服务来发送数据流的应用程序不断向协议软件递交数据八位组。为了提高效率以及减少网络延迟,协议软件在实现时都会从数据流中收集到足够多的数据,组成大小合理的数据包后再送到网络上传输。 无结构的数据 TCP/IP 协议并不区 分结构化的数据流。使用数据流的应用程序必须在开始连接之前就了解数据流的内容并对其格式进行协商。 这点很重要,在程序中表现为 send函数只能发送字符串,这就需要将接收的字符串转化需要的结构化的数据。 全双工连接 TCP/IP 流服务所提供的功能是双向的全双工连接。其中包括了两个独立、流向相反的数据流,而这两个数据流之间不进行显式的交互。 常用协议主要包括 TCP/UDP层协议和 IP层协议。 TCP和 UDP都是传输层协议,都使用 IP协议作为网络层协议。使用 UDP 协议的应用程序必须承担可靠性的工作,包括报文的丢失、重复 、乱序以及连接失效等问题,而程序员编程时则容易疏忽。 2.2 开发平台 操作系统 Windows 2000, 开发工具 VisualC+6.0。 2.3 数据库 SQL Server 2000, 是一个全面的数据库平台,引擎为关系型数据和结构化数据提供了安全可靠的存储功能。 网络游戏 - 6 - 第三章 总体设计 3.1 总体设计的框架 军棋游戏的总体设计框架,客户端如图 3-1所示。 图 3-1 军棋游戏架构客户端 军棋游戏的总体设计框架,服务器如图 3-2所示。 图 3-2 军棋游戏架构服务器 总体设计 - 7 - 3.2 模块功能 概述 客户端类的划分: 游戏基本类:负责处理游戏中一些完成基本功能的类,如处理声音类、处理动画图标,图形按钮等类,基本类的特点是被其他类在特定处所调用,并不动生成对象。 游戏框架类:负责处理游戏中客户端用于显示程序界面和绘制游戏界面以及显示用户信息和广告信息等处理任务。 游戏通信类:负责处理游戏中客户服务器之间的网络传输细节,从而在编程中不用考虑网络通信细节,达到客户和服务器之间的透明的效果。 游戏应用程序类:主要负责处理应用程序中各种设置显示对话框、程序主线程处理、程序中基本的运行类框架的管理,以及游戏中 图形的处理和显示等任务的处理。 游戏处理类:主要用于处理游戏简单逻辑、负责解析和处理与服务器端交互的游戏数据,以及在游戏运行中维护游戏中的各种数据,同时维护处理游戏主线程逻辑等功能。 服务器类的划分: 游戏通信类:负责处理游戏中客户服务器之间的网络传输细节,从而在编程中不用考虑网络通信细节,达到客户和服务器之间透明传输的效果。 游戏协议类:负责处理游戏中客户服务器之间交互所传递的数据,并且对该数据格式进行打包和解包,同时根据该包中所包含的指令串进行相应的操作。 游戏逻辑类:负责处理游戏逻辑,如军棋游戏中用 于维护军棋逻辑,判断下棋,得分等处理类。 用户管理类:用于管理用户资料,在用户登录后通过数据库验证用户名和密码,通过验证后从数据库读取用户的详细资料。同时在程序中维护用户数据,在用户游戏结束和退出游戏时将用户数据保存到数据库中。 服务器框架类:用于管理游戏大厅的数据,包括一些数据的列表。 数据库类:用于网络游戏的服务器端在处理大量的客户资料时,使用数据库进行大量数据的存储和查询所调用的类方法。 网络游戏 - 8 - 3.3 关键算法 模块间的数据传递设计,如图 3-3所示。 图 3-3 模块间的数据传递设计 这样,在 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;iBitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,rect.left,rect.top,SRCCOPY); 最后进行相关的资源回收动 作, 部分代码如下: 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 d4; int ID4; int board1717; BOOL begin4; ; typedef struct MM 网络游戏 - 10 - CString name,sex; int score; ; 连接的 socket保存在如下链表中: typedef CList SOCKET_ARRAY; SOCKET_ARRAY m_connectionList; 与服务器建立连接后,相应的用户数据,保存在 MM 结构数组中,位置为其 socket在 m_connectionList中的相应位置,这样就可以通过连接的 socket找到相应的信息。TT 是保存大厅数据的结构, d 表示四个坐位有没有人, ID 表示就坐的人的 socket 在链表中的位置。 board 为棋盘数据。每个桌子有每个桌子的棋盘数据,互不干扰。随着游戏的进行而不断更新。 begin表示四个玩家有没有下调度完成的指令。 应用矩阵的 变换 实现坐标旋转。不管你坐在哪个方位,玩游戏时,你始终是在正下方,这就需要实现虚拟坐标到目标坐标的旋转变换,如图 3-4。 图 3-4 坐标图 X为实际坐标, x为虚拟坐标,转换公式推导如下,见图 3-5。 图 3-5 坐标变换公式推导 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 /西 总体设计 - 11 - case 3:(a=180o) X, Y, 1=-x+16, -y+16, 1 /北 回溯法求工兵路径,军棋游戏逻辑不复杂,只有工兵能够自由飞行。在这里没有求工兵起点到目标点的 最短 路 径 ,而只是 用 回溯 法 求出 其中一条路径,所以在游戏中你会发现工兵有时候会绕些弯路。这和老鼠走迷宫差不多的。 工兵迷宫数组: int RAILWAY1717= 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, 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, 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表示在该位置只能向左右方向移动。 网络游戏 - 12 - 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,应用程序在执行时通过装入它实现网络通信功能。 Windows Sockets 编程的基本模式,要通过互联网进行通信,你至少需要一对套接字,其中一个运行于客户端,我们称之为 ClientSocket,另一个运行于服务器端,我们称之为 ServerSocket。使用 Socket 进行网络通信一般有两种方式:基于面向连接的流方式和基于无连接的数据报方式。面向连接的的流方式调用过程如图 3-6所示。 总体设计 - 13 - 图 3-6 面向连接的流方式调用过程 网络游戏 - 14 - 第四章 详细设计 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类实现。 用户管理类,由 CServerFrameView类实现。 服务器框架类,由 CServerFrame类实现。 详细设计 - 15 - 4.3 重要模块详述 客户端模块: CBorderButton 类是带有边框的图片按钮类, CClockObject 类是时钟类, CWave是用来播放声音的类,当游戏用户下棋,吃子,起身或坐下时要播放声音,选择在程序中调用 API 函数 PlaySound 直接播放在资源中的声音文件。模块描述如图 4-1。 图 4-1 游戏基本类模块描述 CMainFrame 类是游戏窗口中的游戏大厅框架类,其中包括构架广告显示窗口,可玩的游戏类、工具 栏、游戏桌的信息、显示信息等, CCGameHallFrameView类是用来在游戏大厅窗口左侧显示可以玩的游戏以及游戏室,采用树状结构显示。 CHtmlViewEx 类用于构造广告显示窗口,用于游戏框架中显示广告页。CTableView 显示包含游戏桌的游戏大厅,在大厅中多人在等待开始游戏。模块描述如图 4-2。 图 4-2 游戏框架类模块描述 网络游戏 - 16 - 游戏通信类, CClient,功能为建立和服务器的连接,能及处理通信,采用异步机制,以自定义消息事件处理通信等功能。采用自定义消息: WM_USER + 101。模块描述 如图 4-3。 图 4-3 游戏通信类模块描述 游戏应用程序类, CGameDlg,其中包括对游戏处理类的调用。 CGameDlg 主要负责处理应用程序中各种设置显示对话框、程序主线程处理、以及游戏中的图形的处理和显示等任务的处理。模块描述如图 4-4。 图 4-4 游戏应用程序类模块描述 游戏处理类, TakeGame 主要用于处理游戏简单逻辑、负责解析和处理与服务器端交互的游戏数据,以及在游戏运行时维护游戏中的各种数据,同时维护处理游戏主线程逻辑等功能。模块描述如图 4-5。 图 4-5 游戏处理类模 块描述 详细设计 - 17 - 服务器模块: 游戏通信类,由 CServer 类实现。负责处理游戏中客户与服务器之间的网络连接细节,从而使得对于客户和服务器之间的数据传输可以忽略通信细节。模块描述如图 4-6。 图 4-6 游戏通信类模块描述 游戏协议类,由 CServerProtocol类实现。 游戏协议类负责 解析客户 /服务器端所 传输的协议,同时根据不同的协议调用不同的操作函数,并根据用户状态变化维护用户信息。模块描述如图 4-7。 图 4-7 游戏协议类模块描述 游戏逻辑类负责处理游戏逻辑,在军棋游戏中包括计算得分,计算 赢等。游戏逻辑类 CServerLogic和游戏协议类分离的优点是可以只通过修改逻辑类来改变为不同的网络游戏,如修改为“象棋逻辑”即可以成为象棋游戏,修改为“升级逻辑”即可以成为升级游戏。 用户管理类,直接在 CCServerFrameView 中实现。 数据库类,采用 SQL Server 2000 数据库,只是用来保存玩家的资料等一些数据。采用 MFC ODBC 数据库编程,在程序中为 CServerFrameSet 类。正如 MFC提供的其他类库很好地对相应的 Win32 API 作了封装, MFC 提供的 ODBC 类库也相应地对 ODBC API 作了封装,通过提供一种高级接口而避免直接使用 ODBC API网络游戏 - 18 - 所涉及的种种繁琐处理,简化了对 ODBC 数据库的应用程序编程。模块描述如图4-8。 图 4-8 数据库类模块描述 第五章 程序编码 5.1 数据结构 用 17 17的数组表示军棋的棋盘,如下: int BOARD1717 = -1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,0,0,0,0,0,-1,-1,-1,-1,-1,-1, 程序编码 - 19 - -1,-1,-1,-1,-1, 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, 0,-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, 0,0,0,0,0,0, 0,-1, 0,-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,-1,-1,-1,-1, 0, 7, 3, 4,5, 3, 0,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,10, 0, 1,0, 9,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 8,10, 0,1, 5,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 6, 0, 4,0, 3,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 2, 7, 6,1,11,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,11,12,11,2, 2,-1,-1,-1,-1,-1,-1, ; 1表示棋 盘以外的位置 0 表示棋盘内位置,但无棋子 1 工兵 2 排长 3 连长 4 营长 5 团长 6 旅长 7 师长 8 军长 9 司令 10 炸弹 11 地雷 12 我方军旗 网络游戏 - 20 - 13 上方盟友或敌方的棋子 14 左边敌方的棋子 15 右边敌方的棋子 16 上方军旗 17 左方军旗 18 右方军旗 为了处理工兵的走法的方便,将四个转角斜对的位置恒置为 0,这样在为工兵寻找路径时会方便一些。 游戏协议 以 char(20)作为一次信息的起始点,终点。“”在字符串中用空格代替。以一字符串作为向服务 发出的请求信息,服务器也以相应的一字符串发送回客户端作为应答。 对话: A桌子号聊天内容 坐下: B桌子号方位 调度完成: C桌子号方位 (棋盘数据 )用一维数据形式表示 6 5 的二维数组,数据之间用空格开。 开始游戏: (只由服务器发出 ) D对战类型 下棋: E 桌子号方位起点 (x,y)终点 (x,y) 吃: (只由服务器发出 )(包括移动 ) F 起点 (x,y) + 终点 (x,y) 被吃: (只由服务器发出 ) G 起点 (x,y) + 终点 (x,y) 炸: (只由服务器发出 ) H 起点 (x,y) + 终点 (x,y) 程序编码 - 21 - 输:离开:(包括断线 ) 投降 : I 方位 求和: K 桌子号方位 注册: L 用户名密码 注册成功: M + 用户名 登录: N + 用户名密码 登录结果: O + 1/0 离开: P + 桌子号 方位 请求接收信息: Q + 桌子号 方位 碰: R 起点 (x,y) + 终点 (x,y) 5.2 主要界面 服务器界面如图 5-1所示。 网络游戏 - 22 - 图 5-1 服务器启动界面 客户端大厅界面如图 5-2所示。 程序编码 - 23 - 图 5-2 客户端大厅界面 军棋游戏界面,如图 5-3所示: 网络游戏 - 24 - 图 5-3 军棋游戏界面 5.3 重要模块程序实现 客户端三拆分窗口的实现 BOOL CMainFrame:OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) if(NULL=m_wndSplitter.CreateStatic(this,1,2) return FALSE; if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CTableView),CSize(620,800),pContext) return FALSE; if(NULL=m_wndLeftSplitter.CreateStatic(&m_wndSplitter,2,1, WS_CHILD|WS_VISIBLE,m_wndSplitter.IdFromRowCol(0,1) 程序编码 - 25 - return FALSE; if(!m_wndLeftSplitter.CreateView(0,0,RUNTIME_CLASS(CCGameHallFrameView),CSize(380,300),pContext)| !m_wndLeftSplitter.CreateView(1,0,RUNTIME_CLASS(CHtmlViewEx),CSize(380,500),pContext) return FALSE; pWebView=(CHtmlViewEx*)m_wndLeftSplitter.GetPane(1,0); pServerTreeView=(CCGameHallFrameView*)m_wndLeftSplitter.GetPane(0,0) pTableView=(CTableView*)m_wndSplitter.GetPane(0,0); pServerTreeView-pTable=pTableView; pWebView-Navigate2(/zhou207,0,NULL); return TRUE; 客户端初始化及连接 void CClient:ClientInit() if(WSAAsyncSelect(m_hSocket,m_hWnd,CLI_MESSAGE,FD_READ|FD_WRITE|FD_CLOSE|FD_CONNECT)0) AfxMessageBox(Error in select); BOOL CClient:InitAndConnect(HWND hWnd, UINT port, CString strServer) m_hWnd=hWnd; m_uPort=port; m_strServer=strServer; if(m_hSocket!=NULL) 网络游戏 - 26 - /先将以前打开的套接字关闭 closesocket(m_hSocket); m_hSocket=NULL; /创建面向连接的 socket m_hSocket=socket(AF_INET,SOCK_STREAM,0); ASSERT(m_hSocket!=NULL); ClientInit(); /设置连接信息:网络协议 IP地址端口 m_addr.sin_family=AF_INET; m_addr.sin_addr.S_un.S_addr=inet_addr(m_strServer.GetBuffer(0); m_addr.sin_port=htons(m_uPort); /连接服务器 int ret=0; int error=0; ret=connect(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr); if(ret=SOCKET_ERROR) /连接失败 if(GetLastError()!=WSAEWOULDBLOCK) AfxMessageBox(_T(请确认服务器确实已经打开并工作在同样的端口!); return FALSE; return TRUE; 服务器初始化及连接 程序编码 - 27 - void CServer:ServerInit() /设置 socket 的异步模式 if(WSAAsyncSelect(m_hSocket,m_hWnd,SER_MESSAGE,FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)0) AfxMessageBox(error select); BOOL CServer:InitAndListen(HWND hWnd, UINT port) m_uPort=port; m_hWnd=hWnd; if(m_hSocket!=NULL) /先关闭已经打开的 socket closesocket(m_hSocket); m_hSocket=NULL; /创建面向连接的流方式的套接字 m_hSocket=socket(AF_INET,SOCK_STREAM,0); ASSERT(m_hSocket!=NULL); ServerInit(); m_addr.sin_family=AF_INET; m_addr.sin_addr.S_un.S_addr=INADDR_ANY; m_addr.sin_port=htons(m_uPort); int ret=0; int error=0; /绑定套接字到本机的某个端口 ret=bind(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr); if(ret = SOCKET_ERROR) 网络游戏 - 28 - AfxMessageBox(Binding Error); return FALSE; ret = listen(m_hSocket, 64); if(ret = SOCKET_ERROR) AfxMessageBox(Listen Error); return FALSE; return TRUE; 回溯法寻找工兵路径 BOOL TakeGame:TakeEngineer(CPoint from, CPoint to) POS p;int x,y;engineer=TRUE; p.d=0;p.x=from.x;p.y=from.y;top=0; if(RAILWAYp.xp.y=2) p.d=1; stacktop=p;int f1717; while(top=0) p=stacktop; if(p.x=to.x&p.y=to.y) return TRUE; if(p.dDoModal()=IDOK) name=login-m_name; code=login-m_code; ServerIP=login-m_ServerIP; if(name=|code=|ServerIP=) MessageBox(每项内容都不能为空 ); else r=1; delete login; else register1=new CRegister1(); if(register1-DoModal() if(register1-m_code1=register1-m_code2) code=register1-m_code1; sex=register1-m_sex; ServerIP=register1-m_IP; if(code=|sex=|ServerIP=) MessageBox(每项内容都 不能为空 ); else r=2; delete register1; if(r=1|r=2) if(ClientConnect()=TRUE) /m_Init=TRUE; /pTable-flag=1; /pTable-DrawTable(); pTable-pClient=&m_client; 附录 - 35 - if(r=1) ClientMessage(N); else if(r=2) ClientMessage(L); *pResult = 0; void CCGameHallFrameView:OnSize(UINT nType, int cx, int cy) CFormView:OnSize(nType, cx, cy); / TODO: Add your message handler code here if( m_wndTree.m_hWnd ) / Fill the whole Client Area of the View with the Control m_wndTree.MoveWindow( 0, 0, cx, cy ); LRESULT CCGameHallFrameView:OnClientMessage(WPARAM wParam, LPARAM lParam) char s1024,k; int len;CString str; switch(lParam) case FD_CONNECT: len=GetLastError(); if(len!=0) AfxMessageBox(Error in Connecting); else m_Init=TRUE; return 0; case FD_READ: len=recv(m_client.m_hSocket,s,1024,0); slen=NULL;str=s; k=protocol.Anaysys(str); dealMessage(k); return 0; case FD_WRITE: return 0; case FD_CLOSE: return 0; default: MessageBox(服务器已关闭! ); return 0; 网络游戏 - 36 - BOOL CCGameHallFrameView:ClientConnect() if(m_client.InitAndConnect(m_hWnd,PORT,ServerIP)=FALSE) return FALSE; return TRUE; char CH=char(20); void CCGameHallFrameView:ClientMessage(char k) CString str; str=CH; str+=k; switch(k) case L: str+=code; if(sex=女 ) str+= 2; else str+= 1; str+=CH; /MessageBox(str); Sleep(100); m_client.SendString(str); break; case N: str+=name;str+= ;str+=code; str+=CH; Sleep(100);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论