关闭

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

标签: 网络游戏网络output游戏structinput
1475人阅读 评论(0) 收藏 举报
#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::SendRakServer::Send来发送我们的比特流将导致结构的混乱。现在让我们试着做一些改进。现在,假设我们玩家的坐标由于某种原因,在000,处。那么前面的代码将修改成下面的形式:
 
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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:43225次
    • 积分:655
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:0篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论