RAKNET内核 - BitStream在游戏中的高级概念和使用例子

如果您还不知道RakNet如何发送一个数据包,请先阅读《RAKNET内核 - 数据包的感念》,本文讲基于该篇文章的例子做进一步的的补充,来阐述实际游戏使用BitStream数据流的方式。

官方参考资料:http://www.jenkinssoftware.com/raknet/manual/bitstreams.html



1. 什么是BitStream

BitStream就是字节流的意思,在网络传输中字节流的概念相当于开源节流,只发送应该发送的数据,不会像C++编程里面的内存占用情况。一些数据没必要发送整个结构体的建议使用下面的方式来节省网络流量。因为对于玩家或者其它app的终端用户来说,流量直接影响网速,游戏的响应速度是玩家体验的前提条件,连玩都玩不了就谈不上优化游戏和增加副本等玩法了。


我会使用一个小例子说明游戏服务器和玩家客户端之间如何处理一个Boss的即时坐标的,有时候Boss动了,有时候它根本没动,那么我没必要每次都传送该Boss的坐标吧。

虽然这个例子也是每次都传送Boss的即时状态,但是对于坐标没有改变时可不传。


2. 游戏服务端

if (kbhit())
{
    Gets(message,sizeof(message));
    puts(message); // 输出自己敲打的信息
    server->Send(message, (int) strlen(message)+1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);

    // 下面的代码是本例子新增的,当服务端输入stand的时候代表Boss没动,当输入move的时候Boss移动到Vector3(4,5,6)
    if (strcmp(message, "stand")==0)
    {
        RakNet::BitStream bs;
        bs.Write((RakNet::MessageID)ID_TIMESTAMP);
        bs.Write(RakNet::GetTime());
        bs.Write((unsigned char) 253);
        bs.Write(false);
        server->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
    }
    if (strcmp(message, "move")==0)
    {
        RakNet::BitStream bs;
        bs.Write((RakNet::MessageID)ID_TIMESTAMP);
        bs.Write(RakNet::GetTime());
        bs.Write((unsigned char) 253);
        bs.Write(true);
        bs.Write(4.0f);
        bs.Write(5.0f);
        bs.Write(6.0f);
        server->Send(&bs, HIGH_PRIORITY, RELIABLE, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true);
    }
}

3. 玩家客户端

case 253:
	printf("BitStream...");
	getFromBitStream(p);
	break;

Define Function getFromBitStream()

void getFromBitStream(RakNet::Packet* p) {
    RakNet::MessageID useTimeStamp;
    RakNet::Time timeStamp;
    unsigned char typeId;
    float x,y,z;
    bool isMovable;

    RakNet::BitStream bs(p->data, p->length, false);
    bs.Read(useTimeStamp);
    bs.Read(timeStamp);
    bs.Read(typeId);
    bs.Read(isMovable);

    if (isMovable)
    {
        bs.Read(x);
        bs.Read(y);
        bs.Read(z);
        printf("Boss的坐标移动至 {x: %f, y:%f, z:%f}\n", x, y, z);
    }
    else
    {
        printf("Boss没动\n");
    }
}

4. 运行效果



5. 总结

  1. BitStream可以很方便的逻辑层发送数据而无需经过定义需要发送的数据的格式。
  2. 实际游戏项目的需要判断的逻辑条件非常,您会发现本文介绍的例子多了一些判断条件,这样就可能影响游戏的运行性能和用户体验。

上面两条就是我们考虑使用Struct还是BitStream所需要考虑的问题,当我们传送的数据有固定的格式,建议使用Struct。当BitStream无固定格式的方式发送数据导致性能低下的时候应该马上改良,尽可能的使用Struct。


您可以修改并重新发布本文,如果您能留下本文的参考连结,万分谢谢!
如果您对本文存在疑问,欢迎留言或者直接对本文评论,我会在看到的第一时间回复您。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值