【问题标题】:Game Center - Sending and receiving dataGame Center - 发送和接收数据
【发布时间】:2011-01-01 12:58:56
【问题描述】:

编辑: 我做了一个干净的新项目,但仍然无法正常工作。请下载它,有一些代码可供查看,并且可能很容易让专业人士或任何远程体验的人看到我做错了什么。只是想发送那个整数。

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' 的 int,但没有我需要使用的特殊键吗?

【问题讨论】:

    标签: iphone objective-c multiplayer game-center


    【解决方案1】:

    在本例中,PositionPacket 只是一个结构。下面的行然后将该结构放入一个 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 对象中的东西,因为它只是一个字节桶。您可以发送原始类型,如 int 或示例中的结构,甚至 NSObject(只要它们实现 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: 的方法会更新分数表。

    您可以在此博客条目中找到有关委托和委托方法如何工作的更一般性的讨论/解释:http://mohrt.blogspot.com/2010/01/cocoa-and-delegates.html

    添加:使用提问者发布的代码,我进行了一些修改并制作了一个适用于这个简单用例的版本。 Working Version of Test App To Send One Integer Through GameCenter 我对代码的质量或它对任何东西的适用性不做任何声明。 99.9% 的内容不是我写的——请不要把我在这里发帖作为对其中任何内容的认可。

    吸取的一个教训(我不知道,所以我放在这里希望它可以帮助其他人)是您不能将匹配服务与模拟器一起使用。这意味着您需要两台开发配置的 iOS 设备来测试此场景,并且对于非平凡的程序,可能需要两台开发机器同时调试这两个设备。在解决这个问题时,这个问题花费了我最多的时间。

    【讨论】:

    • 这太好了,非常感谢!更有意义,尽管至于 match 这只是我可以声明的新 GKMatch 还是需要来自特定地方?
    • 在这种方法的情况下,匹配被传递给你。我怀疑在简单的情况下(即一次只进行一场比赛)你不需要担心它/在这些方法中对它做任何事情。如果您正在寻找有关比赛的更多信息,它们来自配对服务。详情在这里:developer.apple.com/library/ios/documentation/…
    • 今晚我会在“真正的”工作之后尝试一下。 :)
    • 我已经编辑了我的答案,以包含一个对我有用的项目版本。代码的主要问题是:1)获取匹配时,您还需要设置myMatch.delegate = self; 2)您需要在sharedMatchmaker 中添加inviteHandler——参见[bit.ly/fBsfOS]。我在 viewDidLoad 中添加了它(可能是错误的地方,但是......) 3) 养成将指针初始化为 nil 的习惯,例如:NSError *error = nil; 垃圾值导致 sendScore 认为没有错误时出现错误。在这些更改之后,它对我有用。如果您遇到问题,请告诉我。
    • 我也在尝试通过游戏中心发送玩家的位置。但无法通过 cocos2d-x 从 gamecenter 发送数据
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多