编辑:
我做了一个干净的新项目,但仍然无法正常工作。请下载它,这里有一些代码可供查看,对于专业人士或任何远程体验的人来说,查看我做错的地方可能很容易。只是尝试发送该整数。
http://www.2shared.com/file/fPOCLlg5/gkTest.html
你好
我试图在我的iPhone游戏中实现Game Center多人游戏,但无法理解我在Apple Docs中以及与第三方有关发送和接收数据的示例。
有人可以在这里解释Apple官方文档中的代码示例:
http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/MatchesandVoice/MatchesandVoice.html#//apple_ref/doc/uid/TP40008304-CH10-SW4
或帮助我弄清楚提供的示例代码。它是一个预先构建的类,用于处理所有游戏中心任务,并且从中发送和接收数据的示例如下:
- (void) sendPosition
{
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
}
}
并收到:
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
Packet *p = (Packet*)[data bytes];
if (p.messageKind == PositionMessage)
// handle a position message.
}
关于此代码的官方文档,我的最大问题是:
PositionPacket
/Packet
来自哪里?假设您要发送/接收数据时,可以这样称呼它们:
[self sendPosition];
或者
[self match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID];
我要输入什么作为比赛,数据和玩家ID?
例如。我有一个名为'score'的整数,但是我不需要使用任何特殊的键吗?
最佳答案
在此示例中,PositionPacket只是一个结构。然后,以下行将该结构放入一个NSData中,该NSData只是一个“字节存储桶”对象。
NSData *packet = [NSData dataWithBytes: &msg length: sizeof(PositionPacket)];
因此,如果您只想发送一个int分数,则可以使用如下所示的sendScore方法:
- (void) sendScore
{
NSError *error;
int myScore = self.score;
NSData *packet = [NSData dataWithBytes:&myScore length:sizeof(myScore)];
[match sendDataToAllPlayers: packet withDataMode: GKMatchSendDataUnreliable error: &error];
if (error != nil)
{
// handle the error
}
}
通常,您需要一个结构,以便提供一些其他信息,使接收者知道它是哪种数据。在示例中,这就是本行的目的:
msg.messageKind = PositionMessage;
通常,您可以发送要封装在NSData对象中的任何内容,因为它只是一个字节存储桶。您可以发送原始类型,例如ints或示例中的struct,甚至可以发送NSObjects(只要它们实现NSCoding即可)。您应该阅读NSKeyedArchiver,NSCoding和NSData以获得有关以这种方式发送和接收NSObject的更多信息。这是Apple在Archving上的引用文档。
至于接收,您无需调用该方法,它会被Kit调用。这就是所谓的“代理方法”(在 cocoa 术语中)或“回调方法”。您可以将其视为您的应用可以异步接收的“电话”。通过实现带有签名的方法:
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID;
...您说的是“我可以接到这种电话”。因此,当GameKit代表您从其他玩家那里接收数据时,它将看到您想要接收此类回调,然后调用该方法-然后由您根据接收到的内容来更新内部应用程序状态。
要继续这个示例,如果您发送了上面描述的简单的“只剩下一个整数”消息,则可以这样实现该方法:
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
int* receivedScorePtr = (int*)[data bytes];
int receivedScore = *receivedScorePtr;
[self updateScore: received forPlayer: playerID];
}
也就是说,当然,假设您有一个名为updateScore:forPlayer:的方法,该方法将更新分数表。
您可以在以下博客条目中找到有关委托(delegate)人和委托(delegate)人方法如何工作的更一般性的讨论/解释:http://mohrt.blogspot.com/2010/01/cocoa-and-delegates.html
已添加:我使用问询者发布的代码,进行了一些修改,并生成了一个适用于该基本用例的版本。 Working Version of Test App To Send One Integer Through GameCenter我对代码的质量或其对任何事物的适用性不做任何声明。我没有写它的99.9%-请不要把我在这里发表的内容作为对其中出现的任何内容的认可。
吸取的教训(我不知道,因此希望在这里对其他人有所帮助)是您不能在模拟器中使用Matchmaking服务。这意味着您需要两个开发配置的iOS设备才能测试这种情况,对于非平凡的程序,可能需要两个开发机来同时调试两个设备。在解决这个问题时,这个问题花费了我最多的时间。
关于iphone - 游戏中心-发送和接收数据,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4574119/