acejoy重新换机房花了一些时间,这一段时间无法登陆。现在终于搞好了。把春节前抽空写的一点东西补上来。
以前写过一些游戏的道具设计,沉淀了几年,一直没有时间回头整理,春节前几日,好多人都回家了,工作也不这么紧张了。于是抽时间写了一个道具功能。放在这里,供大家有兴趣玩赏。
这里是抛砖引玉,代码未必是最优的,但是提供大家一个思路。
本以为几日就能完成,毕竟还是小看它了,因为综合了自己以前的一些代码,发现自己当初的代码通用性以及扩展性都有欠缺。
道具系统有它自己的独立性,可以完全独立于其他系统。比如player,比如AI,比如寻路。(以后有时间我会一一写出相关文章,如果大家有兴趣的话)
想趁机写一个可以支持弹性扩展的。
于是拿了一张白纸,写下如下文字:
(1)实现道具字典的增删改查。
(2)实现道具的组合,分解。
(3)实现道具的任意属性扩展,也就是说,设计者可以随时添加自己想添加的道具属性,而不会影响已有道具的数据流。
(4)实现道具的交易
(5)实现道具的管理,生成监控。
(6)顺带实现一个可循环的邮件系统
(7)实现背包相关功能,存放,删除。以及道具相关执行。
(8)代码必须支持 Linux 和windows两种操作系统。
代码是在2014年春节前两周开始编写的,一直到春节前3天才真正写成。期间考虑了不少情况,导致一些之前的接口和结构不适应而返工。所以花费时间较长。
我会一点点的把这些设计点滴记录下来,给自己,也给想看它的朋友们,整个程序是可以运行的。我会在这个系列文章的最后,把完成可运行的代码程序贴进来供大家玩。
道具系统在整个游戏系统中是很重要的系统。无论MMO,还是页游手游,都需要它。
看上去很简单,但是当实际实现的时候,你会发现其中并不是那么好控制的,要想做到现实意义上的完美,那么需要大家踏下心来一点点的精雕细琢。
先看看,最终实现的界面吧。
有意思吧。
确实很有意思,呵呵(有点小成就感)
在开始了解它之前,我们必须知道,它需要注意什么。
因为前几年做过一些手游和MMO,所以,在这里,我第一考虑的是,道具的唯一性,这很重要,如果是单机游戏,完全可以不用考虑,但是网游中,如果你给别人留下复制的漏洞,你会死的很惨的。
首先,在我看来,先必须对道具总量进行控制。
总量怎么理解?
总量就是,如果把你的游戏想象成一个世界。我在这个世界构造的时候,我就会给这个游戏世界一个现实意义上的上限。(说白了就是道具对象池)
也就是说,无论这个世界上的道具是否被真正创造出来,我会给你一个上限。
比如,这个世界最多容纳1000件道具,无论这些道具是否被创造出来,我都会在程序启动的时候,把这1000件道具对象全部new出来。
你可能会问,你怎么可能知道未出现的道具是什么?你这样new出来是否有意义?
是的,我不知道,你也不知道,但是我能确定的是,这1000件道具的内存大小,这个很重要。
因为在整个道具系统运行过程中,我将不再new和delete任何东西,除了指针。
这样做,一是我可以完全控制我要创造的这个世界中的道具总数量,如果再多,那么道具创造的时候会就会返回失败。
二是我可以在BUG出现的时候,比如某些BUG大量道具生成的时候,有一个上限,让系统损失最小。
三是在游戏过程中,程序不会再有多余的new和delete操作。减少了内存碎片的可能性。
光控制道具总是往往在网游内是不够的,还有一项重要的工作要做。
那就是关键道具的追踪,有些稀有关键道具,要记录生成时间,销毁时间,甚至是转移时间,便于后期的运营追踪。
比如某个玩家被盗号了,物品要必须提供被追踪的途经。
如果对所有的物品都进行这样的追踪,在高并发的游戏 服务器 中,服务器是受不了的,你也不能为了一个血瓶的出现而煞费苦心。
但是所有的道具追踪,都现定于不可叠加的单一道具,因为,如果道具叠加了,这个道具的GUID就会消失。给追踪带来困难。
所以,在稀有道具中,对可叠加的物品,策划的时候就要专门考虑一下。
道具的限制,追踪是网游的基本功。这些事情一般的游戏服务器都是要干的。
好了,废话少说。先看看如果是我,我是怎么做的。
在动手前,我先罗列出了我需要对道具是用的一些基本材料,就像厨师一样,你要准备一些材料才能动手。
以上是我对我需要的道具的一般性兴义。
可能有些朋友问,你不是支持跨平台么,怎么还会有 #include <WinSock2.h>
这里我要解释一下,我用它并非是用socket部分,而是用里面的字符大小端转换。
为了兼容系统,我所有道具数值序列化以后,都会以网络字序存放,当解开的时候,都会以主机字序展示。
在多一句嘴,我为了保证数据的一致性,对enum做了一些限制。
enum ENUM_ITEM_ATTRIBUTE:uint8
这类代码必须在 C++ 0x下才能编译。
如果你不喜欢,直接把:后面的数据类型去掉就行了。
这里我定义了,我可能要用到的道具类型,当然,你可以扩展和删除,只要符合想要的条件就行。
另外,ENUM_ITEM_ATTRIBUTE是数组,你所有道具需要的属性都可以在这里定义。
这里要注意,这里的定义必须是连续的,因为,我需要用这个做数组的索引。
当你要扩展和删除你的属性的时候,必须修改 MAX_ITEM_ATTRIBUTE的属性数组总个数
#define MAX_ITEM_ATTRIBUTE 51 //对象属性个数最大大小
这个宏会被程序调用,当程序启动的时候,会生成于此相等的一个数组。
MAX_ITEM_ATTRIBUTE 的值必须和 ENUM_ITEM_ATTRIBUTE里面的数值一一对应才可以。
另外,由于我个人需要对64位长整形的字序转换,我自己实现了一个函数 htonll和ntohll
因为我的道具唯一ID是uint64位的。
好了,这样材料就差不多了。
下一讲,我将会讲怎么设计道具对象。
以前写过一些游戏的道具设计,沉淀了几年,一直没有时间回头整理,春节前几日,好多人都回家了,工作也不这么紧张了。于是抽时间写了一个道具功能。放在这里,供大家有兴趣玩赏。
这里是抛砖引玉,代码未必是最优的,但是提供大家一个思路。
本以为几日就能完成,毕竟还是小看它了,因为综合了自己以前的一些代码,发现自己当初的代码通用性以及扩展性都有欠缺。
道具系统有它自己的独立性,可以完全独立于其他系统。比如player,比如AI,比如寻路。(以后有时间我会一一写出相关文章,如果大家有兴趣的话)
想趁机写一个可以支持弹性扩展的。
于是拿了一张白纸,写下如下文字:
(1)实现道具字典的增删改查。
(2)实现道具的组合,分解。
(3)实现道具的任意属性扩展,也就是说,设计者可以随时添加自己想添加的道具属性,而不会影响已有道具的数据流。
(4)实现道具的交易
(5)实现道具的管理,生成监控。
(6)顺带实现一个可循环的邮件系统
(7)实现背包相关功能,存放,删除。以及道具相关执行。
(8)代码必须支持 Linux 和windows两种操作系统。
代码是在2014年春节前两周开始编写的,一直到春节前3天才真正写成。期间考虑了不少情况,导致一些之前的接口和结构不适应而返工。所以花费时间较长。
我会一点点的把这些设计点滴记录下来,给自己,也给想看它的朋友们,整个程序是可以运行的。我会在这个系列文章的最后,把完成可运行的代码程序贴进来供大家玩。
道具系统在整个游戏系统中是很重要的系统。无论MMO,还是页游手游,都需要它。
看上去很简单,但是当实际实现的时候,你会发现其中并不是那么好控制的,要想做到现实意义上的完美,那么需要大家踏下心来一点点的精雕细琢。
先看看,最终实现的界面吧。
有意思吧。
确实很有意思,呵呵(有点小成就感)
在开始了解它之前,我们必须知道,它需要注意什么。
因为前几年做过一些手游和MMO,所以,在这里,我第一考虑的是,道具的唯一性,这很重要,如果是单机游戏,完全可以不用考虑,但是网游中,如果你给别人留下复制的漏洞,你会死的很惨的。
首先,在我看来,先必须对道具总量进行控制。
总量怎么理解?
总量就是,如果把你的游戏想象成一个世界。我在这个世界构造的时候,我就会给这个游戏世界一个现实意义上的上限。(说白了就是道具对象池)
也就是说,无论这个世界上的道具是否被真正创造出来,我会给你一个上限。
比如,这个世界最多容纳1000件道具,无论这些道具是否被创造出来,我都会在程序启动的时候,把这1000件道具对象全部new出来。
你可能会问,你怎么可能知道未出现的道具是什么?你这样new出来是否有意义?
是的,我不知道,你也不知道,但是我能确定的是,这1000件道具的内存大小,这个很重要。
因为在整个道具系统运行过程中,我将不再new和delete任何东西,除了指针。
这样做,一是我可以完全控制我要创造的这个世界中的道具总数量,如果再多,那么道具创造的时候会就会返回失败。
二是我可以在BUG出现的时候,比如某些BUG大量道具生成的时候,有一个上限,让系统损失最小。
三是在游戏过程中,程序不会再有多余的new和delete操作。减少了内存碎片的可能性。
光控制道具总是往往在网游内是不够的,还有一项重要的工作要做。
那就是关键道具的追踪,有些稀有关键道具,要记录生成时间,销毁时间,甚至是转移时间,便于后期的运营追踪。
比如某个玩家被盗号了,物品要必须提供被追踪的途经。
如果对所有的物品都进行这样的追踪,在高并发的游戏 服务器 中,服务器是受不了的,你也不能为了一个血瓶的出现而煞费苦心。
但是所有的道具追踪,都现定于不可叠加的单一道具,因为,如果道具叠加了,这个道具的GUID就会消失。给追踪带来困难。
所以,在稀有道具中,对可叠加的物品,策划的时候就要专门考虑一下。
道具的限制,追踪是网游的基本功。这些事情一般的游戏服务器都是要干的。
好了,废话少说。先看看如果是我,我是怎么做的。
在动手前,我先罗列出了我需要对道具是用的一些基本材料,就像厨师一样,你要准备一些材料才能动手。
以上是我对我需要的道具的一般性兴义。
可能有些朋友问,你不是支持跨平台么,怎么还会有 #include <WinSock2.h>
这里我要解释一下,我用它并非是用socket部分,而是用里面的字符大小端转换。
为了兼容系统,我所有道具数值序列化以后,都会以网络字序存放,当解开的时候,都会以主机字序展示。
在多一句嘴,我为了保证数据的一致性,对enum做了一些限制。
enum ENUM_ITEM_ATTRIBUTE:uint8
这类代码必须在 C++ 0x下才能编译。
如果你不喜欢,直接把:后面的数据类型去掉就行了。
这里我定义了,我可能要用到的道具类型,当然,你可以扩展和删除,只要符合想要的条件就行。
另外,ENUM_ITEM_ATTRIBUTE是数组,你所有道具需要的属性都可以在这里定义。
这里要注意,这里的定义必须是连续的,因为,我需要用这个做数组的索引。
当你要扩展和删除你的属性的时候,必须修改 MAX_ITEM_ATTRIBUTE的属性数组总个数
#define MAX_ITEM_ATTRIBUTE 51 //对象属性个数最大大小
这个宏会被程序调用,当程序启动的时候,会生成于此相等的一个数组。
MAX_ITEM_ATTRIBUTE 的值必须和 ENUM_ITEM_ATTRIBUTE里面的数值一一对应才可以。
另外,由于我个人需要对64位长整形的字序转换,我自己实现了一个函数 htonll和ntohll
因为我的道具唯一ID是uint64位的。
好了,这样材料就差不多了。
下一讲,我将会讲怎么设计道具对象。