2D网络游戏开发(网络篇)(八)2

#pragma pack(1)
struct C   // 结构 C 的类型和结构 A 的类型一样
{
 A a;
 B b;
}
#pragma pack(1)
struct D      // 结构 C 的类型和结构 A 的类型一样
{
B b;
A al
}
 
使用比特流来建立数据包
 
我们仍然使用上面的例子,但这次我们决定用比特流来重写他。我们有和前面相同的数据。
 
Unsigned char useTimeStamp; // 将这个分配给 ID_TIMESTAMP
Unsigned long timestamp;   // 把由 getTime() 返回的系统时间放在这里
Unsigned char typeId;      // 这里将把一个数据类型添加到 PacketEnumerations.h 文件中,这里我们设置的是 ID_SET_TIMED_MINE
UseTimeStamp=ID_TIMESTAMP;
TimeStamp=getTime();
TypeId=ID_SET_TIMED_MINE;
 
Bitstream myBitStream;
MyBitStream.Write(useTimeStamp);
MyBitStream.Write(timestamp);
MyBitStream.Write(typeId);
// 假设我们有一个定义为 Mine* mine 对象
myBitStream.Write(mine->GetPosition().x);
myBitStream.Write(mine->GetPosition().y);
myBitStream.Write(mine->GetPosition().z);
myBitStream.Write(mine->GetID());    // 在这个结构中,这是 ObjectId  对象 Id
myBitStream.Write(mine->GetOwner()); // 在这个结构中,这是 PlayerID, 玩家 Id
 
如果我们现在直接使用 RakClient::Send RakServer::Send 来发送我们的比特流将导致结构的混乱。现在让我们试着做一些改进。现在,假设我们玩家的坐标由于某种原因,在 0 0 0 ,处。那么前面的代码将修改成下面的形式:
 
unsigned char useTimeStamp;             // 分配这个到 ID_TIMESTAMP
unsigned long timestamp;                // 存储由函数 getTime() 返回的系统时间
unsigned char typeId;                   // 分配一个类型到 PacketEnumerations.h 中,我们这里设置的是 ID_SET_TIMED_MINE
useTimeStamp=ID_TIMESTAMP;
timestamp=getTime();
typeId=ID_SET_TIMED_MINE;
 
Bitstream myBitStream;
MyBitStream.Write(useTimeStamp);
MyBitStream.Write(timestamp);
MyBitStream.Write(typeId);
 
If(mine->GetPosition().x==0.0f && mine->GetPostion().y==0.0f && mine->GetPosition().z==0.0f)
{
 myBitStream.Write(true);
}
else
{
 myBitStream.Write(false);
 myBitStream.Write(mine->GetPosition().x);
 myBitStream.Write(mine->GetPosition().y);
 myBitStream.Write(mine->GetPositon().z);
}
myBitStream.Write(mine->GetID());     // 在这个结构中,这是物体
myBitStream.Write(mine->GetOwner());   // 在这个结构中,这是玩家
 
写字符流
 
通过重载 BitStream ,可以用数组来写字符流。一个方法是先写数据长度,然后再写数据,内容如下:
void WriteStringToBitStream(char *myString,BitStream *output)
{
 output->Write((unsigned short) strlen(myString));
 output->Write(myString,strlen(myString));
}
它们的编码是相同的,不管怎样,那不是很高效。 Raknet 有一个字符压缩类 StringCompressor 可以进行对字符串的压缩。如果我们想使用这个类来编码数据,可以写成下面的形式:
void WriteStringToBitStream(char *myString,BitStream *output)
{
 stringCompressor->EncodeString(myString,256,output);
}
 
你可以通过下面的形式将压缩的字符串解压出来。
 
Void WriteBitStreamToString(char *myString,BitStream *input)
{
 stringCompressor->DecodeString(myString,256,input);
}
 
在这里, 256 表示了最大的字节数。在编码过程中,如果你的字符串少于 256 个字节,那么将写那整个字符串。相反,如果你的字符串大于 256 个字节,那么就需要将它截断,然后在 256 个字节的数组中进行编码,当然包括终结符 null
 
关于更多内容请访问金桥科普网站( http://popul.jqcq.com   )游戏开发栏目,如你需要游戏开发方面的书籍请参考金桥书城游戏频道( http://book.jqcq.com/category/1_70_740.html )。 如果你在阅读本篇文章时有什么好的建议请来信给我,我的 E_mail: akinggw@126.com. 如果你在使用 SDL 时有什么问题,请到金桥科普网站( http://popul.jqcq.com   )游戏开发栏目,我将详细地为你解答。
 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
游戏 引 擎 是一个处理游戏底层技术的平台,使用游戏引擎,游戏开发人员可以不用 花过多精力去处理系统架构、图形处理等一些底层的技术,可以直接使用引擎提供的 API来进行游戏开发,从而大大缩短游戏开发时间。 本文 通 过 对网络通信和图形处理方面的研究,设计并实现了一个具备消息处理和客 户端动作交互功能的引擎。 本文 设 计 的引擎主要包括三个部分:消息处理系统、自动更新系统、图形处理与动 作交互系统。 消 息 处 理系统包含两部分:网络通信底层模块和服务器端消息处理模块。网络通信 底层模块通过对Socket的API函数进行封装和功能扩展,使得开发人员在构建通信模 型时更加方便。服务器端消息处理模块实现了对客户端发往服务器端的消息进行识别和 处理的功能。 自动 更 新 系统模块由三个子模块组成:文件版本管理模块、文件传输服务器模块和 接受文件模块。这是一个独立的引擎模块,实现了游戏客户端更新版本的整个过程。 图形 处 理 与动作交互系统。设计了游戏中从位图调入、场景显示、角色行走、地图 处理等一系列的API函数,并利用这些函数实现了一个简单的动作交互系统模型。 本 文 研 究的课题初步探讨了2D网络游戏引擎的基本技术架构,对于国内基于2D网络游戏系统开发具有一定的借鉴和参考价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值