找回密码
 注册
查看: 2319|回复: 51

网络游戏::服务器端::设计::讨论

[复制链接]
发表于 2003-11-1 21:51:50 | 显示全部楼层 |阅读模式
在服务器端,每个人物(包括NPC和玩家人物)都是一个对象,这些人物都有各自的位置信息,包括两方面:所在场景,相对于该场景的坐标。使用八叉树来管理场景和人物和物品(也是对象)。从本质上说,NPC和玩家人物是一样的对象(不讨论人物能力和技能的差别,从编程的角度上说是一样的);真正的区别在于玩家人物是受玩家控制的,而NPC是受服务器控制的。每个人物对象和物品对象都有一个全局唯一的ID。
在服务器端,一个玩家人物对象的建立过程是这样的:
首先,玩家客户端会以某个身份发送连接请求给服务器,在身份确认后会为该客户端创建一个TCP连接(使用对象管理这个连接),此即为登录完毕,玩家使用某个人物进入场景时会发送相应的请求给服务器端,服务器端会从数据库中读取相应人物的数据并以其创建并初始化玩家人物对象,然后把玩家人物对象的地址保存到与该客户端相对应的连接对象中 {也就是说,有一个对象管理着一个 服务器和该客户端之间的连接,在这个对象中,有一个数据成员,类型是指针,指向该客户端控制的人物对象
(当然是保存在内存栈里的)。这样,当这个连接收到(客户端通过网络发来的)数据时,可以通过连接对象找到发送这个数据的玩家所控制的人物对象。}。在创建好玩家人物对象后,就将这个对象连入八叉树中,至此登入场景的工作就完成了。
八叉树中是这样的:
八叉树是一种数据结构,是树结构,每个节点对应了空间中的一个空间区域,一般是立方体形的空间区域。每个节点是一个数组,有8个数组元素。每个节点对应的空间区域还可以再划分成八个立方体空间,每个数组元素就是该节点对应空域的子空域,当然每个数组元素也可能只是指向一个空域对象,也可能就是一个空域对象。这样的递归的结构能够帮助进行:渲染时的裁剪(仅客户端)、碰撞检测、对象搜索等操作。
具体的一个空域对象是这样的:
它除了保存了自身空域的基本信息外,还有直接或间接地管理自身空域中的所有人物和物品的功能。
当客户端发出一条操作请求时,发出的数据包包含了这两种数据:
行为目标的ID;行为内容。
这两种数据的数目都是不定的。下面以一个ID和一个行为内容为例,说说服务器端对这个数据包的处理过程:
<还没思考成熟>
服务器端,与该客户端相对应的连接对象收到从网络上发来的一个数据包,解密、解压缩后,得到一个ID和一个行为内容(暂时不讨论这个行为内容的数据结构,在此仅以Message指代它),通过 连接对象 得到玩家人物对象的地址,然后把这个Message和ID加入到人物对象的行为队列中,另一个线程在处理这个人物对象时,从行为队列中取出一个Message和相应的ID,然后把根据ID,从人物对象所在空域对象开始搜索目标对象,如果当前空域中没有,那么就到相邻空域中去搜索,找到目标对象后,把这个Message发送给目标对象,保存在目标对象的 所受行为队列 中。除了  处理 一个对象向其他对象施与行为 的线程  ,还有一个线程,处理对象受到行为影响。这个线程处理上文那个目标对象时,从 所受行为队列 中取出一个Message,然后把这个Message和目标对象自身的地址(this指针中的数据)、施与行为的对象(就是上文那个玩家人物对象)的地址一起传送给Rule对象,使用Rule对象的成员函数进行合法性检测,如果可以按照Message执行,那么返回的就是未加修正的Message,如果进行修正后就可以执行,那么返回的是修正后的Message,如果即使进行修正也不能执行,那么返回的是一个表示什么都不做的Message,(这个检测过程使用的是这个线程自己运算资源,也就是说只是简单的函数调用,并不是把Message传给Rule模块),然后这个线程就会根据得到的Message整理出需要执行的函数的地址(使用函数指针保存)以及需要用的函数参数,然后使用参数执行这个函数,改变目标对象的属性(即数据成员),并把一些必要的信息广播给 目标对象附近的应该能“知道”这次行为的所有对象 ,(这里的广播只是让该线程把这个广播的工作交给网络模块而已,并不是使用该线程的资源来进行广播,而是让网络模块自己的线程资源来进行广播),这样一个行为就处理好了,然后把所受行为队列里的其他行为一一处理掉,再去处理其他的对象。
这些工作我还没思考成熟,比如“时间”这个概念在服务器端怎样体现?因为人物的行为都是有时间花费的,行为与行为之间也有时间间隔;所受到的行为也是有时间的先后的。
</还没思考成熟>
关于八叉树:
根据上文,需要几个线程来维护八叉树中的所有对象,但是如果一项工作只使用一个线程,那么这个线程可能就要维护非常多的对象(可能要维护八叉树中的所有对象),所以,可以考虑一项工作使用多个线程来完成,比如在一定层次上,每个空域对象都有自己的一个线程来维护该空域内的对象(按照空间划分),这样即使服务器处理信息的速度太慢,也是对大家都比较公平的;而一项工作的线程数也许也可以根据在线人数和这些人物的分布情况来进行调整(比如有的较小的空域中却有较多的对象,本来只是它的下面一层的子空域各自有自己的线程,而现在这个空域可以让它的子空域下的子空域,即第二层的子空域,也有各自的线程;而有的同样大小的空域里却只有很少的人,那么就可以让它的所有子空域一起使用同一个线程)。
关于网络模块的初步考虑:
玩家人物对象中也有指针指向和它对应的网络连接对象,这样如果要发送一个信息给这个人物所对应的客户端,就只要把信息发送到这个对象的一个队列中,然后由网络模块来取得这些信息,并通过对应的连接对象发送到客户端上。
一个客户端使用一个TCP连接,这样就不用自己考虑连接的安全性了(真得吗?),即使有上千个客户端同时在线,Linux也是可以创建这么多的连接的。

