MonoTouch:通过GameKit发送/接收NSData
本文关键字:接收 NSData 发送 GameKit 通过 MonoTouch | 更新日期: 2023-09-27 18:32:40
我正在尝试在我的MonoTouch游戏中实现匹配。我已经成功地实现了通过GameKit连接玩家的系统,但我被困在发送和接收数据上。
如何将这个 objective-c 代码转换为 c#?我想发送的数据类型是具有X
和Y
浮点组件的Vector2
类。
NSError *error;
PositionPacket msg;
msg.messageKind = PositionMessage;
msg.x = currentPosition.x;
msg.y = currentPosition.y;
NSData *packet = [NSData dataWithBytes:&msg length:sizeof(PositionPacket)];
[match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error:&error];
if (error != nil)
{
// handle the error
}
任何帮助将不胜感激!
由于OpenTK.Vector2
是用[Serializable]
装饰的,常见的方法是将结构序列化为Stream
(例如MemoryStream
(,然后从中初始化一个新的NSData
,例如使用NSData.FromStream
。这样做有相当多的开销,但它适用于任何结构。
Stream
的更好用法是将您的值写入其中(例如,带有StreamWriter
(。这消除了序列化开销(反射(,并允许您从不同的值生成流(无需创建结构(。
MemoryStream ms = new MemoryStream ();
using (StreamWriter sw = new StreamWriter (ms)) {
sw.Write (v2.X);
sw.Write (v2.Y);
}
ms.Position = 0;
var data = NSData.FromStream (ms);
一种更复杂(但可能更快(的方法是使用接受IntPtr
(指针(和数据大小的unsafe
代码和NSData.FromBytes
。如果您的所有数据都已经在结构中,那么这很容易做到。
黑客方法是将Vector2
转换为monotouch.dll
中已知的类型,例如 PointF
.这将允许您使用 NSData.FromObject
.此 API 适用于NSObject
、最基本的值类型和NSValue
支持或monotouch.dll
内部添加的一些基本类型,例如 RectangleF
, PointF
, ...
var v2 = new OpenTK.Vector2 ();
var pt = new System.Drawing.PointF (v2.X, v2.Y);
var data = NSData.FromObject (pt);
好的,所以我想我在很大程度上都想通了。对于任何感兴趣的人,这是我的解决方案。
unsafe
{
NSError error = new NSError((NSString)"Test", 0);
System.IntPtr pointer = Marshal.AllocHGlobal(sizeof(PointF));
PointF packedData = new PointF(position.X, position.Y);
Marshal.StructureToPtr(packedData, pointer, false);
NSData packet = NSData.FromBytes(pointer, (uint)sizeof(PointF));
currentMatch.SendDataToAllPlayers(packet, GKMatchSendDataMode.Unreliable, error.ClassHandle);
Marshal.FreeHGlobal(pointer);
}
所以我仍然不确定NSError
应该是什么,尽管对于我的项目来说,失败的数据包并不重要。这是接收数据包的代码。
PointF packedData = (PointF)Marshal.PtrToStructure(data.Bytes, typeof(PointF));
var recievedData = new Vector2(packedData.X, packedData.Y);