欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    Java网络游戏框架框架实现.ppt

    • 资源ID:6510108       资源大小:903KB        全文页数:39页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Java网络游戏框架框架实现.ppt

    2006,1,Java高级程序设计专业教程理论讲解部分 Ver 3.1,2006,2,课程概述,网络游戏服务器架构的目标及策略 架构的设计剪子 包袱 捶服务器端的实现剪子 包袱 捶客户端的实现,重点,架构的设计,难点,架构的实现,学习目标,学习网络游戏架构掌握架构的设计及实现利用架构实现网络游戏,2006,3,1设计目标及策略,简易性:,可扩展性:,可测量性:,高性能:,核心类应该被设计的简易 合理.,一个服务器程序可以为多个种类游戏提供服务,服务器同时需要处理非常多的网络连接,必须要可测量.,服务器要实现最快的信息流通.一个较慢的事件处理不能影响其他的事件处理.,2006,4,为了实现以上目的,我们首先要做到以下几点:,将流通的消息压缩成GameEvents(游戏事件),将实现与逻辑分离开,将服务过程分离成各种的线性任务,将各种任务在线程池(thread pool)中备份以便实现并行操作,从任务中分离出事件(event)序列,提供一个可以在同一个服务器程序上实现多个游戏的逻辑框架,1 设计目标及策略,2006,5,2 设计,服务器与客户端的通讯流程如下图:,2006,6,在上图中可以看到,流程序列开始与客户端向服务器端的连接并且服务器处于监听状态.然后,客户端生成并发送一个事件(Event)到服务器.服务器接收到事件,分析并处理这个事件.这个事件通常会引起服务器发送一个或者多个事件到一个或者更多的客户端,客户端接收到这个事件并且处理.然后继续以上的循环.,就像你看到的,大多数的交互都是由客户端引发的,但是服务器也会产生一些不依赖客户端的事件.比如由时间触发的一些事件.,一些设计决策应该考虑到共享服务器的问题.首要的问题就是事件(Event)的设计,因为事件(Event)是服务器程序最重要的数据结构.其次就是要精细的研究哪些类与接口是必须要实现的在讨论处理事件序列之前.,2 设计,2006,7,3 GameEvents分析,客户端与服务器通讯都是通过事件实现的.决定事件的格式对于每一个独立的游戏来说是非常重要的而且要保证服务器架构的透明性,所以我们提供一个事件接口来实现各个阶段的交互.这样,我们就可以为每一个游戏制定各自不同的事件格式了.,现在有很多种不同的数据传输格式.这个选择高度的依赖与每个游戏在我们的游戏框架内主机的实现.多数普通级别 简单的ASCII文本(ASCII text)消息经常被用在聊天程序中.然而一个有实时级别命令的程序就需要更为复杂的结构.这里我们讨论一组可行的方案,你应该根据具体的游戏来设计一个更为适用的事件结构.,2006,8,选择各种事件结构的标准如下:,结构的大小,因为你要在网络上发送事件结构,所以结构的大小非常重要.一个宽带网络可以保证发送很大量的消息.一个三维的游戏通常要比一个二维游戏发送的数据量大.,可读性,保持事件的可读性有利于错误的查找,但是这会与第一个判断条件-结构的大小相冲突.一个折衷的办法就是使用短语(缩略语)以维持可读性.,运行效率,一个事件必须要从一个对象格式转换为可以在网络上发送的格式在网络上流通,然后还要转换回来.在这个过程中,要保持很高的效率并且不能过于复杂.,3 GameEvents分析,2006,9,分析代码的大小,出于对具体设备的考虑,客户端的程序代码不能过大(比如在移动设备上的客户端).所以不能设计过大的代码库来实现事件格式.,可扩展性,该格式应该可以实现多种的事件种类,下面我们来看看几个可行的方案,根据以上的标准分析一下.最后你要选择那种类型的方案对于数据的聚合 函数的制定 带宽的要求以及事件的分析处理都非常的重要.,3 GameEvents分析,2006,10,可行的方案:,java对象,使用java内置的功能使java对象转换为比特流(byte stream).这样做的好处:非常容易实现,结构的大小处理的速度表现都非常出色,只会带来非常小的附加代码因为功能是java内置的.它的缺点是几乎没有可读性.,XML,XML在各种各样的网络通讯及数据存储方面越加的流行起来.对于我们要讨论的事件格式来说,它有非常高的可读性以及对于多种多样的事件类型的可扩展性.然而,它的缺点远远掩盖了它的优点.当它连续的使用时,数据量实在太大了,并且要处理大量的头部信息.它要增加很多的附加代码在客户端上.,3 GameEvents分析,2006,11,可行的方案:,自定义二进制,这种方式主要是将事件直接写到一个字节序列(sequence of bytes)上,用尽可能少的字节来表达各种数据类型.,这种方式通常被用在对传输数据大小极为严格的场合.这种方式提供了最高效的传输数据利用率,并且非常容易输出到网络,分析的效率也非常的高效.不过它也同java对象一样,完全的失去了可读性.但是它是在对带宽要求非常苛刻的条件下唯一的选择.,3 GameEvents分析,2006,12,可行的方案:,二进制编码的XML,在带宽及存储资源允许的情况下,程序员们意识到利用冗长的XML是一件非常不错的事.但是在无线连接的情况下,问题变得比较尖锐.WAP Binary XML格式是W3C推荐针对这类问题的解决方式.,这是一个折衷的好办法,在传输的时候不具可读性,在反编译后又变为普通的XML.这种格式提供了高效的传输数据的利用率,但是无论编码还是解码都要加上头部信息.,3 GameEvents分析,2006,13,4 设计中的术语,GameName.一个游戏的名字.例如象棋 纸牌等.,Game.对于一个GameName的实现.,GameID.一个Game无重复的编码.,Player.一个连接到服务器的用户,他可以参加游戏当然也可以不参加游戏.,PlayerID.一个Player无重复的编码.,Session.一个用户从登陆到退出的过程.这个过程可以有一次或者多次的连接与断线.,SessionID.一个Session无重复的编码.,EventType.一组事件类型(event types)的一个,它决定了这个事件的目的.如:LOGIN CHAT_MSG 或者 MOVE.,2006,14,5 类的设计,服务器端类的关系图如下:,2006,15,客户端类的关系图如下:,5 类的设计,2006,16,5.1共有类与接口,在框架中,存在一些服务器端与客户端共有的类和接口,它们都被定义在 包中.,Attachment EventHandler EventQueue GameConfig GameEvent GameEventDefault Globals NIOUtils Player PlayerDefault,5 类的设计,2006,17,其中有些类和接口需要详细的了解它们的细节,下面我们来介绍一下.,GameEvent 接口,在我们的架构中,我们定义了一个事件接口并且给出一个默认的实现.如果有需要的话,每个游戏应该继承或者干脆替换掉这个默认的实现.GameEvent接口的定义参见源代码.,除了GameEvent以外,还需要有一个处理事件的接口EventListener.它只定义了一个方法,public void handleEvent(GameEvent event);,5.1共有类与接口,5 类的设计,2006,18,GameEventDefault,它是GameEvent的默认实现.它是直接按顺序将数据读写到ByteBuffer中的.,下面看看它的write(),public int write(ByteBuffer buff)int pos=buff.position();buff.putInt(eventType);NIOUtils.putStr(buff,playerId);NIOUtils.putStr(buff,sessionId);buff.putInt(gameId);NIOUtils.putStr(buff,gameName);buff.putInt(numRecipients);for(int i=0;i numRecipients;i+)NIOUtils.putStr(buff,recipientsi);NIOUtils.putStr(buff,message);return buff.position()-pos;,5.1共有类与接口,5 类的设计,2006,19,public void read(ByteBuffer buff)eventType=buff.getInt();playerId=NIOUtils.getStr(buff);sessionId=NIOUtils.getStr(buff);gameId=buff.getInt();gameName=NIOUtils.getStr(buff);numRecipients=buff.getInt();recipients=new StringnumRecipients;for(int i=0;i numRecipients;i+)recipientsi=NIOUtils.getStr(buff);message=NIOUtils.getStr(buff);,这是它的read(),5.1共有类与接口,5 类的设计,2006,20,传送事件协议(Over-the-Wire Event Protocol),在网络上传输的协议的头部信息应该尽量的小.我们定义如下格式:首先发送ClientID(),然后是GameName的哈希码,接着是正文的长度.这些每一部分都是4个字节的长度.最后是正文.,这里我们只讨论如何进行读写,关于如何发送接收我们将在SelectAndRead 和EventWriter 中进行介绍.,5.1共有类与接口,5 类的设计,2006,21,5.2 服务器的实现,服务器框架内只有很少的几个类,EventWriterGameControllerGameServerSelectAndRead,下面我们来浏览一下这些类并且讨论它们在架构中的作用.,5 类的设计,2006,22,GameServer,GameServer是服务器端的核心类,main()也在这个类中.它负责监听客户端的连接并且保持这些连接,实现对GameController的管理.,下面看看GameServer的两个函数的定义.,5.2 服务器的实现,5 类的设计,2006,23,private void initServerSocket()try sSockChan=ServerSocketChannel.open();sSockChan.configureBlocking(false);InetAddress addr=InetAddress.getLocalHost();sSockChan.socket().bind(new InetSocketAddress(addr,Globals.PORT);selector=Selector.open();SelectionKey acceptKey=sSockChan.register(selector,SelectionKey.OP_ACCEPT);catch(Exception e)log.error(error initializing ServerSocket,e);,5.2 服务器的实现,5 类的设计,2006,24,public void run()init();log.info(*GameServer running*);running=true;int numReady=0;while(running)try selector.select();Set readyKeys=selector.selectedKeys();Iterator i=readyKeys.iterator();while(i.hasNext()SelectionKey key=(SelectionKey)i.next();i.remove();,5.2 服务器的实现,5 类的设计,2006,25,ServerSocketChannel ssChannel=(ServerSocketChannel)key.channel();SocketChannel clientChannel=ssChannel.accept();selectAndRead.addNewClient(clientChannel);log.info(got connection from:+clientChannel.socket().getInetAddress();catch(IOException ioe)log.warn(error during serverSocket select():,ioe);catch(Exception e)log.error(exception in run(),e);,5.2 服务器的实现,5 类的设计,2006,26,6 网络服务器的实现,6.1 游戏描述,该游戏实现一个网络版的剪子 包袱 捶的游戏.任意多个玩家可以加入这个游戏.当他们连接并加入游戏后,两个玩家就可以玩任意多个回合的游戏.当两人完成游戏后,服务器给出游戏的结果.在游戏过程当中及游戏结束之后是可以进行聊天的.,6.2 类的设计,我们使用PlayerDefault 和 GameEventDefault 两个类,这样我们就不用再定义player及GameEvent了.在服务器端,我们需要一个GameController,定义RPSController 为GameController.另外我们还需要一个RPSGame 类,来保存游戏的数据.在客户端,建立一个GameClient的子类PSClient及RPSConsoleEventReader 来保持与服务器端的联系.,2006,27,6 网络服务器的实现,服务器端的结构如图:,6.2 类的设计,2006,28,6 网络服务器的实现,这个游戏非常简单,只需要处理很少的GameEvent并且增加少量的描述游戏逻辑的代码.RPSController用来追踪玩家及他们进行的游戏.在详细描述RPSController之前,我们先了解一下它在整个游戏框架中的作用.,发送到客户端的消息被存放到Controller的EventQueue中.然后被Wrap的run()函数检查到后调用RPSController的 processEvent()进行处理.,RPSController 调用其父类的 the sendEvent()or sendBroadcastEvent()将事件发送出去.这两个方法再使用GameServer.write()来把事件放入EventWriter 的EventQueue 中.,RPSController,6.2 类的设计,2006,29,RPSGame,RPSGame描述了剪子 包袱 捶在两个玩家在游戏的时候,并且要保存在每个回合中每个玩家选择的内容及两个玩家分别的游戏记录,输赢或者平手.,RPSClient,这个类只需要描述用户在控制台的输入并且处理来自服务器的事件.当然也会保存一点玩家及游戏的信息.,6.2 类的设计,6 网络服务器的实现,2006,30,public class RPSClient extends GameClient protected static Logger log=Logger.getLogger(RPSClient);protected RPSConsoleEventReader consoleReader;public static void main(String args)BasicConfigurator.configure();RPSClient gc=new RPSClient();gc.init(args);gc.start();public void init(String args)super.init(args);consoleReader=new RPSConsoleEventReader(this,inQueue,outQueue);consoleReader.start();,6.2 类的设计,6 网络服务器的实现,2006,31,protected void shutdown()consoleReader.shutdown();super.shutdown();protected void processIncomingEvents()GameEvent inEvent;while(inQueue.size()0)try inEvent=inQueue.deQueue();switch(inEvent.getType()case GameEventDefault.S_LOGIN_ACK_OK:break;case GameEventDefault.SB_LOGIN:stdOut(login:+inEvent.getMessage();break;,6.2 类的设计,6 网络服务器的实现,2006,32,case GameEventDefault.SB_LOGOUT:stdOut(logout:+inEvent.getMessage();break;case GameEventDefault.SB_CHAT_MSG:stdOut(inEvent.getPlayerId()+:+inEvent.getMessage();break;case GameEventDefault.S_DISCONNECT:stdErr(disconnected from server:+inEvent.getMessage();shutdown();break;case GameEventDefault.S_JOIN_GAME_ACK_OK:stdOut(inEvent.getMessage();inGame=true;break;,6.2 类的设计,6 网络服务器的实现,2006,33,case GameEventDefault.S_JOIN_GAME_ACK_FAIL:stdOut(inEvent.getMessage();inGame=false;break;case GameEventDefault.SB_PLAYER_QUIT:stdOut(inEvent.getMessage();inGame=false;break;default:stdOut(inEvent.getMessage();break;catch(InterruptedException ie),6.2 类的设计,6 网络服务器的实现,2006,34,public String getGameName()return RPS;public GameEvent createGameEvent()return new GameEventDefault();public GameEvent createLoginEvent()return new GameEventDefault(GameEventDefault.C_LOGIN);public GameEvent createDisconnectEvent(String reason)return new GameEventDefault(GameEventDefault.S_DISCONNECT,reason);,6.2 类的设计,6 网络服务器的实现,2006,35,RPSConsoleEventReader,RPSConsolEventReader是客户端通过标准输入设备读入用户消息的类.我们用BufferedReader 来进行行读取.然后生成相应的事件发送到EventQueue 中.,注意:在运行的时候注意,需要在运行命令后面添加两个参数,第一个描述服务器的地址,第二个是登陆用户的名称.,6.2 类的设计,6 网络服务器的实现,2006,36,本课小结,本课介绍了网络游戏框架的设计及实现,并且以石头剪刀布为例在该框架下实现一个简单的游戏。作为一个完整的Java项目,几乎包括了前面所有的知识。,2006,37,小测验,1.简述框架中服务器端类的构成、作用及相互关系。,2006,38,小测验答案,1.简述框架中服务器端类的构成、作用及相互关系。答:略,2006,39,课后作业,【作业1】试编写代码,利用该框架实现一个简单的游戏。,

    注意事项

    本文(Java网络游戏框架框架实现.ppt)为本站会员(牧羊曲112)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开