请大家参与讨论!
发表于 2003-11-3 01:43:09 | 显示全部楼层
大哥,不是泼你冷水,你的内容太泛了,没有一点针对性,有必要重新组织一下
回复

使用道具 举报

 楼主| 发表于 2003-11-3 13:17:59 | 显示全部楼层
这个。。。。。。是灵感嘛~~~
回复

使用道具 举报

发表于 2003-11-3 13:21:44 | 显示全部楼层
我有一个剧本,你要不要看一下,是我最喜欢的一部动画片《HUNTER X HUNTER》的内容
回复

使用道具 举报

 楼主| 发表于 2003-11-3 23:32:10 | 显示全部楼层
晕,现在是讨论游戏引擎的设计呀,还没到策划剧情那一步呢~~
回复

使用道具 举报

发表于 2003-11-4 03:33:25 | 显示全部楼层
对游戏编程我是没有什么兴趣啦,但我一直想做一个Linux下的文件管理器,一个可以充分定制的文件管理器
回复

使用道具 举报

 楼主| 发表于 2003-11-4 12:53:51 | 显示全部楼层
[quote:7bdfe4ced0="asanew"]对游戏编程我是没有什么兴趣啦,但我一直想做一个Linux下的文件管理器,一个可以充分定制的文件管理器[/quote]

你可以发个新贴子,说说你的想法,和大家讨论讨论~~
回复

使用道具 举报

发表于 2003-11-4 13:21:22 | 显示全部楼层
好玩嘛,说不定可以刺激你的灵感呢
回复

使用道具 举报

发表于 2003-11-4 20:54:12 | 显示全部楼层
我晕~
fishcrazy, 《HUNTER X HUNTER》是什呢啊?
回复

使用道具 举报

发表于 2003-11-4 21:04:56 | 显示全部楼层
关于网络模块的初步考虑:
玩家人物对象中也有指针指向和它对应的网络连接对象,这样如果要发送一个信息给这个人物所对应的客户端,就只要把信息发送到这个对象的一个队列中,然后由网络模块来取得这些信息,并通过对应的连接对象发送到客户端上。
一个客户端使用一个TCP连接,这样就不用自己考虑连接的安全性了(真得吗?),即使有上千个客户端同时在线,Linux也是可以创建这么多的连接的。

??我想网络模块不用考虑这些问题的,网络模块只要负责数据的网络传输就好了,当然也可以将加密集成进来,但是网络模块对服务端和客户端都是均等的,也就是说,它只是一个对用户来说透明的通道,给它数据它就会传输,并尽量做得安全高效。当然它会向其它模块提供一些界口函数,但仅此而已……
以上仅代表个人观点,仅供参考
回复

使用道具 举报

发表于 2003-11-4 22:22:24 | 显示全部楼层
《HUNTER X HUNTER》是一个动画片

在里面有一个类似网络RPG的游戏,系统很丰富
回复

使用道具 举报

 楼主| 发表于 2003-11-4 23:19:52 | 显示全部楼层
[quote:c381fe18c4="deaboway"]
关于网络模块的初步考虑:
玩家人物对象中也有指针指向和它对应的网络连接对象,这样如果要发送一个信息给这个人物所对应的客户端,就只要把信息发送到这个对象的一个队列中,然后由网络模块来取得这些信息,并通过对应的连接对象发送到客户端上。
一个客户端使用一个TCP连接,这样就不用自己考虑连接的安全性了(真得吗?),即使有上千个客户端同时在线,Linux也是可以创建这么多的连接的。

??我想网络模块不用考虑这些问题的,网络模块只要负责数据的网络传输就好了,当然也可以将加密集成进来,但是网络模块对服务端和客户端都是均等的,也就是说,它只是一个对用户来说透明的通道,给它数据它就会传输,并尽量做得安全高效。当然它会向其它模块提供一些界口函数,但仅此而已……
以上仅代表个人观点,仅供参考 [/quote]

之所以要把人物对象和连接联系起来,是因为,对于服务器端而言,当收到一个数据包时,需要判断这个数据包是哪个客户端发送的,这个客户端操纵的是哪个人物对象,把人物对象和连接联系起来,那么收到数据时,就可以知道这个操作请求是哪个人物的~不过不知道能不能用select()实现,因为要把网络连接的handle和人物对象的地址封装到一个对象中~
回复

使用道具 举报

发表于 2003-11-5 07:52:24 | 显示全部楼层
sjinny,这些功能应该是在建立了网络连接以后,数据库操作的内容了
回复

使用道具 举报

 楼主| 发表于 2003-11-5 13:12:12 | 显示全部楼层
晕~~~怎么和数据库联系起来了??
数据库的任务:
保存场景中 人物(包括NPC和玩家人物)及物品 的数据成员,恢复它们(即创建这些对象,把数据库中这些对象数据用一个对象作为载体放进游戏场景中)。
回复

使用道具 举报

发表于 2003-11-5 20:35:08 | 显示全部楼层
我的意思是网络连接的问题是不会出现人物这个概念的,不是吗?

它只需要认识数据包就行了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2025-2-9 03:12 , Processed in 0.031908 second(s), 15 queries .

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表