[image]20 网络棋牌输钱原理为什么会一直输里面有何原因。。。

当前位置: >>
网络游戏中网络协议和图像处理应用的研究(1)
武汉理工大学 硕士学位论文 网络游戏中网络协议和图像处理应用的研究 姓名:刘业辉 申请学位级别:硕士 专业:检测技术与自动化装置 指导教师:王天珍
摘要在国际上,整个游戏业的收入已经越过了电影业,2001年,全球的游戏市 场达到165亿美元,而电影业则为160亿美元;在韩国,网络游戏产值已经超过 了他们引以为豪的汽车工业的产值;2003年,为了推动国内游戏产业的发展, 我国已将网络游戏关键技术纳入国家863项目的研究课题。游戏行业发展日新月 异,在日美欧已经成为主流娱乐业。 随着现代网络通讯和无线通讯技术的飞速发展,在线网络游戏已成为游戏发 展的新趋势。网络游戏为入们提供了一个跨国界的虚拟世界,世界各地的人都可 以通过Internet玩同一款游戏,人们甚至可以通过手机或PDA等手持设备随 时随地访问网络游戏。为了实现网络游戏这样的大型实时分布式系统,开发人员 需要解决不少技术问题。 网络游戏技术中很重要的一部分就是网络协议。网络协议应该保证客户机之 间游戏状态的同步;验证客户机游戏动作的合法性,防止作弊;降低延时和响应 时间;时间同步;数据加密和安全传输等。现在的网络游戏使用的主要网络协议 包括对等用户协议、锁步协议、事件锁定、客户端/服务器协议等,本文将简单介绍这些协议。程序开发方法、工具和技术日新月异,采用先进的开发技术有助于提高程序 开发效率,提高程序质量,降低维护费用。本文将介绍采用UML进行程序设计,AOP(Aspect Oriented Programming),IOC(Inverse OfContr01)这些比较新的技术或设计模式,以及经典的MVC模式。 另外,本文还将介绍部分在Java平台上开发2D游戏经常需要采用的图像处理技术。在本文写作过程中,笔者还开发了一个实例小游戏一一俄罗斯方块网络版。 该游戏基于c/s结构的多用户网络游戏框架,客户端采用MvC模式实现,具有一定的理论和实用价值。关键字:网络,网络游戏,程序设计,图像处理 AbstractAccording to statistics,in 2001,the worldwide video game industrg withrevenuesof¥16.5 billion,overtook movie box―office receipts,which was¥16 billion。In South Korea,the output value of onHne game industry has exceeded their automobile industry output value,of which they had been very proud.In 2003,to encourage more domestically developed online games,China government listed 2 onlinegame projectsin China。S”863”High―Tech Program.The game industry isdeveloping rapidly,and has become mainstream of entertainment industry.Withwirelessthe rapid development of modem network communication technology and has become the new trend ofcommunication technology,the online gameoneelectronic game industry.Online game provides throtlgh which people of the entire worldcancrOSS-boundary fictitious worldenjoy thesame game.Peopleeven canenjoythe galne by mobile phoneorPDA at any time and at anyplace.Manytechnique problems should be solved in order to implementing thiscomplicatesYstem?Networkprotocol isoneof the crucial parts of online gametechnology.Networkandprotocol should keep game synchrony of the different usels,verify the legality prevent cheat actions,reduce applied network lock protocol this thesis. To improvereusenetworkdelay andassuredata security.Commonlyprotocolsinclude Peer-to-Peer styleprotocol,Step Lock protocol,Eventbe introduced inand Client/Serverprotoc01.These protocols willof softwaredesign,andfurther improve software developproductivity and quality,people always adopt well-known designpatterns.TheAOP(AspectOrientedProgramming),IOC(inverseOfContr01)and MVC design patternswill be discussed in this thesis.Software Design with UML will also be presented in the thesis.In addition,some the thesis.imageprocessing topicsonJava platform will be introduced inDuring theas onecourseof writing this thesis,the author developedonepractical gameexample.--Tetris Online.Thisgamebasesonamulti―users online gameframework.which uscs the C/S style network protoc01.Keyword:network,onlinegame,software design,image processing 武汉理工大学硕士学位论文第一章概述1.1前言网络让我们的地球变成一个村落!也许大部分人还无法接受这个断言,但一 个无法否认的事实是:网络正在从很多方面彻底改变我们的生活。几年前,当人 们遇到问题时,首先想到的是到图书馆去查阅资料,而现在却说我去“Google” 一下。在人际交往中,传统的信件已经基本上被Email和IM(Instant Message) 所取代。互联网正在赶超电视,逐步上升为“第一媒体”【¨。 随着Interact的发展和普及,网络游戏也逐渐成为主流的娱乐方式。今年年 初轰动一时的盛大收购新浪事件显示了网络游戏在中国的蓬勃发展。盛大于2001 年9月正式进入在线游戏运营市场,短短3年多时间发展成为中国最大的网络游 戏运营商,其总裁陈天桥也以32岁的年龄成为中国首富。现在,中国网络游戏产 业已经处在一个稳定成熟的发展阶段,逐渐形成了完整的产业链,处于产业链上 的渠道销售商、点卡销售商、上网服务业(网吧等)和媒体等,伴随着网络游戏 产业的脉搏,飞速发展起来。而占据产业整体链条上最关键地位的网络游戏运营 商,变得更加成熟和理智。同时,网络游戏公司与主要电信和网络厂商也建立了 非常紧密的合作关系【2】。 在这样的背景下,对网络游戏相关技术进行研究具有一定的社会和经济意义, 对网络游戏开发也有参考价值。1.2网络游戏及相关技术网络游戏并没有一个一致的定义,狭义的理解[31网络游戏专指网络化的RPG 游戏(角色扮演游戏),其目的和方式是建立一个虚拟的世界,在这个世界里的所 有玩家都像是生活一个全新的社会里,这个社会有它自己的各种“法律”,生活在 这个社会里的玩家必须要遵守这些法律。玩家以追求感受为目的进行模拟和角色 扮演,通过自己角色的成长而感受快乐。 武汉理工大学硕士学位论文本文所指的网络游戏并不局限于网络RPG游戏,而是泛指多人通过局域网或互联网一起参与的游戏程序。因此,包括局域网上运行的即时战略(I璐)如《魔兽争霸》、第一人称射击游戏(FPS)如雷神之槌(QUAKE)、反恐精英(CS)等, 也包括通过互联网开展的竞技类游戏,如联众的棋牌游戏。 从技术角度来说,网络游戏是综合性很强的行业,依赖的相关技术包括:游 戏设计、程序设计、数学、人工智能、图形图像、网络、音频处理等【引。在网络 游戏发展的过程中,相关技术的发展极大地促进了网络游戏的发展,如图像处理 技术的发展使游戏界面从早期的文本界面过渡N-维图形界面,现在3D游戏已 经很普遍瞪】。反过来,网络游戏的发展也成为相关技术的强大市场推动力。1.3本文研究的主要内容结合作者的研究方向,本文将讨论以下内容。I.网络游戏中的网络协议网络游戏技术中很重要的一部分就是网络协议。网络协议应该保证客户机之 间游戏状态的同步;验证客户机游戏动作的合法性,防止作弊:降低延时和响应 时间;时间同步;数据加密和安全传输等。现在的网络游戏使用的主要网络协议 包括对等用户协议、锁步协议、事件锁定、网络时间协议等。 2.网络游戏程序设计 程序开发方法、工具和技术日新月异,采用先进的开发技术有助于提高程序 开发效率,提高程序质量,降低维护费用。本文将介绍采用UML进行程序设计, AOP(AspectOrientedProgramming)?IOC(InverseOfContr01)这些比较新的技 术或设计模式,以及经典的MVC模式。3.游戏常用的Java 2D图像处理技术任何游戏都涉及动画和图像处理技术,本文将介绍Java平台下一些常用的图像处理技术。 4.示例游戏设计本文选择C/S结构的网络协议,设计了一个的多用户网络游戏框架,客户端 采用MVC模式,并在此基础上开发了一个实例小游戏一一俄罗斯方块网络版。2游戏机/ 武汉理工大学硕士学位论文1.4定义游戏世界:游戏中的所有状态,包括玩家控制的角色、游戏程序控制的角色、 和这些角色之间的动作和交互状态、以及其他非执行者对象(如物件、障碍物、 区域等)。AI:artificialintelligence,指游戏中的人工智能部分,是游戏开发过程中不可或缺的重要部分。由于硝总是用到那些由程序控制的角色上,因此m有时也专指这些会根据环境智能化地做出动作的角色。1.5本文的结构安排本文在第二章介绍了网络游戏中常用的网络协议,重点介绍了应用层协议, 比较了不同网络协议的优缺点,并提出选择网络协议的标准。本文的第三章介绍 了游戏程序设计中常用的开发技术和方法,首先介绍了使用UML辕助设计,然 后介绍了IOC、AOP、MVC等应用比较广泛的设计模式。在第四章中介绍了在 Java平台上开发2D游戏常用的图像处理技术,主要是进行动画编程时比较重要 的Java线程模型和消除屏幕闪烁的技术。在第五章中介绍了本文示例程序的设 计,设计了一个以事件和组件为基础的游戏框架,而示例游戏则以客户端组件和 服务端组件的方式集成到框架中。最后一章对本文的内容做了总结。 本文在第二至第四章的阐述中尽量采用示例游戏的设计作为实例,而示例程 序的设计则体现了前几章介绍的技术和方法。力图做到理论与实践相结合。3游戏机/ 武汉理工大学硕士学位论文第二章网络游戏中的网络协议2.1网络协议简介 网络协测6】川即网络中(包括互联网)传递、管理信息的一些规范。是网络设备之间相互通信需要共同遵守一定的规则。常见的协议有:TCP/IP协议、 IPX/SPX协议、NetBEUI协议等。在局域网中用得的比较多的是IPX/SPX。如果 访问Interact,则必须使用TCP/邛协议。 另外,OSI参考模型【6l提出了分层明确的框架,这里简单介绍一下这些协议和模型。2.1.10Sl参考模型OSI参考模型即开放系统互联参考模型(OSI Reference Model),即我们通常 所说的网络互联的七层框架,它是国际标准组织(InternationalOrganization forStandardization)于1977年提出的标准,又称为ISO/IEC 7498或X.200建议。值 得注意的是,OSI并没有提供一个可以实现的方法,它不是一个标准而只是一个 制定标准时使用的概念性的框架,更不是一个网络协议。 OSl分为七层,其名字和功能分别如下:1、物理层(Physical Layer):主要功能为定义了网络的物理结构,传输的电磁标准,Bit流的编码及网络的时间原则,如分时复用及分频复用。决定了网络连 接类型(端到端或多端连接)及物理拓扑结构。这一层主要负责实际的信号传输。 2、据链路层(Data Link Review):在两个主机上建立数据链路连接,向物理 层传输数据信号,并对信号进行处理使之无差错并合理的传输。 3、网络层(NetworkLayer):主要负责路由,选择合适的路径,进行阻塞控制等功能。4、传输层(Transfer Layer):最关键的一层,向用户提供端到端(End.to.End) 通讯服务,它屏蔽了下层的数据通信细节,让用户及应用程序不需要考虑实际的4游戏机/ 武汉理工大学硕士学位论文物理通信方法。5、会话层(Session Layer):主要负责两个会话进程之间的通信,即两个会话层实体之间的信息交换,管理数据的交换。6、表示层(Prcscntation Layer):处理通信信号的表示方法,进行不同的格式之间的翻译,并负责数据的加密解密,数据的压缩与恢复。7、应用层(Application Layer):保持应用程序之间建立连接所需要的数据记 录,为用户服务。在实现上,每一层都将本层协议信息作为信息头(header)加在上层传输的 数据上,然后向下层发出,最后通过物理介质传输到对方主机,对方主机的协议 栈再逐层剥离本层的信息头,对数据进行处理,然后把还原的数据发给上一层。 逻辑上,主机的通信是层与层之间的通信,而在物理上是从上向下最后通过物理 信道到对方主机再从下向上传输。2.1.2TOP/』PTCP/IP是“Transport Control Protocol/Intemet Protocol”的简写,中文译名为(传输控制协议/互联网络协议)。TCP/IP是Internet的基础协议,是实际应用中 使用最广泛,最重要的网络协议,相对于0SI,它是当前的工业标准或“事实的 标准”。TCP/IP分为四个层次:应用层(与OSI的应用层对应),传输层(与OSI 的传输层对应),互联层(与OSI的网络层对应),主机.网络层(与OSI的数据 链路层和物理层对应)。TCP/IP协议主要用于广域网,在一些局域网中也有应用, 但是在功能和速度方面有差距。 TCP/IP是在60年代由麻省理工学院和一些商业组织为美国国防部开发的。 在TCP/IP协议基础上开发的ARPANET逐渐发展成为目前规模巨大的Interact。 Interact的巨大影响也使TCP/IP协议成为网络协议的工业标准。有很多流行的 Interact应用协议都是基于TCP,IP协议的,如HTrP,FTP,SMTP,Telnet,SNMP 等,另外,与TCP协议同属于传输层协议的UDP协议应用也很广泛。2.1.3其他协议NetBEUI(NETBIOS Enhanced UserInterface),或NETBIOS增强用户接口。5游戏机/ 武汉理工大学硕士学位论文它是NETBIOS协议的增强版本,是IBM开发的非路由协议,用于携带NETBIOS 通信。NETBEUI缺乏路由和网络层寻址功能,它不需要附加的网络地址和网络 层头尾,所以很快并很有效且适用于只有单个网络或整个环境都桥接起来的小工作组环境。IPX/SPX(Intemetwork Packet Exchange/Sequenced Packet exchange)是NOVELL用于NETWARE客户端朋匣务器的协议群组。IPX具有完全的路由能力, 可用于大型企业网。IPX基于施乐的XEROX’S Network System(XNS)协议,而SPX是基于施乐的XEROX’S SPP(SequencedPacketProtocol:顺序包协议)协议。它和TCP/IP的一个显著不同就是它不使用ip地址,而是使用网卡的物理 地址即(MAC)地址。IPX/SPX在网络普及初期发挥了巨大的作用,所以得到了 很多厂商的支持,包括microsoft,到现在很多软件和硬件都支持这种协议。2.2网络游戏中常用的网络应用层协议网络游戏中使用的底层协议基本上是前述的基本协议,主要使用TCP/IP协 议。在应用层协议(概指传输层以上的协议)的选择上,根据不同游戏的特点, 会有不同的选择【剐。 游戏的网络应用协议的目标主要有: 1.协议应该保证每个客户机之间游戏状态的同步:这是对协议最基本的要求。2.协议应该能够有效地防止玩家欺骗行为。 3.协议应该降低网络延迟,提高响应时间。 4.协议应该考虑数据加密和安全性。 不同类型游戏的网络要求是大不一样的,需要更加具体情况进行选择。在本 节中,作者将介绍几种应用比较广泛的网络协议,包括对等用户、锁步协议、事 件锁定、C/S结构。然后根据这些协议的特点,结合本文示例程序的需求选择一 种协议。6游戏机/ 武汉理工大学硕士学位论文2.2.1对等用户在对等用户协议【8】中,每台计算机都同样重要。每个计算机都拥有着游戏状态的一部分,而且能完全决定在这一部分上发生的事件(一般说来,此部分包含游戏玩家的实体和几个AI的代理)。 优点:此协议的好处就在于由本地计算机拥有的这一部分可以得到立即刷新。 在理想状态下。玩家的计算机将拥有离自己最近的那部分AI代理,因为对于其 他较远的玩家来说,它们就不那么重要了。 缺点:其坏处就是在游戏中的任何两个物体或是对象之间要发生交互都需要 有一个对应的网络包,这样才能在两台不同的计算机之间产生一样的输出。当然, 随着游戏状态的扩张,根据网络通信状态而定的需要发送的包数也会成平方增长。2.2.2C/S结构即客户机朋艮务器结构【81,对于这种结构而言,其最常用的协议就是要求每个 玩家都有一个“客户机”程序,它几乎可以被看成就是一个哑终端;有个服务器 用来运行游戏,概念上,它处在任何客户机的远端,即使在实际情况中它可以是 和某个客户机在同一台机器上的。服务器告诉每个客户机能看到什么,每个客户 机根据玩家的输入决定告诉服务器它希望发生什么事情,服务器根据当前的游戏 状态同意或否决玩家的请求,如果服务器同意了玩家的请求,将更新游戏状态。 并将状态更新通知给客户端,客户端再根据状态更新的通知修改本地的游戏状态, 同时通知游戏界面做出相应的响应。另外为了增加游戏的平滑性的,一般需要在 客户机上对服务器可能的反应作一些预测。 优点:这个协议的好处在于它的简单性,以及能有效地防止欺骗(因为服务 器可以禁止某些非法的动作)。客户机可以随时加入或退出,但是服务器上的游戏仍然存在。缺点:不过,它要求客户机上可见的世界状态要比较少,因为这样就可以不 停地重传游戏状态了。如果游戏状态特别多且更新非常频繁的话,不适合使用这 种协议。7游戏机/ 武汉理工大学硕士学位论文2.2.3锁步协议使用锁步协议I 8】的游戏是在所有参与游戏的计算机上同步运行的。它们从同一个游戏状态开始,游戏时间分为若干周期。在每一个周期里面,每台计算机都 在自己的游戏世界里接受一个动作以前进一步。在此周期的结尾,每台机器都会 告诉其他所有的机器用户究竟做了一些什么动作。同上于所有的机器都知道所有 的用户在做什么,因此它们就可以共同得到在下一个游戏周期的世界,从而保持同步了。优点:这个协议很容易实现,而且其带宽要求也相对较低,因为需要传输的 东西只有用户的输入(有可能数帧才有一个输入)。其带宽与游戏的状态也是无关 的,这对于游戏状态特别多的游戏(如实时策略游戏)来说是一个很大的优点。 与客户机朋匣务器系统有些类似,一些欺骗行为在这种协议下很难实行,因为 任何对游戏状态的非法改动都会使得此机器与其他机器失去同步。在另一方面来说,由于每台机器上都有整个游戏的状态,但是可能会有另外的欺骗――例如,修改游戏以能看见更多的位置。缺点:这个协议的一个缺点就是每秒游戏的周期数是受到往返网络延迟的限 制的。在每个游戏周期的结尾,这些机器在都必须至少收到从所有其他机器来的 一个确认信息,这样才能继续得到会直接影响到游戏,只能间接地通过网络的代 码来影响游戏。这就确保了所有的游戏都是在处理相同的信息,而且必须时刻遵 循这条规则。同时,还必须对时间和随机数生成器保持同步。2.2.4事件锁定事件锁定协议18】需要一个服务器,通常情况下某台客户机同时也是服务器, 每个客户机都可以发送对事件的请求,而事件处理则由服务器来负责,一旦服务 器认为可以发送,那么此事件将同时对所有的客户机广播。 例如,假设有一个典型的实时策略游戏,在其中一个玩家决定要移动一个坦 克。于是玩家在自己的客户机上面发出了移动命令,在执行之前还需要对之进行 合法性的检查。如果合法的话,客户机将向服务器发送一个Request MoveTank包。接下来服务器将进行自己的合法性检验,一旦认为此移动是合法的话,就将8游戏机/ 武汉理工大学硕士学位论文向所有的客户机发送一个Move Tank的包,其中也包括了那个发出请求的客户机。 注意并不是所有的客户机都会同时收到此事件包的,因此必须在事件里面包 含相应的信息,以便于客户机能在适当的时候开始执行事件。例如一个移动的事 件,比方说上述的MoveTank包,可能会包含一系列的地点,其中每个都有一个 相应的到达时间。一个收包比较迟的客户机可以将坦克直接移到当前应在的地点, 或是当差异不大的时候,只需要将其动画加速一下就可以了。 与客户机/服务器系统类似,使用这个协议时一般要对服务器的反馈进行预 测,以增加游戏的平滑性。例如对于移动请求来说,如果服务器很有可能会同意 此请求的话,可以在客户机上即时就开始“非法的”移动。当然这种非法的移动 不能改变真实的游戏状态,这样如果服务器拒绝了这个请求时,只需取消这种临 时的状态就行了,真实状态的改变需要在服务器通过请求时才发生。所有重要的 决策都应该由服务器来处理。如个体的创建与销毁、寻径以及目标瞄准的决策都 是由服务器控制和广播的。然而,移动和进攻都是在每台客户机上独立完成的, 不会产生任何网络流量。 事件锁定协议看起来与C/S结构很类似,但还是有一些区别的。在C/S结构 系统中,服务端一般是专注只提供服务器功能的,而在事件锁定协议中,通常是 其中一台客户机同时充当服务器。C/S结构系统中服务器可以选择只将某些游戏 状态的改变发给部分客户机,而事件锁定协议中所有游戏状态改变的事件会发给 所有客户机。由于这个限制,事件锁定协议中通常所有客户机都保持了整个游戏 世界的完整状态,而C/S结构系统中只有服务器拥有游戏世界的完整状态,客户 端只知道部分的状态。 优点;避免锁步协议中最慢的客户机拖慢所有的人的问题,与锁步协议类似, 能防止玩家修改游戏状态的欺骗行为,但是玩家可能修改游戏以能看见比平常更多的位置。缺点:与C/S结构系统类似,如果客户机需要由服务器处理的大量的事件, 不适用这种协议。2.3游戏网络协议的选择游戏类型决定了游戏网络协议的选择,影响选择的关键因素是游戏状态属性9游戏机/ 武汉理工大学硕士学位论文和游戏事件的要求。如果把打电话看成一种游戏的话,其状态是非常少的,而事件特别多,这时 使用对等用户的协议是恰当的,由于容许少量的事件丢失,传输层使用UDP就可 以了,这种情况下用C/S结构或事件锁定协议肯定是没有必要的。 现在大型的互联网游戏中整个游戏世界非常庞大(游戏状态非常多),而一个 玩家玩游戏时需要的游戏状态只是整个游戏世界的一小部分,一般还容许玩家休 息时,将自己的游戏状态保存下来,这种游戏需要使用客户端,服务器协议。 在一些局域网游戏中,需要传输大量的游戏事件,这时使用锁步协议或者事 件锁定协议都是可行的。 有些游戏还可以组合不同的游戏协议,例如在C/S系统游戏中,使用对等用 户协议让玩家进行语音、视频交互。 对于传输层协议的选择,如果要同步游戏状态,一般应该选择TCP,因为这 是一种保证可靠传输的协议。也有一些游戏开发人员在UDP之上编写了自己的可 靠传输协议,认为他们能改善TCP算法以得到更小的延迟,这是没有必要的。在其他的游戏协议中――例如那些当个体移动的时候就产生网络流量,可能会用在飞行模拟器中的协议――丢包是没什么了不起的,因为更新的数据马上就会到来以更正此丢失产生的错误。这时可以选择UDP作为传输层协议。 写作本文时,将实现一个经典的小游戏一一俄罗斯方块,让两个人可以通过 网络对玩。这个游戏的状态和事件都不多,考虑游戏框架的扩展性,选择了C/S 结构的应用协议,传输层选择TCP协议。游戏机/ 武汉理工大学硕士学位论文第三章游戏程序设计3.1使用UML配合设计3.1.1UML简介UML[gl【10j Ill!是一种标准的图形化建模语言,已经成为面向对象分析和设计的一种标准图形化表示,使用一个通用的图形语言有利于开发人员之间的交流。 有利于提高生产率、减少延期和开发的成本。 UML主要定义了9种类型的图: UML用以下四种静态视图来表示系统的静态部分:类[](Class Diagraml对象I羽(Object Diagram) 组件图(Compoment Diagram) 部署图(Deployment Diagram)使用下面的五种动态视图来表示系统动态的方面:用例图(UsecaseDiagram)顺序匿q(Sequence Diagram)协作图(Collaboration Diagram) 状态m(StatechartDiagraml活动图(Activity Diagram)3.1.1.1类图类图显示了一组类、接口和协作以及它们之间的关系。类图在面向对象的建 模设计中是很常用的。利用类图阐明系统的静态的设计。包含活动类(active classes)的类图通常用来说明系统静态过程。游戏机/ 武汉理工大学硕士学位论文3.1.1.2对象图对象图显示了一组对象和他们之间的关系。使用对象图来说明数据结构,类 图中的类或组件等的实例的静态快照。对象图和类图一样反映系统的静态过程, 但它是从实际的或原型化的情景来表达的。3.1.1.3组件图组件图显示了一些组件和它们之间的关系。使用组件图来说明系统的静态实 现。组件图和类图是有联系的,通常一个组件可以映射成一个或多个类,接口或协作。3.1.1.4分布图分布图显示了一些节点和它们之间的关系。使用分布图来说明系统的静态结 构。分布图和组件图是有联系的,通常一个节点封装了一个或多个组件。3.1.1.5用例图用例图显示了一些用例和角色(特殊的类)和他们的关系。使用用例图来描 述系统静态的功能场景。用例图对于组织和模型化系统的动作是很重要的。3.1.1.6顺序图顺序图是一种交互图(interaction diagram),强调的是时间和消息的次序。一个顺序图显示了一系列的对象和在这些对象之间发送和接收的消息。对象通常是 命名或匿名的类的实例,也可以代表其他事物的实例,例如协作、组件和节点。 使用顺序图来说明系统的动态情况。3.1.1.7协作图协作图是一种交互图(interaction diagram),强调的是发送和接收消息的对象之间的组织结构。一个协作图显示了一系列的对象和在这些对象之间的联系以及 对象间发送和接收的消息。对象通常是命名或匿名的类的实例,也可以代表其他事物的实例,例如协作、组件和节点。使用协作图来说明系统的动态情况。12游戏机/ 武汉理工大学硕士学位论文注意:顺序图和协作图是同构的,它们相互之间可以转化而不损失信息。3.1.1.8状态图状态图显示了一个状态机,由状态、转换、事件和活动组成。使用状态图说 明系统动态情况。状态图对于建模接口的动作、类的动作或协作的动作是重要的。 状态图强调的是事件驱动的对象的动作,这在对反应式系统的建模是相当重要的。3.1.1.9活动图活动图显示了系统中从一个活动到另一个活动的流程。活动图显示了一些活 动,他们很象传统的流程图有序列或分支。活动图对于给系统的功能建模是很重 要的。活动图强调的是对象之间的流程控制。3.1.2使用UML设计程序这一节将以本文示例程序为例,讨论部分UML图在程序设计中的应用。让 我先简单介绍一下游戏的情节。本文的示例程序是经典的俄罗斯方块游戏,游戏 不断产生不同的图形,并且会驱动游戏板上的图形往下落,玩家要控制图形左右 移动或翻转,如果图形落到游戏板上后某一行或多行没有空格的话,游戏会将这 些行去掉,并给玩家加分,并按一定的规则提高游戏的难度。如果玩家最新出现 的一个图形已经无法放置到游戏板上时,玩家就输掉了游戏。看起来,玩家是永 远都无法赢得这个游戏的,因为无论怎样,总会有图形往下落的,也许正因为如 此,这个很古老的游戏至今仍充满魅力。3.1.2.1设计用例设计用例第一步是要标出动作和其参与者。对于这个程序来说我们可以标出两个能发起动作的参与者――游戏的玩家、游戏定时器,另两个参与者一一图形和游戏板是被动的。然后我们需要为情节设计其主要的行为。对于UML来说, 这些行为可以被形式化为用例。用例是非常重要的,因为它们定义了整个系统应该如何建构。在下面的用例图(图3-1)中,参与者是用小人表示的,用例是用椭圆表示的。这些对象中的连线代表的是通信,支持的动作有“使用”和“扩展”,游戏机/ 武汉理工大学硕士学位论文它们将几个用例联系了起来。在此图中,有好几个用例都是扩展移动图形这个用 例的,而定时器执行定时工作这个用例使用了其他几个用例。图3.1:俄罗斯方块游戏用例图3.1.2.2用顺序图细化动作用例对于快速地创建一个有关设计概念的草案是非常好的,但是它们仍然太 抽象了,可能会在更细的概念上产生误解。用顺序图可以描述一个动作执行中的 各个参与者交互的详细情况,或者也可以称为情节。 顺序图(图3―2)描述了用户将图形向左移这个用例的情节: ?模型先检查当前是否有活动的图形: ●检查图形是否可以在游戏板上向左移动:●模型将图形向左移动:】4游戏机/ 武汉理工大学硕士学位论文?模型通知观察者(一般是视图)发生了图形向左移动的事件。国匡圣叵垂鲴!吐Imj:mo垤Created with Poseidon for UMLComwJrttyEditorL Not for Comn∞rcial Use图3-2:移动图形顺序图3.1.2.3使用状态图状态图能展示出一个对象所能经历的不同状态以及其条件转化。这是最适合 用一种图形化工具来表达的。图3.3显示了游戏模型的各种状态:游戏机/ 武汉理工大学硕士学位论文●nEialdCreated_With PoseidonforUMLCommunity EardiorINotforCorm№rciaf Use图3―3:俄罗斯方块游戏状态图3.1.2.4UML工具现在有很多UML工具,最流行的是Bofland Together和Rational Rose,另外还有一个开源的UML建模工具ArgoUML(http://argouml.堍ris.o嘭)也可以使用,本文中使用的Gentleware公司的Poseidon就是基于ArgoUML开发的。3.1.3使用UML的意义使用一个通用的图形语言――统一建模语言(UML)。通过在同一个模型上共同工作,有利用团队中不同角色的沟通,加强开发人员和设计人员之间的协作, 设计人员和开发人员将把注意力放在具体的业务逻辑上,不用去为了相互沟通而去强迫学习另一种设计语言。16游戏机/ 武汉理工大学硕士学位论文除了可以简化设计人员者和开发人员之间的通信以外,UML还有更大的用途。隐含于UML之中的主要思想就是迭代式的建模过程。这意味着不需要f而且 甚至根本不用去想)在开始实现之前就要把整个程序的设计做完。整个开发过程是增量式的,是一个设计人员和开发人员交互的过程。实际上,很多UML开发工 具都有代码生成和逆向工程的功能。因此,开发人员可以先开发然后在需要的时候再去修改设计。通过使用计算机辅助软件工程工具,我们可以在面向对象方法的基础上增量 式地工作,同时还能保持对代码的完全控制,并且有更好的可维护性、更好的文 档,以及程序更强的可重用性。3.2使用IOC容器装配应用程序IOC(Inversionofcontr01)即反转控制模式,Martin Fowler在InversionofControl Containers and the Dependencyhjecfion paRern[12】一文中认为应该HqD109ependency Injection)依赖注入模式更加合适。在大型的系统中,通常整个系统划分成多个组件(或是服务),而这些组件之 间通常都存在相互依赖关系。比如一个处理用户订单的组件,它可能会依赖于产 品及库存管理组件、还会依赖于用户管理组件、处理出现意外情况时可能要给客 户发送邮件或短信通知,因此还会依赖于通讯组件。我们这个订单处理组件该怎 么解决这些依赖关系呢? 直接使用Java的new操作符是不行的,如果使用了new操作符,那就局限 于指定的一种实现了,另外,你还必须预先知道被初始化的组件有些什么依赖关 系,还有,有些组件是根本不能直接使用new操作符的,它们可能只能由J2EE 容器来初始化。 我们可以通过JNDI(JavaNaming and DirectoryInterface)[13】查找,但这样J2EE就假设需要的组件肯定已经进行JNDI绑定了;另外,也可以使用SUNBlueprint推荐的Service Locator模式【14】,这比直接通过JNDI查找方便一些,有没有更好的方法昵? IOC(DI)模式就是用来解决组件间依赖关系的通用解决方案。依赖注入的 原则是很简单的:你只需要声明依赖于哪些组件就行了,剩下的事情由IOC容器17游戏机/ 武汉理工大学硕士学位论文来解决!下面的代码清单是示例游戏中服务器端的Spring组件配置文件,在这个文件 中配置了游戏服务器及其依赖的所有组件,其语法应该是非常简单明了的。<beans> <bean id=”gameServer”class=”game.framework。server.GameServer” init.method=”init”> <property name:-”playerRegister'’><ref bean=”playerRegister”,></property> <property name=”eventDispatcher”) <ref local=”eventDispatcher”/> </property></bean><bean id=”eventDispatcher’。class=”game.framework.dispatcher.DefaultEventDispatcher”> <constmctor-arg><value>1</value></constructor-arg><property namE=”intercepters’’> <list><bean id=”checkAndAddPlayerlfNeccssary”class=”game.framework.util.ObjectMethod”><propeny name=”objoct”> <ref bean=”playerRegister’I,></property>‘propertyname--”eventProcessMethodName”><value>checkAndAddPlayerlfNecessary<,/value>c/property></bean></list> </property>】8游戏机/ 武汉理工大学硕士学位论文</bean><beanid=”eventSender’’class=”game.framework.server.EventSender"><c彻structor-arg><ref bean=”gameServer’'/></constructor-arg><coastructor-arg><value>l</value></constructor.arg></beall><beanid2’’chatter’’class=”game.component.chat.selveLChatter”><property na//le=’'gameServer”><refbean=”gameServer”/></property> </bean><b。如id=”playerRegister”class=’'game.component.server.PlayerRegisteT”><property llallle=”gameServer”> <ref bean=”gameServer’t/></property></bcan><beanid=”tetris”class=’'game.sample.tetris.TetrisGameScⅣ∥><property nalne=”gameServer”><refbean=’’gameServer’f/></property></bean><bean id=”debug’’c18882”org?springframework.aop.interceptor.DebugIntercepton<propcnyname=”useDynamicLogger”><value>true</value></property></bean></beans>19游戏机/ 武汉理工大学硕士学位论文IOC(DI)模式要求组件声明自己需要依赖的其他组件,IOC容器一般支持3种类型的依赖注入:接口注入:为了让容器注入依赖关系,需要实现容器特定的接口,这样组件 又依赖于容器了,因此这种依赖注入方式已较少采用。 Setter方法注入:就是使用JavaBeanDSl属性规则声明对其他组件的依赖,这 在java中很常见,同时也很直观、自然。 构造器注入:通过在构造函数中声明对其他对象的引用来实现,这种方法比 较安全,因为通过构造器初始化对象,可以确保需要的依赖关系都得到满足,而 暴露过多的Setter接口,会对对象封装造成破坏。 使用IOC模式可以将服务的配置与使用分开。实际上,这是一个基本的设计原则――分离接口与实现。现在有很多基于IOC模式的轻量级容器,如Spring框架f15l【…,PicoContainer[171和apache hivemind!“,在示例程序中使用的是 Spring框架。3.3使用AOP加强程序的模块性AOP【l川(AspectOrientedProgramming),面向方面编程,是一个比较热门的of话题。AOP的主要目的是分离关注点(separationCJDrlC圮I'nS),软件系统中有些功能是横跨多个模块的,使用AOP的方法可以将这些横切性(crdsscIltting)关注点提 取为方面(Aspect也有的翻译为“切面”),这些Aspea可以独立实现和进化, 然后可以织入(Weave)到相关的业务过程中,这样可以获得高内聚、低耦合、 模块性更好的软件系统。本文介绍AOP的基本概念及其在Java平台上的应用。3.3.1为什么要AOP我们已经有了OOP(ObjectOricntedProgramming)D8J【加1141l了,面向对象使我们可以很容易实现封装、继承、多态,有了OOP,我们已经可以写出很优雅的代 码,为什么还要AOP昵? 举一个例子说明AOP的作用12”。如果有一个非常大的系统,其中大概有100020游戏机/ 武汉理工大学硕士学位论文万行的代码。假如你要给这样一个应用系统加上“身份认证”的功能,运用OOP 的思想,我们可以增加一个Class(或模块)实现身份认证的功能,然后在需要应 用身份验证的地方,调用该身份认证模块来验证,那么每一个交易都需要修改, 改动是非常大的。也许“身份认证”这个新特性也就是一行、两行的代码,但把 它放进1000万行的代码就会造成其它部分需要大量的修改。这会消耗相当长的时 间,而且会具有相当的风险。所以,我们用另外一种思路去对待这种情况:我们 不去动那1000万行的基本代码,只是把“身份认证”的功能放进一个独立的小 模块,然后再把这个小模块“织入”其他的功能模块中,让它发挥作用。这样一 来,修改的工作量就变得小多了。这是AOP的一个最简单的运用。 AOP的核心思想就是在编程的时候把各种特性分离,分离后的各种特性是相 对独立(正交)的,实现一种特性的时候基本上不用考虑其他的特性,但是这些 松散耦合的特性又可以编织(Weave)成完整的程序。这样的架构是一种松散耦 合的,更加容易实现、理解和维护。 一个软件系统的需求一般可以分解为功能需求(业务需求)和非功能性需求 如日志、事务、安全等,这些非功能性需求通常是横跨多个模块的。如果使用J2EE 容器,这些服务一般可以用宣称式配置的方式让容器来完成。使用AOP的方式, 在J2EE容器外我们也可以比较容易地实现这些服务。3.3.2Java平台上的AOP实现及应用目前.1ava[26l127112s】[29】平台上主要的AOP实现[20l有AspectI[22]、AspcctWerlczI捌、JBoss AOPl24l和Spring AOP[矧,其中Aspectl和AspectWerkz将合并。各个实现有很大的区别㈣,但是其核心概念是一样的,因为他们都是要达到分离关注点这个一致的目标。以下简单介绍一下AOP的基本概念: 1)advice(处理逻辑):advice是我们方面功能的实现,它给被应用Aspect 的模块增加新的行为。比如对于一个事务管理的Aspect,其advice应该 实现事务管理的逻辑。 2)jointpoint(连接点):连接点是Aspect可以插入应用程序的地方,比如对象初始化,方法调用,属性访问,用得最多的是方法调用。3)pointcut(切入点):pointcut可以控制你把哪些advice应用于哪些游戏机/ 武汉理工大学硕士学位论文jointpoint上去,一般可以通过正则表达式来决定哪些jointpoint会获得通知。4)target(目标类):是指那些将应用aspect的类,一般是功能性需求的实 现类。 5)proxy(代理类):使用了proxy的模式。target应用了advice以后就是 proxy,一般proxy实现了target相同的接口或者成为target的子类。 6)weaving(织入):是指应用aspects到一个target对象创建proxy对象的 过程,织入一般发生在编译、类加载或者运行时。 7)aspect(方面):是一个抽象的模块化单元,一个aspect通过advice和 pointcut重新组装业务功能模块,实现某一类带有横切性质的功能,如事务管理。为了便于理解,下面直接使用Java对动态代理的支持,完成一个简单的Aspect示例,JDK Proxy汹¨“1也是Spring AOP中缺省采用的方式。示例代码如下:HelloSarvlce.Javapuhllo interfaoeHelloSarvlce{ nama)jvoid helloI String)HelloImpl.Javapublio olass HelloImpl Imple_entspublioHelloService(voidhello(String nam6)tSystem?out?prIntln(’Hello。+n∞e+。l。)j) )JDKProxyGreetingHandler.javaimportjav6t?1a“g.reflect.InvocationHandler;22游戏机/ 武汉理工大学硕士学位论文jeva.1ang.reflect.Method;importimportjava.1ang.reflect.Proxy;classpublicJDKProxyGreetingHandler implementsInvocationHendler(privateObjecttarget;publicObject invoke(Object proxy.Method method.Object【】args)throwsThrowable(System?out?prinfln(。Welcome.。+args【0】);Object result;method.invoke(target,args):System.out.println(。Goodbye,。+args【0】);return result;publicetatioObject bind《Object target)fhandler―newJDKProxyGreetingHandlerJDKProxyGreetingHandler()jhandler.target=targetj returnProxy.newProxyInstaDce(target.getClass().getcla88Loader(). target?getClass().get工nter£aces{),handler)7publicstatlo voidmain(string(Jargs)(HelloServlce hello;newHelloImpl():hello.hello(。Java。);HelloServiceproxy=(HelloService)bind(hello):proxy?hello(。World。】;游戏机/ 武汉理工大学硕士学位论文运行JDKProxyGreetingHandler类,输出如下:Hello JavalWelcome,WorldHelloWorld IGoodbye,World其中第一句是调用hello.hello(”Java”)产生的,但调用proxy.hell“”World”)却输 出了3旬,我们这里只是简单的在方法执行前后加入了输出语句,利用同样的方 法我们可以做更多事情,比如参数检验、运行日志、事务和安全管理等等。 从这个例子看,JDKProxyGreetingI-Iandler.main方法中的hello对象是我们的 target,JDKProxyGreetingI-Iandler.invoke方法是我们的advice,jointpoint是方法调 用,而JDKPmxyGreetingHandler.bind方法在运行时将advice应用到target上而产 生proxy,这里没有显式的pointcut,实际上就是将advice应用于target的每个方法调用了。JDK Proxy要求target实现某个需要的接口,只支持方法调用这种jointpoint,如果需要在对象初始化、属性访问、流程控制语句等时机应用 Aspect,或者需要应用Aspect的target根本就没有实现某个接口,就需要应用 上面提到的AspectJ、AspectWerkz、JBoss AOP和Spring AOP这些hOP工具了。 这些工具一般提供了IDE支持、完善的pointcut配置等更加强大和易用的特性, 一般使用XML文件、Annotat ion、Javadoc属性来配置Aspect,AspectJ更是扩 展了Java语法,在相关项目网站上可以找到学习文档。AOP的核心思想是以松散 耦合的方式分离关注点,除了使用以上提到的工具,很多情况下都可以利用这种 思想,例如用Servlet过滤器(filter)来处理日志、安全性检查等横切性问题。3.3.3AOP模式总结使用AOP可以把项目中不同Aspect分离开。尤其是那些横切性(crosscuttin曲的问题,例如事务管理、身份认证之类的。分离出来的Aspect可以模块化和重用,这是AOP的核心意义。在项目中应用AOP可以提高项目的模块性,由于不同方 面的代码是相对独立的,因此可以减少耦合度,增加代码重用性,减少代码量,游戏机/ 武汉理工大学硕士学位论文进而提高生产力,提高项目质量。示例游戏中运用了AOP思想,使用一个拦截器检查用户是否已登录,起到了很好的效果,具体见53。1节。3.4MVC模式的应用在开发图形界面程序时,没经验的程序员很容易将界面、控制逻辑、和问题 模型混在一起,形成难以扩展,很难阅读的代码。有很多理由希望将用户界面跟 问题的模型分离开: 1.相对于用户界面,问题模型一般是比较固定的,同一个问题模型可能 会有GUI的界面,同时还要支持命令行和文本输出的接口。2.在软件开发的分工上,界面和模型通常是由不同的程序员来开发的,将不同逻辑的代码分开有利于支持这种不同工种的合作。 3.将控制代码独立出来使程序结构更加清晰,从而可以构造出非常灵活 的控制器。 MVC设计模式[361(MVC:Model.View.Comroller模型.视图.控制)就是用 来解决这类问题的,采用MVC设计模式可以使用户界面和计算模型独立演化, 并且可以形成很灵活,逻辑清晰的控制器。本节将介绍MVC模式及在示例程序 中的应用。3.4.1MVC设计模式简介MVC由Trygve Reenskaug提出,首先被应用在SmallTalk.80环境中,是许多交互和界面系统的构成基础。MVC结构是为那些需要为同样的数据提供多个视图的应用程序而设计的,它很好的实现了数据层与表示层的分离。MVC作为一种开发模型,通常用于分布式应用系统的设计和分析中,以及用于确定系统各 部分问的组织关系。对于界面设计可变性的需求,MVC(Model.View-Controller) 把交互系统的组成分解成模型、视图、控制器三种部件。图3-4是MVC模式中 各部件的交互模型。游戏机/ 武汉理工大学硕士学位论文图3.4:MVC模式交互图 模型3.4.1.1模型的职责如下: 1.模型封装应用程序状态。 2.响应状态查询请求。 3.暴露应用程序的功能 4.将程序状态的改变通知视图可见,模型封装了应用程序的核心逻辑。但模型本身不提供uI元素,但是 可以当模型的状态改变时,可以通知视图,而且提供接口让视图组件查询模型状态。3.4.1.2视图视图的职责如下:1.以该视图特定的方式显示模型2.向模型查询状态游戏机/ 武汉理工大学硕士学位论文3.发送用户控制事件给控制器 4.容许控制器选择视图 在视图中仅仅处理模型的显示,只是作为一种输出数据并允许用户操纵的方 式。如果是命令行形式的视图,那么显示视图仅仅是将模型用文本表示并显示出 来,而操作数据就是用各种文本命令了。对于GUI形式的视图,可以将模型表现 得更丰富,而输入一般主要是用鼠标了。视图并不直接控制模型,而是通过控制 器转发改变模型状态的请求,这样就把控制部分的代码完全独立出来了。3.4.1.3控制器控制器的职责如下:1.定义应用程序的行为2.将用户的行为映射到模型更新请求 3.根据请求选择不同的视图作为响应 控制器接受用户从视图转发的输入并调用模型和视图去完成用户的需求。控 制器本身没有核心的业务逻辑,它只是接收请求并决定调用哪个模型构件去处理 请求,然后用确定用哪个视图来显示模型处理返回的数据。可见控制器是Glue Code,将视图和模型衔接起来了。3.4.2MV0模式在示例程序中的应用示例程序中使用了MVC模式分离模型和视图,并提供了一个可以在不同模 式下工作的控制器,使得很容易通过简单的配置得到差异很大的运行模式,详见5.5.1节。3.5其他设计模式设计模式(Design Patterns)[37】[391描述了那些在我们周围不断重复发生的问题,以及该问题的解决方案的核心。这样,我们就能一次又一次地使用该方案而不必做重复劳动。现在大家都提倡组件复用,而设计模式则提倡更抽象层次的复用,可以说是程序设计思想的复用,好的设计模式是平台无关的,比如MVC模游戏机/ 武汉理工大学硕士学位论文式,这种用来很灵活地构建用户界面的模式在各种平台都能找到其对应的应用。 一般而言,一个模式有四个基本要素:1.模式名称(pattern name)一个助记名,它用一两个词来描述模式的问题、解决方案和效果。命名一个新的模式增加了我们的设计词汇。设计模式允许我们 在较高的抽象层次上进行设计。基于一个模式词汇表,我们自己以及同事之间就 可以讨论模式并在编写文档时使用它们。模式名可以帮助我们思考,便于我们与 其他人交流设计思想及设计结果。找到恰当的模式名也是很重要的。 2.问题(problem) 描述了应该在何时使用模式。它解释了设计问题和问题存在的前因后果,它可能描述了特定的设计问题,妇怎样用对象表示算法等。 也可能描述了导致不灵活设计的类或对象结构。有时候,问题部分会包括使用模 式必须满足的一系列先决条件。 3.解决方案(solution) 描述了设计的组成成分,它们之间的相互关系及各自的职责和协作方式。因为模式就像一个模板,可应用于多种不同场合,所以 解决方案并不描述一个特定而具体的设计或实现,而是提供设计问题的抽象描述 和怎样用一个具有一般意义的元素组合(类或对象组合)来解决这个问题。 4.效果(consequences) 描述了模式应用的效果及使用模式应权衡的问题。尽管我们描述设计决策时,并不总提到模式效果,但它们对于评价设计选择 和理解使用模式的代价及好处具有重要意义。软件效果大多关注对时间和空间的 衡量,它们也表述了语言和实现问题。因为复用是面向对象设计的要素之一,所 以模式效果包括它对系统的灵活性、扩充性或可移植性的影响,显式地列出这些 效果对理解和评价这些模式很有帮助。 设计模式使人们可以更加简单方便地复用成功的设计和体系结构。将已证实 的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。设计模式 帮助你做出有利于系统复用的选择,避免设计损害了系统复用性。通过提供一个 显式类和对象作用关系以及它们之闻潜在联系的说明规范,设计模式甚至能够提 高已有系统的文档管理和系统维护的有效性。简而言之,设计模式可以帮助设计 者更快更好地完成系统设计。 除了前面所说的lOC,AOP,MVC模式外,示例程序中还使用了其他的模式, 比如状态模式:游戏机/ 武汉理工大学硕士学位论文一个对象的行为通常是更加对象的状态而改变的,比如TetrisGameModel其 状态是比较多的,如其状态图(图3.3),如果我们需要对TetrisGameModel进行 move的操作,该怎么实现昵?一般说来,我们会先判断TetrisGameModel是不是 处于Running的状态,如果处于Running状态,我们才真正她去执行move操作, 可以相信,如果对象的状态很多,而支持的操作也很多的话,程序中将充斥着 if-else或switch-case-break语句,这样的代码很容易出错,而且可读性、可维护性 都很差。使用状态模式这个问题将变得很简单,如顺序图(图3.5)所示,把对 象的状态设计成一个类,当别的对象调用本对象的某个操作时,对象简单地将调 用转发给状态去处理。在我们的例子中,NotRunning的状态对move调用什么都 不做,而Running状态才真正做move操作。状态模式是应用很广泛的一个模式。国:pamms:doSomething国:国:Createdwith PoseidonforUMLCommunity Ebtlon.NotforCommercialUse.图3.5:状态模式顺序图 GoF的《设计模式》[rq一书提出了基本的23种设计模式,很多新的模式也 被不断总结出来,而原来的一些设计模式现在被认为是反模式。怎样才能掌握好 设计模式呢?只要记住设计模式是特定问题的一种比较成熟的解决方案的总结, 在具体应用中,如果碰到类似的问题,我们就可以复用同样的解决方案。现有的 比较成熟的设计模式一般是一些软件设计大师总结出来的,运用这些设计模式, 就是站在巨人的肩膀上,很容易得到好的软件设计。现在有很多软件框架,这些 框架一般都应用了一些很好的设计模式,将设计模式具体化了,使用这些框架, 也间接地应用了这些设计模式,有助予提高软件的整体设计水平。游戏机/ 武汉理工大学硕士学位论文第四章游戏常用的Java 2D图像处理技术4.1动画Java动画编程有多种实现方法,但它们实现的基本原理是一样的,即在屏幕 上连续画出一系列的帧来造成运动的感觉。那么由谁驱动来画这些帧呢?这里就要使用Java多线程技术了。4.1.1,Java线程模型图4-1是Java线程模型【30l 131l[321状态图133】,要使用线程,可以扩展Thread 类或实现Runnable接口。线程启动后并没有马上运行,而是处于Runnable的状 态i处于Runnable状态的线程才有机会被调度执行,线程被调度执行就处于 Running的状态了,线程执行完run方法,或者被调用interrupt方法中断就会成为 Dead状态,线程执行过程中执行任何对象的wait方法、执行sleep方法、或执行 同步10操作时会分别转换为Waiting、Sleeping、Blocked的状态,这些都是 Non―Runnable的状态,即使CPU有空余时间,处于这些状态的线程也不会被调 度运行,当导致他们停止运行的情况解除时,他们可以重新转换为Runnable的状 态,等待下次被调度运行。相对于Dead状态,Runnable、Running、Non-Runnable 的状态下的线程都是Alive的。在进行动画编程时,我们经常接触的是sleep方法, 该方法容许线程暂停一段指定的时间,然后恢复执行。游戏机/ 武汉理工大学硕士学位论文图4.1:Java线程模型4.1.2主动绘图一般编写Java的绘图程序都是在Component类的paint(Graphics曲方法中进 行,在动画线程中调用r印aintO方法,repaint方法只是往组件的事件队列中添加 了UPDATE的事件,当Java的AWT线程处理到这个事件时,会调用Component31游戏机/ 武汉理工大学硕士学位论文的updateO方法,在updateO方法中才会调用paint(Graphics g)方法。 由于我们采用了一个单独的动画线程,我们也可以主动绘图,主动绘图就是要通过Component类的getGr印hics0取得Graphics对象,然后将该对象传入 paint(Graphics g)方法中绘图,利用主动绘图一般可以提高绘图的效率。4.2消除屏幕闪烁在Java中,动画发生闪烁有两个原因:一个是由于在显示下一帧画面的时候, 调用了repaint0方法:而repaint0方法被调用时,要清除整个背景,然后才调用 paintO方法显示画面。这样,在清除背景和绘制图像的短暂时间间隔内被用户看 见的就是闪烁。另一个原因是由于paintO方法要进行复杂的计算,绘制每一帧花 费的时间太长,图像中的各个像素值不能同时得到,使得动画的生成频率低于显 示器的刷新频率,从而造成闪烁。有什么办法消除屏幕闪烁呢?4.2.1使用双缓冲技术双缓冲技术【43】是经典的消除屏幕闪烁的技术,由于显示屏上的一段屏幕区域 对应着显卡中的一段缓存,如果直接往缓存中写入我们的图像,而且写入的操作 比较耗时,屏幕上就会看到闪烁。用双缓冲技术,就是另外建立一个离]异(Offscreen) 的缓存,绘图时,先绘到离屏缓存中,然后将离屏缓存中的内容一次性复制到显 卡的缓存中,这样就可以有效地消除闪烁。 在JavaAWT/Swing中,在没有使用主动绘图的情况下,我们通过调用repaint0 函数来间接调用paint(Graphics g)函数,而paint(Graphics g)函数是由 update(Graphics g)函数来调用的。这样update(Oraphics g)函数就成为我们建立离屏缓存的理想场所,而paint(Graphics g)函数可以保持不变,见如下代码:private Image doubleBuffer;public voidupdate(Graphics g){size=getSize0;Dimensjonif(doubleBuffer==null』 武汉理工大学硕士学位论文doubleBuffer.getWidth(this)!=size.width IIdoubleBuffer.getHeight(this)I_size.height)doubleBuffer=createlmage(size.width,size.height);if(doubleBuffer!=null){//paint to double bufferGraphics酚=doubleBuffer.getGraphics0; paint(92); 92.dispose0;//copy double buffertoscreeng.drawlmage(doubleBuffer,0,0,null); }else{//couldnltcreate doublebuffer,just paint toscreenpaint(g);})4.2.2页交换技术(page fI-iPPing)双缓冲技术有效地解决了屏幕闪烁的问题,但它存在一个缺点,就是每次绘 图都需要将离屏缓存中的内容拷贝到屏幕缓存中,如果屏幕的分辨率是800*600, 颜色使用16位的话,一屏就需要800?600+2=938KB,差不多1M的数据,如果 程序中每秒画30帧图像的话,每秒种就要复制大约30M的图像数据!虽然这在 大多数情况下都没有问题,但我们肯定希望有更好的解决方案,这就是页交换技术143】。 武汉理工大学硕士学位论文使用页交换技术同样是有两个缓存,但不是将离屏缓存的数据拷贝到屏幕缓 存中,而是将屏幕缓存直接指向离屏缓存,原来的屏幕缓存变成离屏缓存,这样 就循环往复,就不需要不断地拷贝数据了。 使用页交换又引出另外一个问题,如果在显示器刷新的过程中我们交换了屏 幕缓存,那么就会导致用户看到的屏幕内容一部分来自于原来的屏幕缓存,一部 分来自于当前的屏幕缓存,从而导致屏幕撕裂的情况,为了防止这种情况,我们 必须在显示器更新的间隙交换缓存。幸运的是,Java图像库中已经提供了 BufferStrategy类来解决这个问题。 BufferStrategy类会根据系统环境自动选择最佳的方案来实现缓存,首先,会 尝试页交换,如果不行就使用双缓冲,当使用页交换时,它会等待显示器刷新完 毕才进行页交换。Canvas和Window子类的实例都能有一个BufferStrategy对象, 至少需要两个缓存,可以使用window.createBufferStrategy(2)来使用 BufferStrategy,以下代码通过BufferStrategy取得Graphics对象来绘图。BufferStrategy strategy Graphics g22frame.getBufferStrategy0;strategy.getDrawGraphics0;draw(酚; 昏dispose0; strategy.show0; 武汉理工大学硕士学位论文第五章祥例游戏开发一一俄罗斯方块网络版5。1游戏框架设计游戏框架应该简单、结构清晰、可扩展性好、高性能。示例程序中选择了基 于事件和组件1351的结构,影响性能的组件采用队列缓存事件用多线程处理,该框 架采用Spring框架管理组件,定义了一个功能比较强大的事件转发组件,采用Java NIO进行网络传输。典型的运算流程就是事件在各个组件中流动,见活动图(图5.1)。(㈨mw一一)【翱一e―一*“~№一t)/?:至兰夕∑/、/(晰~蜊cn~)V,(融州eV―sw伽r―一e”一 了(8一‰一Ⅲ一一)(一E脯一一一一)~ 、、、 (“单一t删、州) (一c~”一一)弋8一e一一一一)(s~com一耐一唰)1、上圈5-1:游戏框架事件处理活动图5.2通用类和接口GameEvent:代表游戏中的各种事件; EventHandler:服务器和客户端主要组件都需要实现此接口,只有一个方法35 武汉理工大学硕士学位论文voidhandleEvent(GameEvent event); EventQueue:GameEvent队列,其成员函数都是同步的,可用于多线程。 DefaultEventDispatcher:事件转发组件,根据事件中的组件名和方法名转发事件,支持拦截器。实现EventHandler接口,包含一个EventQueue使用多线程异 步转发事件。5.3服务端设计服务端结构见类图(图5.2),各个类的职责简要描述如下: GameServer:服务端主要类,包含几个缺省的组件,可扩展其他组件。 EventReceiver:服务端接收事件的组件。实现EventHandler接口,包含一个 EventQueue使用多线程接收事件。 EventSender:服务端发送事件的组件。实现EventHandler接口,包含一个 EventQueue使用多线程异步发送事件。 DefaultEventDispatcher:事件转发器,见5.2节。 PlayerRegister:服务端管理用户的组件,提供注册用户,防止重名用户,注 销用户,用户查询等功能。 ServerComponent:服务端组件,支持任意多的服务端组件,网络游戏控制功 能就是由客户端组件和服务端组件联合完成的,日前实现了Chatter和 TetrisGameServer两个组件。 GameConfig:服务端配置信息读取和存放。 Attachment:EventReeeiver类的辅助类。 武汉理工大学硕士学位论文Created州lh Poseidon for UML Commurzly Edmon,Not for Conl_nerclal Use.图5.2:游戏框架服务端类图5.3.1在游戏框架中使用AOP事件转发组件DefaultEventDispatcher类(见5.2节)负责转发接收到的事件, 这个类可以设置拦截器列表,拦截器可以是EvcntHandler接口的实例或者任意组 件的事件处理方法,拦截器会对游戏事件进行预处理,游戏框架中使用一个拦截 器检查用户是否已登录。如果没有登录,则要求用户先登录。配置文件片断见如下代码:<bean id=”eventDispatcher”class=”game.framework.dispatcher.DefaultEventDispatcher”><constructor-arg><value>l</value>c,/constructor-arg><property name=”intercepters“> <list> <bean id=”checkAndAddPlayerlfNecessary’’class=”game.framework.util.ObjectMethod”><propertyIlame---=”object”>37 武汉理工大学硕士学位论文<ref bean=”playerRegister’『/> </property> <property name--”eventProcessMethodName’’> <value>checkAndAddPlayerlfNecessary</value> </property></bearl> </list> </property> </beaD>这里使用的拦截器是playerRegister组件的checkAndAddPlayerlfNecessary事 件处理方法,这个拦截器的效果非常好,可以想象,如果不利用AOP的方法,而 是在每个事件处理方法里判断用户是否已登录,这么做很麻烦的,而且很容易在 某个方法中漏掉这个逻辑,从而导致系统漏洞。5.4客户端设计客户端结构见类图(图5.3),各个类的职责简要描述如下: GameClient:客户端主要类,包含几个缺省的组件,可扩展其他组件。 EventSender:用于向服务器发送事件,实现EventHandler接El,包含一个 EventQueue使用多线程异步发送事件。 NIOEventReader:用于从服务器接收事件,使用一个单独的线程接收事件。 DefaultEventDispatcher:事件转发器,见5.2节。 ClientComponent:客户端组件,支持任意多的客户端组件,网络游戏控制功 能就是由客户端组件和服务端组件联合完成的,目前实现了Chatter和 TetrisControl两个组件。 ClientConfig:用于获取和存储客户端设置。 GameScreen:客户端初始化屏幕,可配置多个屏幕。 Player:代表一个玩家 武汉理工大学硕士学位论文r)'eatedWth PoseidonforUMLCommu,'th'E庙aonNotforCommercialu筠.图5.3:游戏框架客户端类图5.5示例游戏设计示例游戏一一俄罗斯方块网络版是在单机游戏f42】的基础上完成的,作为客户 端和服务端组件集成到游戏框架中。示例游戏的类图见图5_4。其中TctrisControl 类实现ClientComponcnt接口,另外实现服务端组件TctrisGameServer, 武汉理工大学硕士学位论文(::TeatedmPoseidonforUMLCornmurltyEcrdoRNdforConzqlercia]Use图5―4:俄罗斯方块游戏类图5.5.1在示例程序中的应用MVC模式示例程序中使用了MVC模式分离模型和视图,并提供了一个可以在不同模 式下工作的控制器。在示例程序的类图(图5.4)中,TctrisGamcModcl类是模型, 也是程序的核心;GamcPancl类是视图,TetrisControl类是我们的控制器,由于界 面上可能要同时显示玩家和对手的游戏情况,所以TctrisControl类分别持有两个 模型和视图的实例。 当TetrisContr01只被配置一个TctrisGamcModcl模型并将模型设置为主动运 行状态(会初始化一个定时器),另外再配置一个GamePanel视图,这个控制器 可以用于运行单机版的游戏,如图5.5: 武汉理工大学硕士学位论文图5.5:单机模式截屏 如果给TetrisControl配置两个TctrisGamcModcl模型和视图,并将其中一个模型设置为主动运行状态,另一个配置为被动状态,并将主动运行状态的模型同步到被动模型中,如图5?5,可以看到同一个模型控制了两个相同的视图,这在 测试模型同步功能时是很有用的。4l 武汉理工大学硕士学位论文图5.5:模型同步模式截屏如果将两个TctrisGameModel模型都配置成被动模式,将左边的视图的请求转发给服务端组件,并让本地的模型跟服务端模型同步,就是网络版的游戏了, 如图5.6:图5.6:网络版模式截屏 武汉理工大学硕士学位论文M V C模式将模型、视图、控制器组件分离以提高灵活性和复用性,同样的模型、视图和控制器组件,经过简单的配置,就可以组合成差异很大的程序,这是应用MVC模式带来的好处。 武汉理工大学硕士学位论文第六章结束语本文对网络游戏开发中的网络协议、游戏程序设计、图像处理的问题进行了 研究,并在此基础上实现一个示例游戏。 网络游戏中常用的网络应用层协议包括对等用户协议、C/S结构、锁步协议、 事件锁定等,传输层一般使用TCP/UDP,网络协议的选择必须根据游戏类型来决定。游戏程序设计跟一般的程序设计是共通的,本文介绍了使用UML进行面向 对象的设计、使用IOC、AOP、MVC等设计模式和方法的内容,这些技术和方法 在进行一般程序设计时也是适用的。 现代游戏开发中肯定需要使用动画技术,本文介绍了Java游戏动画中需要使 用的Java线程模型及使用双缓冲和页交换消除屏幕闪烁的技术。现代大型的网络 游戏中大量使用了三维图像技术,OpenGL已经成为高性能三维图像处理的工业 标准,得到了大部分软硬件厂商的支持,Sun公司组织的开源项目JOGL[44l使Java 平台对OpenGL提供了很好的支持,由于时间和经验的限制,本文没有涉及三维 图像处理技术。 本文撰写过程中开发了一个示例网络游戏,根据示例游戏的特点,选择了C/S 结构的协议,使用TCP作为传输层;设计了一个简单的游戏框架,这个游戏框架 采用基于事件和组件的结构,示例游戏以客户端组件和服务端组件的形式集成到 游戏框架中,有较好的扩展性和可重用性。 网络游戏是综合性很强的行业,依赖的相关技术包括:游戏设计、程序设计、 数学、人工智能、图形图像处理、网络、音频处理等。由于时间和专业限制,有 些主题在本文中没有讨论。网络游戏作为一个新兴产业,具有很好的发展前景, 很多相关技术也在迅速发展中,这就需要游戏开发人员与时俱进,不断地学习和 发现新的技术和方法。 武汉理工大学硕士学位论文参考文献[1]中国新闻传播学评论(CJR),《电视“强势媒体”地位面临网络挑战》,http://cjr.zj01.com.cn/05cjr/system/2005/05/16/006112233.shtml[2]中国网络游戏产业调查报告活动组委会,《中国网络游戏发展史》, http:{}ⅧⅧjgnnic.net/gnnic/g_develop.php佟国平,[3]《电子竞技运动与网络游戏的区别》,III著,http://news.17173.com/content/2004―6―19/n814 730339.html[4]Richard Rouse尤晓东等译,《游戏设计一一原理与实践》,电子工业出版社2003.10[5] [6]博客中国,《网络游戏历史》,http://wWW.blogchina.com/new/source/122.htmlAndrewS.Tanenbaum.熊桂喜王小虎等译,李学农审,《计算机网络》第3版,清华大学出版社1998.7[7]赛迪网,《网络协议TcP/IP、IPx/SPX、NETBEUI简介》,http://veww.edu.cn/20010830/210056.shtml[8]Dante Treglia编,张磊译,《游戏编程精粹3》,人民邮电出版社2003.7 [9] [10] [11]Fowler M.K.Scott,UML Distilled。Addison-Wesley 1997Gigix,《统一建模语言Un概述》,http://wm uml.org.cn/oobject/20050329lI UML软件工程组织,《u儿模型的基本概念》,htmhttp://ww.uml.org.en/oobject/OObject.asp[12]Martin Fowler,Inversion of Control Containers and the Dependency Injectionpattern,http://w,阿.martinfowler.com/articles/injection.html[13]Todd Sundsted,JNDI overview.http://Ⅲ.javaworld.com/javaworld/jw-Ol一2000/jvr01一howto.html[14]Deepak Alur等,Core J2EE [15] [163Rod Patterns,Pearson,2003.6Johnson等,Spring Framework,http://)nnv.springframework.org/Rod Johnson,JuergenHoeller等著,Spring中文论坛译,(Spring Framework开发参考手册》,http://m.jactiongroup.net/reference/html/index.html [17]Paul Hammant等.Picocontainer,http://Ⅲ.picocontainer.org/[18]Harish Krishnaswamy等,HiveMind,http://jakarta.apache.org/hivemind/ [19]Ramnivas Laddad,1 wantmyAOPhttp:|}Ⅵn.javaworld.com/javaworld/jw-01―2002/jvr-0118一aspect.html[20]MikKersten,《AOP工具比较》, 继续苦读RUP,《程序员》2005年3月http:|{Ⅷ日.ibm.com/developerworks/cn/java/j-aopworkl/index.html[21][22]再访Ivar Jacobson:Eclipse Foundation,aspectj project,http://eclipse.org/aspectj/[23][24]Jonas Bondr等.AspectWerkz,http://aspectwerkz.codehaus.org/ JBoss Inc,JBoss AOP。http://www.jboss.org/products/aopRod[25]Johnson等,Spring AOP,http://,,m.springframework.org/docs/reference/aop.html 武汉理工大学硕士学位论文[26]Mary Campione,Kathy Walrath,A1isonHuml,and the Tutorial Team,The JavaTutorial,Addison―Wesley。Reading,MA,1999<http://java.SUN.com/docs/books/tutorial/>【27]Arnold,Ken,James Gosling,David Holmes。The JavaTMProgramming Language,Third Edition.Addison―Wesley,Boston,2000[2S]JavaTM2 Platform,Standard Edition,v 1.4 API Specification. Sun Microsystems.2003.2<http://java.sun.com/jZse/1.4.1/docs/api/index.html>[29][30]Chan,Patrick,Rosanna Lee,and DouglasKvamer.The JavaTMClass LibrariesSecond Edition.Addison―Welsley,Reading,^IA,1998Joshua Bloch,Effective Java Programming Language Guide,Addi son-Wesley,Reading,MA.2001[31]Cargill,Thomas.SpecificNotification offor JavaThread Synchronizatio n. Conference,1996Proceedings of the PatternLanguagesinaProgramming[32]Flanagan,David,JavaTMNu

我要回帖

更多关于 网络棋牌为什么总是输 的文章

 

随机推荐