#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
)游戏开发栏目,我将详细地为你解答。